[ONOS-6593]Review and Refactor ONOS startup procedures in TestON

Change-Id: I509a8ee7a26c198957bebf59da5c85a0edb8b995
diff --git a/TestON/tests/CHO/CHOtest/CHOtest.params b/TestON/tests/CHO/CHOtest/CHOtest.params
index 9cf0709..3f3683d 100644
--- a/TestON/tests/CHO/CHOtest/CHOtest.params
+++ b/TestON/tests/CHO/CHOtest/CHOtest.params
@@ -22,13 +22,13 @@
     </testcases>
 
     <DEPENDENCY>
-        <path>/tests/CHOtest/dependencies/</path>
+        <path>/tests/CHO/CHOtest/dependencies/</path>
         <wrapper>CHOtestFunctions</wrapper>
     </DEPENDENCY>
 
     <GIT>
-        #autoPull 'on' or 'off'
-        <autoPull>off</autoPull>
+        #autoPull 'True' or 'False'
+        <pull>False</pull>
         <branch>master</branch>
     </GIT>
 
diff --git a/TestON/tests/CHO/CHOtest/CHOtest.py b/TestON/tests/CHO/CHOtest/CHOtest.py
index 60bbfb1..847e543 100644
--- a/TestON/tests/CHO/CHOtest/CHOtest.py
+++ b/TestON/tests/CHO/CHOtest/CHOtest.py
@@ -27,160 +27,59 @@
         import imp
 
         global intentState
-        main.threadID = 0
-        main.testOnDirectory = re.sub( "(/tests)$", "", main.testDir )
-        main.dependencyPath = main.testOnDirectory + \
-                              main.params[ 'DEPENDENCY' ][ 'path' ]
-        wrapperFile = main.params[ 'DEPENDENCY' ][ 'wrapper' ]
-        main.numCtrls = main.params[ 'CTRL' ][ 'numCtrl' ]
-        git_pull = main.params[ 'GIT' ][ 'autoPull' ]
-        git_branch = main.params[ 'GIT' ][ 'branch' ]
-        karafTimeout = main.params[ 'CTRL' ][ 'karafCliTimeout' ]
-        main.linkSleep = int( main.params[ 'timers' ][ 'LinkDiscovery' ] )
-        main.checkIntentsDelay = int( main.params[ 'timers' ][ 'CheckIntentDelay' ] )
-        main.pingSleep = int( main.params[ 'timers' ][ 'pingSleep' ] )
-        main.topoCheckDelay = int( main.params[ 'timers' ][ 'topoCheckDelay' ] )
-        main.pingTimeoutSmallTopo = int( main.params[ 'timers' ][ 'pingTimeoutSmallTopo' ] )
-        main.pingTimeoutLargeTopo = int( main.params[ 'timers' ][ 'pingTimeoutLargeTopo' ] )
-        main.remHostDelay = int( main.params[ 'timers' ][ 'remHostDelay' ] )
-        main.remDevDelay = int( main.params[ 'timers' ][ 'remDevDelay' ] )
-        main.failSwitch = main.params[ 'TEST' ][ 'pauseTest' ]
-        main.emailOnStop = main.params[ 'TEST' ][ 'email' ]
-        main.intentCheck = int( main.params[ 'TEST' ][ 'intentChecks' ] )
-        main.linkCheck = int( main.params[ 'TEST' ][ 'linkChecks' ] )
-        main.topoCheck = int( main.params[ 'TEST' ][ 'topoChecks' ] )
-        main.numPings = int( main.params[ 'TEST' ][ 'numPings' ] )
-        main.newTopo = ""
-        main.CLIs = []
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found exiting the test" )
+            main.exit()
+        main.testSetUp.envSetupDescription()
 
-        main.failSwitch = True if main.failSwitch == "on" else False
-        main.emailOnStop = True if main.emailOnStop == "on" else False
+        try:
+            time1 = time.time()
+            main.dependencyPath = main.testOnDirectory + \
+                                  main.params[ 'DEPENDENCY' ][ 'path' ]
+            wrapperFile = main.params[ 'DEPENDENCY' ][ 'wrapper' ]
+            main.numCtrls = int ( main.params[ 'CTRL' ][ 'numCtrl' ] )
+            main.maxNodes = main.numCtrls
+            karafTimeout = main.params[ 'CTRL' ][ 'karafCliTimeout' ]
+            main.linkSleep = int( main.params[ 'timers' ][ 'LinkDiscovery' ] )
+            main.checkIntentsDelay = int( main.params[ 'timers' ][ 'CheckIntentDelay' ] )
+            main.pingSleep = int( main.params[ 'timers' ][ 'pingSleep' ] )
+            main.topoCheckDelay = int( main.params[ 'timers' ][ 'topoCheckDelay' ] )
+            main.pingTimeoutSmallTopo = int( main.params[ 'timers' ][ 'pingTimeoutSmallTopo' ] )
+            main.pingTimeoutLargeTopo = int( main.params[ 'timers' ][ 'pingTimeoutLargeTopo' ] )
+            main.remHostDelay = int( main.params[ 'timers' ][ 'remHostDelay' ] )
+            main.remDevDelay = int( main.params[ 'timers' ][ 'remDevDelay' ] )
+            main.failSwitch = main.params[ 'TEST' ][ 'pauseTest' ]
+            main.emailOnStop = main.params[ 'TEST' ][ 'email' ]
+            main.intentCheck = int( main.params[ 'TEST' ][ 'intentChecks' ] )
+            main.linkCheck = int( main.params[ 'TEST' ][ 'linkChecks' ] )
+            main.topoCheck = int( main.params[ 'TEST' ][ 'topoChecks' ] )
+            main.numPings = int( main.params[ 'TEST' ][ 'numPings' ] )
+            main.newTopo = ""
 
-        for i in range( 1, int( main.numCtrls ) + 1 ):
-            main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
+            main.failSwitch = True if main.failSwitch == "on" else False
+            main.emailOnStop = True if main.emailOnStop == "on" else False
 
-        main.CHOtestFunctions = imp.load_source( wrapperFile,
-                                                 main.dependencyPath +
-                                                 wrapperFile +
-                                                 ".py" )
+            main.CHOtestFunctions = imp.load_source( wrapperFile,
+                                                     main.dependencyPath +
+                                                     wrapperFile +
+                                                     ".py" )
 
-        main.case( "Set up test environment" )
-        main.log.report( "Set up test environment" )
-        main.log.report( "_______________________" )
+            stepResult = main.testSetUp.envSetup()
+        except Exception as e:
+            main.testSetUp.envSetupException( e )
 
-        main.step( "Apply Cell environment for ONOS" )
-        if ( main.onoscell ):
-            cellName = main.onoscell
-            cell_result = main.ONOSbench.setCell( cellName )
-            utilities.assert_equals( expect=main.TRUE, actual=cell_result,
-                                     onpass="Test step PASS",
-                                     onfail="Test step FAIL" )
-        else:
-            main.log.error( "Please provide onoscell option at TestON CLI to run CHO tests" )
-            main.log.error( "Example: ~/TestON/bin/cli.py run OnosCHO onoscell <cellName>" )
+        main.testSetUp.evnSetupConclusion( stepResult )
+
+        if not main.onoscell :
+            main.log.error("Please provide onoscell option at TestON CLI to run CHO tests")
+            main.log.error("Example: ~/TestON/bin/cli.py run CHOtest onoscell <cellName>")
             main.cleanup()
             main.exit()
 
-        main.step( "Git checkout and pull " + git_branch )
-        if git_pull == 'on':
-            checkout_result = main.ONOSbench.gitCheckout( git_branch )
-            pull_result = main.ONOSbench.gitPull()
-            cp_result = ( checkout_result and pull_result )
-        else:
-            checkout_result = main.TRUE
-            pull_result = main.TRUE
-            main.log.info( "Skipped git checkout and pull" )
-            cp_result = ( checkout_result and pull_result )
-        utilities.assert_equals( expect=main.TRUE, actual=cp_result,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        main.ONOSbench.getVersion( report=True )
-
-        main.step( "Create ONOS package" )
-        packageResult = main.ONOSbench.buckBuild()
-        utilities.assert_equals( expect=main.TRUE, actual=packageResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        main.step( "Uninstall ONOS package on all Nodes" )
-        uninstallResult = main.TRUE
-        for i in range( int( main.numCtrls ) ):
-            main.log.info( "Uninstalling package on ONOS Node IP: " + main.onosIPs[ i ] )
-            u_result = main.ONOSbench.onosUninstall( main.onosIPs[ i ] )
-            utilities.assert_equals( expect=main.TRUE, actual=u_result,
-                                     onpass="Test step PASS",
-                                     onfail="Test step FAIL" )
-            uninstallResult = ( uninstallResult and u_result )
-
-        main.step( "Install ONOS package on all Nodes" )
-        installResult = main.TRUE
-        for i in range( int( main.numCtrls ) ):
-            main.log.info( "Installing package on ONOS Node IP: " + main.onosIPs[ i ] )
-            i_result = main.ONOSbench.onosInstall( node=main.onosIPs[ i ] )
-            utilities.assert_equals( expect=main.TRUE, actual=i_result,
-                                     onpass="Test step PASS",
-                                     onfail="Test step FAIL" )
-            installResult = ( installResult and i_result )
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.TRUE
-        for i in range( int( main.numCtrls ) ):
-            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=main.ONOSip[ i ] )
-        utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        time.sleep( 5 )
-        main.step( "Starting ONOS service" )
-        stopResult = main.TRUE
-        startResult = main.TRUE
-        onosIsUp = main.TRUE
-        for i in range( main.numCtrls ):
-            onosIsUp = onosIsUp and main.ONOSbench.isup( main.ONOSip[ i ] )
-        if onosIsUp == main.TRUE:
-            main.log.report( "ONOS instance is up and ready" )
-        else:
-            main.log.report( "ONOS instance may not be up, stop and " +
-                             "start ONOS again " )
-            for i in range( main.numCtrls ):
-                stopResult = stopResult and \
-                        main.ONOSbench.onosStop( main.ONOSip[ i ] )
-            for i in range( main.numCtrls ):
-                startResult = startResult and \
-                        main.ONOSbench.onosStart( main.ONOSip[ i ] )
-        stepResult = onosIsUp and stopResult and startResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="ONOS service is ready",
-                                 onfail="ONOS service did not start properly" )
-
-        main.step( "Start ONOS CLI on all nodes" )
-        cliResult = main.TRUE
-        main.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.onosIPs[ i ], karafTimeout ] )
-            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
+        setupResult = main.testSetUp.ONOSSetUp( Mininet=main.Mininet1, newCell=False, cellName=main.onoscell )
 
         main.step( "Set IPv6 cfg parameters for Neighbor Discovery" )
         time.sleep( 30 )
@@ -191,8 +90,8 @@
                                  onpass="ipv6NeighborDiscovery cfg is set to true",
                                  onfail="Failed to cfg set ipv6NeighborDiscovery" )
 
-        case1Result = installResult and uninstallResult and statusResult and startCliResult and cfgResult
-        main.log.info( "Time for connecting to CLI: %2f seconds" % ( time2 - time1 ) )
+        case1Result = setupResult and cfgResult
+        main.log.info( "Time for connecting to CLI: %2f seconds" % ( time.time() - time1 ) )
         utilities.assert_equals( expect=main.TRUE, actual=case1Result,
                                  onpass="Set up test environment PASS",
                                  onfail="Set up test environment FAIL" )
@@ -221,7 +120,7 @@
         main.step( "Start Mininet with Att topology" )
         main.newTopo = main.params[ 'TOPO1' ][ 'topo' ]
         mininetDir = main.Mininet1.home + "/custom/"
-        topoPath = main.testDir + "/" + main.TEST + "/dependencies/" + main.newTopo
+        topoPath = main.dependencyPath + main.newTopo
         main.ONOSbench.secureCopy( main.Mininet1.user_name, main.Mininet1.ip_address, topoPath, mininetDir, direction="to" )
         topoPath = mininetDir + main.newTopo
         startStatus = main.Mininet1.startNet( topoFile=topoPath )
@@ -230,13 +129,13 @@
         for i in range( 1, ( main.numMNswitches + 1 ) ):  # 1 to ( num of switches +1 )
             main.Mininet1.assignSwController(
                 sw="s" + str( i ),
-                ip=main.onosIPs )
+                ip=main.ONOSip )
 
         switch_mastership = main.TRUE
         for i in range( 1, ( main.numMNswitches + 1 ) ):
             response = main.Mininet1.getSwController( "s" + str( i ) )
             print( "Response is " + str( response ) )
-            if re.search( "tcp:" + main.onosIPs[ 0 ], response ):
+            if re.search( "tcp:" + main.ONOSip[ 0 ], response ):
                 switch_mastership = switch_mastership and main.TRUE
             else:
                 switch_mastership = main.FALSE
@@ -286,7 +185,7 @@
 
         main.step( "Start Mininet with Chordal topology" )
         mininetDir = main.Mininet1.home + "/custom/"
-        topoPath = main.testDir + "/" + main.TEST + "/dependencies/" + main.newTopo
+        topoPath = main.dependencyPath + main.newTopo
         main.ONOSbench.secureCopy( main.Mininet1.user_name, main.Mininet1.ip_address, topoPath, mininetDir, direction="to" )
         topoPath = mininetDir + main.newTopo
         startStatus = main.Mininet1.startNet( topoFile=topoPath )
@@ -296,13 +195,13 @@
         for i in range( 1, ( main.numMNswitches + 1 ) ):  # 1 to ( num of switches +1 )
             main.Mininet1.assignSwController(
                 sw="s" + str( i ),
-                ip=main.onosIPs )
+                ip=main.ONOSip )
 
         switch_mastership = main.TRUE
         for i in range( 1, ( main.numMNswitches + 1 ) ):
             response = main.Mininet1.getSwController( "s" + str( i ) )
             print( "Response is " + str( response ) )
-            if re.search( "tcp:" + main.onosIPs[ 0 ], response ):
+            if re.search( "tcp:" + main.ONOSip[ 0 ], response ):
                 switch_mastership = switch_mastership and main.TRUE
             else:
                 switch_mastership = main.FALSE
@@ -348,7 +247,7 @@
 
         main.step( "Start Mininet with Spine topology" )
         mininetDir = main.Mininet1.home + "/custom/"
-        topoPath = main.testDir + "/" + main.TEST + "/dependencies/" + main.newTopo
+        topoPath = main.dependencyPath + main.newTopo
         main.ONOSbench.secureCopy( main.Mininet1.user_name, main.Mininet1.ip_address, topoPath, mininetDir, direction="to" )
         topoPath = mininetDir + main.newTopo
         startStatus = main.Mininet1.startNet( topoFile=topoPath )
@@ -356,13 +255,13 @@
         for i in range( 1, ( main.numMNswitches + 1 ) ):  # 1 to ( num of switches +1 )
             main.Mininet1.assignSwController(
                 sw="s" + str( i ),
-                ip=main.onosIPs )
+                ip=main.ONOSip )
 
         switch_mastership = main.TRUE
         for i in range( 1, ( main.numMNswitches + 1 ) ):
             response = main.Mininet1.getSwController( "s" + str( i ) )
             print( "Response is " + str( response ) )
-            if re.search( "tcp:" + main.onosIPs[ 0 ], response ):
+            if re.search( "tcp:" + main.ONOSip[ 0 ], response ):
                 switch_mastership = switch_mastership and main.TRUE
             else:
                 switch_mastership = main.FALSE
@@ -374,7 +273,7 @@
         time.sleep( 5 )
 
         main.step( "Balance devices across controllers" )
-        for i in range( int( main.numCtrls ) ):
+        for i in range( main.numCtrls ):
             balanceResult = main.ONOScli1.balanceMasters()
             # giving some breathing time for ONOS to complete re-balance
             time.sleep( 3 )
@@ -442,7 +341,7 @@
 
                 main.step( "Collect and store each Device ports enabled Count" )
                 time1 = time.time()
-                for i in xrange( 1, ( main.numMNswitches + 1 ), int( main.numCtrls ) ):
+                for i in xrange( 1, ( main.numMNswitches + 1 ), main.numCtrls ):
                     pool = []
                     for cli in main.CLIs:
                         if i >= main.numMNswitches + 1:
@@ -464,7 +363,7 @@
                 main.step( "Collect and store each Device active links Count" )
                 time1 = time.time()
 
-                for i in xrange( 1, ( main.numMNswitches + 1 ), int( main.numCtrls ) ):
+                for i in xrange( 1, ( main.numMNswitches + 1 ), main.numCtrls ):
                     pool = []
                     for cli in main.CLIs:
                         if i >= main.numMNswitches + 1:
@@ -507,14 +406,20 @@
     def CASE200( self, main ):
 
         import time
+        try:
+            from tests.dependencies.utils import Utils
+        except ImportError:
+            main.log.error( "Utils not found. exiting the test" )
+            main.exit()
+        try:
+            main.Utils
+        except ( NameError, AttributeError ):
+            main.Utils = Utils()
+
         main.log.report( "Clean up ONOS" )
         main.case( "Stop topology and remove hosts and devices" )
 
-        main.step( "Stop Topology" )
-        stopStatus = main.Mininet1.stopNet()
-        utilities.assert_equals( expect=main.TRUE, actual=stopStatus,
-                                 onpass="Stopped mininet",
-                                 onfail="Failed to stop mininet" )
+        main.Utils.mininetCleanup( False )
 
         main.log.info( "Constructing host id list" )
         hosts = []
@@ -1232,7 +1137,7 @@
 
         for check in range( main.topoCheck ):
             time1 = time.time()
-            for i in xrange( 1, ( main.numMNswitches + 1 ), int( main.numCtrls ) ):
+            for i in xrange( 1, ( main.numMNswitches + 1 ), main.numCtrls ):
                 pool = []
                 for cli in main.CLIs:
                     if i >= main.numMNswitches + 1:
@@ -1270,7 +1175,7 @@
 
             main.step( "Compare Device active links with reference" )
             time1 = time.time()
-            for i in xrange( 1, ( main.numMNswitches + 1 ), int( main.numCtrls ) ):
+            for i in xrange( 1, ( main.numMNswitches + 1 ), main.numCtrls ):
                 pool = []
                 for cli in main.CLIs:
                     if i >= main.numMNswitches + 1:
@@ -1319,7 +1224,7 @@
                                  onpass="Compare Topology test PASS",
                                  onfail="Compare Topology test FAIL" )
 
-    def CASE60( self ):
+    def CASE60( self, main ):
         """
         Install 300 host intents and verify ping all ( Att Topology )
         """
@@ -1359,7 +1264,7 @@
             main.log.report( "Stopping test" )
             main.stop( email=main.emailOnStop )
 
-    def CASE61( self ):
+    def CASE61( self, main ):
         """
         Install 300 host intents and verify ping all for Chordal Topology
         """
@@ -1398,7 +1303,7 @@
             main.log.report( "Stopping test" )
             main.stop( email=main.emailOnStop )
 
-    def CASE62( self ):
+    def CASE62( self, main ):
         """
         Install 2278 host intents and verify ping all for Spine Topology
         """
@@ -1437,7 +1342,7 @@
             main.log.report( "Stopping test" )
             main.stop( email=main.emailOnStop )
 
-    def CASE160( self ):
+    def CASE160( self, main ):
         """
         Verify IPv6 ping across 300 host intents ( Att Topology )
         """
@@ -1463,7 +1368,7 @@
             main.log.report( "Stopping test" )
             main.stop( email=main.emailOnStop )
 
-    def CASE161( self ):
+    def CASE161( self, main ):
         """
         Verify IPv6 ping across 300 host intents ( Chordal Topology )
         """
@@ -1488,7 +1393,7 @@
             main.log.report( "Stopping test" )
             main.stop( email=main.emailOnStop )
 
-    def CASE162( self ):
+    def CASE162( self, main ):
         """
         Verify IPv6 ping across 2278 host intents ( Spine Topology )
         """
@@ -2385,7 +2290,7 @@
             main.log.report( "Stopping test" )
             main.stop( email=main.emailOnStop )
 
-    def CASE170( self ):
+    def CASE170( self, main ):
         """
         IPv6 ping all with some core links down( Host Intents-Att Topo )
         """
@@ -2411,7 +2316,7 @@
             main.log.report( "Stopping test" )
             main.stop( email=main.emailOnStop )
 
-    def CASE180( self ):
+    def CASE180( self, main ):
         """
         IPv6 ping all with after core links back up( Host Intents-Att Topo )
         """
@@ -2437,7 +2342,7 @@
             main.log.report( "Stopping test" )
             main.stop( email=main.emailOnStop )
 
-    def CASE171( self ):
+    def CASE171( self, main ):
         """
         IPv6 ping all with some core links down( Point Intents-Att Topo )
         """
@@ -2463,7 +2368,7 @@
             main.log.report( "Stopping test" )
             main.stop( email=main.emailOnStop )
 
-    def CASE181( self ):
+    def CASE181( self, main ):
         """
         IPv6 ping all with after core links back up( Point Intents-Att Topo )
         """
@@ -2489,7 +2394,7 @@
             main.log.report( "Stopping test" )
             main.stop( email=main.emailOnStop )
 
-    def CASE172( self ):
+    def CASE172( self, main ):
         """
         IPv6 ping all with some core links down( Host Intents-Chordal Topo )
         """
@@ -2511,7 +2416,7 @@
             onpass="IPv6 Ping across 300 host intents test PASS",
             onfail="IPv6 Ping across 300 host intents test FAIL" )
 
-    def CASE182( self ):
+    def CASE182( self, main ):
         """
         IPv6 ping all with after core links back up( Host Intents-Chordal Topo )
         """
@@ -2537,7 +2442,7 @@
             main.log.report( "Stopping test" )
             main.stop( email=main.emailOnStop )
 
-    def CASE173( self ):
+    def CASE173( self, main ):
         """
         IPv6 ping all with some core links down( Point Intents-Chordal Topo )
         """
@@ -2563,7 +2468,7 @@
             main.log.report( "Stopping test" )
             main.stop( email=main.emailOnStop )
 
-    def CASE183( self ):
+    def CASE183( self, main ):
         """
         IPv6 ping all with after core links back up( Point Intents-Chordal Topo )
         """
@@ -2589,7 +2494,7 @@
             main.log.report( "Stopping test" )
             main.stop( email=main.emailOnStop )
 
-    def CASE174( self ):
+    def CASE174( self, main ):
         """
         IPv6 ping all with some core links down( Host Intents-Spine Topo )
         """
@@ -2615,7 +2520,7 @@
             main.log.report( "Stopping test" )
             main.stop( email=main.emailOnStop )
 
-    def CASE184( self ):
+    def CASE184( self, main ):
         """
         IPv6 ping all with after core links back up( Host Intents-Spine Topo )
         """
@@ -2641,7 +2546,7 @@
             main.log.report( "Stopping test" )
             main.stop( email=main.emailOnStop )
 
-    def CASE175( self ):
+    def CASE175( self, main ):
         """
         IPv6 ping all with some core links down( Point Intents-Spine Topo )
         """
@@ -2667,7 +2572,7 @@
             main.log.report( "Stopping test" )
             main.stop( email=main.emailOnStop )
 
-    def CASE185( self ):
+    def CASE185( self, main ):
         """
         IPv6 ping all with after core links back up( Point Intents-Spine Topo )
         """
@@ -2693,7 +2598,7 @@
             main.log.report( "Stopping test" )
             main.stop( email=main.emailOnStop )
 
-    def CASE90( self ):
+    def CASE90( self, main ):
         """
         Install 600 point intents and verify ping all ( Att Topology )
         """
@@ -2735,7 +2640,7 @@
             main.log.report( "Stopping test" )
             main.stop( email=main.emailOnStop )
 
-    def CASE91( self ):
+    def CASE91( self, main ):
         """
         Install 600 point intents and verify ping all ( Chordal Topology )
         """
@@ -2777,7 +2682,7 @@
             main.log.report( "Stopping test" )
             main.stop( email=main.emailOnStop )
 
-    def CASE92( self ):
+    def CASE92( self, main ):
         """
         Install 4556 point intents and verify ping all ( Spine Topology )
         """
@@ -2819,7 +2724,7 @@
             main.log.report( "Stopping test" )
             main.stop( email=main.emailOnStop )
 
-    def CASE93( self ):
+    def CASE93( self, main ):
         """
         Install multi-single point intents and verify Ping all works
         for att topology
@@ -2835,7 +2740,7 @@
         intentIdList = []
         main.log.info( "MACsDict" + str( main.MACsDict ) )
         time1 = time.time()
-        for i in xrange( 0, len( deviceDPIDsCopy ), int( main.numCtrls ) ):
+        for i in xrange( 0, len( deviceDPIDsCopy ), main.numCtrls ):
             pool = []
             for cli in main.CLIs:
                 egressDevice = deviceDPIDsCopy[ i ]
@@ -2866,7 +2771,7 @@
             time.sleep( main.checkIntentsDelay )
 
             intentState = main.TRUE
-            for e in range( int( main.numCtrls ) ):
+            for e in range( main.numCtrls ):
                 main.log.info( "Checking intents on CLI %s" % ( e + 1 ) )
                 IntentStateIndividual = main.CLIs[ e ].checkIntentState( intentsId=intentIdList )
                 if not IntentStateIndividual:
@@ -2940,7 +2845,7 @@
             main.log.report( "Stopping test" )
             main.stop( email=main.emailOnStop )
 
-    def CASE94( self ):
+    def CASE94( self, main ):
         """
         Install multi-single point intents and verify Ping all works
         for Chordal topology
@@ -2955,7 +2860,7 @@
         intentIdList = []
         main.log.info( "MACsDict" + str( main.MACsDict ) )
         time1 = time.time()
-        for i in xrange( 0, len( deviceDPIDsCopy ), int( main.numCtrls ) ):
+        for i in xrange( 0, len( deviceDPIDsCopy ), main.numCtrls ):
             pool = []
             for cli in main.CLIs:
                 egressDevice = deviceDPIDsCopy[ i ]
@@ -2986,7 +2891,7 @@
             time.sleep( main.checkIntentsDelay )
 
             intentState = main.TRUE
-            for e in range( int( main.numCtrls ) ):
+            for e in range( main.numCtrls ):
                 main.log.info( "Checking intents on CLI %s" % ( e + 1 ) )
                 IntentStateIndividual = main.CLIs[ e ].checkIntentState( intentsId=intentIdList )
                 if not IntentStateIndividual:
@@ -3060,7 +2965,7 @@
             main.log.report( "Stopping test" )
             main.stop( email=main.emailOnStop )
 
-    def CASE95( self ):
+    def CASE95( self, main ):
         """
         Install multi-single point intents and verify Ping all works
         for Spine topology
@@ -3075,7 +2980,7 @@
         intentIdList = []
         main.log.info( "MACsDict" + str( main.MACsDict ) )
         time1 = time.time()
-        for i in xrange( 0, len( deviceDPIDsCopy ), int( main.numCtrls ) ):
+        for i in xrange( 0, len( deviceDPIDsCopy ), main.numCtrls ):
             pool = []
             for cli in main.CLIs:
                 egressDevice = deviceDPIDsCopy[ i ]
@@ -3106,7 +3011,7 @@
             time.sleep( main.checkIntentsDelay )
 
             intentState = main.TRUE
-            for e in range( int( main.numCtrls ) ):
+            for e in range( main.numCtrls ):
                 main.log.info( "Checking intents on CLI %s" % ( e + 1 ) )
                 IntentStateIndividual = main.CLIs[ e ].checkIntentState( intentsId=intentIdList )
                 if not IntentStateIndividual:
@@ -3180,7 +3085,7 @@
             main.log.report( "Stopping test" )
             main.stop( email=main.emailOnStop )
 
-    def CASE96( self ):
+    def CASE96( self, main ):
         """
         Install single-multi point intents and verify Ping all works
         for att topology
@@ -3194,7 +3099,7 @@
         intentIdList = []
         main.log.info( "MACsDict" + str( main.MACsDict ) )
         time1 = time.time()
-        for i in xrange( 0, len( deviceDPIDsCopy ), int( main.numCtrls ) ):
+        for i in xrange( 0, len( deviceDPIDsCopy ), main.numCtrls ):
             pool = []
             for cli in main.CLIs:
                 ingressDevice = deviceDPIDsCopy[ i ]
@@ -3225,7 +3130,7 @@
             time.sleep( main.checkIntentsDelay )
 
             intentState = main.TRUE
-            for e in range( int( main.numCtrls ) ):
+            for e in range( main.numCtrls ):
                 main.log.info( "Checking intents on CLI %s" % ( e + 1 ) )
                 IntentStateIndividual = main.CLIs[ e ].checkIntentState( intentsId=intentIdList )
                 if not IntentStateIndividual:
@@ -3299,7 +3204,7 @@
             main.log.report( "Stopping test" )
             main.stop( email=main.emailOnStop )
 
-    def CASE97( self ):
+    def CASE97( self, main ):
         """
         Install single-multi point intents and verify Ping all works
         for Chordal topology
@@ -3313,7 +3218,7 @@
         intentIdList = []
         main.log.info( "MACsDict" + str( main.MACsDict ) )
         time1 = time.time()
-        for i in xrange( 0, len( deviceDPIDsCopy ), int( main.numCtrls ) ):
+        for i in xrange( 0, len( deviceDPIDsCopy ), main.numCtrls ):
             pool = []
             for cli in main.CLIs:
                 ingressDevice = deviceDPIDsCopy[ i ]
@@ -3344,7 +3249,7 @@
             time.sleep( main.checkIntentsDelay )
 
             intentState = main.TRUE
-            for e in range( int( main.numCtrls ) ):
+            for e in range( main.numCtrls ):
                 main.log.info( "Checking intents on CLI %s" % ( e + 1 ) )
                 IntentStateIndividual = main.CLIs[ e ].checkIntentState( intentsId=intentIdList )
                 if not IntentStateIndividual:
@@ -3418,7 +3323,7 @@
             main.log.report( "Stopping test" )
             main.stop( email=main.emailOnStop )
 
-    def CASE98( self ):
+    def CASE98( self, main ):
         """
         Install single-multi point intents and verify Ping all works
         for Spine topology
@@ -3438,7 +3343,7 @@
         main.log.info( "deviceDPIDsCopy" + str( deviceDPIDsCopy ) )
         main.log.info( "MACsDictCopy" + str( MACsDictCopy ) )
         time1 = time.time()
-        for i in xrange( 0, len( deviceDPIDsCopy ), int( main.numCtrls ) ):
+        for i in xrange( 0, len( deviceDPIDsCopy ), main.numCtrls ):
             pool = []
             for cli in main.CLIs:
                 if i >= len( deviceDPIDsCopy ):
@@ -3469,7 +3374,7 @@
             time.sleep( main.checkIntentsDelay )
 
             intentState = main.TRUE
-            for e in range( int( main.numCtrls ) ):
+            for e in range( main.numCtrls ):
                 main.log.info( "Checking intents on CLI %s" % ( e + 1 ) )
                 IntentStateIndividual = main.CLIs[ e ].checkIntentState( intentsId=intentIdList )
                 if not IntentStateIndividual:
@@ -3543,7 +3448,7 @@
             main.log.report( "Stopping test" )
             main.stop( email=main.emailOnStop )
 
-    def CASE190( self ):
+    def CASE190( self, main ):
         """
         Verify IPv6 ping across 600 Point intents ( Att Topology )
         """
@@ -3569,7 +3474,7 @@
             main.log.report( "Stopping test" )
             main.stop( email=main.emailOnStop )
 
-    def CASE191( self ):
+    def CASE191( self, main ):
         """
         Verify IPv6 ping across 600 Point intents ( Chordal Topology )
         """
@@ -3595,7 +3500,7 @@
             main.log.report( "Stopping test" )
             main.stop( email=main.emailOnStop )
 
-    def CASE192( self ):
+    def CASE192( self, main ):
         """
         Verify IPv6 ping across 4556 Point intents ( Spine Topology )
         """
@@ -3621,7 +3526,7 @@
             main.log.report( "Stopping test" )
             main.stop( email=main.emailOnStop )
 
-    def CASE10( self ):
+    def CASE10( self, main ):
         import time
         import re
         """
@@ -3684,7 +3589,7 @@
                     main.log.info( "Leftover Intent IDs: " + str( intentIdList1 ) )
                     main.log.info( "Length of Leftover Intents list: " + str( len( intentIdList1 ) ) )
                     time1 = time.time()
-                    for i in xrange( 0, len( intentIdList1 ), int( main.numCtrls ) ):
+                    for i in xrange( 0, len( intentIdList1 ), main.numCtrls ):
                         pool = []
                         for cli in main.CLIs:
                             if i >= len( intentIdList1 ):
diff --git a/TestON/tests/CHOTestMonkey/CHOTestMonkey.params b/TestON/tests/CHOTestMonkey/CHOTestMonkey.params
index 6245cf6..5d84a8f 100644
--- a/TestON/tests/CHOTestMonkey/CHOTestMonkey.params
+++ b/TestON/tests/CHOTestMonkey/CHOTestMonkey.params
@@ -23,7 +23,10 @@
     <testcases>
         0,1,2,3,70
     </testcases>
-
+    <GIT>
+        <pull>False</pull>
+        <branch>master</branch>
+    </GIT>
     <TEST>
         <topo>1</topo>
         <IPv6>on</IPv6>
@@ -37,8 +40,6 @@
         <karafCliTimeout>7200000</karafCliTimeout>
         <testDuration>86400</testDuration>
         <package>on</package>
-        <autoPull>off</autoPull>
-        <branch>master</branch>
     </TEST>
 
     <EVENT>
diff --git a/TestON/tests/CHOTestMonkey/CHOTestMonkey.py b/TestON/tests/CHOTestMonkey/CHOTestMonkey.py
index 4a3ae04..71ed301 100644
--- a/TestON/tests/CHOTestMonkey/CHOTestMonkey.py
+++ b/TestON/tests/CHOTestMonkey/CHOTestMonkey.py
@@ -36,167 +36,61 @@
         from tests.CHOTestMonkey.dependencies.EventGenerator import EventGenerator
         from tests.CHOTestMonkey.dependencies.EventScheduler import EventScheduler
 
-        gitPull = main.params[ 'TEST' ][ 'autoPull' ]
-        onosPackage = main.params[ 'TEST' ][ 'package' ]
-        gitBranch = main.params[ 'TEST' ][ 'branch' ]
-        karafTimeout = main.params[ 'TEST' ][ 'karafCliTimeout' ]
-        main.enableIPv6 = main.params[ 'TEST' ][ 'IPv6' ]
-        main.enableIPv6 = True if main.enableIPv6 == "on" else False
-        main.caseSleep = int( main.params[ 'TEST' ][ 'caseSleep' ] )
-        main.numCtrls = int( main.params[ 'TEST' ][ 'numCtrl' ] )
-        main.ONOSip = []
-        main.AllONOSip = main.ONOSbench.getOnosIps()
-        main.controllers = []
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found exiting the test" )
+            main.exit()
+        main.testSetUp.envSetupDescription()
+
+        try:
+            onosPackage = main.params[ 'TEST' ][ 'package' ]
+            karafTimeout = main.params[ 'TEST' ][ 'karafCliTimeout' ]
+            main.enableIPv6 = main.params[ 'TEST' ][ 'IPv6' ]
+            main.enableIPv6 = True if main.enableIPv6 == "on" else False
+            main.caseSleep = int( main.params[ 'TEST' ][ 'caseSleep' ] )
+            main.numCtrls = int( main.params[ 'TEST' ][ 'numCtrl' ] )
+            main.maxNodes = main.numCtrls
+            main.controllers = []
+
+            main.devices = []
+            main.links = []
+            main.hosts = []
+            main.intents = []
+            main.enabledEvents = {}
+            for eventName in main.params[ 'EVENT' ].keys():
+                if main.params[ 'EVENT' ][ eventName ][ 'status' ] == 'on':
+                    main.enabledEvents[ int( main.params[ 'EVENT' ][ eventName ][ 'typeIndex' ] ) ] = eventName
+            print main.enabledEvents
+            main.graph = Graph()
+            main.eventScheduler = EventScheduler()
+            main.eventGenerator = EventGenerator()
+            main.variableLock = Lock()
+            main.mininetLock = Lock()
+            main.ONOSbenchLock = Lock()
+            main.threadID = 0
+            main.eventID = 0
+            main.caseResult = main.TRUE
+            stepResult = main.testSetUp.envSetup()
+        except Exception as e:
+            main.testSetUp.envSetupException(e)
+
+        main.testSetUp.evnSetupConclusion( stepResult )
+
+
         for i in range( 1, main.numCtrls + 1 ):
-            main.ONOSip.append( main.AllONOSip[ i - 1 ] )
             newController = Controller( i )
-            newController.setCLI( getattr( main, 'ONOScli' + str( i ) ) )
+            newController.setCLI( main.CLIs[i - 1] )
             main.controllers.append( newController )
-        main.devices = []
-        main.links = []
-        main.hosts = []
-        main.intents = []
-        main.enabledEvents = {}
-        for eventName in main.params[ 'EVENT' ].keys():
-            if main.params[ 'EVENT' ][ eventName ][ 'status' ] == 'on':
-                main.enabledEvents[ int( main.params[ 'EVENT' ][ eventName ][ 'typeIndex' ] ) ] = eventName
-        print main.enabledEvents
-        main.graph = Graph()
-        main.eventScheduler = EventScheduler()
-        main.eventGenerator = EventGenerator()
-        main.variableLock = Lock()
-        main.mininetLock = Lock()
-        main.ONOSbenchLock = Lock()
-        main.threadID = 0
-        main.eventID = 0
-        main.caseResult = main.TRUE
 
-        main.case( "Set up test environment" )
-        main.log.report( "Set up test environment" )
-        main.log.report( "_______________________" )
-
-        main.step( "Apply Cell environment for ONOS" )
-        if ( main.onoscell ):
-            cellName = main.onoscell
-            cellResult = main.ONOSbench.setCell( cellName )
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=cellResult,
-                                     onpass="Test step PASS",
-                                     onfail="Test step FAIL" )
-        else:
-            main.log.error( "Please provide onoscell option at TestON CLI to run CHO tests" )
-            main.log.error( "Example: ~/TestON/bin/cli.py run CHOTestMonkey onoscell <cellName>" )
+        if not main.onoscell :
+            main.log.error("Please provide onoscell option at TestON CLI to run CHO tests")
+            main.log.error("Example: ~/TestON/bin/cli.py run CHOTestMonkey onoscell <cellName>")
             main.cleanup()
             main.exit()
 
-        main.step( "Git checkout and pull " + gitBranch )
-        if gitPull == 'on':
-            checkoutResult = main.ONOSbench.gitCheckout( gitBranch )
-            pullResult = main.ONOSbench.gitPull()
-            cpResult = ( checkoutResult and pullResult )
-        else:
-            checkoutResult = main.TRUE
-            pullResult = main.TRUE
-            main.log.info( "Skipped git checkout and pull as they are disabled in params file" )
-            cpResult = ( checkoutResult and pullResult )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=cpResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        main.ONOSbench.getVersion( report=True )
-
-        main.step( "Create ONOS package" )
-        if onosPackage == 'on':
-            packageResult = main.ONOSbench.buckBuild()
-        else:
-            packageResult = main.TRUE
-            main.log.info( "Skipped onos package as it is disabled in params file" )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=packageResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        main.step( "Uninstall ONOS package on all Nodes" )
-        uninstallResult = main.TRUE
-        for i in range( main.numCtrls ):
-            main.log.info( "Uninstalling package on ONOS Node IP: " + main.ONOSip[ i ] )
-            uResult = main.ONOSbench.onosUninstall( main.ONOSip[ i ] )
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=uResult,
-                                     onpass="Test step PASS",
-                                     onfail="Test step FAIL" )
-            uninstallResult = ( uninstallResult and uResult )
-
-        main.step( "Install ONOS package on all Nodes" )
-        installResult = main.TRUE
-        for i in range( main.numCtrls ):
-            main.log.info( "Installing package on ONOS Node IP: " + main.ONOSip[ i ] )
-            iResult = main.ONOSbench.onosInstall( node=main.ONOSip[ i ] )
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=iResult,
-                                     onpass="Test step PASS",
-                                     onfail="Test step FAIL" )
-            installResult = ( installResult and iResult )
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.TRUE
-        for i in range( main.numCtrls ):
-            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=main.ONOSip[ i ] )
-        utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        time.sleep( 5 )
-        main.step( "Starting ONOS service" )
-        stopResult = main.TRUE
-        startResult = main.TRUE
-        onosIsUp = main.TRUE
-        for i in range( main.numCtrls ):
-            onosIsUp = onosIsUp and main.ONOSbench.isup( main.ONOSip[ i ] )
-        if onosIsUp == main.TRUE:
-            main.log.report( "ONOS instance is up and ready" )
-        else:
-            main.log.report( "ONOS instance may not be up, stop and " +
-                             "start ONOS again " )
-            for i in range( main.numCtrls ):
-                stopResult = stopResult and \
-                        main.ONOSbench.onosStop( main.ONOSip[ i ] )
-            for i in range( main.numCtrls ):
-                startResult = startResult and \
-                        main.ONOSbench.onosStart( main.ONOSip[ i ] )
-        stepResult = onosIsUp and stopResult and startResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="ONOS service is ready",
-                                 onfail="ONOS service did not start properly" )
-
-        main.step( "Start ONOS CLI on all nodes" )
-        cliResult = main.TRUE
-        startCliResult = main.TRUE
-        pool = []
-        for controller in main.controllers:
-            t = main.Thread( target=controller.startCLI,
-                             threadID=main.threadID,
-                             name="startOnosCli",
-                             args=[] )
-            pool.append( t )
-            t.start()
-            main.threadID = main.threadID + 1
-        for t in pool:
-            t.join()
-            startCliResult = startCliResult and t.result
-        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
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=startCliResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
+        setupResult = main.testSetUp.ONOSSetUp( Mininet=main.Mininet1, newCell=False, cellName=main.onoscell )
 
         main.step( "Set IPv6 cfg parameters for Neighbor Discovery" )
         setIPv6CfgSleep = int( main.params[ 'TEST' ][ 'setIPv6CfgSleep' ] )
@@ -243,7 +137,7 @@
         with main.variableLock:
             main.threadID = main.threadID + 1
 
-        caseResult = installResult and uninstallResult and startCliResult and cfgResult
+        caseResult = setupResult and cfgResult
         utilities.assert_equals( expect=main.TRUE,
                                  actual=caseResult,
                                  onpass="Set up test environment PASS",
diff --git a/TestON/tests/FUNC/FUNCflow/FUNCflow.py b/TestON/tests/FUNC/FUNCflow/FUNCflow.py
index 0bb43aa..ca590e6 100644
--- a/TestON/tests/FUNC/FUNCflow/FUNCflow.py
+++ b/TestON/tests/FUNC/FUNCflow/FUNCflow.py
@@ -6,82 +6,68 @@
     def CASE1( self, main ):
         import os
         import imp
-
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+        except ImportError:
+            main.log.error( "SetUp not found exiting the test" )
+            main.exit()
+        try:
+            main.testSetUp
+        except ( NameError, AttributeError ):
+            main.testSetUp = ONOSSetup()
         """
         - Construct tests variables
         - GIT ( optional )
             - Checkout ONOS master branch
             - Pull latest ONOS code
-        - Building ONOS ( optional )
-            - Install ONOS package
-            - Build ONOS package
         """
-        main.case( "Constructing test variables and building ONOS package" )
-        main.step( "Constructing test variables" )
 
-        # Test variables
-        main.testOnDirectory = os.path.dirname( os.getcwd() )
-        main.cellName = main.params[ 'ENV' ][ 'cellName' ]
-        main.apps = main.params[ 'ENV' ][ 'cellApps' ]
-        gitBranch = main.params[ 'GIT' ][ 'branch' ]
-        gitPull = main.params[ 'GIT' ][ 'pull' ]
-        main.ONOSport = main.params[ 'CTRL' ][ 'port' ]
-        main.dependencyPath = main.testOnDirectory + \
-                              main.params[ 'DEPENDENCY' ][ 'path' ]
-        wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
-        wrapperFile2 = main.params[ 'DEPENDENCY' ][ 'wrapper2' ]
-        main.topology = main.params[ 'DEPENDENCY' ][ 'topology' ]
-        main.maxNodes = int( main.params[ 'SCALE' ][ 'max' ] )
-        main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
-        main.startMNSleep = int( main.params[ 'SLEEP' ][ 'startMN' ] )
-        main.addFlowSleep = int( main.params[ 'SLEEP' ][ 'addFlow' ] )
-        main.delFlowSleep = int( main.params[ 'SLEEP' ][ 'delFlow' ] )
-        main.debug = main.params[ 'DEBUG' ]
-        main.swDPID = main.params[ 'TEST' ][ 'swDPID' ]
-        main.cellData = {}  # for creating cell file
-        main.CLIs = []
-        main.ONOSip = []
+        main.testSetUp.envSetupDescription()
+        stepResult = main.FALSE
+        try:
+            # Test variables
+            main.cellName = main.params[ 'ENV' ][ 'cellName' ]
+            main.apps = main.params[ 'ENV' ][ 'cellApps' ]
+            main.ONOSport = main.params[ 'CTRL' ][ 'port' ]
+            main.dependencyPath = main.testOnDirectory + \
+                                  main.params[ 'DEPENDENCY' ][ 'path' ]
+            wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
+            wrapperFile2 = main.params[ 'DEPENDENCY' ][ 'wrapper2' ]
+            main.topology = main.params[ 'DEPENDENCY' ][ 'topology' ]
+            main.maxNodes = int( main.params[ 'SCALE' ][ 'max' ] )
+            main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
+            main.startMNSleep = int( main.params[ 'SLEEP' ][ 'startMN' ] )
+            main.addFlowSleep = int( main.params[ 'SLEEP' ][ 'addFlow' ] )
+            main.delFlowSleep = int( main.params[ 'SLEEP' ][ 'delFlow' ] )
+            main.debug = main.params[ 'DEBUG' ]
+            main.swDPID = main.params[ 'TEST' ][ 'swDPID' ]
 
-        main.debug = True if "on" in main.debug else False
+            main.debug = True if "on" in main.debug else False
 
-        main.ONOSip = main.ONOSbench.getOnosIps()
+            # -- INIT SECTION, ONLY RUNS ONCE -- #
 
-        # Assigning ONOS cli handles to a list
-        for i in range( 1, main.maxNodes + 1 ):
-            main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
+            try:
+                from tests.FUNC.FUNCflow.dependencies.checkingFlow import CheckingFlow
+                main.checkingFlow = CheckingFlow()
+            except ImportError as e:
+                print e
+                main.log.error("CheckingFlow not found exiting the test")
+                main.exit()
+            copyResult = main.ONOSbench.scp( main.Mininet1,
+                                             main.dependencyPath + main.topology,
+                                             main.Mininet1.home + '/custom/',
+                                             direction="to" )
 
-        # -- INIT SECTION, ONLY RUNS ONCE -- #
-        main.startUp = imp.load_source( wrapperFile1,
-                                        main.dependencyPath +
-                                        wrapperFile1 +
-                                        ".py" )
+            utilities.assert_equals( expect=main.TRUE,
+                                     actual=copyResult,
+                                     onpass="Successfully copy " + "test variables ",
+                                     onfail="Failed to copy test variables" )
 
-        main.topo = imp.load_source( wrapperFile2,
-                                     main.dependencyPath +
-                                     wrapperFile2 +
-                                     ".py" )
+            stepResult = main.testSetUp.envSetup()
 
-        copyResult = main.ONOSbench.scp( main.Mininet1,
-                                         main.dependencyPath + main.topology,
-                                         main.Mininet1.home + '/custom/',
-                                         direction="to" )
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=copyResult,
-                                 onpass="Successfully copy " + "test variables ",
-                                 onfail="Failed to copy test variables" )
-
-        if main.CLIs:
-            stepResult = main.TRUE
-        else:
-            main.log.error( "Did not properly created list of ONOS CLI handle" )
-            stepResult = main.FALSE
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully construct " + "test variables ",
-                                 onfail="Failed to construct test variables" )
-
+        except Exception as e:
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
 
 
     def CASE2( self, main ):
@@ -90,127 +76,32 @@
             - Create cell file
             - Set cell file
             - Verify cell file
+        - Building ONOS
+            - Install ONOS package
+            - Build ONOS package
         - Kill ONOS process
         - Uninstall ONOS cluster
         - Verify ONOS start up
         - Install ONOS cluster
         - Connect to cli
         """
-        import time
-
-        main.numCtrls = int( main.maxNodes )
-
-        main.case( "Starting up " + str( main.numCtrls ) +
-                   " node(s) ONOS cluster" )
-
-        #kill off all onos processes
-        main.log.info( "Safety check, killing all ONOS processes" +
-                       " before initiating environment setup" )
-
-        for i in range( main.maxNodes ):
-            main.ONOSbench.onosDie( main.ONOSip[ i ] )
-
-        main.log.info( "NODE COUNT = " + str( main.numCtrls ) )
-
-        tempOnosIp = []
-        for i in range( main.numCtrls ):
-            tempOnosIp.append( main.ONOSip[ i ] )
-
-        main.ONOSbench.createCellFile( main.ONOSbench.ip_address,
-                                       "temp",
-                                       main.Mininet1.ip_address,
-                                       main.apps,
-                                       tempOnosIp, main.ONOScli1.karafUser )
-
-        main.step( "Apply cell to environment" )
-        cellResult = main.ONOSbench.setCell( "temp" )
-        verifyResult = main.ONOSbench.verifyCell()
-        stepResult = cellResult and verifyResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully applied cell to " + "environment",
-                                 onfail="Failed to apply cell to environment " )
-
-        main.step( "Creating ONOS package" )
-        packageResult = main.ONOSbench.buckBuild()
-        stepResult = packageResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully created ONOS package",
-                                 onfail="Failed to create ONOS package" )
-
-        time.sleep( main.startUpSleep )
-        main.step( "Uninstalling ONOS package" )
-        onosUninstallResult = main.TRUE
-        for ip in main.ONOSip:
-            onosUninstallResult = onosUninstallResult and \
-                    main.ONOSbench.onosUninstall( nodeIp=ip )
-        stepResult = onosUninstallResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully uninstalled ONOS package",
-                                 onfail="Failed to uninstall ONOS package" )
-        time.sleep( main.startUpSleep )
-        main.step( "Installing ONOS package" )
-        onosInstallResult = main.TRUE
-        for i in range( main.numCtrls ):
-            onosInstallResult = onosInstallResult and \
-                    main.ONOSbench.onosInstall( node=main.ONOSip[ i ] )
-        stepResult = onosInstallResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully installed ONOS package",
-                                 onfail="Failed to install ONOS package" )
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.TRUE
-        for i in range( int( main.numCtrls ) ):
-            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=main.ONOSip[ i ] )
-        utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        time.sleep( main.startUpSleep )
-        main.step( "Starting ONOS service" )
-        stopResult = main.TRUE
-        startResult = main.TRUE
-        onosIsUp = main.TRUE
-
-        for i in range( main.numCtrls ):
-            onosIsUp = onosIsUp and main.ONOSbench.isup( main.ONOSip[ i ] )
-        if onosIsUp == main.TRUE:
-            main.log.report( "ONOS instance is up and ready" )
-        else:
-            main.log.report( "ONOS instance may not be up, stop and " +
-                             "start ONOS again " )
-            for i in range( main.numCtrls ):
-                stopResult = stopResult and \
-                        main.ONOSbench.onosStop( main.ONOSip[ i ] )
-            for i in range( main.numCtrls ):
-                startResult = startResult and \
-                        main.ONOSbench.onosStart( main.ONOSip[ i ] )
-        stepResult = onosIsUp and stopResult and startResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="ONOS service is ready",
-                                 onfail="ONOS service did not start properly" )
-
-        main.step( "Start ONOS cli" )
-        cliResult = main.TRUE
-        for i in range( main.numCtrls ):
-            cliResult = cliResult and \
-                        main.CLIs[ i ].startOnosCli( main.ONOSip[ i ] )
-        stepResult = cliResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully start ONOS cli",
-                                 onfail="Failed to start ONOS cli" )
+        main.testSetUp.ONOSSetUp( main.Mininet1 )
 
     def CASE10( self, main ):
         """
             Start Mininet
         """
         import json
+        import time
+        try:
+            from tests.dependencies.topology import Topology
+        except ImportError:
+            main.log.error( "Topology not found exiting the test" )
+            main.exit()
+        try:
+            main.topoRelated
+        except ( NameError, AttributeError ):
+            main.topoRelated = Topology()
 
         main.case( "Setup mininet and compare ONOS topology view to Mininet topology" )
         main.caseExplanation = "Start mininet with custom topology and compare topology " +\
@@ -235,60 +126,7 @@
 
         time.sleep( main.startMNSleep )
 
-        main.step( "Comparing MN topology to ONOS topology" )
-        main.log.info( "Gathering topology information" )
-        devices = main.topo.getAllDevices( main )
-        hosts = main.topo.getAllHosts( main )
-        ports = main.topo.getAllPorts( main )
-        links = main.topo.getAllLinks( main )
-
-        mnSwitches = main.Mininet1.getSwitches()
-        mnLinks = main.Mininet1.getLinks()
-        mnHosts = main.Mininet1.getHosts()
-
-        for controller in range( main.numCtrls ):
-            controllerStr = str( controller + 1 )
-            if devices[ controller ] and ports[ controller ] and\
-                    "Error" not in devices[ controller ] and\
-                    "Error" not in ports[ controller ]:
-
-                currentDevicesResult = main.Mininet1.compareSwitches(
-                        mnSwitches,
-                        json.loads( devices[ controller ] ),
-                        json.loads( ports[ controller ] ) )
-            else:
-                currentDevicesResult = main.FALSE
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=currentDevicesResult,
-                                     onpass="ONOS" + controllerStr +
-                                            " Switches view is correct",
-                                     onfail="ONOS" + controllerStr +
-                                            " Switches view is incorrect" )
-            if links[ controller ] and "Error" not in links[ controller ]:
-                currentLinksResult = main.Mininet1.compareLinks(
-                        mnSwitches, mnLinks,
-                        json.loads( links[ controller ] ) )
-            else:
-                currentLinksResult = main.FALSE
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=currentLinksResult,
-                                     onpass="ONOS" + controllerStr +
-                                            " links view is correct",
-                                     onfail="ONOS" + controllerStr +
-                                            " links view is incorrect" )
-
-            if hosts[ controller ] or "Error" not in hosts[ controller ]:
-                currentHostsResult = main.Mininet1.compareHosts(
-                        mnHosts,
-                        json.loads( hosts[ controller ] ) )
-            else:
-                currentHostsResult = main.FALSE
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=currentHostsResult,
-                                     onpass="ONOS" + controllerStr +
-                                            " hosts exist in Mininet",
-                                     onfail="ONOS" + controllerStr +
-                                            " hosts don't match Mininet" )
+        main.topoRelated.compareTopos( main.Mininet1 )
 
     def CASE66( self, main ):
         """
@@ -532,46 +370,7 @@
         # Giving ONOS time to add the flow
         time.sleep( main.addFlowSleep )
 
-        main.step( "Check flow is in the ADDED state" )
-
-        main.log.info( "Get the flows from ONOS" )
-        try:
-            flows = json.loads( main.ONOSrest.flows() )
-
-            stepResult = main.TRUE
-            for f in flows:
-                if "rest" in f.get( "appId" ):
-                    if "ADDED" not in f.get( "state" ):
-                        stepResult = main.FALSE
-                        main.log.error( "Flow: %s in state: %s" % ( f.get( "id" ), f.get( "state" ) ) )
-        except TypeError:
-            main.log.error( "No Flows found by the REST API" )
-            stepResult = main.FALSE
-        except ValueError:
-            main.log.error( "Problem getting Flows state from REST API.  Exiting test" )
-            main.cleanup()
-            main.exit()
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="All flows are in the ADDED state",
-                                 onfail="All flows are NOT in the ADDED state" )
-
-        main.step( "Check flows are in Mininet's flow table" )
-
-        # get the flow IDs that were added through rest
-        main.log.info( "Getting the flow IDs from ONOS" )
-        flowIds = [ f.get( "id" ) for f in flows if "rest" in f.get( "appId" ) ]
-        # convert the flowIDs to ints then hex and finally back to strings
-        flowIds = [ str( hex( int( x ) ) ) for x in flowIds ]
-        main.log.info( "ONOS flow IDs: {}".format( flowIds ) )
-
-        stepResult = main.Mininet1.checkFlowId( "s1", flowIds, debug=False )
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="All flows are in mininet",
-                                 onfail="All flows are NOT in mininet" )
+        main.checkingFlow.checkFlow()
 
         main.step( "Send a packet to verify the flow is correct" )
 
@@ -654,46 +453,7 @@
         # Giving ONOS time to add the flow
         time.sleep( main.addFlowSleep )
 
-        main.step( "Check flow is in the ADDED state" )
-
-        main.log.info( "Get the flows from ONOS" )
-        try:
-            flows = json.loads( main.ONOSrest.flows() )
-
-            stepResult = main.TRUE
-            for f in flows:
-                if "rest" in f.get( "appId" ):
-                    if "ADDED" not in f.get( "state" ):
-                        stepResult = main.FALSE
-                        main.log.error( "Flow: %s in state: %s" % ( f.get( "id" ), f.get( "state" ) ) )
-        except TypeError:
-            main.log.error( "No Flows found by the REST API" )
-            stepResult = main.FALSE
-        except ValueError:
-            main.log.error( "Problem getting Flows state from REST API.  Exiting test" )
-            main.cleanup()
-            main.exit()
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="All flows are in the ADDED state",
-                                 onfail="All flows are NOT in the ADDED state" )
-
-        main.step( "Check flows are in Mininet's flow table" )
-
-        # get the flow IDs that were added through rest
-        main.log.info( "Getting the flow IDs from ONOS" )
-        flowIds = [ f.get( "id" ) for f in flows if "rest" in f.get( "appId" ) ]
-        # convert the flowIDs to ints then hex and finally back to strings
-        flowIds = [ str( hex( int( x ) ) ) for x in flowIds ]
-        main.log.info( "ONOS flow IDs: {}".format( flowIds ) )
-
-        stepResult = main.Mininet1.checkFlowId( "s1", flowIds, debug=False )
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="All flows are in mininet",
-                                 onfail="All flows are NOT in mininet" )
+        main.checkingFlow.checkFlow()
 
         main.step( "Send a packet to verify the flow is correct" )
 
@@ -1015,46 +775,7 @@
         # Giving ONOS time to add the flow
         time.sleep( main.addFlowSleep )
 
-        main.step( "Check flow is in the ADDED state" )
-
-        main.log.info( "Get the flows from ONOS" )
-        try:
-            flows = json.loads( main.ONOSrest.flows() )
-
-            stepResult = main.TRUE
-            for f in flows:
-                if "rest" in f.get( "appId" ):
-                    if "ADDED" not in f.get( "state" ):
-                        stepResult = main.FALSE
-                        main.log.error( "Flow: %s in state: %s" % ( f.get( "id" ), f.get( "state" ) ) )
-        except TypeError:
-            main.log.error( "No Flows found by the REST API" )
-            stepResult = main.FALSE
-        except ValueError:
-            main.log.error( "Problem getting Flows state from REST API.  Exiting test" )
-            main.cleanup()
-            main.exit()
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="All flows are in the ADDED state",
-                                 onfail="All flows are NOT in the ADDED state" )
-
-        main.step( "Check flows are in Mininet's flow table" )
-
-        # get the flow IDs that were added through rest
-        main.log.info( "Getting the flow IDs from ONOS" )
-        flowIds = [ f.get( "id" ) for f in flows if "rest" in f.get( "appId" ) ]
-        # convert the flowIDs to ints then hex and finally back to strings
-        flowIds = [ str( hex( int( x ) ) ) for x in flowIds ]
-        main.log.info( "ONOS flow IDs: {}".format( flowIds ) )
-
-        stepResult = main.Mininet1.checkFlowId( "s1", flowIds, debug=False )
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="All flows are in mininet",
-                                 onfail="All flows are NOT in mininet" )
+        main.checkingFlow.checkFlow()
 
         main.step( "Send a packet to verify the flow is correct" )
 
@@ -1139,46 +860,7 @@
         # Giving ONOS time to add the flow
         time.sleep( main.addFlowSleep )
 
-        main.step( "Check flow is in the ADDED state" )
-
-        main.log.info( "Get the flows from ONOS" )
-        try:
-            flows = json.loads( main.ONOSrest.flows() )
-
-            stepResult = main.TRUE
-            for f in flows:
-                if "rest" in f.get( "appId" ):
-                    if "ADDED" not in f.get( "state" ):
-                        stepResult = main.FALSE
-                        main.log.error( "Flow: %s in state: %s" % ( f.get( "id" ), f.get( "state" ) ) )
-        except TypeError:
-            main.log.error( "No Flows found by the REST API" )
-            stepResult = main.FALSE
-        except ValueError:
-            main.log.error( "Problem getting Flows state from REST API.  Exiting test" )
-            main.cleanup()
-            main.exit()
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="All flows are in the ADDED state",
-                                 onfail="All flows are NOT in the ADDED state" )
-
-        main.step( "Check flows are in Mininet's flow table" )
-
-        # get the flow IDs that were added through rest
-        main.log.info( "Getting the flow IDs from ONOS" )
-        flowIds = [ f.get( "id" ) for f in flows if "rest" in f.get( "appId" ) ]
-        # convert the flowIDs to ints then hex and finally back to strings
-        flowIds = [ str( hex( int( x ) ) ) for x in flowIds ]
-        main.log.info( "ONOS flow IDs: {}".format( flowIds ) )
-
-        stepResult = main.Mininet1.checkFlowId( "s1", flowIds, debug=False )
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="All flows are in mininet",
-                                 onfail="All flows are NOT in mininet" )
+        main.checkingFlow.checkFlow()
 
         main.step( "Send a packet to verify the flow is correct" )
 
@@ -1260,46 +942,7 @@
         # Giving ONOS time to add the flow
         time.sleep( main.addFlowSleep )
 
-        main.step( "Check flow is in the ADDED state" )
-
-        main.log.info( "Get the flows from ONOS" )
-        try:
-            flows = json.loads( main.ONOSrest.flows() )
-
-            stepResult = main.TRUE
-            for f in flows:
-                if "rest" in f.get( "appId" ):
-                    if "ADDED" not in f.get( "state" ):
-                        stepResult = main.FALSE
-                        main.log.error( "Flow: %s in state: %s" % ( f.get( "id" ), f.get( "state" ) ) )
-        except TypeError:
-            main.log.error( "No Flows found by the REST API" )
-            stepResult = main.FALSE
-        except ValueError:
-            main.log.error( "Problem getting Flows state from REST API.  Exiting test" )
-            main.cleanup()
-            main.exit()
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="All flows are in the ADDED state",
-                                 onfail="All flows are NOT in the ADDED state" )
-
-        main.step( "Check flows are in Mininet's flow table" )
-
-        # get the flow IDs that were added through rest
-        main.log.info( "Getting the flow IDs from ONOS" )
-        flowIds = [ f.get( "id" ) for f in flows if "rest" in f.get( "appId" ) ]
-        # convert the flowIDs to ints then hex and finally back to strings
-        flowIds = [ str( hex( int( x ) ) ) for x in flowIds ]
-        main.log.info( "ONOS flow IDs: {}".format( flowIds ) )
-
-        stepResult = main.Mininet1.checkFlowId( "s1", flowIds, debug=False )
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="All flows are in mininet",
-                                 onfail="All flows are NOT in mininet" )
+        main.checkingFlow.checkFlow()
 
         main.step( "Send a packet to verify the flow is correct" )
 
@@ -1381,46 +1024,7 @@
         # Giving ONOS time to add the flow
         time.sleep( main.addFlowSleep )
 
-        main.step( "Check flow is in the ADDED state" )
-
-        main.log.info( "Get the flows from ONOS" )
-        try:
-            flows = json.loads( main.ONOSrest.flows() )
-
-            stepResult = main.TRUE
-            for f in flows:
-                if "rest" in f.get( "appId" ):
-                    if "ADDED" not in f.get( "state" ):
-                        stepResult = main.FALSE
-                        main.log.error( "Flow: %s in state: %s" % ( f.get( "id" ), f.get( "state" ) ) )
-        except TypeError:
-            main.log.error( "No Flows found by the REST API" )
-            stepResult = main.FALSE
-        except ValueError:
-            main.log.error( "Problem getting Flows state from REST API.  Exiting test" )
-            main.cleanup()
-            main.exit()
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="All flows are in the ADDED state",
-                                 onfail="All flows are NOT in the ADDED state" )
-
-        main.step( "Check flows are in Mininet's flow table" )
-
-        # get the flow IDs that were added through rest
-        main.log.info( "Getting the flow IDs from ONOS" )
-        flowIds = [ f.get( "id" ) for f in flows if "rest" in f.get( "appId" ) ]
-        # convert the flowIDs to ints then hex and finally back to strings
-        flowIds = [ str( hex( int( x ) ) ) for x in flowIds ]
-        main.log.info( "ONOS flow IDs: {}".format( flowIds ) )
-
-        stepResult = main.Mininet1.checkFlowId( "s1", flowIds, debug=False )
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="All flows are in mininet",
-                                 onfail="All flows are NOT in mininet" )
+        main.checkingFlow.checkFlow()
 
         main.step( "Send a packet to verify the flow is correct" )
 
@@ -1537,46 +1141,7 @@
         # Giving ONOS time to add the flow
         time.sleep( main.addFlowSleep )
 
-        main.step( "Check flow is in the ADDED state" )
-
-        main.log.info( "Get the flows from ONOS" )
-        try:
-            flows = json.loads( main.ONOSrest.flows() )
-
-            stepResult = main.TRUE
-            for f in flows:
-                if "rest" in f.get( "appId" ):
-                    if "ADDED" not in f.get( "state" ):
-                        stepResult = main.FALSE
-                        main.log.error( "Flow: %s in state: %s" % ( f.get( "id" ), f.get( "state" ) ) )
-        except TypeError:
-            main.log.error( "No Flows found by the REST API" )
-            stepResult = main.FALSE
-        except ValueError:
-            main.log.error( "Problem getting Flows state from REST API.  Exiting test" )
-            main.cleanup()
-            main.exit()
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="All flows are in the ADDED state",
-                                 onfail="All flows are NOT in the ADDED state" )
-
-        main.step( "Check flows are in Mininet's flow table" )
-
-        # get the flow IDs that were added through rest
-        main.log.info( "Getting the flow IDs from ONOS" )
-        flowIds = [ f.get( "id" ) for f in flows if "rest" in f.get( "appId" ) ]
-        # convert the flowIDs to ints then hex and finally back to strings
-        flowIds = [ str( hex( int( x ) ) ) for x in flowIds ]
-        main.log.info( "ONOS flow IDs: {}".format( flowIds ) )
-
-        stepResult = main.Mininet1.checkFlowId( "s1", flowIds, debug=False )
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="All flows are in mininet",
-                                 onfail="All flows are NOT in mininet" )
+        main.checkingFlow.checkFlow()
 
         main.step( "Send a packet to verify the flow is correct" )
 
@@ -1657,46 +1222,7 @@
         # Giving ONOS time to add the flow
         time.sleep( main.addFlowSleep )
 
-        main.step( "Check flow is in the ADDED state" )
-
-        main.log.info( "Get the flows from ONOS" )
-        try:
-            flows = json.loads( main.ONOSrest.flows() )
-
-            stepResult = main.TRUE
-            for f in flows:
-                if "rest" in f.get( "appId" ):
-                    if "ADDED" not in f.get( "state" ):
-                        stepResult = main.FALSE
-                        main.log.error( "Flow: %s in state: %s" % ( f.get( "id" ), f.get( "state" ) ) )
-        except TypeError:
-            main.log.error( "No Flows found by the REST API" )
-            stepResult = main.FALSE
-        except ValueError:
-            main.log.error( "Problem getting Flows state from REST API.  Exiting test" )
-            main.cleanup()
-            main.exit()
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="All flows are in the ADDED state",
-                                 onfail="All flows are NOT in the ADDED state" )
-
-        main.step( "Check flows are in Mininet's flow table" )
-
-        # get the flow IDs that were added through rest
-        main.log.info( "Getting the flow IDs from ONOS" )
-        flowIds = [ f.get( "id" ) for f in flows if "rest" in f.get( "appId" ) ]
-        # convert the flowIDs to ints then hex and finally back to strings
-        flowIds = [ str( hex( int( x ) ) ) for x in flowIds ]
-        main.log.info( "ONOS flow IDs: {}".format( flowIds ) )
-
-        stepResult = main.Mininet1.checkFlowId( "s1", flowIds, debug=False )
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="All flows are in mininet",
-                                 onfail="All flows are NOT in mininet" )
+        main.checkingFlow.checkFlow()
 
         main.step( "Send a packet to verify the flow is correct" )
 
diff --git a/TestON/tests/FUNC/FUNCflow/dependencies/__init__.py b/TestON/tests/FUNC/FUNCflow/dependencies/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/FUNC/FUNCflow/dependencies/__init__.py
diff --git a/TestON/tests/FUNC/FUNCflow/dependencies/checkingFlow.py b/TestON/tests/FUNC/FUNCflow/dependencies/checkingFlow.py
new file mode 100644
index 0000000..5a5537c
--- /dev/null
+++ b/TestON/tests/FUNC/FUNCflow/dependencies/checkingFlow.py
@@ -0,0 +1,47 @@
+import json
+import time
+class CheckingFlow:
+
+    def __init__( self ):
+        self.default = ''
+
+    def checkFlow( self ):
+        main.step("Check flow is in the ADDED state")
+        main.log.info( "Get the flows from ONOS" )
+        try:
+            flows = json.loads( main.ONOSrest.flows() )
+
+            stepResult = main.TRUE
+            for f in flows:
+                if "rest" in f.get( "appId" ):
+                    if "ADDED" not in f.get( "state" ):
+                        stepResult = main.FALSE
+                        main.log.error( "Flow: %s in state: %s" % ( f.get( "id" ), f.get( "state" ) ) )
+        except TypeError:
+            main.log.error( "No Flows found by the REST API" )
+            stepResult = main.FALSE
+        except ValueError:
+            main.log.error( "Problem getting Flows state from REST API.  Exiting test" )
+            main.cleanup()
+            main.exit()
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="All flows are in the ADDED state",
+                                 onfail="All flows are NOT in the ADDED state" )
+
+        main.step( "Check flows are in Mininet's flow table" )
+
+        # get the flow IDs that were added through rest
+        main.log.info( "Getting the flow IDs from ONOS" )
+        flowIds = [ f.get( "id" ) for f in flows if "rest" in f.get( "appId" ) ]
+        # convert the flowIDs to ints then hex and finally back to strings
+        flowIds = [ str( hex( int( x ) ) ) for x in flowIds ]
+        main.log.info( "ONOS flow IDs: {}".format( flowIds ) )
+
+        stepResult = main.Mininet1.checkFlowId( "s1", flowIds, debug=False )
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="All flows are in mininet",
+                                 onfail="All flows are NOT in mininet" )
diff --git a/TestON/tests/FUNC/FUNCflow/dependencies/startUp.py b/TestON/tests/FUNC/FUNCflow/dependencies/startUp.py
deleted file mode 100644
index a9becf9..0000000
--- a/TestON/tests/FUNC/FUNCflow/dependencies/startUp.py
+++ /dev/null
@@ -1,33 +0,0 @@
-"""
-    This wrapper function is use for starting up onos instance
-"""
-import time
-import os
-import json
-
-
-def onosBuild( main, gitBranch ):
-    """
-        This includes pulling ONOS and building it using maven install
-    """
-    buildResult = main.FALSE
-
-    # Git checkout a branch of ONOS
-    checkOutResult = main.ONOSbench.gitCheckout( gitBranch )
-    # Does the git pull on the branch that was checked out
-    if not checkOutResult:
-        main.log.warn( "Failed to checked out " + gitBranch +
-                                           " branch" )
-    else:
-        main.log.info( "Successfully checked out " + gitBranch +
-                                           " branch" )
-    gitPullResult = main.ONOSbench.gitPull()
-    if gitPullResult == main.ERROR:
-        main.log.error( "Error pulling git branch" )
-    else:
-        main.log.info( "Successfully pulled " + gitBranch + " branch" )
-
-    # buck build
-    buildResult = main.ONOSbench.buckBuild()
-
-    return buildResult
diff --git a/TestON/tests/FUNC/FUNCflow/dependencies/topo.py b/TestON/tests/FUNC/FUNCflow/dependencies/topo.py
deleted file mode 100644
index 7217d4d..0000000
--- a/TestON/tests/FUNC/FUNCflow/dependencies/topo.py
+++ /dev/null
@@ -1,102 +0,0 @@
-"""
-    These functions can be used for topology comparisons
-"""
-import time
-import os
-import json
-
-
-def getAllDevices( main ):
-    """
-        Return a list containing the devices output from each ONOS node
-    """
-    devices = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].devices,
-                         name="devices-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        devices.append( t.result )
-    return devices
-
-
-def getAllHosts( main ):
-    """
-        Return a list containing the hosts output from each ONOS node
-    """
-    hosts = []
-    ipResult = main.TRUE
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].hosts,
-                         name="hosts-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        hosts.append( t.result )
-    return hosts
-
-
-def getAllPorts( main ):
-    """
-        Return a list containing the ports output from each ONOS node
-    """
-    ports = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].ports,
-                         name="ports-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        ports.append( t.result )
-    return ports
-
-
-def getAllLinks( main ):
-    """
-        Return a list containing the links output from each ONOS node
-    """
-    links = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].links,
-                         name="links-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        links.append( t.result )
-    return links
-
-
-def getAllClusters( main ):
-    """
-        Return a list containing the clusters output from each ONOS node
-    """
-    clusters = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].clusters,
-                         name="clusters-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        clusters.append( t.result )
-    return clusters
diff --git a/TestON/tests/FUNC/FUNCgroup/FUNCgroup.params b/TestON/tests/FUNC/FUNCgroup/FUNCgroup.params
index 585eca3..ca223bd 100644
--- a/TestON/tests/FUNC/FUNCgroup/FUNCgroup.params
+++ b/TestON/tests/FUNC/FUNCgroup/FUNCgroup.params
@@ -10,7 +10,7 @@
     # 7    - Testing GROUP with type "INDIRECT"
     # 8    - Deleting the group and flow
     # 100  - Check logs for Errors and Warnings
-    <testcases>1,2,3,5,6,7,8,100</testcases>
+    <testcases>1,2,3,5,6,7,6,100</testcases>
 
     <SCALE>
         <max>1</max>
diff --git a/TestON/tests/FUNC/FUNCgroup/FUNCgroup.py b/TestON/tests/FUNC/FUNCgroup/FUNCgroup.py
index 4c80ee0..f50e7c5 100644
--- a/TestON/tests/FUNC/FUNCgroup/FUNCgroup.py
+++ b/TestON/tests/FUNC/FUNCgroup/FUNCgroup.py
@@ -6,7 +6,6 @@
     def CASE1( self, main ):
         import os
         import imp
-
         """
         - Construct tests variables
         - GIT ( optional )
@@ -16,90 +15,71 @@
             - Install ONOS package
             - Build ONOS package
         """
-        main.case( "Constructing test variables and building ONOS package" )
-        main.step( "Constructing test variables" )
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        main.testSetUp.envSetupDescription()
+        stepResult = main.FALSE
 
-        # Test variables
-        main.testOnDirectory = os.path.dirname( os.getcwd() )
-        main.cellName = main.params[ 'ENV' ][ 'cellName' ]
-        main.apps = main.params[ 'ENV' ][ 'cellApps' ]
-        gitBranch = main.params[ 'GIT' ][ 'branch' ]
-        gitPull = main.params[ 'GIT' ][ 'pull' ]
-        main.ONOSport = main.params[ 'CTRL' ][ 'port' ]
-        main.dependencyPath = main.testOnDirectory + \
-                              main.params[ 'DEPENDENCY' ][ 'path' ]
-        wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
-        wrapperFile2 = main.params[ 'DEPENDENCY' ][ 'wrapper2' ]
-        main.topology = main.params[ 'DEPENDENCY' ][ 'topology' ]
-        bucket = main.params[ 'DEPENDENCY' ][ 'bucket' ]
-        main.maxNodes = int( main.params[ 'SCALE' ][ 'max' ] )
-        main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
-        main.startMNSleep = int( main.params[ 'SLEEP' ][ 'startMN' ] )
-        main.addFlowSleep = int( main.params[ 'SLEEP' ][ 'addFlow' ] )
-        main.delFlowSleep = int( main.params[ 'SLEEP' ][ 'delFlow' ] )
-        main.addGroupSleep = int( main.params[ 'SLEEP' ][ 'addGroup' ] )
-        main.delGroupSleep = int( main.params[ 'SLEEP' ][ 'delGroup' ] )
-        main.debug = main.params[ 'DEBUG' ]
-        main.swDPID = main.params[ 'TEST' ][ 'swDPID' ]
-        egressPort1 = main.params[ 'TEST' ][ 'egressPort1' ]
-        egressPort2 = main.params[ 'TEST' ][ 'egressPort2' ]
-        egressPort3 = main.params[ 'TEST' ][ 'egressPort3' ]
-        ingressPort = main.params[ 'TEST' ][ 'ingressPort' ]
-        appCookie = main.params[ 'TEST' ][ 'appCookie' ]
-        type1 = main.params[ 'TEST' ][ 'type1' ]
-        type2 = main.params[ 'TEST' ][ 'type2' ]
-        groupId = main.params[ 'TEST' ][ 'groupId' ]
-        priority = main.params[ 'TEST' ][ 'priority' ]
-        deviceId = main.params[ 'TEST' ][ 'swDPID' ]
+        try:
+            # Test variables
+            main.cellName = main.params['ENV']['cellName']
+            main.apps = main.params['ENV']['cellApps']
+            main.ONOSport = main.params['CTRL']['port']
+            main.dependencyPath = main.testOnDirectory + \
+                                  main.params['DEPENDENCY']['path']
+            wrapperFile1 = main.params['DEPENDENCY']['wrapper1']
+            wrapperFile2 = main.params['DEPENDENCY']['wrapper2']
+            main.topology = main.params['DEPENDENCY']['topology']
+            bucket = main.params['DEPENDENCY']['bucket']
+            main.maxNodes = int(main.params['SCALE']['max'])
+            main.startUpSleep = int(main.params['SLEEP']['startup'])
+            main.startMNSleep = int(main.params['SLEEP']['startMN'])
+            main.addFlowSleep = int(main.params['SLEEP']['addFlow'])
+            main.delFlowSleep = int(main.params['SLEEP']['delFlow'])
+            main.addGroupSleep = int(main.params['SLEEP']['addGroup'])
+            main.delGroupSleep = int(main.params['SLEEP']['delGroup'])
+            main.debug = main.params['DEBUG']
+            main.swDPID = main.params['TEST']['swDPID']
+            egressPort1 = main.params['TEST']['egressPort1']
+            egressPort2 = main.params['TEST']['egressPort2']
+            egressPort3 = main.params['TEST']['egressPort3']
+            ingressPort = main.params['TEST']['ingressPort']
+            appCookie = main.params['TEST']['appCookie']
+            type1 = main.params['TEST']['type1']
+            type2 = main.params['TEST']['type2']
+            groupId = main.params['TEST']['groupId']
+            priority = main.params['TEST']['priority']
+            deviceId = main.params['TEST']['swDPID']
 
-        main.cellData = {}  # for creating cell file
-        main.CLIs = []
-        main.ONOSip = []
+            main.debug = True if "on" in main.debug else False
+            # -- INIT SECTION, ONLY RUNS ONCE -- #
 
-        main.debug = True if "on" in main.debug else False
+            main.buckets = imp.load_source(bucket,
+                                           main.dependencyPath +
+                                           bucket +
+                                           ".py")
 
-        main.ONOSip = main.ONOSbench.getOnosIps()
+            copyResult = main.ONOSbench.scp(main.Mininet1,
+                                            main.dependencyPath + main.topology,
+                                            main.Mininet1.home + '/custom/',
+                                            direction="to")
 
-        # Assigning ONOS cli handles to a list
-        for i in range( 1, main.maxNodes + 1 ):
-            main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
+            utilities.assert_equals(expect=main.TRUE,
+                                    actual=copyResult,
+                                    onpass="Successfully copy " + "test variables ",
+                                    onfail="Failed to copy test variables")
+            stepResult = main.testSetUp.envSetup()
 
-        # -- INIT SECTION, ONLY RUNS ONCE -- #
-        main.startUp = imp.load_source( wrapperFile1,
-                                        main.dependencyPath +
-                                        wrapperFile1 +
-                                        ".py" )
+        except Exception as e:
+            main.testSetUp.envSetupException( e )
 
-        main.topo = imp.load_source( wrapperFile2,
-                                     main.dependencyPath +
-                                     wrapperFile2 +
-                                     ".py" )
+        main.testSetUp.evnSetupConclusion( stepResult )
 
-        main.buckets = imp.load_source( bucket,
-                                        main.dependencyPath +
-                                        bucket +
-                                        ".py" )
 
-        copyResult = main.ONOSbench.scp( main.Mininet1,
-                                         main.dependencyPath + main.topology,
-                                         main.Mininet1.home + '/custom/',
-                                         direction="to" )
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=copyResult,
-                                 onpass="Successfully copy " + "test variables ",
-                                 onfail="Failed to copy test variables" )
-
-        if main.CLIs:
-            stepResult = main.TRUE
-        else:
-            main.log.error( "Did not properly created list of ONOS CLI handle" )
-            stepResult = main.FALSE
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully construct " + "test variables ",
-                                 onfail="Failed to construct test variables" )
 
     def CASE2( self, main ):
         """
@@ -113,121 +93,23 @@
         - Install ONOS cluster
         - Connect to cli
         """
-        import time
-
-        main.numCtrls = int( main.maxNodes )
-
-        main.case( "Starting up " + str( main.numCtrls ) +
-                   " node(s) ONOS cluster" )
-
-        #kill off all onos processes
-        main.log.info( "Safety check, killing all ONOS processes" +
-                       " before initiating environment setup" )
-
-        for i in range( main.maxNodes ):
-            main.ONOSbench.onosDie( main.ONOSip[ i ] )
-
-        main.log.info( "NODE COUNT = " + str( main.numCtrls ) )
-
-        tempOnosIp = []
-        for i in range( main.numCtrls ):
-            tempOnosIp.append( main.ONOSip[ i ] )
-
-        main.ONOSbench.createCellFile( main.ONOSbench.ip_address,
-                                       "temp",
-                                       main.Mininet1.ip_address,
-                                       main.apps,
-                                       tempOnosIp, main.ONOScli1.karafUser )
-
-        main.step( "Apply cell to environment" )
-        cellResult = main.ONOSbench.setCell( "temp" )
-        verifyResult = main.ONOSbench.verifyCell()
-        stepResult = cellResult and verifyResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully applied cell to " + "environment",
-                                 onfail="Failed to apply cell to environment " )
-
-        main.step( "Creating ONOS package" )
-        packageResult = main.ONOSbench.buckBuild()
-        stepResult = packageResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully created ONOS package",
-                                 onfail="Failed to create ONOS package" )
-
-        time.sleep( main.startUpSleep )
-        main.step( "Uninstalling ONOS package" )
-        onosUninstallResult = main.TRUE
-        for ip in main.ONOSip:
-            onosUninstallResult = onosUninstallResult and \
-                    main.ONOSbench.onosUninstall( nodeIp=ip )
-        stepResult = onosUninstallResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully uninstalled ONOS package",
-                                 onfail="Failed to uninstall ONOS package" )
-        time.sleep( main.startUpSleep )
-        main.step( "Installing ONOS package" )
-        onosInstallResult = main.TRUE
-        for i in range( main.numCtrls ):
-            onosInstallResult = onosInstallResult and \
-                    main.ONOSbench.onosInstall( node=main.ONOSip[ i ] )
-        stepResult = onosInstallResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully installed ONOS package",
-                                 onfail="Failed to install ONOS package" )
-
-        time.sleep( main.startUpSleep )
-        main.step( "Starting ONOS service" )
-        stopResult = main.TRUE
-        startResult = main.TRUE
-        onosIsUp = main.TRUE
-
-        for i in range( main.numCtrls ):
-            onosIsUp = onosIsUp and main.ONOSbench.isup( main.ONOSip[ i ] )
-        if onosIsUp == main.TRUE:
-            main.log.report( "ONOS instance is up and ready" )
-        else:
-            main.log.report( "ONOS instance may not be up, stop and " +
-                             "start ONOS again " )
-            for i in range( main.numCtrls ):
-                stopResult = stopResult and \
-                        main.ONOSbench.onosStop( main.ONOSip[ i ] )
-            for i in range( main.numCtrls ):
-                startResult = startResult and \
-                        main.ONOSbench.onosStart( main.ONOSip[ i ] )
-        stepResult = onosIsUp and stopResult and startResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="ONOS service is ready",
-                                 onfail="ONOS service did not start properly" )
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.TRUE
-        for i in range( int( main.numCtrls ) ):
-            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=main.ONOSip[ i ] )
-        utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        main.step( "Start ONOS cli" )
-        cliResult = main.TRUE
-        for i in range( main.numCtrls ):
-            cliResult = cliResult and \
-                        main.CLIs[ i ].startOnosCli( main.ONOSip[ i ] )
-        stepResult = cliResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully start ONOS cli",
-                                 onfail="Failed to start ONOS cli" )
+        main.testSetUp.ONOSSetUp( main.Mininet1 )
 
     def CASE3( self, main ):
         """
             Start Mininet
         """
         import json
+        import time
+        try:
+            from tests.dependencies.topology import Topology
+        except ImportError:
+            main.log.error( "Topology not found exiting the test" )
+            main.exit()
+        try:
+            main.topoRelated
+        except ( NameError, AttributeError ):
+            main.topoRelated = Topology()
 
         main.case( "Setup mininet and compare ONOS topology view to Mininet topology" )
         main.caseExplanation = "Start mininet with custom topology and compare topology " +\
@@ -252,60 +134,7 @@
 
         time.sleep( main.startMNSleep )
 
-        main.step( "Comparing MN topology to ONOS topology" )
-        main.log.info( "Gathering topology information" )
-        devices = main.topo.getAllDevices( main )
-        hosts = main.topo.getAllHosts( main )
-        ports = main.topo.getAllPorts( main )
-        links = main.topo.getAllLinks( main )
-
-        mnSwitches = main.Mininet1.getSwitches()
-        mnLinks = main.Mininet1.getLinks()
-        mnHosts = main.Mininet1.getHosts()
-
-        for controller in range( main.numCtrls ):
-            controllerStr = str( controller + 1 )
-            if devices[ controller ] and ports[ controller ] and\
-                    "Error" not in devices[ controller ] and\
-                    "Error" not in ports[ controller ]:
-
-                currentDevicesResult = main.Mininet1.compareSwitches(
-                        mnSwitches,
-                        json.loads( devices[ controller ] ),
-                        json.loads( ports[ controller ] ) )
-            else:
-                currentDevicesResult = main.FALSE
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=currentDevicesResult,
-                                     onpass="ONOS" + controllerStr +
-                                            " Switches view is correct",
-                                     onfail="ONOS" + controllerStr +
-                                            " Switches view is incorrect" )
-            if links[ controller ] and "Error" not in links[ controller ]:
-                currentLinksResult = main.Mininet1.compareLinks(
-                        mnSwitches, mnLinks,
-                        json.loads( links[ controller ] ) )
-            else:
-                currentLinksResult = main.FALSE
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=currentLinksResult,
-                                     onpass="ONOS" + controllerStr +
-                                            " links view is correct",
-                                     onfail="ONOS" + controllerStr +
-                                            " links view is incorrect" )
-
-            if hosts[ controller ] or "Error" not in hosts[ controller ]:
-                currentHostsResult = main.Mininet1.compareHosts(
-                        mnHosts,
-                        json.loads( hosts[ controller ] ) )
-            else:
-                currentHostsResult = main.FALSE
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=currentHostsResult,
-                                     onpass="ONOS" + controllerStr +
-                                            " hosts exist in Mininet",
-                                     onfail="ONOS" + controllerStr +
-                                            " hosts don't match Mininet" )
+        main.topoRelated.compareTopos( main.Mininet1 )
 
     def CASE4( self, main ):
         """
@@ -459,7 +288,7 @@
         """
         Sends a packet using  scapy
         """
-        main.step( "Testing Group by sending packet using  Scapy" )
+        main.step( "Testing Group by sending packet using Scapy" )
         main.log.info( "Creating host components" )
         main.Scapy.createHostComponent( "h1" )
         main.Scapy.createHostComponent( "h2" )
@@ -640,7 +469,7 @@
         """
         Sends a packet using scapy
         """
-        main.step( "Testing Group by sending packet using  Scapy" )
+        main.step( "Testing Group by sending packet using Scapy" )
         main.log.info( "Creating host components" )
         main.Scapy.createHostComponent( "h1" )
         main.Scapy.createHostComponent( "h2" )
@@ -676,47 +505,6 @@
                                  onpass="Packet sent to port 1 is received at port 2 successfully!!!",
                                  onfail="Failure!!!Packet sent to port 1 is not received at port 2" )
 
-    def CASE8( self, main ):
-        """
-         Deleting the Group and Flow
-        """
-        import json
-        import time
-        respFlowId = 1
-
-        main.case( "Delete the Group and Flow added through Rest api " )
-        main.step( "Deleting Group and Flows" )
-
-        #Getting Flow ID
-        response = main.ONOSrest.getFlows( deviceId=deviceId )
-        responsejson = json.loads( response )
-        for item in responsejson:
-            if item[ "priority" ] == int( priority ):
-                respFlowId = item[ "id" ]
-
-        main.step( "Deleting the created flow by deviceId and flowId" )
-        flowResponse = main.ONOSrest.removeFlow( deviceId=deviceId,
-                                                 flowId=respFlowId )
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=flowResponse,
-                                 onpass="Deleting flow is successful!!!",
-                                 onfail="Deleting flow is failure!!!" )
-
-        # Giving ONOS time to delete the flow
-        time.sleep( main.delFlowSleep )
-
-        groupResponse = main.ONOSrest.removeGroup( deviceId=deviceId,
-                                                   appCookie=appCookie )
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=groupResponse,
-                                 onpass="Deleting Group is successful!!!",
-                                 onfail="Deleting Group is failure!!!" )
-
-        # Giving ONOS time to delete the group
-        time.sleep( main.delGroupSleep )
-
     def CASE100( self, main ):
         """
             Report errors/warnings/exceptions
diff --git a/TestON/tests/FUNC/FUNCgroup/dependencies/startUp.py b/TestON/tests/FUNC/FUNCgroup/dependencies/startUp.py
deleted file mode 100644
index a9becf9..0000000
--- a/TestON/tests/FUNC/FUNCgroup/dependencies/startUp.py
+++ /dev/null
@@ -1,33 +0,0 @@
-"""
-    This wrapper function is use for starting up onos instance
-"""
-import time
-import os
-import json
-
-
-def onosBuild( main, gitBranch ):
-    """
-        This includes pulling ONOS and building it using maven install
-    """
-    buildResult = main.FALSE
-
-    # Git checkout a branch of ONOS
-    checkOutResult = main.ONOSbench.gitCheckout( gitBranch )
-    # Does the git pull on the branch that was checked out
-    if not checkOutResult:
-        main.log.warn( "Failed to checked out " + gitBranch +
-                                           " branch" )
-    else:
-        main.log.info( "Successfully checked out " + gitBranch +
-                                           " branch" )
-    gitPullResult = main.ONOSbench.gitPull()
-    if gitPullResult == main.ERROR:
-        main.log.error( "Error pulling git branch" )
-    else:
-        main.log.info( "Successfully pulled " + gitBranch + " branch" )
-
-    # buck build
-    buildResult = main.ONOSbench.buckBuild()
-
-    return buildResult
diff --git a/TestON/tests/FUNC/FUNCgroup/dependencies/topo.py b/TestON/tests/FUNC/FUNCgroup/dependencies/topo.py
deleted file mode 100644
index 7217d4d..0000000
--- a/TestON/tests/FUNC/FUNCgroup/dependencies/topo.py
+++ /dev/null
@@ -1,102 +0,0 @@
-"""
-    These functions can be used for topology comparisons
-"""
-import time
-import os
-import json
-
-
-def getAllDevices( main ):
-    """
-        Return a list containing the devices output from each ONOS node
-    """
-    devices = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].devices,
-                         name="devices-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        devices.append( t.result )
-    return devices
-
-
-def getAllHosts( main ):
-    """
-        Return a list containing the hosts output from each ONOS node
-    """
-    hosts = []
-    ipResult = main.TRUE
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].hosts,
-                         name="hosts-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        hosts.append( t.result )
-    return hosts
-
-
-def getAllPorts( main ):
-    """
-        Return a list containing the ports output from each ONOS node
-    """
-    ports = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].ports,
-                         name="ports-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        ports.append( t.result )
-    return ports
-
-
-def getAllLinks( main ):
-    """
-        Return a list containing the links output from each ONOS node
-    """
-    links = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].links,
-                         name="links-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        links.append( t.result )
-    return links
-
-
-def getAllClusters( main ):
-    """
-        Return a list containing the clusters output from each ONOS node
-    """
-    clusters = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].clusters,
-                         name="clusters-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        clusters.append( t.result )
-    return clusters
diff --git a/TestON/tests/FUNC/FUNCintent/FUNCintent.py b/TestON/tests/FUNC/FUNCintent/FUNCintent.py
index cfca916..77ad5f9 100644
--- a/TestON/tests/FUNC/FUNCintent/FUNCintent.py
+++ b/TestON/tests/FUNC/FUNCintent/FUNCintent.py
@@ -9,7 +9,6 @@
     def CASE1( self, main ):
         import imp
         import re
-
         """
         - Construct tests variables
         - GIT ( optional )
@@ -19,26 +18,24 @@
             - Install ONOS package
             - Build ONOS package
         """
-        main.case( "Constructing test variables and building ONOS package" )
-        main.step( "Constructing test variables" )
-        main.caseExplanation = "This test case is mainly for loading " +\
-                               "from params file, and pull and build the " +\
-                               " latest ONOS package"
+
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        main.testSetUp.envSetupDescription()
         stepResult = main.FALSE
 
         # Test variables
         try:
-            main.testOnDirectory = re.sub( "(/tests)$", "", main.testDir )
             main.apps = main.params[ 'ENV' ][ 'cellApps' ]
-            gitBranch = main.params[ 'GIT' ][ 'branch' ]
             main.dependencyPath = main.testOnDirectory + \
                                   main.params[ 'DEPENDENCY' ][ 'path' ]
             main.topology = main.params[ 'DEPENDENCY' ][ 'topology' ]
             main.scale = ( main.params[ 'SCALE' ][ 'size' ] ).split( "," )
-            if main.ONOSbench.maxNodes:
-                main.maxNodes = int( main.ONOSbench.maxNodes )
-            else:
-                main.maxNodes = 0
+
             wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
             wrapperFile2 = main.params[ 'DEPENDENCY' ][ 'wrapper2' ]
             wrapperFile3 = main.params[ 'DEPENDENCY' ][ 'wrapper3' ]
@@ -53,63 +50,31 @@
             main.checkIntentPointSleep = int( main.params[ 'SLEEP' ][ 'checkIntentPoint' ] )
             main.checkTopoAttempts = int( main.params[ 'SLEEP' ][ 'topoAttempts' ] )
             main.flowDurationSleep = int( main.params[ 'SLEEP' ][ 'flowDuration' ] )
-            gitPull = main.params[ 'GIT' ][ 'pull' ]
             main.numSwitch = int( main.params[ 'MININET' ][ 'switch' ] )
             main.numLinks = int( main.params[ 'MININET' ][ 'links' ] )
-            main.cellData = {}  # for creating cell file
             main.hostsData = {}
-            main.CLIs = []
-            main.ONOSip = []
             main.scapyHostNames = main.params[ 'SCAPY' ][ 'HOSTNAMES' ].split( ',' )
             main.scapyHosts = []  # List of scapy hosts for iterating
             main.assertReturnString = ''  # Assembled assert return string
             main.cycle = 0  # How many times FUNCintent has run through its tests
 
-            main.ONOSip = main.ONOSbench.getOnosIps()
-            main.log.debug( "Found ONOS ips: {}".format( main.ONOSip ) )
-
-            # Assigning ONOS cli handles to a list
-            for i in range( 1, main.maxNodes + 1 ):
-                main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
-
             # -- INIT SECTION, ONLY RUNS ONCE -- #
-            main.startUp = imp.load_source( wrapperFile1,
-                                            main.dependencyPath +
-                                            wrapperFile1 +
-                                            ".py" )
 
             main.intents = imp.load_source( wrapperFile2,
                                             main.dependencyPath +
                                             wrapperFile2 +
                                             ".py" )
 
-            main.topo = imp.load_source( wrapperFile3,
-                                         main.dependencyPath +
-                                         wrapperFile3 +
-                                         ".py" )
-
             copyResult1 = main.ONOSbench.scp( main.Mininet1,
                                               main.dependencyPath +
                                               main.topology,
                                               main.Mininet1.home + "custom/",
                                               direction="to" )
-            if main.CLIs:
-                stepResult = main.TRUE
-            else:
-                main.log.error( "Did not properly created list of ONOS CLI handle" )
-                stepResult = main.FALSE
+
+            stepResult = main.testSetUp.envSetup( True )
         except Exception as e:
-            main.log.exception( e )
-            main.cleanup()
-            main.exit()
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully construct " +
-                                        "test variables ",
-                                 onfail="Failed to construct test variables" )
-
-        main.ONOSbench.getVersion( report=True )
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
 
     def CASE2( self, main ):
         """
@@ -123,245 +88,26 @@
         - Install ONOS cluster
         - Connect to cli
         """
-        import time
-        main.cycle += 1
 
-        # main.scale[ 0 ] determines the current number of ONOS controller
-        main.numCtrls = int( main.scale[ 0 ] )
         main.flowCompiler = "Flow Rules"
-        main.initialized = main.TRUE
-
-        main.case( "Starting up " + str( main.numCtrls ) +
-                   " node(s) ONOS cluster" )
-        main.caseExplanation = "Set up ONOS with " + str( main.numCtrls ) +\
-                                " node(s) ONOS cluster"
-
-        #kill off all onos processes
-        main.log.info( "Safety check, killing all ONOS processes" +
-                       " before initiating environment setup" )
-
-        main.step( "Uninstalling ONOS package" )
-        onosUninstallResult = main.TRUE
-        for ip in main.ONOSip:
-            onosUninstallResult = onosUninstallResult and \
-                    main.ONOSbench.onosUninstall( nodeIp=ip )
-        stepResult = onosUninstallResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully uninstalled ONOS package",
-                                 onfail="Failed to uninstall ONOS package" )
-        for i in range( main.maxNodes ):
-            main.ONOSbench.onosDie( main.ONOSip[ i ] )
-
-        main.log.debug( "NODE COUNT = " + str( main.numCtrls ) )
-
-        tempOnosIp = []
-        for i in range( main.numCtrls ):
-            tempOnosIp.append( main.ONOSip[ i ] )
-
-        main.ONOSbench.createCellFile( main.ONOSbench.ip_address,
-                                       "temp", main.Mininet1.ip_address,
-                                       main.apps, tempOnosIp, main.ONOScli1.karafUser )
-
-        main.step( "Apply cell to environment" )
-        cellResult = main.ONOSbench.setCell( "temp" )
-        verifyResult = main.ONOSbench.verifyCell()
-        stepResult = cellResult and verifyResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully applied cell to " +
-                                        "environment",
-                                 onfail="Failed to apply cell to environment " )
-
-        main.step( "Creating ONOS package" )
-        packageResult = main.ONOSbench.buckBuild()
-        stepResult = packageResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully created ONOS package",
-                                 onfail="Failed to create ONOS package" )
-
-        main.step( "Installing ONOS package" )
-        onosInstallResult = main.TRUE
-        for i in range( main.numCtrls ):
-            onosInstallResult = onosInstallResult and \
-                    main.ONOSbench.onosInstall( node=main.ONOSip[ i ] )
-        stepResult = onosInstallResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully installed ONOS package",
-                                 onfail="Failed to install ONOS package" )
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.TRUE
-        for i in range( int( main.numCtrls ) ):
-            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=main.ONOSip[ i ] )
-        utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        main.log.info( "Sleeping {} seconds".format( main.startUpSleep ) )
-        time.sleep( main.startUpSleep )
-        main.step( "Checking ONOS is running" )
-        stopResult = main.TRUE
-        startResult = main.TRUE
-        onosIsUp = main.TRUE
-
-        for i in range( main.numCtrls ):
-            isUp = main.ONOSbench.isup( main.ONOSip[ i ] )
-            onosIsUp = onosIsUp and isUp
-            if isUp == main.TRUE:
-                main.log.report( "ONOS instance {0} is up and ready".format( i + 1 ) )
-            else:
-                main.log.report( "ONOS instance {0} may not be up, stop and ".format( i + 1 ) +
-                                 "start ONOS again " )
-                stopResult = stopResult and main.ONOSbench.onosStop( main.ONOSip[ i ] )
-                startResult = startResult and main.ONOSbench.onosStart( main.ONOSip[ i ] )
-                if not startResult or stopResult:
-                    main.log.report( "ONOS instance {0} did not start correctly.".format( i + 1 ) )
-        stepResult = onosIsUp and stopResult and startResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="ONOS service is ready on all nodes",
-                                 onfail="ONOS service did not start properly on all nodes" )
-
-        main.step( "Start ONOS cli" )
-        cliResult = main.TRUE
-        for i in range( main.numCtrls ):
-            cliResult = cliResult and \
-                        main.CLIs[ i ].startOnosCli( main.ONOSip[ i ] )
-        stepResult = cliResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully start ONOS cli",
-                                 onfail="Failed to start ONOS cli" )
-        if not stepResult:
-            main.initialized = main.FALSE
-
-        # Remove the first element in main.scale list
-        main.scale.remove( main.scale[ 0 ] )
-
+        main.initialized = main.testSetUp.ONOSSetUp( main.Mininet1, True )
         main.intents.report( main )
 
     def CASE8( self, main ):
         """
         Compare ONOS Topology to Mininet Topology
         """
-        import json
-
-        main.case( "Compare ONOS Topology view to Mininet topology" )
-        main.caseExplanation = "Compare topology elements between Mininet" +\
-                                " and ONOS"
-
-        main.log.info( "Gathering topology information from Mininet" )
-        devicesResults = main.FALSE  # Overall Boolean for device correctness
-        linksResults = main.FALSE  # Overall Boolean for link correctness
-        hostsResults = main.FALSE  # Overall Boolean for host correctness
-        deviceFails = []  # Nodes where devices are incorrect
-        linkFails = []  # Nodes where links are incorrect
-        hostFails = []  # Nodes where hosts are incorrect
-        attempts = main.checkTopoAttempts  # Remaining Attempts
-
-        mnSwitches = main.Mininet1.getSwitches()
-        mnLinks = main.Mininet1.getLinks()
-        mnHosts = main.Mininet1.getHosts()
-
-        main.step( "Comparing Mininet topology to ONOS topology" )
-
-        while ( attempts >= 0 ) and\
-                ( not devicesResults or not linksResults or not hostsResults ):
-            main.log.info( "Sleeping {} seconds".format( 2 ) )
-            time.sleep( 2 )
-            if not devicesResults:
-                devices = main.topo.getAllDevices( main )
-                ports = main.topo.getAllPorts( main )
-                devicesResults = main.TRUE
-                deviceFails = []  # Reset for each failed attempt
-            if not linksResults:
-                links = main.topo.getAllLinks( main )
-                linksResults = main.TRUE
-                linkFails = []  # Reset for each failed attempt
-            if not hostsResults:
-                hosts = main.topo.getAllHosts( main )
-                hostsResults = main.TRUE
-                hostFails = []  # Reset for each failed attempt
-
-            #  Check for matching topology on each node
-            for controller in range( main.numCtrls ):
-                controllerStr = str( controller + 1 )  # ONOS node number
-                # Compare Devices
-                if devices[ controller ] and ports[ controller ] and\
-                        "Error" not in devices[ controller ] and\
-                        "Error" not in ports[ controller ]:
-
-                    try:
-                        deviceData = json.loads( devices[ controller ] )
-                        portData = json.loads( ports[ controller ] )
-                    except( TypeError, ValueError ):
-                        main.log.error( "Could not load json: {0} or {1}".format( str( devices[ controller ] ), str( ports[ controller ] ) ) )
-                        currentDevicesResult = main.FALSE
-                    else:
-                        currentDevicesResult = main.Mininet1.compareSwitches(
-                            mnSwitches, deviceData, portData )
-                else:
-                    currentDevicesResult = main.FALSE
-                if not currentDevicesResult:
-                    deviceFails.append( controllerStr )
-                devicesResults = devicesResults and currentDevicesResult
-                # Compare Links
-                if links[ controller ] and "Error" not in links[ controller ]:
-                    try:
-                        linkData = json.loads( links[ controller ] )
-                    except( TypeError, ValueError ):
-                        main.log.error( "Could not load json:" + str( links[ controller ] ) )
-                        currentLinksResult = main.FALSE
-                    else:
-                        currentLinksResult = main.Mininet1.compareLinks(
-                            mnSwitches, mnLinks, linkData )
-                else:
-                    currentLinksResult = main.FALSE
-                if not currentLinksResult:
-                    linkFails.append( controllerStr )
-                linksResults = linksResults and currentLinksResult
-                # Compare Hosts
-                if hosts[ controller ] and "Error" not in hosts[ controller ]:
-                    try:
-                        hostData = json.loads( hosts[ controller ] )
-                    except( TypeError, ValueError ):
-                        main.log.error( "Could not load json:" + str( hosts[ controller ] ) )
-                        currentHostsResult = main.FALSE
-                    else:
-                        currentHostsResult = main.Mininet1.compareHosts(
-                                mnHosts, hostData )
-                else:
-                    currentHostsResult = main.FALSE
-                if not currentHostsResult:
-                    hostFails.append( controllerStr )
-                hostsResults = hostsResults and currentHostsResult
-            # Decrement Attempts Remaining
-            attempts -= 1
-
-        utilities.assert_equals( expect=[],
-                                 actual=deviceFails,
-                                 onpass="ONOS correctly discovered all devices",
-                                 onfail="ONOS incorrectly discovered devices on nodes: " +
-                                 str( deviceFails ) )
-        utilities.assert_equals( expect=[],
-                                 actual=linkFails,
-                                 onpass="ONOS correctly discovered all links",
-                                 onfail="ONOS incorrectly discovered links on nodes: " +
-                                 str( linkFails ) )
-        utilities.assert_equals( expect=[],
-                                 actual=hostFails,
-                                 onpass="ONOS correctly discovered all hosts",
-                                 onfail="ONOS incorrectly discovered hosts on nodes: " +
-                                 str( hostFails ) )
-        topoResults = hostsResults and linksResults and devicesResults
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=topoResults,
-                                 onpass="ONOS correctly discovered the topology",
-                                 onfail="ONOS incorrectly discovered the topology" )
-
+        import time
+        try:
+            from tests.dependencies.topology import Topology
+        except ImportError:
+            main.log.error( "Topology not found exiting the test" )
+            main.exit()
+        try:
+            main.topoRelated
+        except ( NameError, AttributeError ):
+            main.topoRelated = Topology()
+        main.topoRelated.compareTopos( main.Mininet1, main.checkTopoAttempts )
     def CASE10( self, main ):
         """
             Start Mininet topology with OF 1.0 switches
@@ -619,6 +365,15 @@
         """
             Stop mininet and remove scapy host
         """
+        try:
+            from tests.dependencies.utils import Utils
+        except ImportError:
+            main.log.error( "Utils not found exiting the test" )
+            main.exit()
+        try:
+            main.Utils
+        except ( NameError, AttributeError ):
+            main.Utils = Utils()
         main.log.report( "Stop Mininet and Scapy" )
         main.case( "Stop Mininet and Scapy" )
         main.caseExplanation = "Stopping the current mininet topology " +\
@@ -641,13 +396,7 @@
                                  onpass="Successfully stopped scapy and removed host components",
                                  onfail="Failed to stop mininet and scapy" )
 
-        main.step( "Stopping Mininet Topology" )
-        mininetResult = main.Mininet1.stopNet()
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=mininetResult,
-                                 onpass="Successfully stopped mininet and scapy",
-                                 onfail="Failed to stop mininet and scapy" )
+        mininetResult = main.Utils.mininetCleanup( main.Mininet1 )
         # Exit if topology did not load properly
         if not ( mininetResult and scapyResult ):
             main.cleanup()
@@ -657,33 +406,16 @@
         """
             Copy the karaf.log files after each testcase cycle
         """
-        main.log.report( "Copy karaf logs" )
-        main.case( "Copy karaf logs" )
-        main.caseExplanation = "Copying the karaf logs to preserve them through" +\
-                               "reinstalling ONOS"
-        main.step( "Copying karaf logs" )
-        stepResult = main.TRUE
-        scpResult = main.TRUE
-        copyResult = main.TRUE
-        for i in range( main.numCtrls ):
-            main.node = main.CLIs[ i ]
-            ip = main.ONOSip[ i ]
-            main.node.ip_address = ip
-            scpResult = scpResult and main.ONOSbench.scp( main.node,
-                                                          "/opt/onos/log/karaf.log",
-                                                          "/tmp/karaf.log",
-                                                          direction="from" )
-            copyResult = copyResult and main.ONOSbench.cpLogsToDir( "/tmp/karaf.log", main.logdir,
-                                                                    copyFileName=( "karaf.log.node{0}.cycle{1}".format( str( i + 1 ), str( main.cycle ) ) ) )
-            if scpResult and copyResult:
-                stepResult = main.TRUE and stepResult
-            else:
-                stepResult = main.FALSE and stepResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully copied remote ONOS logs",
-                                 onfail="Failed to copy remote ONOS logs" )
-
+        try:
+            from tests.dependencies.utils import Utils
+        except ImportError:
+            main.log.error( "Utils not found exiting the test" )
+            main.exit()
+        try:
+            main.Utils
+        except ( NameError, AttributeError ):
+            main.Utils = Utils()
+        main.Utils.copyKarafLog()
     def CASE1000( self, main ):
         """
             Add host intents between 2 host:
diff --git a/TestON/tests/FUNC/FUNCintent/dependencies/FuncIntentFunction.py b/TestON/tests/FUNC/FUNCintent/dependencies/FuncIntentFunction.py
index 9159e4d..d08154e 100644
--- a/TestON/tests/FUNC/FUNCintent/dependencies/FuncIntentFunction.py
+++ b/TestON/tests/FUNC/FUNCintent/dependencies/FuncIntentFunction.py
@@ -1911,7 +1911,16 @@
         Confirms that all ONOS nodes have discovered all scapy hosts
     """
     import collections
-    hosts = main.topo.getAllHosts( main )  # Get host data from each ONOS node
+    try:
+        from tests.dependencies.topology import Topology
+    except Exception:
+        main.log.error( "Topology not found exiting the test" )
+        main.exit()
+    try:
+        main.topoRelated
+    except Exception:
+        main.topoRelated = Topology()
+    hosts = main.topoRelated.getAllHosts( main.numCtrls, False )  # Get host data from each ONOS node
     hostFails = []  # Reset for each failed attempt
 
     #  Check for matching hosts on each node
diff --git a/TestON/tests/FUNC/FUNCintent/dependencies/startUp.py b/TestON/tests/FUNC/FUNCintent/dependencies/startUp.py
deleted file mode 100644
index ad92fb9..0000000
--- a/TestON/tests/FUNC/FUNCintent/dependencies/startUp.py
+++ /dev/null
@@ -1,33 +0,0 @@
-"""
-    This wrapper function is use for starting up onos instance
-"""
-import time
-import os
-import json
-
-
-def onosBuild( main, gitBranch ):
-    """
-        This includes pulling ONOS and building it using maven install
-    """
-    buildResult = main.FALSE
-
-    # Git checkout a branch of ONOS
-    checkOutResult = main.ONOSbench.gitCheckout( gitBranch )
-    # Does the git pull on the branch that was checked out
-    if not checkOutResult:
-        main.log.warn( "Failed to checked out " + gitBranch +
-                                           " branch" )
-    else:
-        main.log.info( "Successfully checked out " + gitBranch +
-                                           " branch" )
-    gitPullResult = main.ONOSbench.gitPull()
-    if gitPullResult == main.ERROR:
-        main.log.error( "Error pulling git branch" )
-    else:
-        main.log.info( "Successfully pulled " + gitBranch + " branch" )
-
-    # buck Build
-    buildResult = main.ONOSbench.buckBuild()
-
-    return buildResult
diff --git a/TestON/tests/FUNC/FUNCintent/dependencies/topo.py b/TestON/tests/FUNC/FUNCintent/dependencies/topo.py
deleted file mode 100644
index 7217d4d..0000000
--- a/TestON/tests/FUNC/FUNCintent/dependencies/topo.py
+++ /dev/null
@@ -1,102 +0,0 @@
-"""
-    These functions can be used for topology comparisons
-"""
-import time
-import os
-import json
-
-
-def getAllDevices( main ):
-    """
-        Return a list containing the devices output from each ONOS node
-    """
-    devices = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].devices,
-                         name="devices-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        devices.append( t.result )
-    return devices
-
-
-def getAllHosts( main ):
-    """
-        Return a list containing the hosts output from each ONOS node
-    """
-    hosts = []
-    ipResult = main.TRUE
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].hosts,
-                         name="hosts-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        hosts.append( t.result )
-    return hosts
-
-
-def getAllPorts( main ):
-    """
-        Return a list containing the ports output from each ONOS node
-    """
-    ports = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].ports,
-                         name="ports-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        ports.append( t.result )
-    return ports
-
-
-def getAllLinks( main ):
-    """
-        Return a list containing the links output from each ONOS node
-    """
-    links = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].links,
-                         name="links-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        links.append( t.result )
-    return links
-
-
-def getAllClusters( main ):
-    """
-        Return a list containing the clusters output from each ONOS node
-    """
-    clusters = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].clusters,
-                         name="clusters-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        clusters.append( t.result )
-    return clusters
diff --git a/TestON/tests/FUNC/FUNCintentRest/FUNCintentRest.py b/TestON/tests/FUNC/FUNCintentRest/FUNCintentRest.py
index e1d26b0..0e96d69 100644
--- a/TestON/tests/FUNC/FUNCintentRest/FUNCintentRest.py
+++ b/TestON/tests/FUNC/FUNCintentRest/FUNCintentRest.py
@@ -19,7 +19,6 @@
         import time
         import imp
         import re
-
         """
         - Construct tests variables
         - GIT ( optional )
@@ -29,26 +28,22 @@
             - Install ONOS package
             - Build ONOS package
         """
-        main.case( "Constructing test variables and building ONOS package" )
-        main.step( "Constructing test variables" )
-        main.caseExplanation = "This test case is mainly for loading " +\
-                               "from params file, and pull and build the " +\
-                               " latest ONOS package"
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        main.testSetUp.envSetupDescription()
         stepResult = main.FALSE
 
         # Test variables
         try:
-            main.testOnDirectory = re.sub( "(/tests)$", "", main.testDir )
             main.apps = main.params[ 'ENV' ][ 'cellApps' ]
-            gitBranch = main.params[ 'GIT' ][ 'branch' ]
             main.dependencyPath = main.testOnDirectory + \
                                   main.params[ 'DEPENDENCY' ][ 'path' ]
             main.topology = main.params[ 'DEPENDENCY' ][ 'topology' ]
             main.scale = ( main.params[ 'SCALE' ][ 'size' ] ).split( "," )
-            if main.ONOSbench.maxNodes:
-                main.maxNodes = int( main.ONOSbench.maxNodes )
-            else:
-                main.maxNodes = 0
             wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
             wrapperFile2 = main.params[ 'DEPENDENCY' ][ 'wrapper2' ]
             wrapperFile3 = main.params[ 'DEPENDENCY' ][ 'wrapper3' ]
@@ -60,73 +55,30 @@
             main.addIntentSleep = int( main.params[ 'SLEEP' ][ 'addIntent' ] )
             main.checkTopoAttempts = int( main.params[ 'SLEEP' ][ 'topoAttempts' ] )
             main.flowDurationSleep = int( main.params[ 'SLEEP' ][ 'flowDuration' ] )
-            gitPull = main.params[ 'GIT' ][ 'pull' ]
             main.numSwitch = int( main.params[ 'MININET' ][ 'switch' ] )
             main.numLinks = int( main.params[ 'MININET' ][ 'links' ] )
-            main.cellData = {}  # for creating cell file
             main.hostsData = {}
-            main.RESTs = []
-            main.CLIs = []
-            main.ONOSip = []
             main.scapyHostNames = main.params[ 'SCAPY' ][ 'HOSTNAMES' ].split( ',' )
             main.scapyHosts = []  # List of scapy hosts for iterating
             main.assertReturnString = ''  # Assembled assert return string
             main.cycle = 0  # How many times FUNCintent has run through its tests
 
-            main.ONOSip = main.ONOSbench.getOnosIps()
-            print main.ONOSip
-
-            # Assigning ONOS cli handles to a list
-            try:
-                for i in range( 1, main.maxNodes + 1 ):
-                    main.RESTs.append( getattr( main, 'ONOSrest' + str( i ) ) )
-                    main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
-            except AttributeError:
-                main.log.warn( "A " + str( main.maxNodes ) + " node cluster " +
-                               "was defined in env variables, but only " +
-                               str( len( main.RESTs ) ) +
-                               " nodes were defined in the .topo file. " +
-                               "Using " + str( len( main.RESTs ) ) +
-                               " nodes for the test." )
-
             # -- INIT SECTION, ONLY RUNS ONCE -- #
-            main.startUp = imp.load_source( wrapperFile1,
-                                            main.dependencyPath +
-                                            wrapperFile1 +
-                                            ".py" )
 
             main.intentFunction = imp.load_source( wrapperFile2,
                                                    main.dependencyPath +
                                                    wrapperFile2 +
                                                    ".py" )
 
-            main.topo = imp.load_source( wrapperFile3,
-                                         main.dependencyPath +
-                                         wrapperFile3 +
-                                         ".py" )
-
             copyResult1 = main.ONOSbench.scp( main.Mininet1,
                                               main.dependencyPath +
                                               main.topology,
                                               main.Mininet1.home + "custom/",
                                               direction="to" )
-            if main.RESTs and main.CLIs:
-                stepResult = main.TRUE
-            else:
-                main.log.error( "Did not properly created list of ONOS CLI handle" )
-                stepResult = main.FALSE
+            stepResult = main.testSetUp.envSetup( True, True )
         except Exception as e:
-            main.log.exception( e )
-            main.cleanup()
-            main.exit()
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully construct " +
-                                        "test variables ",
-                                 onfail="Failed to construct test variables" )
-
-        main.ONOSbench.getVersion( report=True )
+            main.testSetUp.envSetupException(e)
+        main.testSetUp.evnSetupConclusion( stepResult )
 
     def CASE2( self, main ):
         """
@@ -140,327 +92,21 @@
         - Install ONOS cluster
         - Connect to cli
         """
-        main.cycle += 1
-
-        # main.scale[ 0 ] determines the current number of ONOS controller
-        main.numCtrls = int( main.scale[ 0 ] )
         main.flowCompiler = "Flow Rules"
-        main.initialized = main.TRUE
-
-        main.case( "Starting up " + str( main.numCtrls ) +
-                   " node(s) ONOS cluster" )
-        main.caseExplanation = "Set up ONOS with " + str( main.numCtrls ) +\
-                                " node(s) ONOS cluster"
-
-        #kill off all onos processes
-        main.log.info( "Safety check, killing all ONOS processes" +
-                       " before initiating environment setup" )
-
-        time.sleep( main.startUpSleep )
-
-        main.step( "Uninstalling ONOS package" )
-        onosUninstallResult = main.TRUE
-        for ip in main.ONOSip:
-            onosUninstallResult = onosUninstallResult and \
-                    main.ONOSbench.onosUninstall( nodeIp=ip )
-        stepResult = onosUninstallResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully uninstalled ONOS package",
-                                 onfail="Failed to uninstall ONOS package" )
-
-        time.sleep( main.startUpSleep )
-
-        for i in range( main.maxNodes ):
-            main.ONOSbench.onosDie( main.ONOSip[ i ] )
-
-        print "NODE COUNT = ", main.numCtrls
-
-        tempOnosIp = []
-        for i in range( main.numCtrls ):
-            tempOnosIp.append( main.ONOSip[ i ] )
-
-        main.ONOSbench.createCellFile( main.ONOSbench.ip_address,
-                                       "temp", main.Mininet1.ip_address,
-                                       main.apps, tempOnosIp, main.ONOScli1.karafUser )
-
-        main.step( "Apply cell to environment" )
-        cellResult = main.ONOSbench.setCell( "temp" )
-        verifyResult = main.ONOSbench.verifyCell()
-        stepResult = cellResult and verifyResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully applied cell to " +
-                                        "environment",
-                                 onfail="Failed to apply cell to environment " )
-
-        main.step( "Creating ONOS package" )
-        packageResult = main.ONOSbench.buckBuild()
-        stepResult = packageResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully created ONOS package",
-                                 onfail="Failed to create ONOS package" )
-
-        time.sleep( main.startUpSleep )
-        main.step( "Installing ONOS package" )
-        onosInstallResult = main.TRUE
-        for i in range( main.numCtrls ):
-            onosInstallResult = onosInstallResult and \
-                    main.ONOSbench.onosInstall( node=main.ONOSip[ i ] )
-        stepResult = onosInstallResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully installed ONOS package",
-                                 onfail="Failed to install ONOS package" )
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.TRUE
-        for i in range( int( main.numCtrls ) ):
-            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=main.ONOSip[ i ] )
-        utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        time.sleep( main.startUpSleep )
-        main.step( "Starting ONOS service" )
-        stopResult = main.TRUE
-        startResult = main.TRUE
-        onosIsUp = main.TRUE
-
-        for i in range( main.numCtrls ):
-            onosIsUp = onosIsUp and main.ONOSbench.isup( main.ONOSip[ i ] )
-            if onosIsUp == main.TRUE:
-                main.log.report( "ONOS instance {0} is up and ready".format( i + 1 ) )
-            else:
-                main.log.report( "ONOS instance {0} may not be up, stop and ".format( i + 1 ) +
-                                 "start ONOS again " )
-                stopResult = stopResult and main.ONOSbench.onosStop( main.ONOSip[ i ] )
-                startResult = startResult and main.ONOSbench.onosStart( main.ONOSip[ i ] )
-                if not startResult or stopResult:
-                    main.log.report( "ONOS instance {0} did not start correctly.".format( i + 1 ) )
-        stepResult = onosIsUp and stopResult and startResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="ONOS service is ready",
-                                 onfail="ONOS service did not start properly" )
-        if not stepResult:
-            main.initialized = main.FALSE
-
-        # Start an ONOS cli to provide functionality that is not currently
-        # supported by the Rest API remove this when Leader Checking is supported
-        # by the REST API
-
-        main.step( "Start ONOS cli" )
-        cliResult = main.TRUE
-        for i in range( main.numCtrls ):
-            cliResult = cliResult and \
-                        main.CLIs[ i ].startOnosCli( main.ONOSip[ i ] )
-        stepResult = cliResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully start ONOS cli",
-                                 onfail="Failed to start ONOS cli" )
-        if not stepResult:
-            main.initialized = main.FALSE
-
-        # Remove the first element in main.scale list
-        main.scale.remove( main.scale[ 0 ] )
-
+        main.initialized = main.testSetUp.ONOSSetUp( main.Mininet1, True )
         main.intentFunction.report( main )
 
     def CASE8( self, main ):
-        # OLD FUNCintentRest CASE 8
-        # This remains here for archiving and reference purposes and will be
-        # removed when the new FUNCintentRest is verified to work.
-        # """
-        # Compare Topo
-        # """
-        # import json
-
-        # main.case( "Compare ONOS Topology view to Mininet topology" )
-        # main.caseExplanation = "Compare topology elements between Mininet" +\
-        #                         " and ONOS"
-
-        # main.step( "Gathering topology information" )
-        # # TODO: add a paramaterized sleep here
-        # devicesResults = main.TRUE  # Overall Boolean for device correctness
-        # linksResults = main.TRUE  # Overall Boolean for link correctness
-        # hostsResults = main.TRUE  # Overall Boolean for host correctness
-        # devices = main.topo.getAllDevices( main )
-        # hosts = main.topo.getAllHosts( main )
-        # ports = main.topo.getAllPorts( main )
-        # links = main.topo.getAllLinks( main )
-        # clusters = main.topo.getAllClusters( main )
-
-        # mnSwitches = main.Mininet1.getSwitches()
-        # mnLinks = main.Mininet1.getLinks()
-        # mnHosts = main.Mininet1.getHosts()
-
-        # main.step( "Comparing MN topology to ONOS topology" )
-        # for controller in range( main.numCtrls ):
-        #     controllerStr = str( controller + 1 )
-        #     if devices[ controller ] and ports[ controller ] and\
-        #         "Error" not in devices[ controller ] and\
-        #         "Error" not in ports[ controller ]:
-
-        #         currentDevicesResult = main.Mininet1.compareSwitches(
-        #                 mnSwitches,
-        #                 json.loads( devices[ controller ] ),
-        #                 json.loads( ports[ controller ] ) )
-        #     else:
-        #         currentDevicesResult = main.FALSE
-        #     utilities.assert_equals( expect=main.TRUE,
-        #                              actual=currentDevicesResult,
-        #                              onpass="ONOS" + controllerStr +
-        #                              " Switches view is correct",
-        #                              onfail="ONOS" + controllerStr +
-        #                              " Switches view is incorrect" )
-
-        #     if links[ controller ] and "Error" not in links[ controller ]:
-        #         currentLinksResult = main.Mininet1.compareLinks(
-        #                 mnSwitches, mnLinks,
-        #                 json.loads( links[ controller ] ) )
-        #     else:
-        #         currentLinksResult = main.FALSE
-        #     utilities.assert_equals( expect=main.TRUE,
-        #                              actual=currentLinksResult,
-        #                              onpass="ONOS" + controllerStr +
-        #                              " links view is correct",
-        #                              onfail="ONOS" + controllerStr +
-        #                              " links view is incorrect" )
-
-        #     if hosts[ controller ] or "Error" not in hosts[ controller ]:
-        #         currentHostsResult = main.Mininet1.compareHosts(
-        #                 mnHosts,
-        #                 json.loads( hosts[ controller ] ) )
-        #     else:
-        #         currentHostsResult = main.FALSE
-        #     utilities.assert_equals( expect=main.TRUE,
-        #                              actual=currentHostsResult,
-        #                              onpass="ONOS" + controllerStr +
-        #                              " hosts exist in Mininet",
-        #                              onfail="ONOS" + controllerStr +
-        #                              " hosts don't match Mininet" )
-
-        # NEW FUNCintentRest Case 8 as based off of the CASE 8 from FUNCintent
-        """
-        Compare ONOS Topology to Mininet Topology
-        """
-        import json
-
-        main.case( "Compare ONOS Topology view to Mininet topology" )
-        main.caseExplanation = "Compare topology elements between Mininet" +\
-                                " and ONOS"
-
-        main.log.info( "Gathering topology information from Mininet" )
-        devicesResults = main.FALSE  # Overall Boolean for device correctness
-        linksResults = main.FALSE  # Overall Boolean for link correctness
-        hostsResults = main.FALSE  # Overall Boolean for host correctness
-        deviceFails = []  # Nodes where devices are incorrect
-        linkFails = []  # Nodes where links are incorrect
-        hostFails = []  # Nodes where hosts are incorrect
-        attempts = main.checkTopoAttempts  # Remaining Attempts
-
-        mnSwitches = main.Mininet1.getSwitches()
-        mnLinks = main.Mininet1.getLinks()
-        mnHosts = main.Mininet1.getHosts()
-
-        main.step( "Comparing Mininet topology to ONOS topology" )
-
-        while ( attempts >= 0 ) and\
-                ( not devicesResults or not linksResults or not hostsResults ):
-            time.sleep( 2 )
-            if not devicesResults:
-                devices = main.topo.getAllDevices( main )
-                ports = main.topo.getAllPorts( main )
-                devicesResults = main.TRUE
-                deviceFails = []  # Reset for each failed attempt
-            if not linksResults:
-                links = main.topo.getAllLinks( main )
-                linksResults = main.TRUE
-                linkFails = []  # Reset for each failed attempt
-            if not hostsResults:
-                hosts = main.topo.getAllHosts( main )
-                hostsResults = main.TRUE
-                hostFails = []  # Reset for each failed attempt
-
-            #  Check for matching topology on each node
-            for controller in range( main.numCtrls ):
-                controllerStr = str( controller + 1 )  # ONOS node number
-                # Compare Devices
-                if devices[ controller ] and ports[ controller ] and\
-                        "Error" not in devices[ controller ] and\
-                        "Error" not in ports[ controller ]:
-
-                    try:
-                        deviceData = json.loads( devices[ controller ] )
-                        portData = json.loads( ports[ controller ] )
-                    except ( TypeError, ValueError ):
-                        main.log.error( "Could not load json: {0} or {1}".format( str( devices[ controller ] ),
-                                                                                  str( ports[ controller ] ) ) )
-                        currentDevicesResult = main.FALSE
-                    else:
-                        currentDevicesResult = main.Mininet1.compareSwitches(
-                            mnSwitches, deviceData, portData )
-                else:
-                    currentDevicesResult = main.FALSE
-                if not currentDevicesResult:
-                    deviceFails.append( controllerStr )
-                devicesResults = devicesResults and currentDevicesResult
-                # Compare Links
-                if links[ controller ] and "Error" not in links[ controller ]:
-                    try:
-                        linkData = json.loads( links[ controller ] )
-                    except ( TypeError, ValueError ):
-                        main.log.error( "Could not load json:" + str( links[ controller ] ) )
-                        currentLinksResult = main.FALSE
-                    else:
-                        currentLinksResult = main.Mininet1.compareLinks(
-                            mnSwitches, mnLinks, linkData )
-                else:
-                    currentLinksResult = main.FALSE
-                if not currentLinksResult:
-                    linkFails.append( controllerStr )
-                linksResults = linksResults and currentLinksResult
-                # Compare Hosts
-                if hosts[ controller ] and "Error" not in hosts[ controller ]:
-                    try:
-                        hostData = json.loads( hosts[ controller ] )
-                    except ( TypeError, ValueError ):
-                        main.log.error( "Could not load json:" + str( hosts[ controller ] ) )
-                        currentHostsResult = main.FALSE
-                    else:
-                        currentHostsResult = main.Mininet1.compareHosts(
-                                mnHosts, hostData )
-                else:
-                    currentHostsResult = main.FALSE
-                if not currentHostsResult:
-                    hostFails.append( controllerStr )
-                hostsResults = hostsResults and currentHostsResult
-            # Decrement Attempts Remaining
-            attempts -= 1
-
-        utilities.assert_equals( expect=[],
-                                 actual=deviceFails,
-                                 onpass="ONOS correctly discovered all devices",
-                                 onfail="ONOS incorrectly discovered devices on nodes: " +
-                                 str( deviceFails ) )
-        utilities.assert_equals( expect=[],
-                                 actual=linkFails,
-                                 onpass="ONOS correctly discovered all links",
-                                 onfail="ONOS incorrectly discovered links on nodes: " +
-                                 str( linkFails ) )
-        utilities.assert_equals( expect=[],
-                                 actual=hostFails,
-                                 onpass="ONOS correctly discovered all hosts",
-                                 onfail="ONOS incorrectly discovered hosts on nodes: " +
-                                 str( hostFails ) )
-        topoResults = hostsResults and linksResults and devicesResults
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=topoResults,
-                                 onpass="ONOS correctly discovered the topology",
-                                 onfail="ONOS incorrectly discovered the topology" )
+        try:
+            from tests.dependencies.topology import Topology
+        except ImportError:
+            main.log.error( "Topology not found exiting the test" )
+            main.exit()
+        try:
+            main.topoRelated
+        except ( NameError, AttributeError ):
+            main.topoRelated = Topology()
+        main.topoRelated.compareTopos( main.Mininet1, main.checkTopoAttempts )
 
     def CASE9( self, main ):
         """
@@ -643,7 +289,7 @@
             main.initialized = main.FALSE
 
     def CASE15( self, main ):
-        """
+        """main.topo.
             Discover all hosts with scapy arp packets and store its data to a dictionary
         """
         if main.initialized == main.FALSE:
@@ -733,6 +379,15 @@
         """
             Stop mininet and remove scapy hosts
         """
+        try:
+            from tests.dependencies.utils import Utils
+        except ImportError:
+            main.log.error( "Utils not found exiting the test" )
+            main.exit()
+        try:
+            main.Utils
+        except ( NameError, AttributeError ):
+            main.Utils = Utils()
         main.log.report( "Stop Mininet and Scapy" )
         main.case( "Stop Mininet and Scapy" )
         main.caseExplanation = "Stopping the current mininet topology " +\
@@ -756,13 +411,7 @@
                                  onpass="Successfully stopped scapy and removed host components",
                                  onfail="Failed to stop mininet and scapy" )
 
-        main.step( "Stopping Mininet Topology" )
-        mininetResult = main.Mininet1.stopNet()
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully stop mininet",
-                                 onfail="Failed to stop mininet" )
+        mininetResult = main.Utils.mininetCleanup( main.Mininet1 )
         # Exit if topology did not load properly
         if not ( mininetResult and scapyResult ):
             main.cleanup()
@@ -772,34 +421,16 @@
         """
             Copy the karaf.log files after each testcase cycle
         """
-        main.log.report( "Copy karaf logs" )
-        main.case( "Copy karaf logs" )
-        main.caseExplanation = "Copying the karaf logs to preserve them through" +\
-                               "reinstalling ONOS"
-        main.step( "Copying karaf logs" )
-        stepResult = main.TRUE
-        scpResult = main.TRUE
-        copyResult = main.TRUE
-        for i in range( main.numCtrls ):
-            main.node = main.CLIs[ i ]
-            ip = main.ONOSip[ i ]
-            main.node.ip_address = ip
-            scpResult = scpResult and main.ONOSbench.scp( main.node,
-                                                          "/opt/onos/log/karaf.log",
-                                                          "/tmp/karaf.log",
-                                                          direction="from" )
-            copyResult = copyResult and main.ONOSbench.cpLogsToDir( "/tmp/karaf.log", main.logdir,
-                                                                    copyFileName=( "karaf.log.node{0}.cycle{1}".format(
-                                                                        str( i + 1 ), str( main.cycle ) ) ) )
-            if scpResult and copyResult:
-                stepResult = main.TRUE and stepResult
-            else:
-                stepResult = main.FALSE and stepResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully copied remote ONOS logs",
-                                 onfail="Failed to copy remote ONOS logs" )
-
+        try:
+            from tests.dependencies.utils import Utils
+        except ImportError:
+            main.log.error( "Utils not found exiting the test" )
+            main.exit()
+        try:
+            main.Utils
+        except ( NameError, AttributeError ):
+            main.Utils = Utils()
+        main.Utils.copyKarafLog()
     def CASE1000( self, main ):
         """
             Add host intents between 2 host:
diff --git a/TestON/tests/FUNC/FUNCintentRest/dependencies/FuncIntentFunction.py b/TestON/tests/FUNC/FUNCintentRest/dependencies/FuncIntentFunction.py
index 38861b6..b99fb42 100644
--- a/TestON/tests/FUNC/FUNCintentRest/dependencies/FuncIntentFunction.py
+++ b/TestON/tests/FUNC/FUNCintentRest/dependencies/FuncIntentFunction.py
@@ -1490,7 +1490,16 @@
     """
     import collections
     scapyHostCount = len( main.scapyHosts )
-    hosts = main.topo.getAllHosts( main )  # Get host data from each ONOS node
+    try:
+        from tests.dependencies.topology import Topology
+    except Exception:
+        main.log.error( "Topology not found exiting the test" )
+        main.exit()
+    try:
+        main.topoRelated
+    except ( NameError, AttributeError ):
+        main.topoRelated = Topology()
+    hosts = main.topoRelated.getAllHosts( main.numCtrls, False )  # Get host data from each ONOS node
     hostFails = []  # Reset for each failed attempt
 
     #  Check for matching hosts on each node
diff --git a/TestON/tests/FUNC/FUNCintentRest/dependencies/startUp.py b/TestON/tests/FUNC/FUNCintentRest/dependencies/startUp.py
deleted file mode 100644
index ad92fb9..0000000
--- a/TestON/tests/FUNC/FUNCintentRest/dependencies/startUp.py
+++ /dev/null
@@ -1,33 +0,0 @@
-"""
-    This wrapper function is use for starting up onos instance
-"""
-import time
-import os
-import json
-
-
-def onosBuild( main, gitBranch ):
-    """
-        This includes pulling ONOS and building it using maven install
-    """
-    buildResult = main.FALSE
-
-    # Git checkout a branch of ONOS
-    checkOutResult = main.ONOSbench.gitCheckout( gitBranch )
-    # Does the git pull on the branch that was checked out
-    if not checkOutResult:
-        main.log.warn( "Failed to checked out " + gitBranch +
-                                           " branch" )
-    else:
-        main.log.info( "Successfully checked out " + gitBranch +
-                                           " branch" )
-    gitPullResult = main.ONOSbench.gitPull()
-    if gitPullResult == main.ERROR:
-        main.log.error( "Error pulling git branch" )
-    else:
-        main.log.info( "Successfully pulled " + gitBranch + " branch" )
-
-    # buck Build
-    buildResult = main.ONOSbench.buckBuild()
-
-    return buildResult
diff --git a/TestON/tests/FUNC/FUNCintentRest/dependencies/topo.py b/TestON/tests/FUNC/FUNCintentRest/dependencies/topo.py
deleted file mode 100644
index 7217d4d..0000000
--- a/TestON/tests/FUNC/FUNCintentRest/dependencies/topo.py
+++ /dev/null
@@ -1,102 +0,0 @@
-"""
-    These functions can be used for topology comparisons
-"""
-import time
-import os
-import json
-
-
-def getAllDevices( main ):
-    """
-        Return a list containing the devices output from each ONOS node
-    """
-    devices = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].devices,
-                         name="devices-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        devices.append( t.result )
-    return devices
-
-
-def getAllHosts( main ):
-    """
-        Return a list containing the hosts output from each ONOS node
-    """
-    hosts = []
-    ipResult = main.TRUE
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].hosts,
-                         name="hosts-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        hosts.append( t.result )
-    return hosts
-
-
-def getAllPorts( main ):
-    """
-        Return a list containing the ports output from each ONOS node
-    """
-    ports = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].ports,
-                         name="ports-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        ports.append( t.result )
-    return ports
-
-
-def getAllLinks( main ):
-    """
-        Return a list containing the links output from each ONOS node
-    """
-    links = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].links,
-                         name="links-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        links.append( t.result )
-    return links
-
-
-def getAllClusters( main ):
-    """
-        Return a list containing the clusters output from each ONOS node
-    """
-    clusters = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].clusters,
-                         name="clusters-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        clusters.append( t.result )
-    return clusters
diff --git a/TestON/tests/FUNC/FUNCipv6Intent/FUNCipv6Intent.py b/TestON/tests/FUNC/FUNCipv6Intent/FUNCipv6Intent.py
index 148f52d..2e933db 100644
--- a/TestON/tests/FUNC/FUNCipv6Intent/FUNCipv6Intent.py
+++ b/TestON/tests/FUNC/FUNCipv6Intent/FUNCipv6Intent.py
@@ -9,7 +9,6 @@
     def CASE1( self, main ):
         import imp
         import re
-
         """
         - Construct tests variables
         - GIT ( optional )
@@ -19,25 +18,21 @@
             - Install ONOS package
             - Build ONOS package
         """
-        main.case( "Constructing test variables and building ONOS package" )
-        main.step( "Constructing test variables" )
-        main.caseExplanation = "This test case is mainly for loading " +\
-                               "from params file, and pull and build the " +\
-                               " latest ONOS package"
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        main.testSetUp.envSetupDescription()
         stepResult = main.FALSE
         # Test variables
         try:
-            main.testOnDirectory = re.sub( "(/tests)$", "", main.testDir )
             main.apps = main.params[ 'ENV' ][ 'cellApps' ]
-            gitBranch = main.params[ 'GIT' ][ 'branch' ]
             main.dependencyPath = main.testOnDirectory + \
                                   main.params[ 'DEPENDENCY' ][ 'path' ]
             main.topology = main.params[ 'DEPENDENCY' ][ 'topology' ]
             main.scale = ( main.params[ 'SCALE' ][ 'size' ] ).split( "," )
-            if main.ONOSbench.maxNodes:
-                main.maxNodes = int( main.ONOSbench.maxNodes )
-            else:
-                main.maxNodes = 0
             wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
             wrapperFile2 = main.params[ 'DEPENDENCY' ][ 'wrapper2' ]
             wrapperFile3 = main.params[ 'DEPENDENCY' ][ 'wrapper3' ]
@@ -47,60 +42,27 @@
             main.rerouteSleep = int( main.params[ 'SLEEP' ][ 'reroute' ] )
             main.fwdSleep = int( main.params[ 'SLEEP' ][ 'fwd' ] )
             main.checkTopoAttempts = int( main.params[ 'SLEEP' ][ 'topoAttempts' ] )
-            gitPull = main.params[ 'GIT' ][ 'pull' ]
             main.numSwitch = int( main.params[ 'MININET' ][ 'switch' ] )
             main.numLinks = int( main.params[ 'MININET' ][ 'links' ] )
-            main.cellData = {}  # for creating cell file
             main.hostsData = {}
-            main.CLIs = []
-            main.ONOSip = []
             main.assertReturnString = ''  # Assembled assert return string
 
-            main.ONOSip = main.ONOSbench.getOnosIps()
-            print main.ONOSip
-
-            # Assigning ONOS cli handles to a list
-            for i in range( 1, main.maxNodes + 1 ):
-                main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
-
             # -- INIT SECTION, ONLY RUNS ONCE -- #
-            main.startUp = imp.load_source( wrapperFile1,
-                                            main.dependencyPath +
-                                            wrapperFile1 +
-                                            ".py" )
 
             main.intentFunction = imp.load_source( wrapperFile2,
                                                    main.dependencyPath +
                                                    wrapperFile2 +
                                                    ".py" )
 
-            main.topo = imp.load_source( wrapperFile3,
-                                         main.dependencyPath +
-                                         wrapperFile3 +
-                                         ".py" )
-
             copyResult1 = main.ONOSbench.scp( main.Mininet1,
                                               main.dependencyPath +
                                               main.topology,
                                               main.Mininet1.home,
                                               direction="to" )
-            if main.CLIs:
-                stepResult = main.TRUE
-            else:
-                main.log.error( "Did not properly created list of ONOS CLI handle" )
-                stepResult = main.FALSE
+            stepResult = main.testSetUp.envSetup( True )
         except Exception as e:
-            main.log.exception( e )
-            main.cleanup()
-            main.exit()
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully construct " +
-                                        "test variables ",
-                                 onfail="Failed to construct test variables" )
-
-        main.ONOSbench.getVersion( report=True )
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
 
     def CASE2( self, main ):
         """
@@ -115,122 +77,13 @@
         - Connect to cli
         """
         import time
-        # main.scale[ 0 ] determines the current number of ONOS controller
-        main.numCtrls = int( main.scale[ 0 ] )
 
-        main.case( "Starting up " + str( main.numCtrls ) +
-                   " node(s) ONOS cluster" )
-        main.caseExplanation = "Set up ONOS with " + str( main.numCtrls ) +\
-                                " node(s) ONOS cluster"
-
-        #kill off all onos processes
-        main.log.info( "Safety check, killing all ONOS processes" +
-                       " before initiating environment setup" )
-
-        for i in range( main.maxNodes ):
-            main.ONOSbench.onosDie( main.ONOSip[ i ] )
-
-        print "NODE COUNT = ", main.numCtrls
-
-        tempOnosIp = []
-        for i in range( main.numCtrls ):
-            tempOnosIp.append( main.ONOSip[ i ] )
-
-        main.ONOSbench.createCellFile( main.ONOSbench.ip_address,
-                                       "temp", main.Mininet1.ip_address,
-                                       main.apps, tempOnosIp, main.ONOScli1.karafUser )
-
-        main.step( "Apply cell to environment" )
-        cellResult = main.ONOSbench.setCell( "temp" )
-        verifyResult = main.ONOSbench.verifyCell()
-        stepResult = cellResult and verifyResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully applied cell to " +
-                                        "environment",
-                                 onfail="Failed to apply cell to environment " )
-
-        main.step( "Creating ONOS package" )
-        packageResult = main.ONOSbench.buckBuild()
-        stepResult = packageResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully created ONOS package",
-                                 onfail="Failed to create ONOS package" )
-
-        time.sleep( main.startUpSleep )
-        main.step( "Uninstalling ONOS package" )
-        onosUninstallResult = main.TRUE
-        for ip in main.ONOSip:
-            onosUninstallResult = onosUninstallResult and \
-                    main.ONOSbench.onosUninstall( nodeIp=ip )
-        stepResult = onosUninstallResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully uninstalled ONOS package",
-                                 onfail="Failed to uninstall ONOS package" )
-
-        time.sleep( main.startUpSleep )
-        main.step( "Installing ONOS package" )
-        onosInstallResult = main.TRUE
-        for i in range( main.numCtrls ):
-            onosInstallResult = onosInstallResult and \
-                    main.ONOSbench.onosInstall( node=main.ONOSip[ i ] )
-        stepResult = onosInstallResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully installed ONOS package",
-                                 onfail="Failed to install ONOS package" )
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.TRUE
-        for i in range( int( main.numCtrls ) ):
-            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=main.ONOSip[ i ] )
-        utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        time.sleep( main.startUpSleep )
-        main.step( "Starting ONOS service" )
-        stopResult = main.TRUE
-        startResult = main.TRUE
-        onosIsUp = main.TRUE
-
-        for i in range( main.numCtrls ):
-            onosIsUp = onosIsUp and main.ONOSbench.isup( main.ONOSip[ i ] )
-        if onosIsUp == main.TRUE:
-            main.log.report( "ONOS instance is up and ready" )
-        else:
-            main.log.report( "ONOS instance may not be up, stop and " +
-                             "start ONOS again " )
-
-            for i in range( main.numCtrls ):
-                stopResult = stopResult and \
-                        main.ONOSbench.onosStop( main.ONOSip[ i ] )
-            for i in range( main.numCtrls ):
-                startResult = startResult and \
-                        main.ONOSbench.onosStart( main.ONOSip[ i ] )
-        stepResult = onosIsUp and stopResult and startResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="ONOS service is ready",
-                                 onfail="ONOS service did not start properly" )
-
-        main.step( "Start ONOS cli" )
-        cliResult = main.TRUE
-        for i in range( main.numCtrls ):
-            cliResult = cliResult and \
-                        main.CLIs[ i ].startOnosCli( main.ONOSip[ i ] )
-        stepResult = cliResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully start ONOS cli",
-                                 onfail="Failed to start ONOS cli" )
+        main.initialized = main.testSetUp.ONOSSetUp( main.Mininet1, True )
 
         main.step( "Checking that ONOS is ready" )
         for i in range( 3 ):
             ready = True
-            for i in range( int( main.scale[ 0 ] ) ):
+            for i in range ( main.numCtrls ):
                 output = main.CLIs[ i ].summary()
                 if not output:
                     ready = False
@@ -250,9 +103,6 @@
                                  onpass="ipv6NeighborDiscovery cfg is set to true",
                                  onfail="Failed to cfg set ipv6NeighborDiscovery" )
 
-        # Remove the first element in main.scale list
-        main.scale.remove( main.scale[ 0 ] )
-
         main.intentFunction.report( main )
 
     def CASE11( self, main ):
@@ -357,18 +207,17 @@
         """
             Stop mininet
         """
-        main.log.report( "Stop Mininet topology" )
-        main.case( "Stop Mininet topology" )
-        main.caseExplanation = "Stopping the current mininet topology " +\
-                                "to start up fresh"
-
-        main.step( "Stopping Mininet Topology" )
-        topoResult = main.Mininet1.stopNet()
-        stepResult = topoResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully stop mininet",
-                                 onfail="Failed to stop mininet" )
+        try:
+            from tests.dependencies.utils import Utils
+        except ImportError:
+            main.log.error( "Utils not found exiting the test" )
+            main.exit()
+        try:
+            main.Utils
+        except ( NameError, AttributeError ):
+            main.Utils = Utils()
+        main.Utils.mininetCleanIntro()
+        topoResult = main.Utils.mininetCleanup( main.Mininet1 )
         # Exit if topology did not load properly
         if not topoResult:
             main.cleanup()
diff --git a/TestON/tests/FUNC/FUNCipv6Intent/dependencies/startUp.py b/TestON/tests/FUNC/FUNCipv6Intent/dependencies/startUp.py
deleted file mode 100644
index a9becf9..0000000
--- a/TestON/tests/FUNC/FUNCipv6Intent/dependencies/startUp.py
+++ /dev/null
@@ -1,33 +0,0 @@
-"""
-    This wrapper function is use for starting up onos instance
-"""
-import time
-import os
-import json
-
-
-def onosBuild( main, gitBranch ):
-    """
-        This includes pulling ONOS and building it using maven install
-    """
-    buildResult = main.FALSE
-
-    # Git checkout a branch of ONOS
-    checkOutResult = main.ONOSbench.gitCheckout( gitBranch )
-    # Does the git pull on the branch that was checked out
-    if not checkOutResult:
-        main.log.warn( "Failed to checked out " + gitBranch +
-                                           " branch" )
-    else:
-        main.log.info( "Successfully checked out " + gitBranch +
-                                           " branch" )
-    gitPullResult = main.ONOSbench.gitPull()
-    if gitPullResult == main.ERROR:
-        main.log.error( "Error pulling git branch" )
-    else:
-        main.log.info( "Successfully pulled " + gitBranch + " branch" )
-
-    # buck build
-    buildResult = main.ONOSbench.buckBuild()
-
-    return buildResult
diff --git a/TestON/tests/FUNC/FUNCipv6Intent/dependencies/topo.py b/TestON/tests/FUNC/FUNCipv6Intent/dependencies/topo.py
deleted file mode 100644
index 7217d4d..0000000
--- a/TestON/tests/FUNC/FUNCipv6Intent/dependencies/topo.py
+++ /dev/null
@@ -1,102 +0,0 @@
-"""
-    These functions can be used for topology comparisons
-"""
-import time
-import os
-import json
-
-
-def getAllDevices( main ):
-    """
-        Return a list containing the devices output from each ONOS node
-    """
-    devices = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].devices,
-                         name="devices-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        devices.append( t.result )
-    return devices
-
-
-def getAllHosts( main ):
-    """
-        Return a list containing the hosts output from each ONOS node
-    """
-    hosts = []
-    ipResult = main.TRUE
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].hosts,
-                         name="hosts-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        hosts.append( t.result )
-    return hosts
-
-
-def getAllPorts( main ):
-    """
-        Return a list containing the ports output from each ONOS node
-    """
-    ports = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].ports,
-                         name="ports-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        ports.append( t.result )
-    return ports
-
-
-def getAllLinks( main ):
-    """
-        Return a list containing the links output from each ONOS node
-    """
-    links = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].links,
-                         name="links-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        links.append( t.result )
-    return links
-
-
-def getAllClusters( main ):
-    """
-        Return a list containing the clusters output from each ONOS node
-    """
-    clusters = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].clusters,
-                         name="clusters-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        clusters.append( t.result )
-    return clusters
diff --git a/TestON/tests/FUNC/FUNCnetCfg/FUNCnetCfg.py b/TestON/tests/FUNC/FUNCnetCfg/FUNCnetCfg.py
index 4895b3b..65a5477 100644
--- a/TestON/tests/FUNC/FUNCnetCfg/FUNCnetCfg.py
+++ b/TestON/tests/FUNC/FUNCnetCfg/FUNCnetCfg.py
@@ -10,93 +10,47 @@
     def CASE1( self, main ):
         import imp
         import re
-
         """
         - Construct tests variables
         - GIT ( optional )
             - Checkout ONOS master branch
             - Pull latest ONOS code
         """
-        main.case( "Constructing test variables and building ONOS package" )
-        main.step( "Constructing test variables" )
-        main.caseExplanation = "This test case is mainly for loading " +\
-                               "from params file, and pull and build the " +\
-                               " latest ONOS package"
+
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        main.testSetUp.envSetupDescription()
         stepResult = main.FALSE
 
         # Test variables
         try:
-            main.testOnDirectory = re.sub( "(/tests)$", "", main.testDir )
             main.apps = main.params[ 'ENV' ][ 'cellApps' ]
-            gitBranch = main.params[ 'GIT' ][ 'branch' ]
             main.dependencyPath = main.testOnDirectory + \
                                   main.params[ 'DEPENDENCY' ][ 'path' ]
-            if main.ONOSbench.maxNodes:
-                main.maxNodes = int( main.ONOSbench.maxNodes )
-            else:
-                main.maxNodes = 0
             wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
             wrapperFile2 = main.params[ 'DEPENDENCY' ][ 'wrapper2' ]
             wrapperFile3 = main.params[ 'DEPENDENCY' ][ 'wrapper3' ]
             main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
             main.gossipTime = int( main.params[ 'SLEEP' ][ 'cfgGossip' ] )
             main.SetNetCfgSleep = int( main.params[ 'SLEEP' ][ 'SetNetCfgSleep' ] )
-            gitPull = main.params[ 'GIT' ][ 'pull' ]
-            main.cellData = {}  # for creating cell file
             main.hostsData = {}
-            main.nodes = []
-            main.ONOSip = []
             main.retrytimes = int( main.params[ 'RETRY' ] )
             main.retrysleep = int( main.params[ 'RetrySleep' ] )
-            main.ONOSip = main.ONOSbench.getOnosIps()
-
-            # Assigning ONOS cli handles to a list
-            try:
-                for i in range( 1, main.maxNodes + 1 ):
-                    main.nodes.append( getattr( main, 'ONOSrest' + str( i ) ) )
-            except AttributeError:
-                main.log.warn( "A " + str( main.maxNodes ) + " node cluster " +
-                               "was defined in env variables, but only " +
-                               str( len( main.nodes ) ) +
-                               " nodes were defined in the .topo file. " +
-                               "Using " + str( len( main.nodes ) ) +
-                               " nodes for the test." )
-
-            main.numCtrls = len( main.nodes )
 
             # -- INIT SECTION, SHOULD ONLY BE RUN ONCE -- #
-            main.startUp = imp.load_source( wrapperFile1,
-                                            main.dependencyPath +
-                                            wrapperFile1 +
-                                            ".py" )
-
             main.netCfg = imp.load_source( wrapperFile2,
                                            main.dependencyPath +
                                            wrapperFile2 +
                                            ".py" )
 
-            main.topo = imp.load_source( wrapperFile3,
-                                         main.dependencyPath +
-                                         wrapperFile3 +
-                                         ".py" )
-
-            if main.nodes:
-                stepResult = main.TRUE
-            else:
-                main.log.error( "Did not properly created list of ONOS handle" )
-                stepResult = main.FALSE
+            stepResult = main.testSetUp.envSetup( hasRest=True, hasCli=False )
         except Exception as e:
-            main.log.exception( e )
-            main.cleanup()
-            main.exit()
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully construct " +
-                                        "test variables ",
-                                 onfail="Failed to construct test variables" )
-
-        main.ONOSbench.getVersion( report=True )
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
 
     def CASE2( self, main ):
         """
@@ -111,170 +65,22 @@
         - Connect to cli
         """
         import time
-        main.case( "Starting up " + str( main.numCtrls ) +
-                   " node(s) ONOS cluster" )
-        main.caseExplanation = "Set up ONOS with " + str( main.numCtrls ) +\
-                                " node(s) ONOS cluster"
-
-        # kill off all onos processes
-        main.log.info( "Safety check, killing all ONOS processes" +
-                       " before initiating environment setup" )
-
-        for i in range( main.maxNodes ):
-            main.ONOSbench.onosStop( main.ONOSip[ i ] )
-            main.ONOSbench.onosDie( main.ONOSip[ i ] )
-
-        tempOnosIp = []
-        for i in range( main.numCtrls ):
-            tempOnosIp.append( main.ONOSip[ i ] )
-
-        main.ONOSbench.createCellFile( main.ONOSbench.ip_address,
-                                       "temp", main.Mininet1.ip_address,
-                                       main.apps, tempOnosIp, main.ONOScli1.karafUser )
-
-        main.step( "Apply cell to environment" )
-        cellResult = main.ONOSbench.setCell( "temp" )
-        verifyResult = main.ONOSbench.verifyCell()
-        stepResult = cellResult and verifyResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully applied cell to environment",
-                                 onfail="Failed to apply cell to environment " )
-
-        main.step( "Creating ONOS package" )
-        packageResult = main.ONOSbench.buckBuild()
-        stepResult = packageResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully created ONOS package",
-                                 onfail="Failed to create ONOS package" )
-
-        main.step( "Uninstalling ONOS package" )
-        onosUninstallResult = main.TRUE
-        for ip in main.ONOSip:
-            onosUninstallResult = onosUninstallResult and \
-                    main.ONOSbench.onosUninstall( nodeIp=ip )
-        stepResult = onosUninstallResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully uninstalled ONOS package",
-                                 onfail="Failed to uninstall ONOS package" )
-
-        time.sleep( main.startUpSleep )
-        main.step( "Installing ONOS package" )
-        onosInstallResult = main.TRUE
-        for i in range( main.numCtrls ):
-            onosInstallResult = onosInstallResult and \
-                    main.ONOSbench.onosInstall( node=main.ONOSip[ i ] )
-        stepResult = onosInstallResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully installed ONOS package",
-                                 onfail="Failed to install ONOS package" )
-
-        time.sleep( main.startUpSleep )
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.TRUE
-        for i in range( int( main.numCtrls ) ):
-            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=main.ONOSip[ i ] )
-        utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        time.sleep( main.startUpSleep )
-        main.step( "Starting ONOS service" )
-        stopResult = main.TRUE
-        startResult = main.TRUE
-        onosIsUp = main.TRUE
-
-        for i in range( main.numCtrls ):
-            isUp = main.ONOSbench.isup( main.ONOSip[ i ] )
-            onosIsUp = onosIsUp and isUp
-            if isUp == main.TRUE:
-                main.log.report( "ONOS instance {0} is up and ready".format( i + 1 ) )
-            else:
-                main.log.report( "ONOS instance {0} may not be up, stop and ".format( i + 1 ) +
-                                 "start ONOS again " )
-                stopResult = stopResult and \
-                        main.ONOSbench.onosStop( main.ONOSip[ i ] )
-                startResult = startResult and \
-                        main.ONOSbench.onosStart( main.ONOSip[ i ] )
-            stepResult = onosIsUp and stopResult and startResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="ONOS service is ready",
-                                 onfail="ONOS service did not start properly" )
+        main.testSetUp.ONOSSetUp( main.Mininet1, hasCli=False )
 
     def CASE8( self, main ):
         """
         Compare Topo
         """
-        import json
-
-        main.case( "Compare ONOS Topology view to Mininet topology" )
-        main.caseExplanation = "Compare topology elements between Mininet" +\
-                                " and ONOS"
-
-        main.step( "Gathering topology information" )
-        # TODO: add a parameterized sleep here
-        devicesResults = main.TRUE
-        linksResults = main.TRUE
-        hostsResults = main.TRUE
-        devices = main.topo.getAllDevices( main )
-        hosts = main.topo.getAllHosts( main )
-        ports = main.topo.getAllPorts( main )
-        links = main.topo.getAllLinks( main )
-        clusters = main.topo.getAllClusters( main )
-
-        mnSwitches = main.Mininet1.getSwitches()
-        mnLinks = main.Mininet1.getLinks()
-        mnHosts = main.Mininet1.getHosts()
-
-        main.step( "Comparing MN topology to ONOS topology" )
-        for controller in range( main.numCtrls ):
-            controllerStr = str( controller + 1 )
-            if devices[ controller ] and ports[ controller ] and\
-               "Error" not in devices[ controller ] and\
-               "Error" not in ports[ controller ]:
-
-                currentDevicesResult = main.Mininet1.compareSwitches(
-                        mnSwitches,
-                        json.loads( devices[ controller ] ),
-                        json.loads( ports[ controller ] ) )
-            else:
-                currentDevicesResult = main.FALSE
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=currentDevicesResult,
-                                     onpass="ONOS" + controllerStr +
-                                     " Switches view is correct",
-                                     onfail="ONOS" + controllerStr +
-                                     " Switches view is incorrect" )
-
-            if links[ controller ] and "Error" not in links[ controller ]:
-                currentLinksResult = main.Mininet1.compareLinks(
-                        mnSwitches, mnLinks,
-                        json.loads( links[ controller ] ) )
-            else:
-                currentLinksResult = main.FALSE
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=currentLinksResult,
-                                     onpass="ONOS" + controllerStr +
-                                     " links view is correct",
-                                     onfail="ONOS" + controllerStr +
-                                     " links view is incorrect" )
-
-            if hosts[ controller ] or "Error" not in hosts[ controller ]:
-                currentHostsResult = main.Mininet1.compareHosts(
-                        mnHosts,
-                        json.loads( hosts[ controller ] ) )
-            else:
-                currentHostsResult = main.FALSE
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=currentHostsResult,
-                                     onpass="ONOS" + controllerStr +
-                                     " hosts exist in Mininet",
-                                     onfail="ONOS" + controllerStr +
-                                     " hosts don't match Mininet" )
+        try:
+            from tests.dependencies.topology import Topology
+        except ImportError:
+            main.log.error( "Topology not found exiting the test" )
+            main.exit()
+        try:
+            main.topoRelated
+        except ( NameError, AttributeError ):
+            main.topoRelated = Topology()
+        main.topoRelated.compareTopos( main.Mininet1 )
 
     def CASE9( self, main ):
         """
@@ -373,18 +179,17 @@
         """
             Stop mininet
         """
-        main.log.report( "Stop Mininet topology" )
-        main.case( "Stop Mininet topology" )
-        main.caseExplanation = "Stopping the current mininet topology " +\
-                                "to start up fresh"
-
-        main.step( "Stopping Mininet Topology" )
-        topoResult = main.Mininet1.stopNet()
-        stepResult = topoResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully stop mininet",
-                                 onfail="Failed to stop mininet" )
+        try:
+            from tests.dependencies.utils import Utils
+        except ImportError:
+            main.log.error( "Utils not found exiting the test" )
+            main.exit()
+        try:
+            main.Utils
+        except ( NameError, AttributeError ):
+            main.Utils = Utils()
+        main.Utils.mininetCleanIntro()
+        topoResult = main.Utils.mininetCleanup( main.Mininet1 )
         # Exit if topology did not load properly
         if not topoResult:
             main.cleanup()
@@ -404,7 +209,7 @@
                                ", the other disallowed."
 
 
-        pprint = main.nodes[ 0 ].pprint
+        pprint = main.RESTs[ 0 ].pprint
 
         main.step( "Add Net Cfg for switch1" )
 
@@ -558,7 +363,7 @@
         main.caseExplanation = "Add Network Configurations for discovered " +\
                                "devices. One device is allowed" +\
                                ", the other disallowed."
-        pprint = main.nodes[ 0 ].pprint
+        pprint = main.RESTs[ 0 ].pprint
 
         main.step( "Add Net Cfg for switch2" )
         try:
@@ -884,7 +689,7 @@
 
         """
         import json
-        pprint = main.nodes[ 0 ].pprint
+        pprint = main.RESTs[ 0 ].pprint
         main.case( "Posting network configurations to the top level web resource" )
         main.step( "Get json object from Net Cfg" )
         getinfo = utilities.retry( f=main.ONOSrest1.getNetCfg,
diff --git a/TestON/tests/FUNC/FUNCnetCfg/dependencies/netCfg.py b/TestON/tests/FUNC/FUNCnetCfg/dependencies/netCfg.py
index b2e4f56..9e5404a 100644
--- a/TestON/tests/FUNC/FUNCnetCfg/dependencies/netCfg.py
+++ b/TestON/tests/FUNC/FUNCnetCfg/dependencies/netCfg.py
@@ -11,7 +11,7 @@
     """
     main.step( "Check net config" )
     if gossipTime:
-        time.sleep( gossipTime * len( main.nodes ) )
+        time.sleep( gossipTime * len( main.RESTs ) )
     responses = []
     result = utilities.retry( f=checkNodeResponses,
                               retValue=False,
@@ -26,7 +26,7 @@
 
 def checkNodeResponses ( main, responses ):
     numberOfFailedNodes = 0  # Tracks the number of nodes that failed to get net configuration
-    for node in main.nodes:
+    for node in main.RESTs:
         response = node.getNetCfg( )
         responses.append( node.pprint( response ) )
         if response == main.FALSE:
diff --git a/TestON/tests/FUNC/FUNCnetCfg/dependencies/startUp.py b/TestON/tests/FUNC/FUNCnetCfg/dependencies/startUp.py
deleted file mode 100644
index 9ebeb60..0000000
--- a/TestON/tests/FUNC/FUNCnetCfg/dependencies/startUp.py
+++ /dev/null
@@ -1,31 +0,0 @@
-"""
-    This wrapper function is use for starting up onos instance
-"""
-import time
-
-
-def onosBuild( main, gitBranch ):
-    """
-        This includes pulling ONOS and building it using maven install
-    """
-    buildResult = main.FALSE
-
-    # Git checkout a branch of ONOS
-    checkOutResult = main.ONOSbench.gitCheckout( gitBranch )
-    # Does the git pull on the branch that was checked out
-    if not checkOutResult:
-        main.log.warn( "Failed to checked out " + gitBranch +
-                                           " branch" )
-    else:
-        main.log.info( "Successfully checked out " + gitBranch +
-                                           " branch" )
-    gitPullResult = main.ONOSbench.gitPull()
-    if gitPullResult == main.ERROR:
-        main.log.error( "Error pulling git branch" )
-    else:
-        main.log.info( "Successfully pulled " + gitBranch + " branch" )
-
-    # buck build
-    buildResult = main.ONOSbench.buckBuild()
-
-    return buildResult
diff --git a/TestON/tests/FUNC/FUNCnetCfg/dependencies/topo.py b/TestON/tests/FUNC/FUNCnetCfg/dependencies/topo.py
deleted file mode 100644
index 7217d4d..0000000
--- a/TestON/tests/FUNC/FUNCnetCfg/dependencies/topo.py
+++ /dev/null
@@ -1,102 +0,0 @@
-"""
-    These functions can be used for topology comparisons
-"""
-import time
-import os
-import json
-
-
-def getAllDevices( main ):
-    """
-        Return a list containing the devices output from each ONOS node
-    """
-    devices = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].devices,
-                         name="devices-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        devices.append( t.result )
-    return devices
-
-
-def getAllHosts( main ):
-    """
-        Return a list containing the hosts output from each ONOS node
-    """
-    hosts = []
-    ipResult = main.TRUE
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].hosts,
-                         name="hosts-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        hosts.append( t.result )
-    return hosts
-
-
-def getAllPorts( main ):
-    """
-        Return a list containing the ports output from each ONOS node
-    """
-    ports = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].ports,
-                         name="ports-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        ports.append( t.result )
-    return ports
-
-
-def getAllLinks( main ):
-    """
-        Return a list containing the links output from each ONOS node
-    """
-    links = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].links,
-                         name="links-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        links.append( t.result )
-    return links
-
-
-def getAllClusters( main ):
-    """
-        Return a list containing the clusters output from each ONOS node
-    """
-    clusters = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].clusters,
-                         name="clusters-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        clusters.append( t.result )
-    return clusters
diff --git a/TestON/tests/FUNC/FUNCnetconf/FUNCnetconf.py b/TestON/tests/FUNC/FUNCnetconf/FUNCnetconf.py
index 09867a3..5e40d18 100644
--- a/TestON/tests/FUNC/FUNCnetconf/FUNCnetconf.py
+++ b/TestON/tests/FUNC/FUNCnetconf/FUNCnetconf.py
@@ -10,7 +10,6 @@
         import time
         import imp
         import re
-
         """
         - Construct tests variables
         - GIT ( optional )
@@ -20,26 +19,22 @@
             - Install ONOS package
             - Build ONOS package
         """
-        main.case( "Constructing test variables and building ONOS package" )
-        main.step( "Constructing test variables" )
-        main.caseExplanation = "This test case is mainly for loading " +\
-                               "from params file, and pull and build the " +\
-                               " latest ONOS package"
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        main.testSetUp.envSetupDescription()
         stepResult = main.FALSE
 
         # Test variables
         try:
-            main.testOnDirectory = re.sub( "(/tests)$", "", main.testDir )
             main.apps = main.params[ 'ENV' ][ 'cellApps' ]
-            gitBranch = main.params[ 'GIT' ][ 'branch' ]
             main.dependencyPath = main.testOnDirectory + \
                                   main.params[ 'DEPENDENCY' ][ 'path' ]
             # main.topology = main.params[ 'DEPENDENCY' ][ 'topology' ]
             main.scale = ( main.params[ 'SCALE' ][ 'size' ] ).split( "," )
-            if main.ONOSbench.maxNodes:
-                main.maxNodes = int( main.ONOSbench.maxNodes )
-            else:
-                main.maxNodes = 0
             wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
             wrapperFile2 = main.params[ 'DEPENDENCY' ][ 'wrapper2' ]
             wrapperFile3 = main.params[ 'DEPENDENCY' ][ 'wrapper3' ]
@@ -57,62 +52,27 @@
             main.configPort = main.params[ 'CONFIGURE' ][ 'cfgAppPort' ]
             main.cycle = 0  # How many times FUNCintent has run through its tests
 
-            gitPull = main.params[ 'GIT' ][ 'pull' ]
-            main.cellData = {}  # for creating cell file
             main.hostsData = {}
-            main.CLIs = []
-            main.CLIs2 = []
-            main.ONOSip = []
             main.assertReturnString = ''  # Assembled assert return string
 
-            main.ONOSip = main.ONOSbench.getOnosIps()
-            print main.ONOSip
-
-            # Assigning ONOS cli handles to a list
-            for i in range( 1, main.maxNodes + 1 ):
-                main.CLIs.append( getattr( main, 'ONOSrest' + str( i ) ) )
-                main.CLIs2.append( getattr( main, 'ONOScli' + str( i ) ) )
-
             # -- INIT SECTION, ONLY RUNS ONCE -- #
-            main.startUp = imp.load_source( wrapperFile1,
-                                            main.dependencyPath +
-                                            wrapperFile1 +
-                                            ".py" )
 
             main.netconfFunction = imp.load_source( wrapperFile2,
                                                     main.dependencyPath +
                                                     wrapperFile2 +
                                                     ".py" )
 
-            main.topo = imp.load_source( wrapperFile3,
-                                         main.dependencyPath +
-                                         wrapperFile3 +
-                                         ".py" )
-
+            stepResult = main.testSetUp.envSetup( True, True )
             # Uncomment out the following if a mininet topology is added
             # copyResult1 = main.ONOSbench.scp( main.Mininet1,
             #                                   main.dependencyPath +
             #                                   main.topology,
             #                                   main.Mininet1.home + "custom/",
             #                                   direction="to" )
-
-            if main.CLIs and main.CLIs2:
-                stepResult = main.TRUE
-            else:
-                main.log.error( "Did not properly created list of ONOS CLI handle" )
-                stepResult = main.FALSE
         except Exception as e:
-            main.log.exception( e )
-            main.cleanup()
-            main.exit()
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
 
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully construct " +
-                                        "test variables ",
-                                 onfail="Failed to construct test variables" )
-
-        main.ONOSbench.getVersion( report=True )
 
     def CASE2( self, main ):
         """
@@ -126,164 +86,28 @@
         - Install ONOS cluster
         - Connect to cli
         """
-        main.cycle += 1
-
-        # main.scale[ 0 ] determines the current number of ONOS controller
-        main.numCtrls = int( main.scale[ 0 ] )
-
-        main.case( "Starting up " + str( main.numCtrls ) +
-                   " node(s) ONOS cluster" )
-        main.caseExplanation = "Set up ONOS with " + str( main.numCtrls ) +\
-                                " node(s) ONOS cluster"
-
-        #kill off all onos processes
-        main.log.info( "Safety check, killing all ONOS processes" +
-                       " before initiating environment setup" )
-
-        time.sleep( main.startUpSleep )
-        main.step( "Uninstalling ONOS package" )
-        onosUninstallResult = main.TRUE
-        for ip in main.ONOSip:
-            onosUninstallResult = onosUninstallResult and \
-                    main.ONOSbench.onosUninstall( nodeIp=ip )
-        stepResult = onosUninstallResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully uninstalled ONOS package",
-                                 onfail="Failed to uninstall ONOS package" )
-
-        for i in range( main.maxNodes ):
-            main.ONOSbench.onosDie( main.ONOSip[ i ] )
-
-        main.log.info( "NODE COUNT = " + str( main.numCtrls ) )
-
-        tempOnosIp = []
-        for i in range( main.numCtrls ):
-            tempOnosIp.append( main.ONOSip[ i ] )
-
-        main.ONOSbench.createCellFile( main.ONOSbench.ip_address,
-                                       "temp", main.Mininet1.ip_address,
-                                       main.apps, tempOnosIp, main.ONOScli1.karafUser )
-
-        main.step( "Apply cell to environment" )
-        cellResult = main.ONOSbench.setCell( "temp" )
-        verifyResult = main.ONOSbench.verifyCell()
-        stepResult = cellResult and verifyResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully applied cell to " +
-                                        "environment",
-                                 onfail="Failed to apply cell to environment " )
-
-        main.step( "Creating ONOS package" )
-        packageResult = main.ONOSbench.buckBuild()
-        stepResult = packageResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully created ONOS package",
-                                 onfail="Failed to create ONOS package" )
-
-        time.sleep( main.startUpSleep )
-        main.step( "Installing ONOS package" )
-        onosInstallResult = main.TRUE
-        for i in range( main.numCtrls ):
-            onosInstallResult = onosInstallResult and \
-                    main.ONOSbench.onosInstall( node=main.ONOSip[ i ], options="" )
-        stepResult = onosInstallResult
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully installed ONOS package",
-                                 onfail="Failed to install ONOS package" )
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.TRUE
-        for i in range( int( main.numCtrls ) ):
-            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=main.ONOSip[ i ] )
-        utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        time.sleep( main.startUpSleep )
-        main.step( "Starting ONOS service" )
-        stopResult = main.TRUE
-        startResult = main.TRUE
-        onosIsUp = main.TRUE
-
-        for i in range( main.numCtrls ):
-            onosIsUp = onosIsUp and main.ONOSbench.isup( main.ONOSip[ i ] )
-        if onosIsUp == main.TRUE:
-            main.log.report( "ONOS instance is up and ready" )
-        else:
-            main.log.report( "ONOS instance may not be up, stop and " +
-                             "start ONOS again " )
-            for i in range( main.numCtrls ):
-                stopResult = stopResult and \
-                        main.ONOSbench.onosStop( main.ONOSip[ i ] )
-            for i in range( main.numCtrls ):
-                startResult = startResult and \
-                        main.ONOSbench.onosStart( main.ONOSip[ i ] )
-        stepResult = onosIsUp and stopResult and startResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="ONOS service is ready",
-                                 onfail="ONOS service did not start properly" )
-
-        # Start an ONOS cli to provide functionality that is not currently
-        # supported by the Rest API remove this when Leader Checking is supported
-        # by the REST API
-
-        main.step( "Start ONOS cli" )
-        cliResult = main.TRUE
-        for i in range( main.numCtrls ):
-            cliResult = cliResult and \
-                        main.CLIs2[ i ].startOnosCli( main.ONOSip[ i ] )
-        stepResult = cliResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully start ONOS cli",
-                                 onfail="Failed to start ONOS cli" )
-
-        # Remove the first element in main.scale list
-        main.scale.remove( main.scale[ 0 ] )
+        main.testSetUp.ONOSSetUp( main.Mininet1, True )
 
     def CASE19( self, main ):
         """
             Copy the karaf.log files after each testcase cycle
         """
-        main.log.report( "Copy karaf logs" )
-        main.case( "Copy karaf logs" )
-        main.caseExplanation = "Copying the karaf logs to preserve them through" +\
-                               "reinstalling ONOS"
-        main.step( "Copying karaf logs" )
-        stepResult = main.TRUE
-        scpResult = main.TRUE
-        copyResult = main.TRUE
-        for i in range( main.numCtrls ):
-            main.node = main.CLIs2[ i ]
-            ip = main.ONOSip[ i ]
-            main.node.ip_address = ip
-            scpResult = scpResult and main.ONOSbench.scp( main.node,
-                                                          "/opt/onos/log/karaf.log",
-                                                          "/tmp/karaf.log",
-                                                          direction="from" )
-            copyResult = copyResult and main.ONOSbench.cpLogsToDir( "/tmp/karaf.log", main.logdir,
-                                                                    copyFileName=( "karaf.log.node{0}.cycle{1}".format( str( i + 1 ), str( main.cycle ) ) ) )
-            if scpResult and copyResult:
-                stepResult = main.TRUE and stepResult
-            else:
-                stepResult = main.FALSE and stepResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully copied remote ONOS logs",
-                                 onfail="Failed to copy remote ONOS logs" )
-
+        try:
+            from tests.dependencies.utils import Utils
+        except ImportError:
+            main.log.error( "Utils not found exiting the test" )
+            main.exit()
+        try:
+            main.Utils
+        except ( NameError, AttributeError ):
+            main.Utils = Utils()
+        main.Utils.copyKarafLog()
     def CASE100( self, main ):
         """
             Start NETCONF app and OFC-Server or make sure that they are already running
         """
         assert main, "There is no main"
-        assert main.CLIs, "There is no main.CLIs"
+        assert main.RESTs, "There is no main.RESTs"
         assert main.numCtrls, "Placed the total number of switch topology in \
                                 main.numCtrls"
 
@@ -316,7 +140,7 @@
                 -The file is built from information loaded from the .params file
         """
         assert main, "There is no main"
-        assert main.CLIs, "There is no main.CLIs"
+        assert main.RESTs, "There is no main.RESTs"
         assert main.numCtrls, "Placed the total number of switch topology in \
                                 main.numCtrls"
 
@@ -339,7 +163,7 @@
             Push a configuration and bring up a switch
         """
         assert main, "There is no main"
-        assert main.CLIs, "There is no main.CLIs"
+        assert main.RESTs, "There is no main.RESTs"
         assert main.numCtrls, "Placed the total number of switch topology in \
                                 main.numCtrls"
 
diff --git a/TestON/tests/FUNC/FUNCnetconf/dependencies/netconf.py b/TestON/tests/FUNC/FUNCnetconf/dependencies/netconf.py
index 7cc2258..b67a5f7 100644
--- a/TestON/tests/FUNC/FUNCnetconf/dependencies/netconf.py
+++ b/TestON/tests/FUNC/FUNCnetconf/dependencies/netconf.py
@@ -18,7 +18,7 @@
         the OF-Config server is running on the node to be configured
     """
     startResult = main.FALSE
-    startResult = main.CLIs[ 0 ].activateApp( appName="org.onosproject.netconf" )
+    startResult = main.RESTs[ 0 ].activateApp( appName="org.onosproject.netconf" )
     return startResult
 
 
@@ -96,7 +96,7 @@
     method = "POST"
     data = main.cfgJson
     configResult = main.FALSE
-    sendResult = main.CLIs[ 0 ].send( url=url, method=method, data=data )
+    sendResult = main.RESTs[ 0 ].send( url=url, method=method, data=data )
     main.log.info( "Device configuration request response code: " + str( sendResult[ 0 ] ) )
     if ( 200 <= sendResult[ 0 ] <= 299 ):
         configResult = main.TRUE
@@ -117,8 +117,8 @@
     addressResult = main.FALSE
     driverResult = main.FALSE
     try:
-        apiResult = main.CLIs[ 0 ].devices()
-        cliResult = main.CLIs2[ 0 ].devices()
+        apiResult = main.RESTs[ 0 ].devices()
+        cliResult = main.CLIs[ 0 ].devices()
 
         apiDict = json.loads( apiResult )
         cliDict = json.loads( cliResult )
diff --git a/TestON/tests/FUNC/FUNCnetconf/dependencies/startUp.py b/TestON/tests/FUNC/FUNCnetconf/dependencies/startUp.py
deleted file mode 100644
index a9becf9..0000000
--- a/TestON/tests/FUNC/FUNCnetconf/dependencies/startUp.py
+++ /dev/null
@@ -1,33 +0,0 @@
-"""
-    This wrapper function is use for starting up onos instance
-"""
-import time
-import os
-import json
-
-
-def onosBuild( main, gitBranch ):
-    """
-        This includes pulling ONOS and building it using maven install
-    """
-    buildResult = main.FALSE
-
-    # Git checkout a branch of ONOS
-    checkOutResult = main.ONOSbench.gitCheckout( gitBranch )
-    # Does the git pull on the branch that was checked out
-    if not checkOutResult:
-        main.log.warn( "Failed to checked out " + gitBranch +
-                                           " branch" )
-    else:
-        main.log.info( "Successfully checked out " + gitBranch +
-                                           " branch" )
-    gitPullResult = main.ONOSbench.gitPull()
-    if gitPullResult == main.ERROR:
-        main.log.error( "Error pulling git branch" )
-    else:
-        main.log.info( "Successfully pulled " + gitBranch + " branch" )
-
-    # buck build
-    buildResult = main.ONOSbench.buckBuild()
-
-    return buildResult
diff --git a/TestON/tests/FUNC/FUNCnetconf/dependencies/topo.py b/TestON/tests/FUNC/FUNCnetconf/dependencies/topo.py
deleted file mode 100644
index 7217d4d..0000000
--- a/TestON/tests/FUNC/FUNCnetconf/dependencies/topo.py
+++ /dev/null
@@ -1,102 +0,0 @@
-"""
-    These functions can be used for topology comparisons
-"""
-import time
-import os
-import json
-
-
-def getAllDevices( main ):
-    """
-        Return a list containing the devices output from each ONOS node
-    """
-    devices = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].devices,
-                         name="devices-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        devices.append( t.result )
-    return devices
-
-
-def getAllHosts( main ):
-    """
-        Return a list containing the hosts output from each ONOS node
-    """
-    hosts = []
-    ipResult = main.TRUE
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].hosts,
-                         name="hosts-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        hosts.append( t.result )
-    return hosts
-
-
-def getAllPorts( main ):
-    """
-        Return a list containing the ports output from each ONOS node
-    """
-    ports = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].ports,
-                         name="ports-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        ports.append( t.result )
-    return ports
-
-
-def getAllLinks( main ):
-    """
-        Return a list containing the links output from each ONOS node
-    """
-    links = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].links,
-                         name="links-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        links.append( t.result )
-    return links
-
-
-def getAllClusters( main ):
-    """
-        Return a list containing the clusters output from each ONOS node
-    """
-    clusters = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].clusters,
-                         name="clusters-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        clusters.append( t.result )
-    return clusters
diff --git a/TestON/tests/FUNC/FUNCoptical/FUNCoptical.py b/TestON/tests/FUNC/FUNCoptical/FUNCoptical.py
index c7ae463..9d800a7 100644
--- a/TestON/tests/FUNC/FUNCoptical/FUNCoptical.py
+++ b/TestON/tests/FUNC/FUNCoptical/FUNCoptical.py
@@ -7,219 +7,75 @@
         self.default = ''
 
     def CASE1( self, main ):
-        import time
         import imp
+        import time
         import re
-
         """
-        - Construct tests variables
-        - GIT ( optional )
-            - Checkout ONOS master branch
-            - Pull latest ONOS code
-        - Building ONOS ( optional )
-            - Install ONOS package
-            - Build ONOS package
+           - Construct tests variables
+           - GIT ( optional )
+               - Checkout ONOS master branch
+               - Pull latest ONOS code
+           - Building ONOS ( optional )
+               - Install ONOS package
+               - Build ONOS package
         """
-        main.case( "Constructing test variables and building ONOS package" )
-        main.step( "Constructing test variables" )
-        main.caseExplanation = "This test case is mainly for loading " +\
-                               "from params file, and pull and build the " +\
-                               " latest ONOS package"
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        main.testSetUp.envSetupDescription()
         stepResult = main.FALSE
-
         # Test variables
         try:
-            main.testOnDirectory = re.sub( "(/tests)$", "", main.testDir )
             main.apps = main.params[ 'ENV' ][ 'cellApps' ]
-            gitBranch = main.params[ 'GIT' ][ 'branch' ]
             main.dependencyPath = main.testOnDirectory + \
                                   main.params[ 'DEPENDENCY' ][ 'path' ]
             main.scale = ( main.params[ 'SCALE' ][ 'size' ] ).split( "," )
-            if main.ONOSbench.maxNodes:
-                main.maxNodes = int( main.ONOSbench.maxNodes )
-            else:
-                main.maxNodes = 0
             wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
             main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
             main.checkIntentSleep = int( main.params[ 'SLEEP' ][ 'checkintent' ] )
             main.checkTopoAttempts = int( main.params[ 'SLEEP' ][ 'topoAttempts' ] )
-            gitPull = main.params[ 'GIT' ][ 'pull' ]
             main.switches = int( main.params[ 'MININET' ][ 'switch' ] )
             main.links = int( main.params[ 'MININET' ][ 'links' ] )
             main.hosts = int( main.params[ 'MININET' ][ 'hosts' ] )
             main.opticalTopo = main.params[ 'MININET' ][ 'toponame' ]
-            main.cellData = {}  # For creating cell file
             main.hostsData = {}
-            main.CLIs = []
-            main.ONOSip = []  # List of IPs of active ONOS nodes. CASE 2
             main.activeONOSip = []
             main.assertReturnString = ''  # Assembled assert return string
             main.cycle = 0  # How many times FUNCintent has run through its tests
 
-            main.ONOSip = main.ONOSbench.getOnosIps()
-
-            # Assigning ONOS cli handles to a list
-            for i in range( 1, main.maxNodes + 1 ):
-                main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
-
             # -- INIT SECTION, ONLY RUNS ONCE -- #
-            main.topo = imp.load_source( wrapperFile1,
-                                         main.dependencyPath +
-                                         wrapperFile1 +
-                                         ".py" )
-            if main.CLIs:
-                stepResult = main.TRUE
-            else:
-                main.log.error( "Did not properly created list of ONOS CLI handle" )
-                stepResult = main.FALSE
+            stepResult = main.testSetUp.envSetup( True )
         except Exception as e:
-            main.log.exception( e )
-            main.cleanup()
-            main.exit()
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully construct " +
-                                        "test variables ",
-                                 onfail="Failed to construct test variables" )
-
-        main.ONOSbench.getVersion( report=True )
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
 
     def CASE2( self, main ):
         """
-        - Set up cell
-            - Create cell file
-            - Set cell file
-            - Verify cell file
-        - Kill ONOS process
-        - Uninstall ONOS cluster
-        - Verify ONOS start up
-        - Install ONOS cluster
-        - Connect to cli
+            - Set up cell
+                - Create cell file
+                - Set cell file
+                - Verify cell file
+            - Kill ONOS process
+            - Uninstall ONOS cluster
+            - Verify ONOS start up
+            - Install ONOS cluster
+            - Connect to cli
         """
-        main.cycle += 1
-
-        # main.scale[ 0 ] determines the current number of ONOS controller
-        main.numCtrls = int( main.scale[ 0 ] )
         main.flowCompiler = "Flow Rules"
-
-        main.case( "Starting up " + str( main.numCtrls ) +
-                   " node(s) ONOS cluster" )
-        main.caseExplanation = "Set up ONOS with " + str( main.numCtrls ) +\
-                                " node(s) ONOS cluster"
-
-        #kill off all onos processes
-        main.log.info( "Safety check, killing all ONOS processes" +
-                       " before initiating environment setup" )
-
-        for i in range( main.maxNodes ):
-            main.ONOSbench.onosDie( main.ONOSip[ i ] )
-
-        print "NODE COUNT = ", main.numCtrls
-
-        tempOnosIp = []
-        for i in range( main.numCtrls ):
-            tempOnosIp.append( main.ONOSip[ i ] )
-
-        main.ONOSbench.createCellFile( main.ONOSbench.ip_address,
-                                       "temp", main.Mininet1.ip_address,
-                                       main.apps, tempOnosIp, main.ONOScli1.karafUser )
-
-        main.step( "Apply cell to environment" )
-        cellResult = main.ONOSbench.setCell( "temp" )
-        verifyResult = main.ONOSbench.verifyCell()
-        stepResult = cellResult and verifyResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully applied cell to " +
-                                        "environment",
-                                 onfail="Failed to apply cell to environment " )
-
-        main.step( "Creating ONOS package" )
-        packageResult = main.ONOSbench.buckBuild()
-        stepResult = packageResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully created ONOS package",
-                                 onfail="Failed to create ONOS package" )
-
-        time.sleep( main.startUpSleep )
-        main.step( "Uninstalling ONOS package" )
-        onosUninstallResult = main.TRUE
-        for ip in main.ONOSip:
-            onosUninstallResult = onosUninstallResult and \
-                    main.ONOSbench.onosUninstall( nodeIp=ip )
-        stepResult = onosUninstallResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully uninstalled ONOS package",
-                                 onfail="Failed to uninstall ONOS package" )
-
-        time.sleep( main.startUpSleep )
-        main.step( "Installing ONOS package" )
-        onosInstallResult = main.TRUE
-        del main.activeONOSip[:]
-        for i in range( main.numCtrls ):
-            onosInstallResult = onosInstallResult and \
-                    main.ONOSbench.onosInstall( node=main.ONOSip[ i ] )
-            # Populate activeONOSip
-            main.activeONOSip.append( main.ONOSip[ i ] )
-        stepResult = onosInstallResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully installed ONOS package",
-                                 onfail="Failed to install ONOS package" )
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.TRUE
-        for i in range( int( main.numCtrls ) ):
-            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=main.ONOSip[ i ] )
-        utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        time.sleep( main.startUpSleep )
-        main.step( "Starting ONOS service" )
-        stopResult = main.TRUE
-        startResult = main.TRUE
-        onosIsUp = main.TRUE
-
-        for i in range( main.numCtrls ):
-            isUp = main.ONOSbench.isup( main.ONOSip[ i ] )
-            onosIsUp = onosIsUp and isUp
-            if isUp == main.TRUE:
-                main.log.report( "ONOS instance {0} is up and ready".format( i + 1 ) )
-            else:
-                main.log.report( "ONOS instance {0} may not be up, stop and ".format( i + 1 ) +
-                                 "start ONOS again " )
-                stopResult = stopResult and main.ONOSbench.onosStop( main.ONOSip[ i ] )
-                startResult = startResult and main.ONOSbench.onosStart( main.ONOSip[ i ] )
-                if not startResult or stopResult:
-                    main.log.report( "ONOS instance {0} did not start correctly.".format( i + 1 ) )
-        stepResult = onosIsUp and stopResult and startResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="ONOS service is ready on all nodes",
-                                 onfail="ONOS service did not start properly on all nodes" )
-
-        main.step( "Start ONOS cli" )
-        cliResult = main.TRUE
-        for i in range( main.numCtrls ):
-            cliResult = cliResult and \
-                        main.CLIs[ i ].startOnosCli( main.ONOSip[ i ] )
-        stepResult = cliResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully start ONOS cli",
-                                 onfail="Failed to start ONOS cli" )
-
-        # Remove the first element in main.scale list
-        main.scale.remove( main.scale[ 0 ] )
+        main.testSetUp.ONOSSetUp( main.LincOE, True )
 
     def CASE10( self, main ):
         """
             Start Mininet opticalTest Topology
         """
+        del main.activeONOSip[:]
+        for i in range( main.numCtrls ):
+            # Populate activeONOSip
+            main.activeONOSip.append( main.ONOSip[ i ] )
+
         main.case( "Mininet with Linc-OE startup" )
         main.step( "Push TopoDDriver.json to ONOS through onos-netcfg" )
         topoResult = main.ONOSbench.onosNetCfg( controllerIps=main.activeONOSip, path=main.dependencyPath,
@@ -234,7 +90,7 @@
         time.sleep( 10 )
         controllerIPs = ','.join( main.activeONOSip )
         cIps = ""
-        for i in range(0,4):
+        for i in range( 0, 4 ):
             cIps += controllerIPs + ' '
         opticalMnScript = main.LincOE.runOpticalMnScript( ctrllerIP=cIps, topology=main.opticalTopo )
         topoResult = opticalMnScript
@@ -248,17 +104,17 @@
         """
             Stop mininet
         """
-        main.log.report( "Stop Mininet topology" )
-        main.case( "Stop Mininet topology" )
-        main.caseExplanation = "Stopping the current mininet topology " +\
-                                "to start up fresh"
-
-        main.step( "Stopping Mininet Topology" )
-        topoResult = main.LincOE.stopNet( timeout=180 )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=topoResult,
-                                 onpass="Successfully stopped mininet",
-                                 onfail="Failed to stopped mininet" )
+        try:
+            from tests.dependencies.utils import Utils
+        except ImportError:
+            main.log.error( "Utils not found exiting the test" )
+            main.exit()
+        try:
+            main.Utils
+        except ( NameError, AttributeError ):
+            main.Utils = Utils()
+        main.Utils.mininetCleanIntro()
+        topoResult = main.Utils.mininetCleanup( main.LincOE, timeout=180 )
         # Exit if topology did not load properly
         if not topoResult:
             main.cleanup()
@@ -307,33 +163,16 @@
         """
             Copy the karaf.log files after each testcase cycle
         """
-        main.log.report( "Copy karaf logs" )
-        main.case( "Copy karaf logs" )
-        main.caseExplanation = "Copying the karaf logs to preserve them through" +\
-                               "reinstalling ONOS"
-        main.step( "Copying karaf logs" )
-        stepResult = main.TRUE
-        scpResult = main.TRUE
-        copyResult = main.TRUE
-        for i in range( main.numCtrls ):
-            main.node = main.CLIs[ i ]
-            ip = main.ONOSip[ i ]
-            main.node.ip_address = ip
-            scpResult = scpResult and main.ONOSbench.scp( main.node,
-                                                          "/opt/onos/log/karaf.log",
-                                                          "/tmp/karaf.log",
-                                                          direction="from" )
-            copyResult = copyResult and main.ONOSbench.cpLogsToDir( "/tmp/karaf.log", main.logdir,
-                                                                    copyFileName=( "karaf.log.node{0}.cycle{1}".format( str( i + 1 ), str( main.cycle ) ) ) )
-            if scpResult and copyResult:
-                stepResult = main.TRUE and stepResult
-            else:
-                stepResult = main.FALSE and stepResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully copied remote ONOS logs",
-                                 onfail="Failed to copy remote ONOS logs" )
-
+        try:
+            from tests.dependencies.utils import Utils
+        except ImportError:
+            main.log.error( "Utils not found exiting the test" )
+            main.exit()
+        try:
+            main.Utils
+        except ( NameError, AttributeError ):
+            main.Utils = Utils()
+        main.Utils.copyKarafLog()
     def CASE21( self, main ):
         """
             Run pingall to discover all hosts
@@ -379,7 +218,15 @@
         Compare ONOS Topology to Mininet Topology
         """
         import json
-
+        try:
+            from tests.dependencies.topology import Topology
+        except ImportError:
+            main.log.error( "Topology not found exiting the test" )
+            main.exit()
+        try:
+            main.topoRelated
+        except ( NameError, AttributeError ):
+            main.topoRelated = Topology()
         main.case( "Compare ONOS Topology view to Mininet topology" )
         main.caseExplanation = "Compare topology elements between Mininet" +\
                                 " and ONOS"
@@ -403,16 +250,16 @@
                 ( not devicesResults or not linksResults or not hostsResults ):
             time.sleep( 2 )
             if not devicesResults:
-                devices = main.topo.getAllDevices( main )
-                ports = main.topo.getAllPorts( main )
+                devices = main.topoRelated.getAllDevices( main.numCtrls, False )
+                ports = main.topoRelated.getAllPorts( main.numCtrls, False )
                 devicesResults = main.TRUE
                 deviceFails = []  # Reset for each attempt
             if not linksResults:
-                links = main.topo.getAllLinks( main )
+                links = main.topoRelated.getAllLinks( main.numCtrls, False )
                 linksResults = main.TRUE
                 linkFails = []  # Reset for each attempt
             if not hostsResults:
-                hosts = main.topo.getAllHosts( main )
+                hosts = main.topoRelated.getAllHosts( main.numCtrls, False )
                 hostsResults = main.TRUE
                 hostFails = []  # Reset for each attempt
 
@@ -507,6 +354,7 @@
                                  onpass="ONOS correctly discovered the topology",
                                  onfail="ONOS incorrectly discovered the topology" )
 
+
     def CASE31( self, main ):
         import time
         """
diff --git a/TestON/tests/FUNC/FUNCoptical/dependencies/topo.py b/TestON/tests/FUNC/FUNCoptical/dependencies/topo.py
deleted file mode 100644
index 7217d4d..0000000
--- a/TestON/tests/FUNC/FUNCoptical/dependencies/topo.py
+++ /dev/null
@@ -1,102 +0,0 @@
-"""
-    These functions can be used for topology comparisons
-"""
-import time
-import os
-import json
-
-
-def getAllDevices( main ):
-    """
-        Return a list containing the devices output from each ONOS node
-    """
-    devices = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].devices,
-                         name="devices-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        devices.append( t.result )
-    return devices
-
-
-def getAllHosts( main ):
-    """
-        Return a list containing the hosts output from each ONOS node
-    """
-    hosts = []
-    ipResult = main.TRUE
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].hosts,
-                         name="hosts-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        hosts.append( t.result )
-    return hosts
-
-
-def getAllPorts( main ):
-    """
-        Return a list containing the ports output from each ONOS node
-    """
-    ports = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].ports,
-                         name="ports-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        ports.append( t.result )
-    return ports
-
-
-def getAllLinks( main ):
-    """
-        Return a list containing the links output from each ONOS node
-    """
-    links = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].links,
-                         name="links-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        links.append( t.result )
-    return links
-
-
-def getAllClusters( main ):
-    """
-        Return a list containing the clusters output from each ONOS node
-    """
-    clusters = []
-    threads = []
-    for i in range( main.numCtrls ):
-        t = main.Thread( target=main.CLIs[ i ].clusters,
-                         name="clusters-" + str( i ),
-                         args=[] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        clusters.append( t.result )
-    return clusters
diff --git a/TestON/tests/FUNC/FUNCovsdbtest/FUNCovsdbtest.py b/TestON/tests/FUNC/FUNCovsdbtest/FUNCovsdbtest.py
index 0737e63..c5f7415 100644
--- a/TestON/tests/FUNC/FUNCovsdbtest/FUNCovsdbtest.py
+++ b/TestON/tests/FUNC/FUNCovsdbtest/FUNCovsdbtest.py
@@ -37,123 +37,32 @@
         import os
         import time
         main.log.info( "ONOS Single node start ovsdb test - initialization" )
-        main.case( "Setting up test environment" )
-        main.caseExplanation = "Setup the test environment including " +\
-                                "installing ONOS, start ONOS."
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        main.testSetUp.envSetupDescription()
+        stepResult = main.FALSE
 
-        # load some variables from the params file
-        main.step( "Constructing test variables" )
-        gitPull = main.params[ 'GIT' ][ 'pull' ]
-        gitBranch = main.params[ 'GIT' ][ 'branch' ]
-        cellName = main.params[ 'ENV' ][ 'cellName' ]
-        ipList = os.getenv( main.params[ 'CTRL' ][ 'ip1' ] )
-        main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
-        cellAppString = main.params[ 'ENV' ][ 'cellApps' ]
+        try:
+            # load some variables from the params file
+            main.step( "Constructing test variables" )
+            cellName = main.params[ 'ENV' ][ 'cellName' ]
+            main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
+            main.apps = main.params[ 'ENV' ][ 'cellApps' ]
 
-        main.ONOSbench.getVersion( report=True )
+            main.maxNodes = 1
 
-        main.log.info( "Safety check, killing all ONOS processes" +
-                       " before initiating environment setup" )
+            stepResult = main.testSetUp.envSetup( hasNode=True )
 
-        main.log.info( "Removing raft logs" )
-        main.ONOSbench.onosRemoveRaftLogs()
+        except Exception as e:
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
 
-        main.CLIs = []
-        main.nodes = []
-        main.numCtrls = 1
 
-        for i in range( 1, main.numCtrls + 1 ):
-            try:
-                main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
-                main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
-                ipList.append( main.nodes[ -1 ].ip_address )
-            except AttributeError:
-                break
-
-        main.step( "Uninstalling ONOS package" )
-        onosUninstallResult = main.TRUE
-        for node in main.nodes:
-            onosUninstallResult = onosUninstallResult and main.ONOSbench.onosUninstall( node.ip_address )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=onosUninstallResult,
-                                 onpass="Successfully uninstalled ONOS package",
-                                 onfail="Failed to uninstall ONOS package" )
-        time.sleep( main.startUpSleep )
-
-        # Make sure ONOS process is not running
-        main.log.info( "Killing any ONOS processes" )
-        killResults = main.TRUE
-        for node in main.nodes:
-            killed = main.ONOSbench.onosKill( node.ip_address )
-            killResults = killResults and killed
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=onosUninstallResult,
-                                 onpass="Successfully kill all ONOS processes",
-                                 onfail="Failed to kill all ONOS processes" )
-
-        main.step( "Create cell file" )
-        main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
-                                       main.OVSDB1.ip_address,
-                                       cellAppString, ipList, main.ONOScli1.karafUser )
-
-        main.step( "Apply cell to environment" )
-        cellResult = main.ONOSbench.setCell( cellName )
-        verifyResult = main.ONOSbench.verifyCell()
-        stepResult = cellResult and verifyResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully applied cell to environment",
-                                 onfail="Failed to apply cell to environment" )
-
-        main.step( "Creating ONOS package" )
-        packageResult = main.ONOSbench.buckBuild()
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=packageResult,
-                                 onpass="Successfully created ONOS package",
-                                 onfail="Failed to create ONOS package" )
-
-        time.sleep( main.startUpSleep )
-        main.step( "Installing ONOS package" )
-        onosInstallResult = main.ONOSbench.onosInstall( options="-f", node=main.nodes[ 0 ].ip_address )
-        utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
-                                 onpass="Successfully installed ONOS package",
-                                 onfail="Failed to install ONOS package" )
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.TRUE
-        for i in range( int( main.numCtrls ) ):
-            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=main.nodes[ i ].ip_address )
-        utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        time.sleep( main.startUpSleep )
-        main.step( "Starting ONOS service" )
-        stopResult = main.TRUE
-        startResult = main.TRUE
-        onos1Isup = main.TRUE
-        for i in range( 2 ):
-            Isup = main.ONOSbench.isup( main.nodes[ 0 ].ip_address )
-            onos1Isup = onos1Isup and Isup
-            if onos1Isup:
-                main.log.report( "ONOS instance {0} is up and ready".format( i + 1 ) )
-            else:
-                main.log.report( "ONOS instance {0} may not be up, stop and ".format( i + 1 ) +
-                                 "start ONOS again" )
-                stopResult = stopResult and main.ONOSbench.onosStop( main.ONOSip[ i ] )
-                startResult = startResult and main.ONOSbench.onosStart( main.ONOSip[ i ] )
-                if not startResult or stopResult:
-                    main.log.report( "ONOS instance {0} did not start correctly.".format( i + 1 ) )
-        stepResult = onos1Isup and stopResult and startResult
-        utilities.assert_equals( expect=main.TRUE, actual=stepResult,
-                                 onpass="ONOS service is ready on all nodes",
-                                 onfail="ONOS service did not start properly on all nodes" )
-
-        main.step( "Starting ONOS CLI sessions" )
-        cliResults = main.ONOScli1.startOnosCli( main.nodes[ 0 ].ip_address )
-        utilities.assert_equals( expect=main.TRUE, actual=cliResults,
-                                 onpass="Successfully start ONOS cli",
-                                 onfail="Failed to start ONOS cli" )
+        cliResults = main.testSetUp.ONOSSetUp( main.OVSDB1, cellName=cellName, removeLog=True )
 
         if cliResults == main.FALSE:
             main.log.error( "Failed to start ONOS, stopping test" )
diff --git a/TestON/tests/FUNC/FUNCvirNetNB/FUNCvirNetNB.py b/TestON/tests/FUNC/FUNCvirNetNB/FUNCvirNetNB.py
index 7734bdd..bdfe044 100644
--- a/TestON/tests/FUNC/FUNCvirNetNB/FUNCvirNetNB.py
+++ b/TestON/tests/FUNC/FUNCvirNetNB/FUNCvirNetNB.py
@@ -48,114 +48,31 @@
         import os
         main.log.info( "ONOS Single node Start " +
                        "VirtualNet Northbound test - initialization" )
-        main.case( "Setting up test environment" )
-        main.caseExplanation  = "Setup the test environment including " +\
-                                "installing ONOS,start ONOS."
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        main.testSetUp.envSetupDescription()
+        stepResult = main.FALSE
+        try:
+            main.apps = main.params['ENV']['cellApps']
+            cellName = main.params['ENV']['cellName']
+            main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
+            stepResult = main.testSetUp.envSetup( hasNode=True )
+        except Exception as e:
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
 
-        # load some variables from the params file
-        PULLCODE = False
-        if main.params[ 'GIT' ][ 'pull' ] == 'True':
-            PULLCODE = True
-        gitBranch = main.params[ 'GIT' ][ 'branch' ]
-        cellName = main.params[ 'ENV' ][ 'cellName' ]
-        ipList = os.getenv( main.params[ 'CTRL' ][ 'ip1' ] )
+        main.maxNodes = 1
 
-        main.step( "Create cell file and apply to environment" )
-        cellAppString = main.params[ 'ENV' ][ 'cellApps' ]
-        main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
-                                       main.Mininet1.ip_address,
-                                       cellAppString, ipList, main.ONOScli1.karafUser )
+        cliResults = main.testSetUp.ONOSSetUp( main.Mininet1, cellName=cellName, removeLog=True )
 
-        cellResult = main.ONOSbench.setCell( cellName )
-        verifyResult = main.ONOSbench.verifyCell()
-
-        stepResult = cellResult and verifyResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully applied cell to " +
-                                        "environment",
-                                 onfail="Failed to apply cell to environment " )
-
-        #FIXME:this is short term fix
-        main.log.info( "Removing raft logs" )
-        main.ONOSbench.onosRemoveRaftLogs()
-
-        main.CLIs = []
-        main.nodes = []
-        main.numCtrls = 1
-        main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
-
-        for i in range( 1, main.numCtrls + 1 ):
-            try:
-                main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
-                main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
-                ipList.append( main.nodes[ -1 ].ip_address )
-            except AttributeError:
-                break
-
-        main.log.info( "Uninstalling ONOS" )
-        for node in main.nodes:
-            main.ONOSbench.onosUninstall( node.ip_address )
-
-        #Make sure ONOS is DEAD
-        main.log.info( "Killing any ONOS processes" )
-        killResults = main.TRUE
-        for node in main.nodes:
-            killed = main.ONOSbench.onosKill( node.ip_address )
-            killResults = killResults and killed
-
-        gitPullResult = main.TRUE
-        main.log.info( "Git checkout and pull " + gitBranch )
-        if PULLCODE:
-            main.ONOSbench.gitCheckout( gitBranch )
-            gitPullResult = main.ONOSbench.gitPull()
-            # values of 1 or 3 are good
-            utilities.assert_lesser( expect=0, actual=gitPullResult,
-                                      onpass="Git pull successful",
-                                      onfail="Git pull failed" )
-        main.ONOSbench.getVersion( report=True )
-
-        main.step( "Creating ONOS package" )
-        packageResult = main.ONOSbench.buckBuild()
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=packageResult,
-                                 onpass="Successfully created ONOS package",
-                                 onfail="Failed to create ONOS package " )
-        time.sleep( main.startUpSleep )
-
-        main.step( "Installing ONOS package" )
-        onosInstallResult = main.ONOSbench.onosInstall(
-            options="-f", node=main.nodes[ 0 ].ip_address )
-        utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
-                                 onpass="ONOS install successful",
-                                 onfail="ONOS install failed" )
-        time.sleep( main.startUpSleep )
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.ONOSbench.onosSecureSSH( node=main.nodes[ 0 ].ip_address )
-        utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        main.step( "Checking if ONOS is up yet" )
-
-        for i in range( 2 ):
-            onos1Isup = main.ONOSbench.isup( main.nodes[ 0 ].ip_address )
-            if onos1Isup:
-                break
-        utilities.assert_equals( expect=main.TRUE, actual=onos1Isup,
-                                 onpass="ONOS startup successful",
-                                 onfail="ONOS startup failed" )
-        time.sleep( main.startUpSleep )
-
-        main.step( "Starting ONOS CLI sessions" )
-
-        print main.nodes[ 0 ].ip_address
-        cliResults = main.ONOScli1.startOnosCli( main.nodes[ 0 ].ip_address )
-        utilities.assert_equals( expect=main.TRUE, actual=cliResults,
-                                 onpass="ONOS cli startup successful",
-                                 onfail="ONOS cli startup failed" )
-        time.sleep( main.startUpSleep )
+        if cliResults == main.FALSE:
+            main.log.error( "Failed to start ONOS, stopping test" )
+            main.cleanup()
+            main.exit()
 
         main.step( "App Ids check" )
         appCheck = main.ONOScli1.appToIDCheck()
@@ -166,11 +83,6 @@
                                  onpass="App Ids seem to be correct",
                                  onfail="Something is wrong with app Ids" )
 
-        if cliResults == main.FALSE:
-            main.log.error( "Failed to start ONOS, stopping test" )
-            main.cleanup()
-            main.exit()
-
         main.step( "Install org.onosproject.vtn app" )
         installResults = main.ONOScli1.activateApp( "org.onosproject.vtn" )
         utilities.assert_equals( expect=main.TRUE, actual=installResults,
diff --git a/TestON/tests/HA/HAclusterRestart/HAclusterRestart.params b/TestON/tests/HA/HAclusterRestart/HAclusterRestart.params
index 3911747..c55b26c 100644
--- a/TestON/tests/HA/HAclusterRestart/HAclusterRestart.params
+++ b/TestON/tests/HA/HAclusterRestart/HAclusterRestart.params
@@ -33,8 +33,10 @@
         <cellName>HA</cellName>
         <appString>drivers,openflow,proxyarp,mobility</appString>
     </ENV>
-    <Git> False </Git>
-    <branch> master </branch>
+    <GIT>
+        <pull>False</pull>
+        <branch>master</branch>
+    </GIT>
     <num_controllers> 7 </num_controllers>
     <tcpdump> False </tcpdump>
 
diff --git a/TestON/tests/HA/HAclusterRestart/HAclusterRestart.py b/TestON/tests/HA/HAclusterRestart/HAclusterRestart.py
index 3047df2..8b06dbd 100644
--- a/TestON/tests/HA/HAclusterRestart/HAclusterRestart.py
+++ b/TestON/tests/HA/HAclusterRestart/HAclusterRestart.py
@@ -50,1723 +50,66 @@
         import json
         main.log.info( "ONOS HA test: Restart all ONOS nodes - " +
                          "initialization" )
-        main.case( "Setting up test environment" )
-        main.caseExplanation = "Setup the test environment including " +\
-                                "installing ONOS, starting Mininet and ONOS" +\
-                                "cli sessions."
-
-        # load some variables from the params file
-        PULLCODE = False
-        if main.params[ 'Git' ] == 'True':
-            PULLCODE = True
-        gitBranch = main.params[ 'branch' ]
-        cellName = main.params[ 'ENV' ][ 'cellName' ]
-
-        main.numCtrls = int( main.params[ 'num_controllers' ] )
-        if main.ONOSbench.maxNodes:
-            if main.ONOSbench.maxNodes < main.numCtrls:
-                main.numCtrls = int( main.ONOSbench.maxNodes )
-        # set global variables
-        global ONOS1Port
-        global ONOS2Port
-        global ONOS3Port
-        global ONOS4Port
-        global ONOS5Port
-        global ONOS6Port
-        global ONOS7Port
         # These are for csv plotting in jenkins
-        global labels
-        global data
-        labels = []
-        data = []
-
-        # 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' ]
-
+        main.HAlabels = []
+        main.HAdata = []
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found exiting the test" )
+            main.exit()
+        main.testSetUp.envSetupDescription()
         try:
             from tests.HA.dependencies.HA import HA
             main.HA = HA()
+            # load some variables from the params file
+            cellName = main.params[ 'ENV' ][ 'cellName' ]
+            main.apps = main.params[ 'ENV' ][ 'appString' ]
+            main.numCtrls = int( main.params[ 'num_controllers' ] )
+            if main.ONOSbench.maxNodes and \
+                            main.ONOSbench.maxNodes < main.numCtrls:
+                main.numCtrls = int( main.ONOSbench.maxNodes )
+            main.maxNodes = main.numCtrls
+            stepResult = main.testSetUp.envSetup( hasNode=True )
         except Exception as e:
-            main.log.exception( e )
-            main.cleanup()
-            main.exit()
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
+        main.HA.generateGraph( "HAclusterRestart" )
 
-        main.CLIs = []
-        main.nodes = []
-        ipList = []
-        for i in range( 1, main.numCtrls + 1 ):
-            try:
-                main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
-                main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
-                ipList.append( main.nodes[ -1 ].ip_address )
-            except AttributeError:
-                break
+        main.testSetUp.ONOSSetUp( main.Mininet1, cellName=cellName, removeLog=True,
+                                  extraApply=main.HA.startingMininet )
 
-        main.step( "Create cell file" )
-        cellAppString = main.params[ 'ENV' ][ 'appString' ]
-        main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
-                                       main.Mininet1.ip_address,
-                                       cellAppString, ipList, main.ONOScli1.karafUser )
-        main.step( "Applying cell variable to environment" )
-        cellResult = main.ONOSbench.setCell( cellName )
-        verifyResult = main.ONOSbench.verifyCell()
-
-        # FIXME:this is short term fix
-        main.log.info( "Removing raft logs" )
-        main.ONOSbench.onosRemoveRaftLogs()
-
-        main.log.info( "Uninstalling ONOS" )
-        for node in main.nodes:
-            main.ONOSbench.onosUninstall( node.ip_address )
-
-        # Make sure ONOS is DEAD
-        main.log.info( "Killing any ONOS processes" )
-        killResults = main.TRUE
-        for node in main.nodes:
-            killed = main.ONOSbench.onosKill( node.ip_address )
-            killResults = killResults and killed
-
-        gitPullResult = main.TRUE
-
-        main.step( "Starting Mininet" )
-        # scp topo file to mininet
-        # TODO: move to params?
-        topoName = "obelisk.py"
-        filePath = main.ONOSbench.home + "/tools/test/topos/"
-        main.ONOSbench.scp( main.Mininet1,
-                            filePath + topoName,
-                            main.Mininet1.home,
-                            direction="to" )
-        mnResult = main.Mininet1.startNet()
-        utilities.assert_equals( expect=main.TRUE, actual=mnResult,
-                                 onpass="Mininet Started",
-                                 onfail="Error starting Mininet" )
-
-        main.step( "Git checkout and pull " + gitBranch )
-        if PULLCODE:
-            main.ONOSbench.gitCheckout( gitBranch )
-            gitPullResult = main.ONOSbench.gitPull()
-            # values of 1 or 3 are good
-            utilities.assert_lesser( expect=0, actual=gitPullResult,
-                                      onpass="Git pull successful",
-                                      onfail="Git pull failed" )
-        main.ONOSbench.getVersion( report=True )
-
-        # GRAPHS
-        # NOTE: important params here:
-        #       job = name of Jenkins job
-        #       Plot Name = Plot-HA, only can be used if multiple plots
-        #       index = The number of the graph under plot name
-        job = "HAclusterRestart"
-        plotName = "Plot-HA"
-        index = "2"
-        graphs = '<ac:structured-macro ac:name="html">\n'
-        graphs += '<ac:plain-text-body><![CDATA[\n'
-        graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
-                  '/plot/' + plotName + '/getPlot?index=' + index +\
-                  '&width=500&height=300"' +\
-                  'noborder="0" width="500" height="300" scrolling="yes" ' +\
-                  'seamless="seamless"></iframe>\n'
-        graphs += ']]></ac:plain-text-body>\n'
-        graphs += '</ac:structured-macro>\n'
-        main.log.wiki( graphs )
-
-        main.step( "Creating ONOS package" )
-        packageResult = main.ONOSbench.buckBuild()
-        utilities.assert_equals( expect=main.TRUE, actual=packageResult,
-                                 onpass="ONOS package successful",
-                                 onfail="ONOS package failed" )
-
-        main.step( "Installing ONOS package" )
-        onosInstallResult = main.TRUE
-        for node in main.nodes:
-            tmpResult = main.ONOSbench.onosInstall( options="-f",
-                                                    node=node.ip_address )
-            onosInstallResult = onosInstallResult and tmpResult
-        utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
-                                 onpass="ONOS install successful",
-                                 onfail="ONOS install failed" )
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.TRUE
-        for node in main.nodes:
-            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=node.ip_address )
-        utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        main.step( "Checking if ONOS is up yet" )
-        for i in range( 2 ):
-            onosIsupResult = main.TRUE
-            for node in main.nodes:
-                started = main.ONOSbench.isup( node.ip_address )
-                if not started:
-                    main.log.error( node.name + " hasn't started" )
-                onosIsupResult = onosIsupResult and started
-            if onosIsupResult == main.TRUE:
-                break
-        utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
-                                 onpass="ONOS startup successful",
-                                 onfail="ONOS startup failed" )
-
-        main.step( "Starting ONOS CLI sessions" )
-        cliResults = main.TRUE
-        threads = []
-        for i in range( main.numCtrls ):
-            t = main.Thread( target=main.CLIs[ i ].startOnosCli,
-                             name="startOnosCli-" + str( i ),
-                             args=[ main.nodes[ i ].ip_address ] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            cliResults = cliResults and t.result
-        utilities.assert_equals( expect=main.TRUE, actual=cliResults,
-                                 onpass="ONOS cli startup successful",
-                                 onfail="ONOS cli startup failed" )
-
-        # Create a list of active nodes for use when some nodes are stopped
-        main.activeNodes = [ i for i in range( 0, len( main.CLIs ) ) ]
-
-        if main.params[ 'tcpdump' ].lower() == "true":
-            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' ] )
-
-        main.step( "Checking ONOS nodes" )
-        nodeResults = utilities.retry( main.HA.nodesCheck,
-                                       False,
-                                       args=[ main.activeNodes ],
-                                       attempts=5 )
-
-        utilities.assert_equals( expect=True, actual=nodeResults,
-                                 onpass="Nodes check successful",
-                                 onfail="Nodes check NOT successful" )
-
-        if not nodeResults:
-            for i in main.activeNodes:
-                cli = main.CLIs[ i ]
-                main.log.debug( "{} components not ACTIVE: \n{}".format(
-                    cli.name,
-                    cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
-            main.log.error( "Failed to start ONOS, stopping test" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Activate apps defined in the params file" )
-        # get data from the params
-        apps = main.params.get( 'apps' )
-        if apps:
-            apps = apps.split( ',' )
-            main.log.warn( apps )
-            activateResult = True
-            for app in apps:
-                main.CLIs[ 0 ].app( app, "Activate" )
-            # TODO: check this worked
-            time.sleep( 10 )  # wait for apps to activate
-            for app in apps:
-                state = main.CLIs[ 0 ].appStatus( app )
-                if state == "ACTIVE":
-                    activateResult = activateResult and True
-                else:
-                    main.log.error( "{} is in {} state".format( app, state ) )
-                    activateResult = False
-            utilities.assert_equals( expect=True,
-                                     actual=activateResult,
-                                     onpass="Successfully activated apps",
-                                     onfail="Failed to activate apps" )
-        else:
-            main.log.warn( "No apps were specified to be loaded after startup" )
-
-        main.step( "Set ONOS configurations" )
-        config = main.params.get( 'ONOS_Configuration' )
-        if config:
-            main.log.debug( config )
-            checkResult = main.TRUE
-            for component in config:
-                for setting in config[ component ]:
-                    value = config[ component ][ setting ]
-                    check = main.CLIs[ 0 ].setCfg( component, setting, value )
-                    main.log.info( "Value was changed? {}".format( main.TRUE == check ) )
-                    checkResult = check and checkResult
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=checkResult,
-                                     onpass="Successfully set config",
-                                     onfail="Failed to set config" )
-        else:
-            main.log.warn( "No configurations were specified to be changed after startup" )
-
-        main.step( "App Ids check" )
-        appCheck = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
-                             name="appToIDCheck-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            appCheck = appCheck and t.result
-        if appCheck != main.TRUE:
-            node = main.activeNodes[ 0 ]
-            main.log.warn( main.CLIs[ node ].apps() )
-            main.log.warn( main.CLIs[ node ].appIDs() )
-        utilities.assert_equals( expect=main.TRUE, actual=appCheck,
-                                 onpass="App Ids seem to be correct",
-                                 onfail="Something is wrong with app Ids" )
+        main.HA.initialSetUp()
 
     def CASE2( self, main ):
         """
         Assign devices to controllers
         """
-        import re
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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.case( "Assigning devices to controllers" )
-        main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
-                                "and check that an ONOS node becomes the " +\
-                                "master of the device."
-        main.step( "Assign switches to controllers" )
-
-        ipList = []
-        for i in range( main.numCtrls ):
-            ipList.append( main.nodes[ i ].ip_address )
-        swList = []
-        for i in range( 1, 29 ):
-            swList.append( "s" + str( i ) )
-        main.Mininet1.assignSwController( sw=swList, ip=ipList )
-
-        mastershipCheck = main.TRUE
-        for i in range( 1, 29 ):
-            response = main.Mininet1.getSwController( "s" + str( i ) )
-            try:
-                main.log.info( str( response ) )
-            except Exception:
-                main.log.info( repr( response ) )
-            for node in main.nodes:
-                if re.search( "tcp:" + node.ip_address, response ):
-                    mastershipCheck = mastershipCheck and main.TRUE
-                else:
-                    main.log.error( "Error, node " + node.ip_address + " is " +
-                                    "not in the list of controllers s" +
-                                    str( i ) + " is connecting to." )
-                    mastershipCheck = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=mastershipCheck,
-            onpass="Switch mastership assigned correctly",
-            onfail="Switches not assigned correctly to controllers" )
+        main.HA.assignDevices( main )
 
     def CASE21( self, main ):
         """
         Assign mastership to controllers
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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.case( "Assigning Controller roles for switches" )
-        main.caseExplanation = "Check that ONOS is connected to each " +\
-                                "device. Then manually assign" +\
-                                " mastership to specific ONOS nodes using" +\
-                                " 'device-role'"
-        main.step( "Assign mastership of switches to specific controllers" )
-        # Manually assign mastership to the controller we want
-        roleCall = main.TRUE
-
-        ipList = []
-        deviceList = []
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        try:
-            # Assign mastership to specific controllers. This assignment was
-            # determined for a 7 node cluser, but will work with any sized
-            # cluster
-            for i in range( 1, 29 ):  # switches 1 through 28
-                # set up correct variables:
-                if i == 1:
-                    c = 0
-                    ip = main.nodes[ c ].ip_address  # ONOS1
-                    deviceId = onosCli.getDevice( "1000" ).get( 'id' )
-                elif i == 2:
-                    c = 1 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS2
-                    deviceId = onosCli.getDevice( "2000" ).get( 'id' )
-                elif i == 3:
-                    c = 1 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS2
-                    deviceId = onosCli.getDevice( "3000" ).get( 'id' )
-                elif i == 4:
-                    c = 3 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS4
-                    deviceId = onosCli.getDevice( "3004" ).get( 'id' )
-                elif i == 5:
-                    c = 2 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS3
-                    deviceId = onosCli.getDevice( "5000" ).get( 'id' )
-                elif i == 6:
-                    c = 2 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS3
-                    deviceId = onosCli.getDevice( "6000" ).get( 'id' )
-                elif i == 7:
-                    c = 5 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS6
-                    deviceId = onosCli.getDevice( "6007" ).get( 'id' )
-                elif i >= 8 and i <= 17:
-                    c = 4 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS5
-                    dpid = '3' + str( i ).zfill( 3 )
-                    deviceId = onosCli.getDevice( dpid ).get( 'id' )
-                elif i >= 18 and i <= 27:
-                    c = 6 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS7
-                    dpid = '6' + str( i ).zfill( 3 )
-                    deviceId = onosCli.getDevice( dpid ).get( 'id' )
-                elif i == 28:
-                    c = 0
-                    ip = main.nodes[ c ].ip_address  # ONOS1
-                    deviceId = onosCli.getDevice( "2800" ).get( 'id' )
-                else:
-                    main.log.error( "You didn't write an else statement for " +
-                                    "switch s" + str( i ) )
-                    roleCall = main.FALSE
-                # Assign switch
-                assert deviceId, "No device id for s" + str( i ) + " in ONOS"
-                # TODO: make this controller dynamic
-                roleCall = roleCall and onosCli.deviceRole( deviceId, ip )
-                ipList.append( ip )
-                deviceList.append( deviceId )
-        except ( AttributeError, AssertionError ):
-            main.log.exception( "Something is wrong with ONOS device view" )
-            main.log.info( onosCli.devices() )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=roleCall,
-            onpass="Re-assigned switch mastership to designated controller",
-            onfail="Something wrong with deviceRole calls" )
-
-        main.step( "Check mastership was correctly assigned" )
-        roleCheck = main.TRUE
-        # NOTE: This is due to the fact that device mastership change is not
-        #       atomic and is actually a multi step process
-        time.sleep( 5 )
-        for i in range( len( ipList ) ):
-            ip = ipList[ i ]
-            deviceId = deviceList[ i ]
-            # Check assignment
-            master = onosCli.getRole( deviceId ).get( 'master' )
-            if ip in master:
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-                main.log.error( "Error, controller " + ip + " is not" +
-                                " master " + "of device " +
-                                str( deviceId ) + ". Master is " +
-                                repr( master ) + "." )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=roleCheck,
-            onpass="Switches were successfully reassigned to designated " +
-                   "controller",
-            onfail="Switches were not successfully reassigned" )
-
+        main.HA.assignMastership( main )
     def CASE3( self, main ):
         """
         Assign intents
         """
-        import time
-        import json
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-        try:
-            labels
-        except NameError:
-            main.log.error( "labels not defined, setting to []" )
-            labels = []
-        try:
-            data
-        except NameError:
-            main.log.error( "data not defined, setting to []" )
-            data = []
-        # NOTE: we must reinstall intents until we have a persistant intent
-        #        datastore!
-        main.case( "Adding host Intents" )
-        main.caseExplanation = "Discover hosts by using pingall then " +\
-                                "assign predetermined host-to-host intents." +\
-                                " After installation, check that the intent" +\
-                                " is distributed to all nodes and the state" +\
-                                " is INSTALLED"
-
-        # install onos-app-fwd
-        main.step( "Install reactive forwarding app" )
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        installResults = onosCli.activateApp( "org.onosproject.fwd" )
-        utilities.assert_equals( expect=main.TRUE, actual=installResults,
-                                 onpass="Install fwd successful",
-                                 onfail="Install fwd failed" )
-
-        main.step( "Check app ids" )
-        appCheck = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
-                             name="appToIDCheck-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            appCheck = appCheck and t.result
-        if appCheck != main.TRUE:
-            main.log.warn( onosCli.apps() )
-            main.log.warn( onosCli.appIDs() )
-        utilities.assert_equals( expect=main.TRUE, actual=appCheck,
-                                 onpass="App Ids seem to be correct",
-                                 onfail="Something is wrong with app Ids" )
-
-        main.step( "Discovering Hosts( Via pingall for now )" )
-        # FIXME: Once we have a host discovery mechanism, use that instead
-        # REACTIVE FWD test
-        pingResult = main.FALSE
-        passMsg = "Reactive Pingall test passed"
-        time1 = time.time()
-        pingResult = main.Mininet1.pingall()
-        time2 = time.time()
-        if not pingResult:
-            main.log.warn( "First pingall failed. Trying again..." )
-            pingResult = main.Mininet1.pingall()
-            passMsg += " on the second try"
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=pingResult,
-            onpass=passMsg,
-            onfail="Reactive Pingall failed, " +
-                   "one or more ping pairs failed" )
-        main.log.info( "Time for pingall: %2f seconds" %
-                       ( time2 - time1 ) )
-        # timeout for fwd flows
-        time.sleep( 11 )
-        # uninstall onos-app-fwd
-        main.step( "Uninstall reactive forwarding app" )
-        node = main.activeNodes[ 0 ]
-        uninstallResult = main.CLIs[ node ].deactivateApp( "org.onosproject.fwd" )
-        utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
-                                 onpass="Uninstall fwd successful",
-                                 onfail="Uninstall fwd failed" )
-
-        main.step( "Check app ids" )
-        threads = []
-        appCheck2 = main.TRUE
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
-                             name="appToIDCheck-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            appCheck2 = appCheck2 and t.result
-        if appCheck2 != main.TRUE:
-            node = main.activeNodes[ 0 ]
-            main.log.warn( main.CLIs[ node ].apps() )
-            main.log.warn( main.CLIs[ node ].appIDs() )
-        utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
-                                 onpass="App Ids seem to be correct",
-                                 onfail="Something is wrong with app Ids" )
-
-        main.step( "Add host intents via cli" )
-        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 ) )
-            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 = onosCli.getHost( host1 )
-            host2Dict = onosCli.getHost( host2 )
-            host1Id = None
-            host2Id = None
-            if host1Dict and host2Dict:
-                host1Id = host1Dict.get( 'id', None )
-                host2Id = host2Dict.get( 'id', None )
-            if host1Id and host2Id:
-                nodeNum = ( i % len( main.activeNodes ) )
-                node = main.activeNodes[ nodeNum ]
-                tmpId = main.CLIs[ node ].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 for h" + str( i ) +
-                                " and/or h" + str( i + 10 ) )
-                node = main.activeNodes[ 0 ]
-                hosts = main.CLIs[ node ].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
-        utilities.assert_equals( expect=main.TRUE, actual=hostResult,
-                                 onpass="Found a host id for each host",
-                                 onfail="Error looking up host ids" )
-
-        intentStart = time.time()
-        onosIds = onosCli.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
-        if intentAddResult:
-            intentStop = time.time()
-        else:
-            intentStop = None
-        # Print the intent states
-        intents = onosCli.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 = onosCli.leaders()
-        try:
-            missing = False
-            if leaders:
-                parsedLeaders = json.loads( leaders )
-                main.log.warn( json.dumps( parsedLeaders,
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-                # check for all intent partitions
-                topics = []
-                for i in range( 14 ):
-                    topics.append( "work-partition-" + str( i ) )
-                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" )
-                        missing = True
-            else:
-                main.log.error( "leaders() returned None" )
-        except ( ValueError, TypeError ):
-            main.log.exception( "Error parsing leaders" )
-            main.log.error( repr( leaders ) )
-        # Check all nodes
-        if missing:
-            for i in main.activeNodes:
-                response = main.CLIs[ i ].leaders( jsonFormat=False )
-                main.log.warn( str( main.CLIs[ i ].name ) + " leaders output: \n" +
-                               str( response ) )
-
-        partitions = onosCli.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 = onosCli.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( intentAddResult and not missingIntents and
-                                installedCheck )
-        if not intentAddResult:
-            main.log.error( "Error in pushing host intents to ONOS" )
-
-        main.step( "Intent Anti-Entropy dispersion" )
-        for j in range( 100 ):
-            correct = True
-            main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
-            for i in main.activeNodes:
-                onosIds = []
-                ids = main.CLIs[ i ].getAllIntentsId()
-                onosIds.append( ids )
-                main.log.debug( "Intents in " + main.CLIs[ i ].name + ": " +
-                                str( sorted( onosIds ) ) )
-                if sorted( ids ) != sorted( intentIds ):
-                    main.log.warn( "Set of intent IDs doesn't match" )
-                    correct = False
-                    break
-                else:
-                    intents = json.loads( main.CLIs[ i ].intents() )
-                    for intent in intents:
-                        if intent[ 'state' ] != "INSTALLED":
-                            main.log.warn( "Intent " + intent[ 'id' ] +
-                                           " is " + intent[ 'state' ] )
-                            correct = False
-                            break
-            if correct:
-                break
-            else:
-                time.sleep( 1 )
-        if not intentStop:
-            intentStop = time.time()
-        global gossipTime
-        gossipTime = intentStop - intentStart
-        main.log.info( "It took about " + str( gossipTime ) +
-                        " seconds for all intents to appear in each node" )
-        append = False
-        title = "Gossip Intents"
-        count = 1
-        while append is False:
-            curTitle = title + str( count )
-            if curTitle not in labels:
-                labels.append( curTitle )
-                data.append( str( gossipTime ) )
-                append = True
-            else:
-                count += 1
-        gossipPeriod = int( main.params[ 'timers' ][ 'gossip' ] )
-        maxGossipTime = gossipPeriod * len( main.activeNodes )
-        utilities.assert_greater_equals(
-                expect=maxGossipTime, actual=gossipTime,
-                onpass="ECM anti-entropy for intents worked within " +
-                       "expected time",
-                onfail="Intent ECM anti-entropy took too long. " +
-                       "Expected time:{}, Actual time:{}".format( maxGossipTime,
-                                                                  gossipTime ) )
-        if gossipTime <= maxGossipTime:
-            intentAddResult = True
-
-        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 = onosCli.getAllIntentsId()
-            main.log.info( "Submitted intents: " + str( intentIds ) )
-            main.log.info( "Intents in ONOS: " + str( onosIds ) )
-            # Print the intent states
-            intents = onosCli.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 = onosCli.leaders()
-            try:
-                missing = False
-                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( "work-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" )
-                            missing = True
-                else:
-                    main.log.error( "leaders() returned None" )
-            except ( ValueError, TypeError ):
-                main.log.exception( "Error parsing leaders" )
-                main.log.error( repr( leaders ) )
-            # Check all nodes
-            if missing:
-                for i in main.activeNodes:
-                    node = main.CLIs[ i ]
-                    response = node.leaders( jsonFormat=False )
-                    main.log.warn( str( node.name ) + " leaders output: \n" +
-                                   str( response ) )
-
-            partitions = onosCli.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 = onosCli.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 ) )
+        main.HA.assignIntents(main)
 
     def CASE4( self, main ):
         """
         Ping across added host intents
         """
-        import json
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-        main.case( "Verify connectivity by sending traffic across Intents" )
-        main.caseExplanation = "Ping across added host intents to check " +\
-                                "functionality and check the state of " +\
-                                "the intent"
-
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        main.step( "Check Intent state" )
-        installedCheck = False
-        loopCount = 0
-        while not installedCheck and loopCount < 40:
-            installedCheck = True
-            # Print the intent states
-            intents = onosCli.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." )
-            # Print states
-            intentStates.sort()
-            for i, s in intentStates:
-                count += 1
-                main.log.info( "%-6s%-15s%-15s" %
-                               ( str( count ), str( i ), str( s ) ) )
-            if not installedCheck:
-                time.sleep( 1 )
-                loopCount += 1
-        utilities.assert_equals( expect=True, actual=installedCheck,
-                                 onpass="Intents are all INSTALLED",
-                                 onfail="Intents are not all in " +
-                                        "INSTALLED state" )
-
-        main.step( "Ping across added host intents" )
-        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.error(
-                "Intents have not been installed correctly, pings failed." )
-            # TODO: pretty print
-            main.log.warn( "ONOS1 intents: " )
-            try:
-                tmpIntents = onosCli.intents()
-                main.log.warn( json.dumps( json.loads( tmpIntents ),
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-            except ( ValueError, TypeError ):
-                main.log.warn( repr( tmpIntents ) )
-        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." )
-
-        main.step( "Check leadership of topics" )
-        leaders = onosCli.leaders()
-        topicCheck = main.TRUE
-        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
-                # TODO: Look at Devices as topics now that it uses this system
-                topics = []
-                for i in range( 14 ):
-                    topics.append( "work-partition-" + str( i ) )
-                # FIXME: this should only be after we start the app
-                # FIXME: topics.append( "org.onosproject.election" )
-                # Print leaders output
-                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" )
-                        topicCheck = main.FALSE
-            else:
-                main.log.error( "leaders() returned None" )
-                topicCheck = main.FALSE
-        except ( ValueError, TypeError ):
-            topicCheck = main.FALSE
-            main.log.exception( "Error parsing leaders" )
-            main.log.error( repr( leaders ) )
-            # TODO: Check for a leader of these topics
-        # Check all nodes
-        if topicCheck:
-            for i in main.activeNodes:
-                node = main.CLIs[ i ]
-                response = node.leaders( jsonFormat=False )
-                main.log.warn( str( node.name ) + " leaders output: \n" +
-                               str( response ) )
-
-        utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
-                                 onpass="intent Partitions is in leaders",
-                                 onfail="Some topics were lost " )
-        # Print partitions
-        partitions = onosCli.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 ) )
-        # Print Pending Map
-        pendingMap = onosCli.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 = onosCli.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 = onosCli.leaders()
-            try:
-                missing = False
-                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( "work-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" )
-                            missing = True
-                else:
-                    main.log.error( "leaders() returned None" )
-            except ( ValueError, TypeError ):
-                main.log.exception( "Error parsing leaders" )
-                main.log.error( repr( leaders ) )
-            if missing:
-                for i in main.activeNodes:
-                    node = main.CLIs[ i ]
-                    response = node.leaders( jsonFormat=False )
-                    main.log.warn( str( node.name ) + " leaders output: \n" +
-                                   str( response ) )
-
-            partitions = onosCli.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 = onosCli.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 ) )
-        # Print flowrules
-        node = main.activeNodes[ 0 ]
-        main.log.debug( main.CLIs[ node ].flows( jsonFormat=False ) )
-        main.step( "Wait a minute then ping again" )
-        # the wait is above
-        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.error(
-                "Intents have not been installed correctly, pings failed." )
-            # TODO: pretty print
-            main.log.warn( "ONOS1 intents: " )
-            try:
-                tmpIntents = onosCli.intents()
-                main.log.warn( json.dumps( json.loads( tmpIntents ),
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-            except ( ValueError, TypeError ):
-                main.log.warn( repr( tmpIntents ) )
-        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." )
+        main.HA.pingAcrossHostIntent( main, True, True )
 
     def CASE5( self, main ):
         """
         Reading state of ONOS
         """
-        import json
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        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 each other and also with past states
-
-        main.step( "Check that each switch has a master" )
-        global mastershipState
-        mastershipState = '[]'
-
-        # Assert that each device has a master
-        rolesNotNull = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( "Get the Mastership of each switch from each controller" )
-        ONOSMastership = []
-        mastershipCheck = main.FALSE
-        consistentMastership = True
-        rolesResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSMastership ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSMastership[ i ] or "Error" in ONOSMastership[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " roles" )
-                main.log.warn( "ONOS" + node + " 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.info(
-                "Switch roles are consistent across all ONOS nodes" )
-        else:
-            consistentMastership = False
-        utilities.assert_equals(
-            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( len( main.activeNodes ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                try:
-                    main.log.warn(
-                        "ONOS" + node + " 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 = []
-        ONOSIntents = []
-        intentCheck = main.FALSE
-        consistentIntents = True
-        intentsResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSIntents ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " intents" )
-                main.log.warn( "ONOS" + node + " 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.info( "Intents are consistent across all ONOS " +
-                             "nodes" )
-        else:
-            consistentIntents = False
-            main.log.error( "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:
-            # Try to make it easy to figure out what is happening
-            #
-            # Intent      ONOS1      ONOS2    ...
-            #  0x01     INSTALLED  INSTALLING
-            #  ...        ...         ...
-            #  ...        ...         ...
-            title = "   Id"
-            for n in main.activeNodes:
-                title += " " * 10 + "ONOS" + str( n + 1 )
-            main.log.warn( title )
-            # get all intent keys in the cluster
-            keys = []
-            try:
-                # Get the set of all intent keys
-                for nodeStr in ONOSIntents:
-                    node = json.loads( nodeStr )
-                    for intent in node:
-                        keys.append( intent.get( 'id' ) )
-                keys = set( keys )
-                # For each intent key, print the state on each node
-                for key in keys:
-                    row = "%-13s" % key
-                    for nodeStr in ONOSIntents:
-                        node = json.loads( nodeStr )
-                        for intent in node:
-                            if intent.get( 'id', "Error" ) == key:
-                                row += "%-15s" % intent.get( 'state' )
-                    main.log.warn( row )
-                # End of intent state table
-            except ValueError as e:
-                main.log.exception( e )
-                main.log.debug( "nodeStr was: " + repr( nodeStr ) )
-
-        if intentsResults and not consistentIntents:
-            # print the json objects
-            n = str( main.activeNodes[ -1 ] + 1 )
-            main.log.debug( "ONOS" + n + " intents: " )
-            main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
-                                        sort_keys=True,
-                                        indent=4,
-                                        separators=( ',', ': ' ) ) )
-            for i in range( len( ONOSIntents ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
-                    main.log.debug( "ONOS" + node + " intents: " )
-                    main.log.debug( json.dumps( json.loads( ONOSIntents[ i ] ),
-                                                sort_keys=True,
-                                                indent=4,
-                                                separators=( ',', ': ' ) ) )
-                else:
-                    main.log.debug( "ONOS" + node + " intents match ONOS" +
-                                    n + " intents" )
-        elif intentsResults and consistentIntents:
-            intentCheck = main.TRUE
-            intentState = ONOSIntents[ 0 ]
-
-        main.step( "Get the flows from each controller" )
-        global flowState
-        flowState = []
-        ONOSFlows = []
-        ONOSFlowsJson = []
-        flowCheck = main.FALSE
-        consistentFlows = True
-        flowsResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].flows,
-                             name="flows-" + str( i ),
-                             args=[],
-                             kwargs={ 'jsonFormat': True } )
-            threads.append( t )
-            t.start()
-
-        # NOTE: Flows command can take some time to run
-        time.sleep( 30 )
-        for t in threads:
-            t.join()
-            result = t.result
-            ONOSFlows.append( result )
-
-        for i in range( len( ONOSFlows ) ):
-            num = str( main.activeNodes[ i ] + 1 )
-            if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
-                main.log.error( "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.info( "Flow count is consistent across all ONOS nodes" )
-        else:
-            consistentFlows = False
-        utilities.assert_equals(
-            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( len( ONOSFlows ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                try:
-                    main.log.warn(
-                        "ONOS" + node + " flows: " +
-                        json.dumps( json.loads( ONOSFlows[ i ] ), sort_keys=True,
-                                    indent=4, separators=( ',', ': ' ) ) )
-                except ( ValueError, TypeError ):
-                    main.log.warn( "ONOS" + node + " 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.Mininet1.getFlowTable( "s" + str( i ), version="1.3", debug=False ) )
-        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" )
-        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( "Collecting topology information from ONOS" )
-        devices = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].devices,
-                             name="devices-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            devices.append( t.result )
-        hosts = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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" )
-                main.log.warn( repr( t.result ) )
-                hosts.append( None )
-
-        ports = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].ports,
-                             name="ports-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            ports.append( t.result )
-        links = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].links,
-                             name="links-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            links.append( t.result )
-        clusters = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].clusters,
-                             name="clusters-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            clusters.append( t.result )
-        # Compare json objects for hosts and dataplane clusters
-
-        # hosts
-        main.step( "Host view is consistent across ONOS nodes" )
-        consistentHostsResult = main.TRUE
-        for controller in range( len( hosts ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if hosts[ controller ] and "Error" not in hosts[ controller ]:
-                if hosts[ controller ] == hosts[ 0 ]:
-                    continue
-                else:  # hosts not consistent
-                    main.log.error( "hosts from ONOS" +
-                                     controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    main.log.warn( repr( hosts[ controller ] ) )
-                    consistentHostsResult = main.FALSE
-
-            else:
-                main.log.error( "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" )
-
-        main.step( "Each host has an IP address" )
-        ipResult = main.TRUE
-        for controller in range( 0, len( hosts ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if hosts[ controller ]:
-                for host in hosts[ controller ]:
-                    if not host.get( 'ipAddresses', [] ):
-                        main.log.error( "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
-        main.step( "Cluster view is consistent across ONOS nodes" )
-        consistentClustersResult = main.TRUE
-        for controller in range( len( clusters ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if "Error" not in clusters[ controller ]:
-                if clusters[ controller ] == clusters[ 0 ]:
-                    continue
-                else:  # clusters not consistent
-                    main.log.error( "clusters from ONOS" + controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    consistentClustersResult = main.FALSE
-
-            else:
-                main.log.error( "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" )
-        if not consistentClustersResult:
-            main.log.debug( clusters )
-
-        # there should always only be one cluster
-        main.step( "Cluster view correct across ONOS nodes" )
-        try:
-            numClusters = len( json.loads( clusters[ 0 ] ) )
-        except ( ValueError, TypeError ):
-            main.log.exception( "Error parsing clusters[0]: " +
-                                repr( clusters[ 0 ] ) )
-            numClusters = "ERROR"
-        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
-        linksResults = main.TRUE
-        hostsResults = main.TRUE
-        mnSwitches = main.Mininet1.getSwitches()
-        mnLinks = main.Mininet1.getLinks()
-        mnHosts = main.Mininet1.getHosts()
-        for controller in main.activeNodes:
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if devices[ controller ] and ports[ controller ] and\
-                    "Error" not in devices[ controller ] and\
-                    "Error" not in ports[ controller ]:
-                currentDevicesResult = main.Mininet1.compareSwitches(
-                        mnSwitches,
-                        json.loads( devices[ controller ] ),
-                        json.loads( ports[ controller ] ) )
-            else:
-                currentDevicesResult = main.FALSE
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=currentDevicesResult,
-                                     onpass="ONOS" + controllerStr +
-                                     " Switches view is correct",
-                                     onfail="ONOS" + controllerStr +
-                                     " Switches view is incorrect" )
-            if links[ controller ] and "Error" not in links[ controller ]:
-                currentLinksResult = main.Mininet1.compareLinks(
-                        mnSwitches, mnLinks,
-                        json.loads( links[ controller ] ) )
-            else:
-                currentLinksResult = main.FALSE
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=currentLinksResult,
-                                     onpass="ONOS" + controllerStr +
-                                     " links view is correct",
-                                     onfail="ONOS" + controllerStr +
-                                     " links view is incorrect" )
-
-            if hosts[ controller ] and "Error" not in hosts[ controller ]:
-                currentHostsResult = main.Mininet1.compareHosts(
-                        mnHosts,
-                        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
-            linksResults = linksResults and currentLinksResult
-            hostsResults = hostsResults and currentHostsResult
-
-        main.step( "Device information is correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=devicesResults,
-            onpass="Device information is correct",
-            onfail="Device information is incorrect" )
-
-        main.step( "Links are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=linksResults,
-            onpass="Link are correct",
-            onfail="Links are incorrect" )
-
-        main.step( "Hosts are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=hostsResults,
-            onpass="Hosts are correct",
-            onfail="Hosts are incorrect" )
+        main.HA.readingState( main )
 
     def CASE6( self, main ):
         """
@@ -1779,17 +122,15 @@
         assert main.CLIs, "main.CLIs not defined"
         assert main.nodes, "main.nodes not defined"
         try:
-            labels
-        except NameError:
-            main.log.error( "labels not defined, setting to []" )
-            global labels
-            labels = []
+            main.HAlabels
+        except ( NameError, AttributeError ):
+            main.log.error( "main.HAlabels not defined, setting to []" )
+            main.HAlabels = []
         try:
-            data
-        except NameError:
-            main.log.error( "data not defined, setting to []" )
-            global data
-            data = []
+            main.HAdata
+        except ( NameError, AttributeError ):
+            main.log.error( "main.HAdata not defined, setting to []" )
+            main.HAdata = []
         # Reset non-persistent variables
         try:
             iCounterValue = 0
@@ -1866,8 +207,8 @@
         # protocol has had time to work
         main.restartTime = time.time() - killTime
         main.log.debug( "Restart time: " + str( main.restartTime ) )
-        labels.append( "Restart" )
-        data.append( str( main.restartTime ) )
+        main.HAlabels.append( "Restart" )
+        main.HAdata.append( str( main.restartTime ) )
 
         # Rerun for election on restarted nodes
         runResults = main.TRUE
@@ -1892,286 +233,10 @@
         """
         Check state after ONOS failure
         """
-        import json
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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
-        rolesNotNull = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( "Read device roles from ONOS" )
-        ONOSMastership = []
-        mastershipCheck = main.FALSE
-        consistentMastership = True
-        rolesResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSMastership ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSMastership[ i ] or "Error" in ONOSMastership[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " roles" )
-                main.log.warn( "ONOS" + node + " 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.info(
-                "Switch roles are consistent across all ONOS nodes" )
-        else:
-            consistentMastership = False
-        utilities.assert_equals(
-            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( len( ONOSMastership ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                main.log.warn( "ONOS" + node + " roles: ",
-                               json.dumps( json.loads( ONOSMastership[ i ] ),
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-        elif rolesResults and consistentMastership:
-            mastershipCheck = main.TRUE
-
-        # NOTE: we expect mastership to change on controller failure
-
-        main.step( "Get the intents and compare across all nodes" )
-        ONOSIntents = []
-        intentCheck = main.FALSE
-        consistentIntents = True
-        intentsResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSIntents ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " intents" )
-                main.log.warn( "ONOS" + node + " 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.info( "Intents are consistent across all ONOS " +
-                             "nodes" )
-        else:
-            consistentIntents = False
-
-        # Try to make it easy to figure out what is happening
-        #
-        # Intent      ONOS1      ONOS2    ...
-        #  0x01     INSTALLED  INSTALLING
-        #  ...        ...         ...
-        #  ...        ...         ...
-        title = "   ID"
-        for n in main.activeNodes:
-            title += " " * 10 + "ONOS" + str( n + 1 )
-        main.log.warn( title )
-        # get all intent keys in the cluster
-        keys = []
-        for nodeStr in ONOSIntents:
-            node = json.loads( nodeStr )
-            for intent in node:
-                keys.append( intent.get( 'id' ) )
-        keys = set( keys )
-        for key in keys:
-            row = "%-13s" % key
-            for nodeStr in ONOSIntents:
-                node = json.loads( nodeStr )
-                for intent in node:
-                    if intent.get( 'id' ) == key:
-                        row += "%-15s" % intent.get( 'state' )
-            main.log.warn( row )
-        # End table view
-
-        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' ] )
-            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( len( main.activeNodes ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                main.log.warn( "ONOS" + node + " 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?
-        sameIntents = main.FALSE
-        try:
-            intentState
-        except NameError:
-            main.log.warn( "No previous intent state was saved" )
-        else:
-            if intentState and intentState == ONOSIntents[ 0 ]:
-                sameIntents = main.TRUE
-                main.log.info( "Intents are consistent with before failure" )
-            # TODO: possibly the states have changed? we may need to figure out
-            #       what the acceptable states are
-            elif len( intentState ) == len( ONOSIntents[ 0 ] ):
-                sameIntents = main.TRUE
-                try:
-                    before = json.loads( intentState )
-                    after = json.loads( ONOSIntents[ 0 ] )
-                    for intent in before:
-                        if intent not in after:
-                            sameIntents = main.FALSE
-                            main.log.debug( "Intent is not currently in ONOS " +
-                                            "(at least in the same form):" )
-                            main.log.debug( json.dumps( intent ) )
-                except ( ValueError, TypeError ):
-                    main.log.exception( "Exception printing intents" )
-                    main.log.debug( repr( ONOSIntents[ 0 ] ) )
-                    main.log.debug( repr( intentState ) )
-            if sameIntents == main.FALSE:
-                try:
-                    main.log.debug( "ONOS intents before: " )
-                    main.log.debug( json.dumps( json.loads( intentState ),
-                                                sort_keys=True, indent=4,
-                                                separators=( ',', ': ' ) ) )
-                    main.log.debug( "Current ONOS intents: " )
-                    main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
-                                                sort_keys=True, indent=4,
-                                                separators=( ',', ': ' ) ) )
-                except ( ValueError, TypeError ):
-                    main.log.exception( "Exception printing intents" )
-                    main.log.debug( repr( ONOSIntents[ 0 ] ) )
-                    main.log.debug( repr( intentState ) )
-            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
-        for i in range( 28 ):
-            main.log.info( "Checking flow table on s" + str( i + 1 ) )
-            tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
-            curSwitch = main.Mininet1.flowTableComp( flows[ i ], tmpFlows )
-            FlowTables = FlowTables and curSwitch
-            if curSwitch == main.FALSE:
-                main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
-        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.HA.checkStateAfterONOS( main, afterWhich=0, isRestart=True )
 
-        main.Mininet2.pingLongKill()
-        """
-        # main.step( "Check the continuous pings to ensure that no packets " +
-        #            "were dropped during component failure" )
-        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.info( "No loss of dataplane connectivity" )
-        # utilities.assert_equals(
-        #     expect=main.FALSE,
-        #     actual=LossInPings,
-        #     onpass="No Loss of connectivity",
-        #     onfail="Loss of dataplane connectivity detected" )
-
-        # NOTE: Since intents are not persisted with IntnentStore,
-        #       we expect loss in dataplane connectivity
-        LossInPings = main.FALSE
-        """
         main.step( "Leadership Election is still functional" )
         # Test of LeadershipElection
         leaderList = []
@@ -2206,680 +271,45 @@
         """
         Compare topo
         """
-        import json
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        main.case( "Compare ONOS Topology view to Mininet topology" )
-        main.caseExplanation = "Compare topology objects between Mininet" +\
-                                " and ONOS"
-        topoResult = main.FALSE
-        topoFailMsg = "ONOS topology don't match Mininet"
-        elapsed = 0
-        count = 0
-        main.step( "Comparing ONOS topology to MN topology" )
-        startTime = time.time()
-        # Give time for Gossip to work
-        while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
-            devicesResults = main.TRUE
-            linksResults = main.TRUE
-            hostsResults = main.TRUE
-            hostAttachmentResults = True
-            count += 1
-            cliStart = time.time()
-            devices = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="devices-" + str( i ),
-                                 args=[ main.CLIs[ i ].devices, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                devices.append( t.result )
-            hosts = []
-            ipResult = main.TRUE
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="hosts-" + str( i ),
-                                 args=[ main.CLIs[ i ].hosts, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                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 ) )
-                    hosts.append( None )
-            for controller in range( 0, len( hosts ) ):
-                controllerStr = str( main.activeNodes[ controller ] + 1 )
-                if hosts[ controller ]:
-                    for host in hosts[ controller ]:
-                        if host is None or host.get( 'ipAddresses', [] ) == []:
-                            main.log.error(
-                                "Error with host ipAddresses on controller" +
-                                controllerStr + ": " + str( host ) )
-                            ipResult = main.FALSE
-            ports = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="ports-" + str( i ),
-                                 args=[ main.CLIs[ i ].ports, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                ports.append( t.result )
-            links = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="links-" + str( i ),
-                                 args=[ main.CLIs[ i ].links, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                links.append( t.result )
-            clusters = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="clusters-" + str( i ),
-                                 args=[ main.CLIs[ i ].clusters, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                clusters.append( t.result )
-
-            elapsed = time.time() - startTime
-            cliTime = time.time() - cliStart
-            print "Elapsed time: " + str( elapsed )
-            print "CLI time: " + str( cliTime )
-
-            if all( e is None for e in devices ) and\
-               all( e is None for e in hosts ) and\
-               all( e is None for e in ports ) and\
-               all( e is None for e in links ) and\
-               all( e is None for e in clusters ):
-                topoFailMsg = "Could not get topology from ONOS"
-                main.log.error( topoFailMsg )
-                continue  # Try again, No use trying to compare
-
-            mnSwitches = main.Mininet1.getSwitches()
-            mnLinks = main.Mininet1.getLinks()
-            mnHosts = main.Mininet1.getHosts()
-            for controller in range( len( main.activeNodes ) ):
-                controllerStr = str( main.activeNodes[ controller ] + 1 )
-                if devices[ controller ] and ports[ controller ] and\
-                        "Error" not in devices[ controller ] and\
-                        "Error" not in ports[ controller ]:
-
-                    try:
-                        currentDevicesResult = main.Mininet1.compareSwitches(
-                                mnSwitches,
-                                json.loads( devices[ controller ] ),
-                                json.loads( ports[ controller ] ) )
-                    except ( TypeError, ValueError ) as e:
-                        main.log.exception( "Object not as expected; devices={!r}\nports={!r}".format(
-                            devices[ controller ], ports[ controller ] ) )
-                else:
-                    currentDevicesResult = main.FALSE
-                utilities.assert_equals( expect=main.TRUE,
-                                         actual=currentDevicesResult,
-                                         onpass="ONOS" + controllerStr +
-                                         " Switches view is correct",
-                                         onfail="ONOS" + controllerStr +
-                                         " Switches view is incorrect" )
-
-                if links[ controller ] and "Error" not in links[ controller ]:
-                    currentLinksResult = main.Mininet1.compareLinks(
-                            mnSwitches, mnLinks,
-                            json.loads( links[ controller ] ) )
-                else:
-                    currentLinksResult = main.FALSE
-                utilities.assert_equals( expect=main.TRUE,
-                                         actual=currentLinksResult,
-                                         onpass="ONOS" + controllerStr +
-                                         " links view is correct",
-                                         onfail="ONOS" + controllerStr +
-                                         " links view is incorrect" )
-                if hosts[ controller ] and "Error" not in hosts[ controller ]:
-                    currentHostsResult = main.Mininet1.compareHosts(
-                            mnHosts,
-                            hosts[ controller ] )
-                elif hosts[ controller ] == []:
-                    currentHostsResult = main.TRUE
-                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" )
-                # CHECKING HOST ATTACHMENT POINTS
-                hostAttachment = True
-                zeroHosts = False
-                # FIXME: topo-HA/obelisk specific mappings:
-                # key is mac and value is dpid
-                mappings = {}
-                for i in range( 1, 29 ):  # hosts 1 through 28
-                    # set up correct variables:
-                    macId = "00:" * 5 + hex( i ).split( "0x" )[ 1 ].upper().zfill( 2 )
-                    if i == 1:
-                        deviceId = "1000".zfill( 16 )
-                    elif i == 2:
-                        deviceId = "2000".zfill( 16 )
-                    elif i == 3:
-                        deviceId = "3000".zfill( 16 )
-                    elif i == 4:
-                        deviceId = "3004".zfill( 16 )
-                    elif i == 5:
-                        deviceId = "5000".zfill( 16 )
-                    elif i == 6:
-                        deviceId = "6000".zfill( 16 )
-                    elif i == 7:
-                        deviceId = "6007".zfill( 16 )
-                    elif i >= 8 and i <= 17:
-                        dpid = '3' + str( i ).zfill( 3 )
-                        deviceId = dpid.zfill( 16 )
-                    elif i >= 18 and i <= 27:
-                        dpid = '6' + str( i ).zfill( 3 )
-                        deviceId = dpid.zfill( 16 )
-                    elif i == 28:
-                        deviceId = "2800".zfill( 16 )
-                    mappings[ macId ] = deviceId
-                if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
-                    if hosts[ controller ] == []:
-                        main.log.warn( "There are no hosts discovered" )
-                        zeroHosts = True
-                    else:
-                        for host in hosts[ controller ]:
-                            mac = None
-                            location = None
-                            device = None
-                            port = None
-                            try:
-                                mac = host.get( 'mac' )
-                                assert mac, "mac field could not be found for this host object"
-
-                                location = host.get( 'locations' )[ 0 ]
-                                assert location, "location field could not be found for this host object"
-
-                                # Trim the protocol identifier off deviceId
-                                device = str( location.get( 'elementId' ) ).split( ':' )[ 1 ]
-                                assert device, "elementId field could not be found for this host location object"
-
-                                port = location.get( 'port' )
-                                assert port, "port field could not be found for this host location object"
-
-                                # Now check if this matches where they should be
-                                if mac and device and port:
-                                    if str( port ) != "1":
-                                        main.log.error( "The attachment port is incorrect for " +
-                                                        "host " + str( mac ) +
-                                                        ". Expected: 1 Actual: " + str( port ) )
-                                        hostAttachment = False
-                                    if device != mappings[ str( mac ) ]:
-                                        main.log.error( "The attachment device is incorrect for " +
-                                                        "host " + str( mac ) +
-                                                        ". Expected: " + mappings[ str( mac ) ] +
-                                                        " Actual: " + device )
-                                        hostAttachment = False
-                                else:
-                                    hostAttachment = False
-                            except AssertionError:
-                                main.log.exception( "Json object not as expected" )
-                                main.log.error( repr( host ) )
-                                hostAttachment = False
-                else:
-                    main.log.error( "No hosts json output or \"Error\"" +
-                                    " in output. hosts = " +
-                                    repr( hosts[ controller ] ) )
-                if zeroHosts is False:
-                    # TODO: Find a way to know if there should be hosts in a
-                    #       given point of the test
-                    hostAttachment = True
-
-                # END CHECKING HOST ATTACHMENT POINTS
-                devicesResults = devicesResults and currentDevicesResult
-                linksResults = linksResults and currentLinksResult
-                hostsResults = hostsResults and currentHostsResult
-                hostAttachmentResults = hostAttachmentResults and\
-                                        hostAttachment
-                topoResult = ( devicesResults and linksResults
-                               and hostsResults and ipResult and
-                               hostAttachmentResults )
-        utilities.assert_equals( expect=True,
-                                 actual=topoResult,
-                                 onpass="ONOS topology matches Mininet",
-                                 onfail=topoFailMsg )
-        # End of While loop to pull ONOS state
-
-        # Compare json objects for hosts and dataplane clusters
-
-        # hosts
-        main.step( "Hosts view is consistent across all ONOS nodes" )
-        consistentHostsResult = main.TRUE
-        for controller in range( len( hosts ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
-                if hosts[ controller ] == hosts[ 0 ]:
-                    continue
-                else:  # hosts not consistent
-                    main.log.error( "hosts from ONOS" + controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    main.log.warn( repr( hosts[ controller ] ) )
-                    consistentHostsResult = main.FALSE
-
-            else:
-                main.log.error( "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" )
-
-        main.step( "Hosts information is correct" )
-        hostsResults = hostsResults and ipResult
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=hostsResults,
-            onpass="Host information is correct",
-            onfail="Host information is incorrect" )
-
-        main.step( "Host attachment points to the network" )
-        utilities.assert_equals(
-            expect=True,
-            actual=hostAttachmentResults,
-            onpass="Hosts are correctly attached to the network",
-            onfail="ONOS did not correctly attach hosts to the network" )
-
-        # Strongly connected clusters of devices
-        main.step( "Clusters view is consistent across all ONOS nodes" )
-        consistentClustersResult = main.TRUE
-        for controller in range( len( clusters ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if "Error" not in clusters[ controller ]:
-                if clusters[ controller ] == clusters[ 0 ]:
-                    continue
-                else:  # clusters not consistent
-                    main.log.error( "clusters from ONOS" +
-                                     controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    consistentClustersResult = main.FALSE
-            else:
-                main.log.error( "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" )
-        if not consistentClustersResult:
-            main.log.debug( clusters )
-
-        main.step( "There is only one SCC" )
-        # there should always only be one cluster
-        try:
-            numClusters = len( json.loads( clusters[ 0 ] ) )
-        except ( ValueError, TypeError ):
-            main.log.exception( "Error parsing clusters[0]: " +
-                                repr( clusters[ 0 ] ) )
-            numClusters = "ERROR"
-        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 linksResults
-                       and hostsResults and consistentHostsResult
-                       and consistentClustersResult and clusterResults
-                       and ipResult and hostAttachmentResults )
-
-        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" )
-
-        main.step( "Device information is correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=devicesResults,
-            onpass="Device information is correct",
-            onfail="Device information is incorrect" )
-
-        main.step( "Links are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=linksResults,
-            onpass="Link are correct",
-            onfail="Links are incorrect" )
-
-        main.step( "Hosts are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=hostsResults,
-            onpass="Hosts are correct",
-            onfail="Hosts are incorrect" )
-
-        # FIXME: move this to an ONOS state case
-        main.step( "Checking ONOS nodes" )
-        nodeResults = utilities.retry( main.HA.nodesCheck,
-                                       False,
-                                       args=[ main.activeNodes ],
-                                       attempts=5 )
-
-        utilities.assert_equals( expect=True, actual=nodeResults,
-                                 onpass="Nodes check successful",
-                                 onfail="Nodes check NOT successful" )
-        if not nodeResults:
-            for i in main.activeNodes:
-                main.log.debug( "{} components not ACTIVE: \n{}".format(
-                    main.CLIs[ i ].name,
-                    main.CLIs[ i ].sendline( "scr:list | grep -v ACTIVE" ) ) )
-
-        if not topoResult:
-            main.cleanup()
-            main.exit()
+        main.HA.compareTopo( main )
 
     def CASE9( self, main ):
         """
         Link s3-s28 down
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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"
-        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 successful",
-                                 onfail="Failed to bring link down" )
-        # TODO do some sort of check here
+        main.HA.linkDown( main )
 
     def CASE10( self, main ):
         """
         Link s3-s28 up
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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"
-        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 successful",
-                                 onfail="Failed to bring link up" )
-        # TODO do some sort of check here
+        main.HA.linkUp( main )
 
     def CASE11( self, main ):
         """
         Switch Down
         """
         # NOTE: You should probably run a topology check after this
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
-
-        description = "Killing a switch to ensure it is discovered correctly"
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        main.case( description )
-        switch = main.params[ 'kill' ][ 'switch' ]
-        switchDPID = main.params[ 'kill' ][ 'dpid' ]
-
-        # TODO: Make this switch parameterizable
-        main.step( "Kill " + switch )
-        main.log.info( "Deleting " + switch )
-        main.Mininet1.delSwitch( switch )
-        main.log.info( "Waiting " + str( switchSleep ) +
-                       " seconds for switch down to be discovered" )
-        time.sleep( switchSleep )
-        device = onosCli.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 successful",
-                                 onfail="Failed to kill switch?" )
+        main.HA.switchDown( main )
 
     def CASE12( self, main ):
         """
         Switch Up
         """
         # NOTE: You should probably run a topology check after this
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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' ]
-        switchDPID = main.params[ 'kill' ][ 'dpid' ]
-        links = main.params[ 'kill' ][ 'links' ].split()
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        description = "Adding a switch to ensure it is discovered correctly"
-        main.case( description )
-
-        main.step( "Add back " + switch )
-        main.Mininet1.addSwitch( switch, dpid=switchDPID )
-        for peer in links:
-            main.Mininet1.addLink( switch, peer )
-        ipList = [ node.ip_address for node in main.nodes ]
-        main.Mininet1.assignSwController( sw=switch, ip=ipList )
-        main.log.info( "Waiting " + str( switchSleep ) +
-                       " seconds for switch up to be discovered" )
-        time.sleep( switchSleep )
-        device = onosCli.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 successful",
-                                 onfail="Failed to add switch?" )
+        main.HA.switchUp( main )
 
     def CASE13( self, main ):
         """
         Clean up
         """
-        import os
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        # printing colors to terminal
-        colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
-                   'blue': '\033[94m', 'green': '\033[92m',
-                   'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
-        main.case( "Test Cleanup" )
-        main.step( "Killing tcpdumps" )
-        main.Mininet2.stopTcpdump()
-
-        testname = main.TEST
-        if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
-            main.step( "Copying MN pcap and ONOS log files to test station" )
-            teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
-            teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
-            # NOTE: MN Pcap file is being saved to logdir.
-            #       We scp this file as MN and TestON aren't necessarily the same vm
-
-            # FIXME: To be replaced with a Jenkin's post script
-            # TODO: Load these from params
-            # NOTE: must end in /
-            logFolder = "/opt/onos/log/"
-            logFiles = [ "karaf.log", "karaf.log.1" ]
-            # NOTE: must end in /
-            for f in logFiles:
-                for node in main.nodes:
-                    dstName = main.logdir + "/" + node.name + "-" + f
-                    main.ONOSbench.secureCopy( node.user_name, node.ip_address,
-                                               logFolder + f, dstName )
-            # std*.log's
-            # NOTE: must end in /
-            logFolder = "/opt/onos/var/"
-            logFiles = [ "stderr.log", "stdout.log" ]
-            # NOTE: must end in /
-            for f in logFiles:
-                for node in main.nodes:
-                    dstName = main.logdir + "/" + node.name + "-" + f
-                    main.ONOSbench.secureCopy( node.user_name, node.ip_address,
-                                               logFolder + f, dstName )
-        else:
-            main.log.debug( "skipping saving log files" )
-
-        main.step( "Stopping Mininet" )
-        mnResult = main.Mininet1.stopNet()
-        utilities.assert_equals( expect=main.TRUE, actual=mnResult,
-                                 onpass="Mininet stopped",
-                                 onfail="MN cleanup NOT successful" )
-
-        main.step( "Checking ONOS Logs for errors" )
-        for node in main.nodes:
-            main.log.debug( "Checking logs for errors on " + node.name + ":" )
-            main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
-
-        try:
-            timerLog = open( main.logdir + "/Timers.csv", 'w' )
-            main.log.error( ", ".join( labels ) + "\n" + ", ".join( data ) )
-            timerLog.write( ", ".join( labels ) + "\n" + ", ".join( data ) )
-            timerLog.close()
-        except NameError as e:
-            main.log.exception( e )
+        main.HA.cleanUp( main )
 
     def CASE14( self, main ):
         """
         start election app on all onos nodes
         """
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        main.case( "Start Leadership Election app" )
-        main.step( "Install leadership election app" )
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        appResult = onosCli.activateApp( "org.onosproject.election" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=appResult,
-            onpass="Election app installed",
-            onfail="Something went wrong with installing Leadership election" )
-
-        main.step( "Run for election on each node" )
-        for i in main.activeNodes:
-            main.CLIs[ i ].electionTestRun()
-        time.sleep( 5 )
-        activeCLIs = [ main.CLIs[ i ] for i in main.activeNodes ]
-        sameResult, leaders = main.HA.consistentLeaderboards( activeCLIs )
-        utilities.assert_equals(
-            expect=True,
-            actual=sameResult,
-            onpass="All nodes see the same leaderboards",
-            onfail="Inconsistent leaderboards" )
-
-        if sameResult:
-            leader = leaders[ 0 ][ 0 ]
-            if main.nodes[ main.activeNodes[ 0 ] ].ip_address in leader:
-                correctLeader = True
-            else:
-                correctLeader = False
-            main.step( "First node was elected leader" )
-            utilities.assert_equals(
-                expect=True,
-                actual=correctLeader,
-                onpass="Correct leader was elected",
-                onfail="Incorrect leader" )
+        main.HA.startElectionApp( main )
 
     def CASE15( self, main ):
         """
@@ -2896,196 +326,16 @@
             old and new variable prefixes refer to data from before vs after
                 withdrawl and later before withdrawl vs after re-election
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        description = "Check that Leadership Election is still functional"
-        main.case( description )
-        # NOTE: Need to re-run after restarts since being a canidate is not persistant
-
-        oldLeaders = []  # list of lists of each nodes' candidates before
-        newLeaders = []  # list of lists of each nodes' candidates after
-        oldLeader = ''  # the old leader from oldLeaders, None if not same
-        newLeader = ''  # the new leaders fron newLoeaders, None if not same
-        oldLeaderCLI = None  # the CLI of the old leader used for re-electing
-        expectNoLeader = False  # True when there is only one leader
-        if main.numCtrls == 1:
-            expectNoLeader = True
-
-        main.step( "Run for election on each node" )
-        electionResult = main.TRUE
-
-        for i in main.activeNodes:  # run test election on each node
-            if main.CLIs[ i ].electionTestRun() == main.FALSE:
-                electionResult = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=electionResult,
-            onpass="All nodes successfully ran for leadership",
-            onfail="At least one node failed to run for leadership" )
-
-        if electionResult == main.FALSE:
-            main.log.error(
-                "Skipping Test Case because Election Test App isn't loaded" )
-            main.skipCase()
-
-        main.step( "Check that each node shows the same leader and candidates" )
-        failMessage = "Nodes have different leaderboards"
-        activeCLIs = [ main.CLIs[ i ] for i in main.activeNodes ]
-        sameResult, oldLeaders = main.HA.consistentLeaderboards( activeCLIs )
-        if sameResult:
-            oldLeader = oldLeaders[ 0 ][ 0 ]
-            main.log.warn( oldLeader )
-        else:
-            oldLeader = None
-        utilities.assert_equals(
-            expect=True,
-            actual=sameResult,
-            onpass="Leaderboards are consistent for the election topic",
-            onfail=failMessage )
-
-        main.step( "Find current leader and withdraw" )
-        withdrawResult = main.TRUE
-        # do some sanity checking on leader before using it
-        if oldLeader is None:
-            main.log.error( "Leadership isn't consistent." )
-            withdrawResult = main.FALSE
-        # Get the CLI of the oldLeader
-        for i in main.activeNodes:
-            if oldLeader == main.nodes[ i ].ip_address:
-                oldLeaderCLI = main.CLIs[ i ]
-                break
-        else:  # FOR/ELSE statement
-            main.log.error( "Leader election, could not find current leader" )
-        if oldLeader:
-            withdrawResult = oldLeaderCLI.electionTestWithdraw()
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=withdrawResult,
-            onpass="Node was withdrawn from election",
-            onfail="Node was not withdrawn from election" )
-
-        main.step( "Check that a new node was elected leader" )
-        failMessage = "Nodes have different leaders"
-        # Get new leaders and candidates
-        newLeaderResult, newLeaders = main.HA.consistentLeaderboards( activeCLIs )
-        newLeader = None
-        if newLeaderResult:
-            if newLeaders[ 0 ][ 0 ] == 'none':
-                main.log.error( "No leader was elected on at least 1 node" )
-                if not expectNoLeader:
-                    newLeaderResult = False
-            newLeader = newLeaders[ 0 ][ 0 ]
-
-        # Check that the new leader is not the older leader, which was withdrawn
-        if newLeader == oldLeader:
-            newLeaderResult = False
-            main.log.error( "All nodes still see old leader: " + str( oldLeader ) +
-                            " as the current leader" )
-        utilities.assert_equals(
-            expect=True,
-            actual=newLeaderResult,
-            onpass="Leadership election passed",
-            onfail="Something went wrong with Leadership election" )
-
-        main.step( "Check that that new leader was the candidate of old leader" )
-        # candidates[ 2 ] should become the top candidate after withdrawl
-        correctCandidateResult = main.TRUE
-        if expectNoLeader:
-            if newLeader == 'none':
-                main.log.info( "No leader expected. None found. Pass" )
-                correctCandidateResult = main.TRUE
-            else:
-                main.log.info( "Expected no leader, got: " + str( newLeader ) )
-                correctCandidateResult = main.FALSE
-        elif len( oldLeaders[ 0 ] ) >= 3:
-            if newLeader == oldLeaders[ 0 ][ 2 ]:
-                # correct leader was elected
-                correctCandidateResult = main.TRUE
-            else:
-                correctCandidateResult = main.FALSE
-                main.log.error( "Candidate {} was elected. {} should have had priority.".format(
-                                    newLeader, oldLeaders[ 0 ][ 2 ] ) )
-        else:
-            main.log.warn( "Could not determine who should be the correct leader" )
-            main.log.debug( oldLeaders[ 0 ] )
-            correctCandidateResult = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=correctCandidateResult,
-            onpass="Correct Candidate Elected",
-            onfail="Incorrect Candidate Elected" )
-
-        main.step( "Run for election on old leader( just so everyone " +
-                   "is in the hat )" )
-        if oldLeaderCLI is not None:
-            runResult = oldLeaderCLI.electionTestRun()
-        else:
-            main.log.error( "No old leader to re-elect" )
-            runResult = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=runResult,
-            onpass="App re-ran for election",
-            onfail="App failed to run for election" )
-
-        main.step(
-            "Check that oldLeader is a candidate, and leader if only 1 node" )
-        # verify leader didn't just change
-        # Get new leaders and candidates
-        reRunLeaders = []
-        time.sleep( 5 )  # Paremterize
-        positionResult, reRunLeaders = main.HA.consistentLeaderboards( activeCLIs )
-
-        # Check that the re-elected node is last on the candidate List
-        if not reRunLeaders[ 0 ]:
-            positionResult = main.FALSE
-        elif oldLeader != reRunLeaders[ 0 ][ -1 ]:
-            main.log.error( "Old Leader ({}) not in the proper position: {} ".format( str( oldLeader ),
-                                                                                      str( reRunLeaders[ 0 ] ) ) )
-            positionResult = main.FALSE
-        utilities.assert_equals(
-            expect=True,
-            actual=positionResult,
-            onpass="Old leader successfully re-ran for election",
-            onfail="Something went wrong with Leadership election after " +
-                   "the old leader re-ran for election" )
+        main.HA.isElectionFunctional( main )
 
     def CASE16( self, main ):
         """
         Install Distributed Primitives app
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        # Variables for the distributed primitives tests
-        main.pCounterName = "TestON-Partitions"
-        main.pCounterValue = 0
-        main.onosSet = set( [] )
-        main.onosSetName = "TestON-set"
-
-        description = "Install Primitives app"
-        main.case( description )
-        main.step( "Install Primitives app" )
-        appName = "org.onosproject.distributedprimitives"
-        node = main.activeNodes[ 0 ]
-        appResults = main.CLIs[ node ].activateApp( appName )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=appResults,
-                                 onpass="Primitives app activated",
-                                 onfail="Primitives app not activated" )
-        time.sleep( 5 )  # To allow all nodes to activate
+        main.HA.installDistributedPrimitiveApp( main )
 
     def CASE17( self, main ):
         """
         Check for basic functionality with distributed primitives
         """
-        main.HA.CASE17( main )
+        main.HA.checkDistPrimitivesFunc( main )
diff --git a/TestON/tests/HA/HAcontinuousStopNodes/HAcontinuousStopNodes.params b/TestON/tests/HA/HAcontinuousStopNodes/HAcontinuousStopNodes.params
index 4e02d2b..9d590be 100644
--- a/TestON/tests/HA/HAcontinuousStopNodes/HAcontinuousStopNodes.params
+++ b/TestON/tests/HA/HAcontinuousStopNodes/HAcontinuousStopNodes.params
@@ -35,8 +35,10 @@
         <cellName>HA</cellName>
         <appString>drivers,openflow,proxyarp,mobility</appString>
     </ENV>
-    <Git> False </Git>
-    <branch> master </branch>
+    <GIT>
+        <pull>False</pull>
+        <branch>master</branch>
+    </GIT>
     <num_controllers> 7 </num_controllers>
     <tcpdump> False </tcpdump>
 
diff --git a/TestON/tests/HA/HAcontinuousStopNodes/HAcontinuousStopNodes.py b/TestON/tests/HA/HAcontinuousStopNodes/HAcontinuousStopNodes.py
index 8252e1e..024d823 100644
--- a/TestON/tests/HA/HAcontinuousStopNodes/HAcontinuousStopNodes.py
+++ b/TestON/tests/HA/HAcontinuousStopNodes/HAcontinuousStopNodes.py
@@ -52,1722 +52,70 @@
         import json
         main.log.info( "ONOS HA test: Stop a minority of ONOS nodes - " +
                          "initialization" )
-        main.case( "Setting up test environment" )
-        main.caseExplanation = "Setup the test environment including " +\
-                                "installing ONOS, starting Mininet and ONOS" +\
-                                "cli sessions."
-
-        # load some variables from the params file
-        PULLCODE = False
-        if main.params[ 'Git' ] == 'True':
-            PULLCODE = True
-        gitBranch = main.params[ 'branch' ]
-        cellName = main.params[ 'ENV' ][ 'cellName' ]
-
-        main.numCtrls = int( main.params[ 'num_controllers' ] )
-        if main.ONOSbench.maxNodes:
-            if main.ONOSbench.maxNodes < main.numCtrls:
-                main.numCtrls = int( main.ONOSbench.maxNodes )
         # set global variables
-        global ONOS1Port
-        global ONOS2Port
-        global ONOS3Port
-        global ONOS4Port
-        global ONOS5Port
-        global ONOS6Port
-        global ONOS7Port
         # These are for csv plotting in jenkins
-        global labels
-        global data
-        labels = []
-        data = []
-
-        # 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' ]
-
+        main.HAlabels = []
+        main.HAdata = []
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        main.testSetUp.envSetupDescription()
         try:
             from tests.HA.dependencies.HA import HA
             main.HA = HA()
+            # load some variables from the params file
+            cellName = main.params[ 'ENV' ][ 'cellName' ]
+            main.apps = main.params[ 'ENV' ][ 'appString' ]
+            main.numCtrls = int( main.params[ 'num_controllers' ] )
+            if main.ONOSbench.maxNodes and\
+                        main.ONOSbench.maxNodes < main.numCtrls:
+                main.numCtrls = int( main.ONOSbench.maxNodes )
+            main.maxNodes = main.numCtrls
+            stepResult = main.testSetUp.envSetup( hasNode=True )
         except Exception as e:
-            main.log.exception( e )
-            main.cleanup()
-            main.exit()
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
+        main.HA.generateGraph( "HAcontinuousStopNodes" )
 
-        main.CLIs = []
-        main.nodes = []
-        ipList = []
-        for i in range( 1, main.numCtrls + 1 ):
-            try:
-                main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
-                main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
-                ipList.append( main.nodes[ -1 ].ip_address )
-            except AttributeError:
-                break
+        main.testSetUp.ONOSSetUp( main.Mininet1, cellName=cellName, removeLog=True,
+                                 extraApply=main.HA.customizeOnosGenPartitions,
+                                 extraClean=main.HA.cleanUpGenPartition )
 
-        main.step( "Create cell file" )
-        cellAppString = main.params[ 'ENV' ][ 'appString' ]
-        main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
-                                       main.Mininet1.ip_address,
-                                       cellAppString, ipList, main.ONOScli1.karafUser )
-        main.step( "Applying cell variable to environment" )
-        cellResult = main.ONOSbench.setCell( cellName )
-        verifyResult = main.ONOSbench.verifyCell()
+        main.HA.initialSetUp()
 
-        # FIXME:this is short term fix
-        main.log.info( "Removing raft logs" )
-        main.ONOSbench.onosRemoveRaftLogs()
-
-        main.log.info( "Uninstalling ONOS" )
-        for node in main.nodes:
-            main.ONOSbench.onosUninstall( node.ip_address )
-
-        # Make sure ONOS is DEAD
-        main.log.info( "Killing any ONOS processes" )
-        killResults = main.TRUE
-        for node in main.nodes:
-            killed = main.ONOSbench.onosKill( node.ip_address )
-            killResults = killResults and killed
-
-        gitPullResult = main.TRUE
-
-        main.step( "Starting Mininet" )
-        # scp topo file to mininet
-        # TODO: move to params?
-        topoName = "obelisk.py"
-        filePath = main.ONOSbench.home + "/tools/test/topos/"
-        main.ONOSbench.scp( main.Mininet1,
-                            filePath + topoName,
-                            main.Mininet1.home,
-                            direction="to" )
-        mnResult = main.Mininet1.startNet()
-        utilities.assert_equals( expect=main.TRUE, actual=mnResult,
-                                 onpass="Mininet Started",
-                                 onfail="Error starting Mininet" )
-
-        main.step( "Git checkout and pull " + gitBranch )
-        if PULLCODE:
-            main.ONOSbench.gitCheckout( gitBranch )
-            gitPullResult = main.ONOSbench.gitPull()
-            # values of 1 or 3 are good
-            utilities.assert_lesser( expect=0, actual=gitPullResult,
-                                      onpass="Git pull successful",
-                                      onfail="Git pull failed" )
-        main.ONOSbench.getVersion( report=True )
-
-        # GRAPHS
-        # NOTE: important params here:
-        #       job = name of Jenkins job
-        #       Plot Name = Plot-HA, only can be used if multiple plots
-        #       index = The number of the graph under plot name
-        job = "HAcontinuousStopNodes"
-        plotName = "Plot-HA"
-        index = "2"
-        graphs = '<ac:structured-macro ac:name="html">\n'
-        graphs += '<ac:plain-text-body><![CDATA[\n'
-        graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
-                  '/plot/' + plotName + '/getPlot?index=' + index +\
-                  '&width=500&height=300"' +\
-                  'noborder="0" width="500" height="300" scrolling="yes" ' +\
-                  'seamless="seamless"></iframe>\n'
-        graphs += ']]></ac:plain-text-body>\n'
-        graphs += '</ac:structured-macro>\n'
-        main.log.wiki( graphs )
-
-        main.step( "Creating ONOS package" )
-        # copy gen-partions file to ONOS
-        # NOTE: this assumes TestON and ONOS are on the same machine
-        srcFile = main.testDir + "/HA/dependencies/onos-gen-partitions"
-        dstDir = main.ONOSbench.home + "/tools/test/bin/onos-gen-partitions"
-        cpResult = main.ONOSbench.secureCopy( main.ONOSbench.user_name,
-                                              main.ONOSbench.ip_address,
-                                              srcFile,
-                                              dstDir,
-                                              pwd=main.ONOSbench.pwd,
-                                              direction="from" )
-        packageResult = main.ONOSbench.buckBuild()
-        utilities.assert_equals( expect=main.TRUE, actual=packageResult,
-                                 onpass="ONOS package successful",
-                                 onfail="ONOS package failed" )
-
-        main.step( "Installing ONOS package" )
-        onosInstallResult = main.TRUE
-        for node in main.nodes:
-            tmpResult = main.ONOSbench.onosInstall( options="-f",
-                                                    node=node.ip_address )
-            onosInstallResult = onosInstallResult and tmpResult
-        utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
-                                 onpass="ONOS install successful",
-                                 onfail="ONOS install failed" )
-        # clean up gen-partitions file
-        try:
-            main.ONOSbench.handle.sendline( "cd " + main.ONOSbench.home )
-            main.ONOSbench.handle.expect( main.ONOSbench.home + "\$" )
-            main.ONOSbench.handle.sendline( "git checkout -- tools/test/bin/onos-gen-partitions" )
-            main.ONOSbench.handle.expect( main.ONOSbench.home + "\$" )
-            main.log.info( " Cleaning custom gen partitions file, response was: \n" +
-                           str( main.ONOSbench.handle.before ) )
-        except ( pexpect.TIMEOUT, pexpect.EOF ):
-            main.log.exception( "ONOSbench: pexpect exception found:" +
-                                main.ONOSbench.handle.before )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.TRUE
-        for node in main.nodes:
-            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=node.ip_address )
-        utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        main.step( "Checking if ONOS is up yet" )
-        for i in range( 2 ):
-            onosIsupResult = main.TRUE
-            for node in main.nodes:
-                started = main.ONOSbench.isup( node.ip_address )
-                if not started:
-                    main.log.error( node.name + " hasn't started" )
-                onosIsupResult = onosIsupResult and started
-            if onosIsupResult == main.TRUE:
-                break
-        utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
-                                 onpass="ONOS startup successful",
-                                 onfail="ONOS startup failed" )
-
-        main.step( "Starting ONOS CLI sessions" )
-        cliResults = main.TRUE
-        threads = []
-        for i in range( main.numCtrls ):
-            t = main.Thread( target=main.CLIs[ i ].startOnosCli,
-                             name="startOnosCli-" + str( i ),
-                             args=[ main.nodes[ i ].ip_address ] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            cliResults = cliResults and t.result
-        utilities.assert_equals( expect=main.TRUE, actual=cliResults,
-                                 onpass="ONOS cli startup successful",
-                                 onfail="ONOS cli startup failed" )
-
-        # Create a list of active nodes for use when some nodes are stopped
-        main.activeNodes = [ i for i in range( 0, len( main.CLIs ) ) ]
-
-        if main.params[ 'tcpdump' ].lower() == "true":
-            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' ] )
-
-        main.step( "Checking ONOS nodes" )
-        nodeResults = utilities.retry( main.HA.nodesCheck,
-                                       False,
-                                       args=[ main.activeNodes ],
-                                       attempts=5 )
-
-        utilities.assert_equals( expect=True, actual=nodeResults,
-                                 onpass="Nodes check successful",
-                                 onfail="Nodes check NOT successful" )
-
-        if not nodeResults:
-            for i in main.activeNodes:
-                cli = main.CLIs[ i ]
-                main.log.debug( "{} components not ACTIVE: \n{}".format(
-                    cli.name,
-                    cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
-            main.log.error( "Failed to start ONOS, stopping test" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Activate apps defined in the params file" )
-        # get data from the params
-        apps = main.params.get( 'apps' )
-        if apps:
-            apps = apps.split( ',' )
-            main.log.warn( apps )
-            activateResult = True
-            for app in apps:
-                main.CLIs[ 0 ].app( app, "Activate" )
-            # TODO: check this worked
-            time.sleep( 10 )  # wait for apps to activate
-            for app in apps:
-                state = main.CLIs[ 0 ].appStatus( app )
-                if state == "ACTIVE":
-                    activateResult = activateResult and True
-                else:
-                    main.log.error( "{} is in {} state".format( app, state ) )
-                    activateResult = False
-            utilities.assert_equals( expect=True,
-                                     actual=activateResult,
-                                     onpass="Successfully activated apps",
-                                     onfail="Failed to activate apps" )
-        else:
-            main.log.warn( "No apps were specified to be loaded after startup" )
-
-        main.step( "Set ONOS configurations" )
-        config = main.params.get( 'ONOS_Configuration' )
-        if config:
-            main.log.debug( config )
-            checkResult = main.TRUE
-            for component in config:
-                for setting in config[ component ]:
-                    value = config[ component ][ setting ]
-                    check = main.CLIs[ 0 ].setCfg( component, setting, value )
-                    main.log.info( "Value was changed? {}".format( main.TRUE == check ) )
-                    checkResult = check and checkResult
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=checkResult,
-                                     onpass="Successfully set config",
-                                     onfail="Failed to set config" )
-        else:
-            main.log.warn( "No configurations were specified to be changed after startup" )
-
-        main.step( "App Ids check" )
-        appCheck = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
-                             name="appToIDCheck-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            appCheck = appCheck and t.result
-        if appCheck != main.TRUE:
-            node = main.activeNodes[ 0 ]
-            main.log.warn( main.CLIs[ node ].apps() )
-            main.log.warn( main.CLIs[ node ].appIDs() )
-        utilities.assert_equals( expect=main.TRUE, actual=appCheck,
-                                 onpass="App Ids seem to be correct",
-                                 onfail="Something is wrong with app Ids" )
 
     def CASE2( self, main ):
         """
         Assign devices to controllers
         """
-        import re
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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.case( "Assigning devices to controllers" )
-        main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
-                                "and check that an ONOS node becomes the " +\
-                                "master of the device."
-        main.step( "Assign switches to controllers" )
-
-        ipList = []
-        for i in range( main.numCtrls ):
-            ipList.append( main.nodes[ i ].ip_address )
-        swList = []
-        for i in range( 1, 29 ):
-            swList.append( "s" + str( i ) )
-        main.Mininet1.assignSwController( sw=swList, ip=ipList )
-
-        mastershipCheck = main.TRUE
-        for i in range( 1, 29 ):
-            response = main.Mininet1.getSwController( "s" + str( i ) )
-            try:
-                main.log.info( str( response ) )
-            except Exception:
-                main.log.info( repr( response ) )
-            for node in main.nodes:
-                if re.search( "tcp:" + node.ip_address, response ):
-                    mastershipCheck = mastershipCheck and main.TRUE
-                else:
-                    main.log.error( "Error, node " + node.ip_address + " is " +
-                                    "not in the list of controllers s" +
-                                    str( i ) + " is connecting to." )
-                    mastershipCheck = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=mastershipCheck,
-            onpass="Switch mastership assigned correctly",
-            onfail="Switches not assigned correctly to controllers" )
+        main.HA.assignDevices( main )
 
     def CASE21( self, main ):
         """
         Assign mastership to controllers
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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.case( "Assigning Controller roles for switches" )
-        main.caseExplanation = "Check that ONOS is connected to each " +\
-                                "device. Then manually assign" +\
-                                " mastership to specific ONOS nodes using" +\
-                                " 'device-role'"
-        main.step( "Assign mastership of switches to specific controllers" )
-        # Manually assign mastership to the controller we want
-        roleCall = main.TRUE
-
-        ipList = []
-        deviceList = []
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        try:
-            # Assign mastership to specific controllers. This assignment was
-            # determined for a 7 node cluser, but will work with any sized
-            # cluster
-            for i in range( 1, 29 ):  # switches 1 through 28
-                # set up correct variables:
-                if i == 1:
-                    c = 0
-                    ip = main.nodes[ c ].ip_address  # ONOS1
-                    deviceId = onosCli.getDevice( "1000" ).get( 'id' )
-                elif i == 2:
-                    c = 1 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS2
-                    deviceId = onosCli.getDevice( "2000" ).get( 'id' )
-                elif i == 3:
-                    c = 1 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS2
-                    deviceId = onosCli.getDevice( "3000" ).get( 'id' )
-                elif i == 4:
-                    c = 3 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS4
-                    deviceId = onosCli.getDevice( "3004" ).get( 'id' )
-                elif i == 5:
-                    c = 2 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS3
-                    deviceId = onosCli.getDevice( "5000" ).get( 'id' )
-                elif i == 6:
-                    c = 2 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS3
-                    deviceId = onosCli.getDevice( "6000" ).get( 'id' )
-                elif i == 7:
-                    c = 5 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS6
-                    deviceId = onosCli.getDevice( "6007" ).get( 'id' )
-                elif i >= 8 and i <= 17:
-                    c = 4 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS5
-                    dpid = '3' + str( i ).zfill( 3 )
-                    deviceId = onosCli.getDevice( dpid ).get( 'id' )
-                elif i >= 18 and i <= 27:
-                    c = 6 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS7
-                    dpid = '6' + str( i ).zfill( 3 )
-                    deviceId = onosCli.getDevice( dpid ).get( 'id' )
-                elif i == 28:
-                    c = 0
-                    ip = main.nodes[ c ].ip_address  # ONOS1
-                    deviceId = onosCli.getDevice( "2800" ).get( 'id' )
-                else:
-                    main.log.error( "You didn't write an else statement for " +
-                                    "switch s" + str( i ) )
-                    roleCall = main.FALSE
-                # Assign switch
-                assert deviceId, "No device id for s" + str( i ) + " in ONOS"
-                # TODO: make this controller dynamic
-                roleCall = roleCall and onosCli.deviceRole( deviceId, ip )
-                ipList.append( ip )
-                deviceList.append( deviceId )
-        except ( AttributeError, AssertionError ):
-            main.log.exception( "Something is wrong with ONOS device view" )
-            main.log.info( onosCli.devices() )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=roleCall,
-            onpass="Re-assigned switch mastership to designated controller",
-            onfail="Something wrong with deviceRole calls" )
-
-        main.step( "Check mastership was correctly assigned" )
-        roleCheck = main.TRUE
-        # NOTE: This is due to the fact that device mastership change is not
-        #       atomic and is actually a multi step process
-        time.sleep( 5 )
-        for i in range( len( ipList ) ):
-            ip = ipList[ i ]
-            deviceId = deviceList[ i ]
-            # Check assignment
-            master = onosCli.getRole( deviceId ).get( 'master' )
-            if ip in master:
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-                main.log.error( "Error, controller " + ip + " is not" +
-                                " master " + "of device " +
-                                str( deviceId ) + ". Master is " +
-                                repr( master ) + "." )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=roleCheck,
-            onpass="Switches were successfully reassigned to designated " +
-                   "controller",
-            onfail="Switches were not successfully reassigned" )
+        main.HA.assignMastership( main )
 
     def CASE3( self, main ):
         """
         Assign intents
         """
-        import time
-        import json
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-        main.case( "Adding host Intents" )
-        main.caseExplanation = "Discover hosts by using pingall then " +\
-                                "assign predetermined host-to-host intents." +\
-                                " After installation, check that the intent" +\
-                                " is distributed to all nodes and the state" +\
-                                " is INSTALLED"
-
-        # install onos-app-fwd
-        main.step( "Install reactive forwarding app" )
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        installResults = onosCli.activateApp( "org.onosproject.fwd" )
-        utilities.assert_equals( expect=main.TRUE, actual=installResults,
-                                 onpass="Install fwd successful",
-                                 onfail="Install fwd failed" )
-
-        main.step( "Check app ids" )
-        appCheck = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
-                             name="appToIDCheck-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            appCheck = appCheck and t.result
-        if appCheck != main.TRUE:
-            main.log.warn( onosCli.apps() )
-            main.log.warn( onosCli.appIDs() )
-        utilities.assert_equals( expect=main.TRUE, actual=appCheck,
-                                 onpass="App Ids seem to be correct",
-                                 onfail="Something is wrong with app Ids" )
-
-        main.step( "Discovering Hosts( Via pingall for now )" )
-        # FIXME: Once we have a host discovery mechanism, use that instead
-        # REACTIVE FWD test
-        pingResult = main.FALSE
-        passMsg = "Reactive Pingall test passed"
-        time1 = time.time()
-        pingResult = main.Mininet1.pingall()
-        time2 = time.time()
-        if not pingResult:
-            main.log.warn( "First pingall failed. Trying again..." )
-            pingResult = main.Mininet1.pingall()
-            passMsg += " on the second try"
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=pingResult,
-            onpass=passMsg,
-            onfail="Reactive Pingall failed, " +
-                   "one or more ping pairs failed" )
-        main.log.info( "Time for pingall: %2f seconds" %
-                       ( time2 - time1 ) )
-        # timeout for fwd flows
-        time.sleep( 11 )
-        # uninstall onos-app-fwd
-        main.step( "Uninstall reactive forwarding app" )
-        node = main.activeNodes[ 0 ]
-        uninstallResult = main.CLIs[ node ].deactivateApp( "org.onosproject.fwd" )
-        utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
-                                 onpass="Uninstall fwd successful",
-                                 onfail="Uninstall fwd failed" )
-
-        main.step( "Check app ids" )
-        threads = []
-        appCheck2 = main.TRUE
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
-                             name="appToIDCheck-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            appCheck2 = appCheck2 and t.result
-        if appCheck2 != main.TRUE:
-            node = main.activeNodes[ 0 ]
-            main.log.warn( main.CLIs[ node ].apps() )
-            main.log.warn( main.CLIs[ node ].appIDs() )
-        utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
-                                 onpass="App Ids seem to be correct",
-                                 onfail="Something is wrong with app Ids" )
-
-        main.step( "Add host intents via cli" )
-        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 ) )
-            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 = onosCli.getHost( host1 )
-            host2Dict = onosCli.getHost( host2 )
-            host1Id = None
-            host2Id = None
-            if host1Dict and host2Dict:
-                host1Id = host1Dict.get( 'id', None )
-                host2Id = host2Dict.get( 'id', None )
-            if host1Id and host2Id:
-                nodeNum = ( i % len( main.activeNodes ) )
-                node = main.activeNodes[ nodeNum ]
-                tmpId = main.CLIs[ node ].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 for h" + str( i ) +
-                                " and/or h" + str( i + 10 ) )
-                node = main.activeNodes[ 0 ]
-                hosts = main.CLIs[ node ].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
-        utilities.assert_equals( expect=main.TRUE, actual=hostResult,
-                                 onpass="Found a host id for each host",
-                                 onfail="Error looking up host ids" )
-
-        intentStart = time.time()
-        onosIds = onosCli.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
-        if intentAddResult:
-            intentStop = time.time()
-        else:
-            intentStop = None
-        # Print the intent states
-        intents = onosCli.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 = onosCli.leaders()
-        try:
-            missing = False
-            if leaders:
-                parsedLeaders = json.loads( leaders )
-                main.log.warn( json.dumps( parsedLeaders,
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-                # check for all intent partitions
-                topics = []
-                for i in range( 14 ):
-                    topics.append( "work-partition-" + str( i ) )
-                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" )
-                        missing = True
-            else:
-                main.log.error( "leaders() returned None" )
-        except ( ValueError, TypeError ):
-            main.log.exception( "Error parsing leaders" )
-            main.log.error( repr( leaders ) )
-        # Check all nodes
-        if missing:
-            for i in main.activeNodes:
-                response = main.CLIs[ i ].leaders( jsonFormat=False )
-                main.log.warn( str( main.CLIs[ i ].name ) + " leaders output: \n" +
-                               str( response ) )
-
-        partitions = onosCli.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 = onosCli.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( intentAddResult and not missingIntents and
-                                installedCheck )
-        if not intentAddResult:
-            main.log.error( "Error in pushing host intents to ONOS" )
-
-        main.step( "Intent Anti-Entropy dispersion" )
-        for j in range( 100 ):
-            correct = True
-            main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
-            for i in main.activeNodes:
-                onosIds = []
-                ids = main.CLIs[ i ].getAllIntentsId()
-                onosIds.append( ids )
-                main.log.debug( "Intents in " + main.CLIs[ i ].name + ": " +
-                                str( sorted( onosIds ) ) )
-                if sorted( ids ) != sorted( intentIds ):
-                    main.log.warn( "Set of intent IDs doesn't match" )
-                    correct = False
-                    break
-                else:
-                    intents = json.loads( main.CLIs[ i ].intents() )
-                    for intent in intents:
-                        if intent[ 'state' ] != "INSTALLED":
-                            main.log.warn( "Intent " + intent[ 'id' ] +
-                                           " is " + intent[ 'state' ] )
-                            correct = False
-                            break
-            if correct:
-                break
-            else:
-                time.sleep( 1 )
-        if not intentStop:
-            intentStop = time.time()
-        global gossipTime
-        gossipTime = intentStop - intentStart
-        main.log.info( "It took about " + str( gossipTime ) +
-                        " seconds for all intents to appear in each node" )
-        gossipPeriod = int( main.params[ 'timers' ][ 'gossip' ] )
-        maxGossipTime = gossipPeriod * len( main.activeNodes )
-        utilities.assert_greater_equals(
-                expect=maxGossipTime, actual=gossipTime,
-                onpass="ECM anti-entropy for intents worked within " +
-                       "expected time",
-                onfail="Intent ECM anti-entropy took too long. " +
-                       "Expected time:{}, Actual time:{}".format( maxGossipTime,
-                                                                  gossipTime ) )
-        if gossipTime <= maxGossipTime:
-            intentAddResult = True
-
-        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 = onosCli.getAllIntentsId()
-            main.log.info( "Submitted intents: " + str( intentIds ) )
-            main.log.info( "Intents in ONOS: " + str( onosIds ) )
-            # Print the intent states
-            intents = onosCli.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 = onosCli.leaders()
-            try:
-                missing = False
-                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( "work-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" )
-                            missing = True
-                else:
-                    main.log.error( "leaders() returned None" )
-            except ( ValueError, TypeError ):
-                main.log.exception( "Error parsing leaders" )
-                main.log.error( repr( leaders ) )
-            # Check all nodes
-            if missing:
-                for i in main.activeNodes:
-                    node = main.CLIs[ i ]
-                    response = node.leaders( jsonFormat=False )
-                    main.log.warn( str( node.name ) + " leaders output: \n" +
-                                   str( response ) )
-
-            partitions = onosCli.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 = onosCli.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 ) )
+        main.HA.assignIntents( main )
 
     def CASE4( self, main ):
         """
         Ping across added host intents
         """
-        import json
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-        main.case( "Verify connectivity by sending traffic across Intents" )
-        main.caseExplanation = "Ping across added host intents to check " +\
-                                "functionality and check the state of " +\
-                                "the intent"
-
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        main.step( "Check Intent state" )
-        installedCheck = False
-        loopCount = 0
-        while not installedCheck and loopCount < 40:
-            installedCheck = True
-            # Print the intent states
-            intents = onosCli.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." )
-            # Print states
-            intentStates.sort()
-            for i, s in intentStates:
-                count += 1
-                main.log.info( "%-6s%-15s%-15s" %
-                               ( str( count ), str( i ), str( s ) ) )
-            if not installedCheck:
-                time.sleep( 1 )
-                loopCount += 1
-        utilities.assert_equals( expect=True, actual=installedCheck,
-                                 onpass="Intents are all INSTALLED",
-                                 onfail="Intents are not all in " +
-                                        "INSTALLED state" )
-
-        main.step( "Ping across added host intents" )
-        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.error(
-                "Intents have not been installed correctly, pings failed." )
-            # TODO: pretty print
-            main.log.warn( "ONOS1 intents: " )
-            try:
-                tmpIntents = onosCli.intents()
-                main.log.warn( json.dumps( json.loads( tmpIntents ),
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-            except ( ValueError, TypeError ):
-                main.log.warn( repr( tmpIntents ) )
-        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." )
-
-        main.step( "Check leadership of topics" )
-        leaders = onosCli.leaders()
-        topicCheck = main.TRUE
-        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
-                # TODO: Look at Devices as topics now that it uses this system
-                topics = []
-                for i in range( 14 ):
-                    topics.append( "work-partition-" + str( i ) )
-                # FIXME: this should only be after we start the app
-                # FIXME: topics.append( "org.onosproject.election" )
-                # Print leaders output
-                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" )
-                        topicCheck = main.FALSE
-            else:
-                main.log.error( "leaders() returned None" )
-                topicCheck = main.FALSE
-        except ( ValueError, TypeError ):
-            topicCheck = main.FALSE
-            main.log.exception( "Error parsing leaders" )
-            main.log.error( repr( leaders ) )
-            # TODO: Check for a leader of these topics
-        # Check all nodes
-        if topicCheck:
-            for i in main.activeNodes:
-                node = main.CLIs[ i ]
-                response = node.leaders( jsonFormat=False )
-                main.log.warn( str( node.name ) + " leaders output: \n" +
-                               str( response ) )
-
-        utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
-                                 onpass="intent Partitions is in leaders",
-                                 onfail="Some topics were lost " )
-        # Print partitions
-        partitions = onosCli.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 ) )
-        # Print Pending Map
-        pendingMap = onosCli.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 = onosCli.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 = onosCli.leaders()
-            try:
-                missing = False
-                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( "work-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" )
-                            missing = True
-                else:
-                    main.log.error( "leaders() returned None" )
-            except ( ValueError, TypeError ):
-                main.log.exception( "Error parsing leaders" )
-                main.log.error( repr( leaders ) )
-            if missing:
-                for i in main.activeNodes:
-                    node = main.CLIs[ i ]
-                    response = node.leaders( jsonFormat=False )
-                    main.log.warn( str( node.name ) + " leaders output: \n" +
-                                   str( response ) )
-
-            partitions = onosCli.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 = onosCli.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 ) )
-        # Print flowrules
-        main.log.debug( onosCli.flows( jsonFormat=False ) )
-        main.step( "Wait a minute then ping again" )
-        # the wait is above
-        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.error(
-                "Intents have not been installed correctly, pings failed." )
-            # TODO: pretty print
-            main.log.warn( "ONOS1 intents: " )
-            try:
-                tmpIntents = onosCli.intents()
-                main.log.warn( json.dumps( json.loads( tmpIntents ),
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-            except ( ValueError, TypeError ):
-                main.log.warn( repr( tmpIntents ) )
-        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." )
+        main.HA.pingAcrossHostIntent( main, True, False )
 
     def CASE5( self, main ):
         """
         Reading state of ONOS
         """
-        import json
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        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 each other and also with past states
-
-        main.step( "Check that each switch has a master" )
-        global mastershipState
-        mastershipState = '[]'
-
-        # Assert that each device has a master
-        rolesNotNull = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( "Get the Mastership of each switch from each controller" )
-        ONOSMastership = []
-        mastershipCheck = main.FALSE
-        consistentMastership = True
-        rolesResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSMastership ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSMastership[ i ] or "Error" in ONOSMastership[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " roles" )
-                main.log.warn( "ONOS" + node + " 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.info(
-                "Switch roles are consistent across all ONOS nodes" )
-        else:
-            consistentMastership = False
-        utilities.assert_equals(
-            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( len( main.activeNodes ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                try:
-                    main.log.warn(
-                        "ONOS" + node + " 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 = []
-        ONOSIntents = []
-        intentCheck = main.FALSE
-        consistentIntents = True
-        intentsResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSIntents ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " intents" )
-                main.log.warn( "ONOS" + node + " 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.info( "Intents are consistent across all ONOS " +
-                             "nodes" )
-        else:
-            consistentIntents = False
-            main.log.error( "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:
-            # Try to make it easy to figure out what is happening
-            #
-            # Intent      ONOS1      ONOS2    ...
-            #  0x01     INSTALLED  INSTALLING
-            #  ...        ...         ...
-            #  ...        ...         ...
-            title = "   Id"
-            for n in main.activeNodes:
-                title += " " * 10 + "ONOS" + str( n + 1 )
-            main.log.warn( title )
-            # get all intent keys in the cluster
-            keys = []
-            try:
-                # Get the set of all intent keys
-                for nodeStr in ONOSIntents:
-                    node = json.loads( nodeStr )
-                    for intent in node:
-                        keys.append( intent.get( 'id' ) )
-                keys = set( keys )
-                # For each intent key, print the state on each node
-                for key in keys:
-                    row = "%-13s" % key
-                    for nodeStr in ONOSIntents:
-                        node = json.loads( nodeStr )
-                        for intent in node:
-                            if intent.get( 'id', "Error" ) == key:
-                                row += "%-15s" % intent.get( 'state' )
-                    main.log.warn( row )
-                # End of intent state table
-            except ValueError as e:
-                main.log.exception( e )
-                main.log.debug( "nodeStr was: " + repr( nodeStr ) )
-
-        if intentsResults and not consistentIntents:
-            # print the json objects
-            n = str( main.activeNodes[ -1 ] + 1 )
-            main.log.debug( "ONOS" + n + " intents: " )
-            main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
-                                        sort_keys=True,
-                                        indent=4,
-                                        separators=( ',', ': ' ) ) )
-            for i in range( len( ONOSIntents ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
-                    main.log.debug( "ONOS" + node + " intents: " )
-                    main.log.debug( json.dumps( json.loads( ONOSIntents[ i ] ),
-                                                sort_keys=True,
-                                                indent=4,
-                                                separators=( ',', ': ' ) ) )
-                else:
-                    main.log.debug( "ONOS" + node + " intents match ONOS" +
-                                    n + " intents" )
-        elif intentsResults and consistentIntents:
-            intentCheck = main.TRUE
-            intentState = ONOSIntents[ 0 ]
-
-        main.step( "Get the flows from each controller" )
-        global flowState
-        flowState = []
-        ONOSFlows = []
-        ONOSFlowsJson = []
-        flowCheck = main.FALSE
-        consistentFlows = True
-        flowsResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].flows,
-                             name="flows-" + str( i ),
-                             args=[],
-                             kwargs={ 'jsonFormat': True } )
-            threads.append( t )
-            t.start()
-
-        # NOTE: Flows command can take some time to run
-        time.sleep( 30 )
-        for t in threads:
-            t.join()
-            result = t.result
-            ONOSFlows.append( result )
-
-        for i in range( len( ONOSFlows ) ):
-            num = str( main.activeNodes[ i ] + 1 )
-            if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
-                main.log.error( "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.info( "Flow count is consistent across all ONOS nodes" )
-        else:
-            consistentFlows = False
-        utilities.assert_equals(
-            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( len( ONOSFlows ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                try:
-                    main.log.warn(
-                        "ONOS" + node + " flows: " +
-                        json.dumps( json.loads( ONOSFlows[ i ] ), sort_keys=True,
-                                    indent=4, separators=( ',', ': ' ) ) )
-                except ( ValueError, TypeError ):
-                    main.log.warn( "ONOS" + node + " 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.Mininet1.getFlowTable( "s" + str( i ), version="1.3", debug=False ) )
-        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" )
-        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( "Collecting topology information from ONOS" )
-        devices = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].devices,
-                             name="devices-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            devices.append( t.result )
-        hosts = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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" )
-                main.log.warn( repr( t.result ) )
-                hosts.append( None )
-
-        ports = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].ports,
-                             name="ports-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            ports.append( t.result )
-        links = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].links,
-                             name="links-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            links.append( t.result )
-        clusters = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].clusters,
-                             name="clusters-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            clusters.append( t.result )
-        # Compare json objects for hosts and dataplane clusters
-
-        # hosts
-        main.step( "Host view is consistent across ONOS nodes" )
-        consistentHostsResult = main.TRUE
-        for controller in range( len( hosts ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if hosts[ controller ] and "Error" not in hosts[ controller ]:
-                if hosts[ controller ] == hosts[ 0 ]:
-                    continue
-                else:  # hosts not consistent
-                    main.log.error( "hosts from ONOS" +
-                                     controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    main.log.warn( repr( hosts[ controller ] ) )
-                    consistentHostsResult = main.FALSE
-
-            else:
-                main.log.error( "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" )
-
-        main.step( "Each host has an IP address" )
-        ipResult = main.TRUE
-        for controller in range( 0, len( hosts ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if hosts[ controller ]:
-                for host in hosts[ controller ]:
-                    if not host.get( 'ipAddresses', [] ):
-                        main.log.error( "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
-        main.step( "Cluster view is consistent across ONOS nodes" )
-        consistentClustersResult = main.TRUE
-        for controller in range( len( clusters ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if "Error" not in clusters[ controller ]:
-                if clusters[ controller ] == clusters[ 0 ]:
-                    continue
-                else:  # clusters not consistent
-                    main.log.error( "clusters from ONOS" + controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    consistentClustersResult = main.FALSE
-
-            else:
-                main.log.error( "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" )
-        if not consistentClustersResult:
-            main.log.debug( clusters )
-
-        # there should always only be one cluster
-        main.step( "Cluster view correct across ONOS nodes" )
-        try:
-            numClusters = len( json.loads( clusters[ 0 ] ) )
-        except ( ValueError, TypeError ):
-            main.log.exception( "Error parsing clusters[0]: " +
-                                repr( clusters[ 0 ] ) )
-            numClusters = "ERROR"
-        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
-        linksResults = main.TRUE
-        hostsResults = main.TRUE
-        mnSwitches = main.Mininet1.getSwitches()
-        mnLinks = main.Mininet1.getLinks()
-        mnHosts = main.Mininet1.getHosts()
-        for controller in main.activeNodes:
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if devices[ controller ] and ports[ controller ] and\
-                    "Error" not in devices[ controller ] and\
-                    "Error" not in ports[ controller ]:
-                currentDevicesResult = main.Mininet1.compareSwitches(
-                        mnSwitches,
-                        json.loads( devices[ controller ] ),
-                        json.loads( ports[ controller ] ) )
-            else:
-                currentDevicesResult = main.FALSE
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=currentDevicesResult,
-                                     onpass="ONOS" + controllerStr +
-                                     " Switches view is correct",
-                                     onfail="ONOS" + controllerStr +
-                                     " Switches view is incorrect" )
-            if links[ controller ] and "Error" not in links[ controller ]:
-                currentLinksResult = main.Mininet1.compareLinks(
-                        mnSwitches, mnLinks,
-                        json.loads( links[ controller ] ) )
-            else:
-                currentLinksResult = main.FALSE
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=currentLinksResult,
-                                     onpass="ONOS" + controllerStr +
-                                     " links view is correct",
-                                     onfail="ONOS" + controllerStr +
-                                     " links view is incorrect" )
-
-            if hosts[ controller ] and "Error" not in hosts[ controller ]:
-                currentHostsResult = main.Mininet1.compareHosts(
-                        mnHosts,
-                        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
-            linksResults = linksResults and currentLinksResult
-            hostsResults = hostsResults and currentHostsResult
-
-        main.step( "Device information is correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=devicesResults,
-            onpass="Device information is correct",
-            onfail="Device information is incorrect" )
-
-        main.step( "Links are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=linksResults,
-            onpass="Link are correct",
-            onfail="Links are incorrect" )
-
-        main.step( "Hosts are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=hostsResults,
-            onpass="Hosts are correct",
-            onfail="Hosts are incorrect" )
+        main.HA.readingState( main )
 
     def CASE61( self, main ):
         """
@@ -1837,378 +185,19 @@
         """
         The bring up stopped nodes
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-        assert main.kill, "main.kill not defined"
-        main.case( "Restart minority of ONOS nodes" )
-
-        main.step( "Restarting " + str( len( main.kill ) ) + " ONOS nodes" )
-        startResults = main.TRUE
-        restartTime = time.time()
-        for i in main.kill:
-            startResults = startResults and\
-                           main.ONOSbench.onosStart( main.nodes[ i ].ip_address )
-        utilities.assert_equals( expect=main.TRUE, actual=startResults,
-                                 onpass="ONOS nodes started successfully",
-                                 onfail="ONOS nodes NOT successfully started" )
-
-        main.step( "Checking if ONOS is up yet" )
-        count = 0
-        onosIsupResult = main.FALSE
-        while onosIsupResult == main.FALSE and count < 10:
-            onosIsupResult = main.TRUE
-            for i in main.kill:
-                onosIsupResult = onosIsupResult and\
-                                 main.ONOSbench.isup( main.nodes[ i ].ip_address )
-            count = count + 1
-        utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
-                                 onpass="ONOS restarted successfully",
-                                 onfail="ONOS restart NOT successful" )
-
-        main.step( "Restarting ONOS main.CLIs" )
-        cliResults = main.TRUE
-        for i in main.kill:
-            cliResults = cliResults and\
-                         main.CLIs[ i ].startOnosCli( main.nodes[ i ].ip_address )
-            main.activeNodes.append( i )
-        utilities.assert_equals( expect=main.TRUE, actual=cliResults,
-                                 onpass="ONOS cli restarted",
-                                 onfail="ONOS cli did not restart" )
-        main.activeNodes.sort()
-        try:
-            assert list( set( main.activeNodes ) ) == main.activeNodes,\
-                   "List of active nodes has duplicates, this likely indicates something was run out of order"
-        except AssertionError:
-            main.log.exception( "" )
-            main.cleanup()
-            main.exit()
-
-        # Grab the time of restart so we chan check how long the gossip
-        # protocol has had time to work
-        main.restartTime = time.time() - restartTime
-        main.log.debug( "Restart time: " + str( main.restartTime ) )
-
-        main.step( "Checking ONOS nodes" )
-        nodeResults = utilities.retry( main.HA.nodesCheck,
-                                       False,
-                                       args=[ main.activeNodes ],
-                                       sleep=15,
-                                       attempts=5 )
-
-        utilities.assert_equals( expect=True, actual=nodeResults,
-                                 onpass="Nodes check successful",
-                                 onfail="Nodes check NOT successful" )
-
-        if not nodeResults:
-            for i in main.activeNodes:
-                cli = main.CLIs[ i ]
-                main.log.debug( "{} components not ACTIVE: \n{}".format(
-                    cli.name,
-                    cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
-            main.log.error( "Failed to start ONOS, stopping test" )
-            main.cleanup()
-            main.exit()
-        node = main.activeNodes[ 0 ]
-        main.log.debug( main.CLIs[ node ].nodes( jsonFormat=False ) )
-        main.log.debug( main.CLIs[ node ].leaders( jsonFormat=False ) )
-        main.log.debug( main.CLIs[ node ].partitions( jsonFormat=False ) )
-        main.log.debug( main.CLIs[ node ].apps( jsonFormat=False ) )
-
-        main.step( "Rerun for election on the node(s) that were killed" )
-        runResults = main.TRUE
-        for i in main.kill:
-            runResults = runResults and\
-                         main.CLIs[ i ].electionTestRun()
-        utilities.assert_equals( expect=main.TRUE, actual=runResults,
-                                 onpass="ONOS nodes reran for election topic",
-                                 onfail="Errror rerunning for election" )
+        main.HA.bringUpStoppedNode( main )
 
     def CASE7( self, main ):
         """
         Check state after ONOS failure
         """
-        import json
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
         try:
             main.kill
         except AttributeError:
             main.kill = []
 
-        main.case( "Running ONOS Constant State Tests" )
+        main.HA.checkStateAfterONOS( main, afterWhich=0 )
 
-        main.step( "Check that each switch has a master" )
-        # Assert that each device has a master
-        rolesNotNull = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( "Read device roles from ONOS" )
-        ONOSMastership = []
-        mastershipCheck = main.FALSE
-        consistentMastership = True
-        rolesResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSMastership ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSMastership[ i ] or "Error" in ONOSMastership[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " roles" )
-                main.log.warn( "ONOS" + node + " 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.info(
-                "Switch roles are consistent across all ONOS nodes" )
-        else:
-            consistentMastership = False
-        utilities.assert_equals(
-            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( len( ONOSMastership ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                main.log.warn( "ONOS" + node + " roles: ",
-                               json.dumps( json.loads( ONOSMastership[ i ] ),
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-
-        # NOTE: we expect mastership to change on controller failure
-
-        main.step( "Get the intents and compare across all nodes" )
-        ONOSIntents = []
-        intentCheck = main.FALSE
-        consistentIntents = True
-        intentsResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSIntents ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " intents" )
-                main.log.warn( "ONOS" + node + " 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.info( "Intents are consistent across all ONOS " +
-                             "nodes" )
-        else:
-            consistentIntents = False
-
-        # Try to make it easy to figure out what is happening
-        #
-        # Intent      ONOS1      ONOS2    ...
-        #  0x01     INSTALLED  INSTALLING
-        #  ...        ...         ...
-        #  ...        ...         ...
-        title = "   ID"
-        for n in main.activeNodes:
-            title += " " * 10 + "ONOS" + str( n + 1 )
-        main.log.warn( title )
-        # get all intent keys in the cluster
-        keys = []
-        for nodeStr in ONOSIntents:
-            node = json.loads( nodeStr )
-            for intent in node:
-                keys.append( intent.get( 'id' ) )
-        keys = set( keys )
-        for key in keys:
-            row = "%-13s" % key
-            for nodeStr in ONOSIntents:
-                node = json.loads( nodeStr )
-                for intent in node:
-                    if intent.get( 'id' ) == key:
-                        row += "%-15s" % intent.get( 'state' )
-            main.log.warn( row )
-        # End table view
-
-        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' ] )
-            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( len( main.activeNodes ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                main.log.warn( "ONOS" + node + " 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?
-        sameIntents = main.FALSE
-        try:
-            intentState
-        except NameError:
-            main.log.warn( "No previous intent state was saved" )
-        else:
-            if intentState and intentState == ONOSIntents[ 0 ]:
-                sameIntents = main.TRUE
-                main.log.info( "Intents are consistent with before failure" )
-            # TODO: possibly the states have changed? we may need to figure out
-            #       what the acceptable states are
-            elif len( intentState ) == len( ONOSIntents[ 0 ] ):
-                sameIntents = main.TRUE
-                try:
-                    before = json.loads( intentState )
-                    after = json.loads( ONOSIntents[ 0 ] )
-                    for intent in before:
-                        if intent not in after:
-                            sameIntents = main.FALSE
-                            main.log.debug( "Intent is not currently in ONOS " +
-                                            "(at least in the same form):" )
-                            main.log.debug( json.dumps( intent ) )
-                except ( ValueError, TypeError ):
-                    main.log.exception( "Exception printing intents" )
-                    main.log.debug( repr( ONOSIntents[ 0 ] ) )
-                    main.log.debug( repr( intentState ) )
-            if sameIntents == main.FALSE:
-                try:
-                    main.log.debug( "ONOS intents before: " )
-                    main.log.debug( json.dumps( json.loads( intentState ),
-                                                sort_keys=True, indent=4,
-                                                separators=( ',', ': ' ) ) )
-                    main.log.debug( "Current ONOS intents: " )
-                    main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
-                                                sort_keys=True, indent=4,
-                                                separators=( ',', ': ' ) ) )
-                except ( ValueError, TypeError ):
-                    main.log.exception( "Exception printing intents" )
-                    main.log.debug( repr( ONOSIntents[ 0 ] ) )
-                    main.log.debug( repr( intentState ) )
-            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
-        for i in range( 28 ):
-            main.log.info( "Checking flow table on s" + str( i + 1 ) )
-            tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
-            curSwitch = main.Mininet1.flowTableComp( flows[ i ], tmpFlows )
-            FlowTables = FlowTables and curSwitch
-            if curSwitch == main.FALSE:
-                main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
-        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.Mininet2.pingLongKill()
-        """
-        main.step( "Check the continuous pings to ensure that no packets " +
-                   "were dropped during component failure" )
-        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.info( "No loss of dataplane connectivity" )
-        utilities.assert_equals(
-            expect=main.FALSE,
-            actual=LossInPings,
-            onpass="No Loss of connectivity",
-            onfail="Loss of dataplane connectivity detected" )
-        """
         main.step( "Leadership Election is still functional" )
         # Test of LeadershipElection
         leaderList = []
@@ -2253,680 +242,49 @@
         """
         Compare topo
         """
-        import json
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
+        main.HA.compareTopo( main )
 
-        main.case( "Compare ONOS Topology view to Mininet topology" )
-        main.caseExplanation = "Compare topology objects between Mininet" +\
-                                " and ONOS"
-        topoResult = main.FALSE
-        topoFailMsg = "ONOS topology don't match Mininet"
-        elapsed = 0
-        count = 0
-        main.step( "Comparing ONOS topology to MN topology" )
-        startTime = time.time()
-        # Give time for Gossip to work
-        while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
-            devicesResults = main.TRUE
-            linksResults = main.TRUE
-            hostsResults = main.TRUE
-            hostAttachmentResults = True
-            count += 1
-            cliStart = time.time()
-            devices = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="devices-" + str( i ),
-                                 args=[ main.CLIs[ i ].devices, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
 
-            for t in threads:
-                t.join()
-                devices.append( t.result )
-            hosts = []
-            ipResult = main.TRUE
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="hosts-" + str( i ),
-                                 args=[ main.CLIs[ i ].hosts, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                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 ) )
-                    hosts.append( None )
-            for controller in range( 0, len( hosts ) ):
-                controllerStr = str( main.activeNodes[ controller ] + 1 )
-                if hosts[ controller ]:
-                    for host in hosts[ controller ]:
-                        if host is None or host.get( 'ipAddresses', [] ) == []:
-                            main.log.error(
-                                "Error with host ipAddresses on controller" +
-                                controllerStr + ": " + str( host ) )
-                            ipResult = main.FALSE
-            ports = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="ports-" + str( i ),
-                                 args=[ main.CLIs[ i ].ports, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                ports.append( t.result )
-            links = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="links-" + str( i ),
-                                 args=[ main.CLIs[ i ].links, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                links.append( t.result )
-            clusters = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="clusters-" + str( i ),
-                                 args=[ main.CLIs[ i ].clusters, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                clusters.append( t.result )
-
-            elapsed = time.time() - startTime
-            cliTime = time.time() - cliStart
-            print "Elapsed time: " + str( elapsed )
-            print "CLI time: " + str( cliTime )
-
-            if all( e is None for e in devices ) and\
-               all( e is None for e in hosts ) and\
-               all( e is None for e in ports ) and\
-               all( e is None for e in links ) and\
-               all( e is None for e in clusters ):
-                topoFailMsg = "Could not get topology from ONOS"
-                main.log.error( topoFailMsg )
-                continue  # Try again, No use trying to compare
-
-            mnSwitches = main.Mininet1.getSwitches()
-            mnLinks = main.Mininet1.getLinks()
-            mnHosts = main.Mininet1.getHosts()
-            for controller in range( len( main.activeNodes ) ):
-                controllerStr = str( main.activeNodes[ controller ] + 1 )
-                if devices[ controller ] and ports[ controller ] and\
-                        "Error" not in devices[ controller ] and\
-                        "Error" not in ports[ controller ]:
-
-                    try:
-                        currentDevicesResult = main.Mininet1.compareSwitches(
-                                mnSwitches,
-                                json.loads( devices[ controller ] ),
-                                json.loads( ports[ controller ] ) )
-                    except ( TypeError, ValueError ) as e:
-                        main.log.exception( "Object not as expected; devices={!r}\nports={!r}".format(
-                            devices[ controller ], ports[ controller ] ) )
-                else:
-                    currentDevicesResult = main.FALSE
-                utilities.assert_equals( expect=main.TRUE,
-                                         actual=currentDevicesResult,
-                                         onpass="ONOS" + controllerStr +
-                                         " Switches view is correct",
-                                         onfail="ONOS" + controllerStr +
-                                         " Switches view is incorrect" )
-
-                if links[ controller ] and "Error" not in links[ controller ]:
-                    currentLinksResult = main.Mininet1.compareLinks(
-                            mnSwitches, mnLinks,
-                            json.loads( links[ controller ] ) )
-                else:
-                    currentLinksResult = main.FALSE
-                utilities.assert_equals( expect=main.TRUE,
-                                         actual=currentLinksResult,
-                                         onpass="ONOS" + controllerStr +
-                                         " links view is correct",
-                                         onfail="ONOS" + controllerStr +
-                                         " links view is incorrect" )
-                if hosts[ controller ] and "Error" not in hosts[ controller ]:
-                    currentHostsResult = main.Mininet1.compareHosts(
-                            mnHosts,
-                            hosts[ controller ] )
-                elif hosts[ controller ] == []:
-                    currentHostsResult = main.TRUE
-                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" )
-                # CHECKING HOST ATTACHMENT POINTS
-                hostAttachment = True
-                zeroHosts = False
-                # FIXME: topo-HA/obelisk specific mappings:
-                # key is mac and value is dpid
-                mappings = {}
-                for i in range( 1, 29 ):  # hosts 1 through 28
-                    # set up correct variables:
-                    macId = "00:" * 5 + hex( i ).split( "0x" )[ 1 ].upper().zfill( 2 )
-                    if i == 1:
-                        deviceId = "1000".zfill( 16 )
-                    elif i == 2:
-                        deviceId = "2000".zfill( 16 )
-                    elif i == 3:
-                        deviceId = "3000".zfill( 16 )
-                    elif i == 4:
-                        deviceId = "3004".zfill( 16 )
-                    elif i == 5:
-                        deviceId = "5000".zfill( 16 )
-                    elif i == 6:
-                        deviceId = "6000".zfill( 16 )
-                    elif i == 7:
-                        deviceId = "6007".zfill( 16 )
-                    elif i >= 8 and i <= 17:
-                        dpid = '3' + str( i ).zfill( 3 )
-                        deviceId = dpid.zfill( 16 )
-                    elif i >= 18 and i <= 27:
-                        dpid = '6' + str( i ).zfill( 3 )
-                        deviceId = dpid.zfill( 16 )
-                    elif i == 28:
-                        deviceId = "2800".zfill( 16 )
-                    mappings[ macId ] = deviceId
-                if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
-                    if hosts[ controller ] == []:
-                        main.log.warn( "There are no hosts discovered" )
-                        zeroHosts = True
-                    else:
-                        for host in hosts[ controller ]:
-                            mac = None
-                            location = None
-                            device = None
-                            port = None
-                            try:
-                                mac = host.get( 'mac' )
-                                assert mac, "mac field could not be found for this host object"
-
-                                location = host.get( 'locations' )[ 0 ]
-                                assert location, "location field could not be found for this host object"
-
-                                # Trim the protocol identifier off deviceId
-                                device = str( location.get( 'elementId' ) ).split( ':' )[ 1 ]
-                                assert device, "elementId field could not be found for this host location object"
-
-                                port = location.get( 'port' )
-                                assert port, "port field could not be found for this host location object"
-
-                                # Now check if this matches where they should be
-                                if mac and device and port:
-                                    if str( port ) != "1":
-                                        main.log.error( "The attachment port is incorrect for " +
-                                                        "host " + str( mac ) +
-                                                        ". Expected: 1 Actual: " + str( port ) )
-                                        hostAttachment = False
-                                    if device != mappings[ str( mac ) ]:
-                                        main.log.error( "The attachment device is incorrect for " +
-                                                        "host " + str( mac ) +
-                                                        ". Expected: " + mappings[ str( mac ) ] +
-                                                        " Actual: " + device )
-                                        hostAttachment = False
-                                else:
-                                    hostAttachment = False
-                            except AssertionError:
-                                main.log.exception( "Json object not as expected" )
-                                main.log.error( repr( host ) )
-                                hostAttachment = False
-                else:
-                    main.log.error( "No hosts json output or \"Error\"" +
-                                    " in output. hosts = " +
-                                    repr( hosts[ controller ] ) )
-                if zeroHosts is False:
-                    hostAttachment = True
-
-                # END CHECKING HOST ATTACHMENT POINTS
-                devicesResults = devicesResults and currentDevicesResult
-                linksResults = linksResults and currentLinksResult
-                hostsResults = hostsResults and currentHostsResult
-                hostAttachmentResults = hostAttachmentResults and\
-                                        hostAttachment
-                topoResult = ( devicesResults and linksResults
-                               and hostsResults and ipResult and
-                               hostAttachmentResults )
-        utilities.assert_equals( expect=True,
-                                 actual=topoResult,
-                                 onpass="ONOS topology matches Mininet",
-                                 onfail=topoFailMsg )
-        # End of While loop to pull ONOS state
-
-        # Compare json objects for hosts and dataplane clusters
-
-        # hosts
-        main.step( "Hosts view is consistent across all ONOS nodes" )
-        consistentHostsResult = main.TRUE
-        for controller in range( len( hosts ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
-                if hosts[ controller ] == hosts[ 0 ]:
-                    continue
-                else:  # hosts not consistent
-                    main.log.error( "hosts from ONOS" + controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    main.log.warn( repr( hosts[ controller ] ) )
-                    consistentHostsResult = main.FALSE
-
-            else:
-                main.log.error( "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" )
-
-        main.step( "Hosts information is correct" )
-        hostsResults = hostsResults and ipResult
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=hostsResults,
-            onpass="Host information is correct",
-            onfail="Host information is incorrect" )
-
-        main.step( "Host attachment points to the network" )
-        utilities.assert_equals(
-            expect=True,
-            actual=hostAttachmentResults,
-            onpass="Hosts are correctly attached to the network",
-            onfail="ONOS did not correctly attach hosts to the network" )
-
-        # Strongly connected clusters of devices
-        main.step( "Clusters view is consistent across all ONOS nodes" )
-        consistentClustersResult = main.TRUE
-        for controller in range( len( clusters ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if "Error" not in clusters[ controller ]:
-                if clusters[ controller ] == clusters[ 0 ]:
-                    continue
-                else:  # clusters not consistent
-                    main.log.error( "clusters from ONOS" +
-                                     controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    consistentClustersResult = main.FALSE
-            else:
-                main.log.error( "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" )
-        if not consistentClustersResult:
-            main.log.debug( clusters )
-
-        main.step( "There is only one SCC" )
-        # there should always only be one cluster
-        try:
-            numClusters = len( json.loads( clusters[ 0 ] ) )
-        except ( ValueError, TypeError ):
-            main.log.exception( "Error parsing clusters[0]: " +
-                                repr( clusters[ 0 ] ) )
-            numClusters = "ERROR"
-        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 linksResults
-                       and hostsResults and consistentHostsResult
-                       and consistentClustersResult and clusterResults
-                       and ipResult and hostAttachmentResults )
-
-        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" )
-
-        main.step( "Device information is correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=devicesResults,
-            onpass="Device information is correct",
-            onfail="Device information is incorrect" )
-
-        main.step( "Links are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=linksResults,
-            onpass="Link are correct",
-            onfail="Links are incorrect" )
-
-        main.step( "Hosts are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=hostsResults,
-            onpass="Hosts are correct",
-            onfail="Hosts are incorrect" )
-
-        # FIXME: move this to an ONOS state case
-        main.step( "Checking ONOS nodes" )
-        nodeResults = utilities.retry( main.HA.nodesCheck,
-                                       False,
-                                       args=[ main.activeNodes ],
-                                       attempts=5 )
-
-        utilities.assert_equals( expect=True, actual=nodeResults,
-                                 onpass="Nodes check successful",
-                                 onfail="Nodes check NOT successful" )
-        if not nodeResults:
-            for i in main.activeNodes:
-                main.log.debug( "{} components not ACTIVE: \n{}".format(
-                    main.CLIs[ i ].name,
-                    main.CLIs[ i ].sendline( "scr:list | grep -v ACTIVE" ) ) )
-
-        if not topoResult:
-            main.cleanup()
-            main.exit()
 
     def CASE9( self, main ):
         """
         Link s3-s28 down
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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"
-        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 successful",
-                                 onfail="Failed to bring link down" )
-        # TODO do some sort of check here
+        main.HA.linkDown( main )
 
     def CASE10( self, main ):
         """
         Link s3-s28 up
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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"
-        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 successful",
-                                 onfail="Failed to bring link up" )
-        # TODO do some sort of check here
+        main.HA.linkUp( main )
 
     def CASE11( self, main ):
         """
         Switch Down
         """
         # NOTE: You should probably run a topology check after this
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
-
-        description = "Killing a switch to ensure it is discovered correctly"
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        main.case( description )
-        switch = main.params[ 'kill' ][ 'switch' ]
-        switchDPID = main.params[ 'kill' ][ 'dpid' ]
-
-        # TODO: Make this switch parameterizable
-        main.step( "Kill " + switch )
-        main.log.info( "Deleting " + switch )
-        main.Mininet1.delSwitch( switch )
-        main.log.info( "Waiting " + str( switchSleep ) +
-                       " seconds for switch down to be discovered" )
-        time.sleep( switchSleep )
-        device = onosCli.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 successful",
-                                 onfail="Failed to kill switch?" )
+        main.HA.switchDown( main )
 
     def CASE12( self, main ):
         """
         Switch Up
         """
         # NOTE: You should probably run a topology check after this
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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' ]
-        switchDPID = main.params[ 'kill' ][ 'dpid' ]
-        links = main.params[ 'kill' ][ 'links' ].split()
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        description = "Adding a switch to ensure it is discovered correctly"
-        main.case( description )
-
-        main.step( "Add back " + switch )
-        main.Mininet1.addSwitch( switch, dpid=switchDPID )
-        for peer in links:
-            main.Mininet1.addLink( switch, peer )
-        ipList = [ node.ip_address for node in main.nodes ]
-        main.Mininet1.assignSwController( sw=switch, ip=ipList )
-        main.log.info( "Waiting " + str( switchSleep ) +
-                       " seconds for switch up to be discovered" )
-        time.sleep( switchSleep )
-        device = onosCli.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 successful",
-                                 onfail="Failed to add switch?" )
+        main.HA.switchUp( main )
 
     def CASE13( self, main ):
         """
         Clean up
         """
-        import os
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        # printing colors to terminal
-        colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
-                   'blue': '\033[94m', 'green': '\033[92m',
-                   'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
-        main.case( "Test Cleanup" )
-        main.step( "Killing tcpdumps" )
-        main.Mininet2.stopTcpdump()
-
-        testname = main.TEST
-        if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
-            main.step( "Copying MN pcap and ONOS log files to test station" )
-            teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
-            teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
-            # NOTE: MN Pcap file is being saved to logdir.
-            #       We scp this file as MN and TestON aren't necessarily the same vm
-
-            # FIXME: To be replaced with a Jenkin's post script
-            # TODO: Load these from params
-            # NOTE: must end in /
-            logFolder = "/opt/onos/log/"
-            logFiles = [ "karaf.log", "karaf.log.1" ]
-            # NOTE: must end in /
-            for f in logFiles:
-                for node in main.nodes:
-                    dstName = main.logdir + "/" + node.name + "-" + f
-                    main.ONOSbench.secureCopy( node.user_name, node.ip_address,
-                                               logFolder + f, dstName )
-            # std*.log's
-            # NOTE: must end in /
-            logFolder = "/opt/onos/var/"
-            logFiles = [ "stderr.log", "stdout.log" ]
-            # NOTE: must end in /
-            for f in logFiles:
-                for node in main.nodes:
-                    dstName = main.logdir + "/" + node.name + "-" + f
-                    main.ONOSbench.secureCopy( node.user_name, node.ip_address,
-                                               logFolder + f, dstName )
-        else:
-            main.log.debug( "skipping saving log files" )
-
-        main.step( "Stopping Mininet" )
-        mnResult = main.Mininet1.stopNet()
-        utilities.assert_equals( expect=main.TRUE, actual=mnResult,
-                                 onpass="Mininet stopped",
-                                 onfail="MN cleanup NOT successful" )
-
-        main.step( "Checking ONOS Logs for errors" )
-        for node in main.nodes:
-            main.log.debug( "Checking logs for errors on " + node.name + ":" )
-            main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
-
-        try:
-            timerLog = open( main.logdir + "/Timers.csv", 'w' )
-            # Overwrite with empty line and close
-            labels = "Gossip Intents, Restart"
-            data = str( gossipTime ) + ", " + str( main.restartTime )
-            timerLog.write( labels + "\n" + data )
-            timerLog.close()
-        except NameError as e:
-            main.log.exception( e )
+        main.HAlabels.append( "Restart" )
+        main.HAdata.append( str( main.restartTime ) )
+        main.HA.cleanUp( main )
 
     def CASE14( self, main ):
         """
         start election app on all onos nodes
         """
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        main.case( "Start Leadership Election app" )
-        main.step( "Install leadership election app" )
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        appResult = onosCli.activateApp( "org.onosproject.election" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=appResult,
-            onpass="Election app installed",
-            onfail="Something went wrong with installing Leadership election" )
-
-        main.step( "Run for election on each node" )
-        for i in main.activeNodes:
-            main.CLIs[ i ].electionTestRun()
-        time.sleep( 5 )
-        activeCLIs = [ main.CLIs[ i ] for i in main.activeNodes ]
-        sameResult, leaders = main.HA.consistentLeaderboards( activeCLIs )
-        utilities.assert_equals(
-            expect=True,
-            actual=sameResult,
-            onpass="All nodes see the same leaderboards",
-            onfail="Inconsistent leaderboards" )
-
-        if sameResult:
-            leader = leaders[ 0 ][ 0 ]
-            if main.nodes[ main.activeNodes[ 0 ] ].ip_address in leader:
-                correctLeader = True
-            else:
-                correctLeader = False
-            main.step( "First node was elected leader" )
-            utilities.assert_equals(
-                expect=True,
-                actual=correctLeader,
-                onpass="Correct leader was elected",
-                onfail="Incorrect leader" )
+        main.HA.startElectionApp( main )
 
     def CASE15( self, main ):
         """
@@ -2943,196 +301,16 @@
             old and new variable prefixes refer to data from before vs after
                 withdrawl and later before withdrawl vs after re-election
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        description = "Check that Leadership Election is still functional"
-        main.case( description )
-        # NOTE: Need to re-run after restarts since being a canidate is not persistant
-
-        oldLeaders = []  # list of lists of each nodes' candidates before
-        newLeaders = []  # list of lists of each nodes' candidates after
-        oldLeader = ''  # the old leader from oldLeaders, None if not same
-        newLeader = ''  # the new leaders fron newLoeaders, None if not same
-        oldLeaderCLI = None  # the CLI of the old leader used for re-electing
-        expectNoLeader = False  # True when there is only one leader
-        if main.numCtrls == 1:
-            expectNoLeader = True
-
-        main.step( "Run for election on each node" )
-        electionResult = main.TRUE
-
-        for i in main.activeNodes:  # run test election on each node
-            if main.CLIs[ i ].electionTestRun() == main.FALSE:
-                electionResult = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=electionResult,
-            onpass="All nodes successfully ran for leadership",
-            onfail="At least one node failed to run for leadership" )
-
-        if electionResult == main.FALSE:
-            main.log.error(
-                "Skipping Test Case because Election Test App isn't loaded" )
-            main.skipCase()
-
-        main.step( "Check that each node shows the same leader and candidates" )
-        failMessage = "Nodes have different leaderboards"
-        activeCLIs = [ main.CLIs[ i ] for i in main.activeNodes ]
-        sameResult, oldLeaders = main.HA.consistentLeaderboards( activeCLIs )
-        if sameResult:
-            oldLeader = oldLeaders[ 0 ][ 0 ]
-            main.log.warn( oldLeader )
-        else:
-            oldLeader = None
-        utilities.assert_equals(
-            expect=True,
-            actual=sameResult,
-            onpass="Leaderboards are consistent for the election topic",
-            onfail=failMessage )
-
-        main.step( "Find current leader and withdraw" )
-        withdrawResult = main.TRUE
-        # do some sanity checking on leader before using it
-        if oldLeader is None:
-            main.log.error( "Leadership isn't consistent." )
-            withdrawResult = main.FALSE
-        # Get the CLI of the oldLeader
-        for i in main.activeNodes:
-            if oldLeader == main.nodes[ i ].ip_address:
-                oldLeaderCLI = main.CLIs[ i ]
-                break
-        else:  # FOR/ELSE statement
-            main.log.error( "Leader election, could not find current leader" )
-        if oldLeader:
-            withdrawResult = oldLeaderCLI.electionTestWithdraw()
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=withdrawResult,
-            onpass="Node was withdrawn from election",
-            onfail="Node was not withdrawn from election" )
-
-        main.step( "Check that a new node was elected leader" )
-        failMessage = "Nodes have different leaders"
-        # Get new leaders and candidates
-        newLeaderResult, newLeaders = main.HA.consistentLeaderboards( activeCLIs )
-        newLeader = None
-        if newLeaderResult:
-            if newLeaders[ 0 ][ 0 ] == 'none':
-                main.log.error( "No leader was elected on at least 1 node" )
-                if not expectNoLeader:
-                    newLeaderResult = False
-            newLeader = newLeaders[ 0 ][ 0 ]
-
-        # Check that the new leader is not the older leader, which was withdrawn
-        if newLeader == oldLeader:
-            newLeaderResult = False
-            main.log.error( "All nodes still see old leader: " + str( oldLeader ) +
-                            " as the current leader" )
-        utilities.assert_equals(
-            expect=True,
-            actual=newLeaderResult,
-            onpass="Leadership election passed",
-            onfail="Something went wrong with Leadership election" )
-
-        main.step( "Check that that new leader was the candidate of old leader" )
-        # candidates[ 2 ] should become the top candidate after withdrawl
-        correctCandidateResult = main.TRUE
-        if expectNoLeader:
-            if newLeader == 'none':
-                main.log.info( "No leader expected. None found. Pass" )
-                correctCandidateResult = main.TRUE
-            else:
-                main.log.info( "Expected no leader, got: " + str( newLeader ) )
-                correctCandidateResult = main.FALSE
-        elif len( oldLeaders[ 0 ] ) >= 3:
-            if newLeader == oldLeaders[ 0 ][ 2 ]:
-                # correct leader was elected
-                correctCandidateResult = main.TRUE
-            else:
-                correctCandidateResult = main.FALSE
-                main.log.error( "Candidate {} was elected. {} should have had priority.".format(
-                                    newLeader, oldLeaders[ 0 ][ 2 ] ) )
-        else:
-            main.log.warn( "Could not determine who should be the correct leader" )
-            main.log.debug( oldLeaders[ 0 ] )
-            correctCandidateResult = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=correctCandidateResult,
-            onpass="Correct Candidate Elected",
-            onfail="Incorrect Candidate Elected" )
-
-        main.step( "Run for election on old leader( just so everyone " +
-                   "is in the hat )" )
-        if oldLeaderCLI is not None:
-            runResult = oldLeaderCLI.electionTestRun()
-        else:
-            main.log.error( "No old leader to re-elect" )
-            runResult = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=runResult,
-            onpass="App re-ran for election",
-            onfail="App failed to run for election" )
-
-        main.step(
-            "Check that oldLeader is a candidate, and leader if only 1 node" )
-        # verify leader didn't just change
-        # Get new leaders and candidates
-        reRunLeaders = []
-        time.sleep( 5 )  # Paremterize
-        positionResult, reRunLeaders = main.HA.consistentLeaderboards( activeCLIs )
-
-        # Check that the re-elected node is last on the candidate List
-        if not reRunLeaders[ 0 ]:
-            positionResult = main.FALSE
-        elif oldLeader != reRunLeaders[ 0 ][ -1 ]:
-            main.log.error( "Old Leader ({}) not in the proper position: {} ".format( str( oldLeader ),
-                                                                                      str( reRunLeaders[ 0 ] ) ) )
-            positionResult = main.FALSE
-        utilities.assert_equals(
-            expect=True,
-            actual=positionResult,
-            onpass="Old leader successfully re-ran for election",
-            onfail="Something went wrong with Leadership election after " +
-                   "the old leader re-ran for election" )
+        main.HA.isElectionFunctional( main )
 
     def CASE16( self, main ):
         """
         Install Distributed Primitives app
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        # Variables for the distributed primitives tests
-        main.pCounterName = "TestON-Partitions"
-        main.pCounterValue = 0
-        main.onosSet = set( [] )
-        main.onosSetName = "TestON-set"
-
-        description = "Install Primitives app"
-        main.case( description )
-        main.step( "Install Primitives app" )
-        appName = "org.onosproject.distributedprimitives"
-        node = main.activeNodes[ 0 ]
-        appResults = main.CLIs[ node ].activateApp( appName )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=appResults,
-                                 onpass="Primitives app activated",
-                                 onfail="Primitives app not activated" )
-        time.sleep( 5 )  # To allow all nodes to activate
+        main.HA.installDistributedPrimitiveApp( main )
 
     def CASE17( self, main ):
         """
         Check for basic functionality with distributed primitives
         """
-        main.HA.CASE17( main )
+        main.HA.checkDistPrimitivesFunc( main )
diff --git a/TestON/tests/HA/HAfullNetPartition/HAfullNetPartition.params b/TestON/tests/HA/HAfullNetPartition/HAfullNetPartition.params
index 55936ce..93b3e02 100644
--- a/TestON/tests/HA/HAfullNetPartition/HAfullNetPartition.params
+++ b/TestON/tests/HA/HAfullNetPartition/HAfullNetPartition.params
@@ -35,8 +35,10 @@
         <cellName>HA</cellName>
         <appString>drivers,openflow,proxyarp,mobility</appString>
     </ENV>
-    <Git> False </Git>
-    <branch> master </branch>
+    <GIT>
+        <pull>False</pull>
+        <branch>master</branch>
+    </GIT>
     <num_controllers> 7 </num_controllers>
     <tcpdump> False </tcpdump>
 
diff --git a/TestON/tests/HA/HAfullNetPartition/HAfullNetPartition.py b/TestON/tests/HA/HAfullNetPartition/HAfullNetPartition.py
index e9e8e1a..b5c1e86 100644
--- a/TestON/tests/HA/HAfullNetPartition/HAfullNetPartition.py
+++ b/TestON/tests/HA/HAfullNetPartition/HAfullNetPartition.py
@@ -52,1723 +52,70 @@
         import json
         main.log.info( "ONOS HA test: Partition ONOS nodes into two sub-clusters - " +
                          "initialization" )
-        main.case( "Setting up test environment" )
-        main.caseExplanation = "Setup the test environment including " +\
-                                "installing ONOS, starting Mininet and ONOS" +\
-                                "cli sessions."
-
-        # load some variables from the params file
-        PULLCODE = False
-        if main.params[ 'Git' ] == 'True':
-            PULLCODE = True
-        gitBranch = main.params[ 'branch' ]
-        cellName = main.params[ 'ENV' ][ 'cellName' ]
-
-        main.numCtrls = int( main.params[ 'num_controllers' ] )
-        if main.ONOSbench.maxNodes:
-            if main.ONOSbench.maxNodes < main.numCtrls:
-                main.numCtrls = int( main.ONOSbench.maxNodes )
         # set global variables
-        global ONOS1Port
-        global ONOS2Port
-        global ONOS3Port
-        global ONOS4Port
-        global ONOS5Port
-        global ONOS6Port
-        global ONOS7Port
         # These are for csv plotting in jenkins
-        global labels
-        global data
-        labels = []
-        data = []
-
-        # 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' ]
-
+        main.HAlabels = []
+        main.HAdata = []
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        main.testSetUp.envSetupDescription()
         try:
             from tests.HA.dependencies.HA import HA
             main.HA = HA()
+            # load some variables from the params file
+            cellName = main.params[ 'ENV' ][ 'cellName' ]
+            main.apps = main.params[ 'ENV' ][ 'appString' ]
+            main.numCtrls = int( main.params[ 'num_controllers' ] )
+            if main.ONOSbench.maxNodes and\
+                        main.ONOSbench.maxNodes < main.numCtrls:
+                main.numCtrls = int( main.ONOSbench.maxNodes )
+            main.maxNodes = main.numCtrls
+            stepResult = main.testSetUp.envSetup( hasNode=True )
         except Exception as e:
-            main.log.exception( e )
-            main.cleanup()
-            main.exit()
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
+        main.HA.generateGraph( "HAfullNetPartition" )
 
-        main.CLIs = []
-        main.nodes = []
-        ipList = []
-        for i in range( 1, main.numCtrls + 1 ):
-            try:
-                main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
-                main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
-                ipList.append( main.nodes[ -1 ].ip_address )
-            except AttributeError:
-                break
+        main.testSetUp.ONOSSetUp( main.Mininet1, cellName=cellName, removeLog=True,
+                                 extraApply=main.HA.customizeOnosGenPartitions,
+                                 extraClean=main.HA.cleanUpGenPartition )
 
-        main.step( "Create cell file" )
-        cellAppString = main.params[ 'ENV' ][ 'appString' ]
-        main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
-                                       main.Mininet1.ip_address,
-                                       cellAppString, ipList, main.ONOScli1.karafUser )
-        main.step( "Applying cell variable to environment" )
-        cellResult = main.ONOSbench.setCell( cellName )
-        verifyResult = main.ONOSbench.verifyCell()
+        main.HA.initialSetUp()
 
-        # FIXME:this is short term fix
-        main.log.info( "Removing raft logs" )
-        main.ONOSbench.onosRemoveRaftLogs()
-
-        main.log.info( "Uninstalling ONOS" )
-        for node in main.nodes:
-            main.ONOSbench.onosUninstall( node.ip_address )
-
-        # Make sure ONOS is DEAD
-        main.log.info( "Killing any ONOS processes" )
-        killResults = main.TRUE
-        for node in main.nodes:
-            killed = main.ONOSbench.onosKill( node.ip_address )
-            killResults = killResults and killed
-
-        gitPullResult = main.TRUE
-
-        main.step( "Starting Mininet" )
-        # scp topo file to mininet
-        # TODO: move to params?
-        topoName = "obelisk.py"
-        filePath = main.ONOSbench.home + "/tools/test/topos/"
-        main.ONOSbench.scp( main.Mininet1,
-                            filePath + topoName,
-                            main.Mininet1.home,
-                            direction="to" )
-        mnResult = main.Mininet1.startNet()
-        utilities.assert_equals( expect=main.TRUE, actual=mnResult,
-                                 onpass="Mininet Started",
-                                 onfail="Error starting Mininet" )
-
-        main.step( "Git checkout and pull " + gitBranch )
-        if PULLCODE:
-            main.ONOSbench.gitCheckout( gitBranch )
-            gitPullResult = main.ONOSbench.gitPull()
-            # values of 1 or 3 are good
-            utilities.assert_lesser( expect=0, actual=gitPullResult,
-                                      onpass="Git pull successful",
-                                      onfail="Git pull failed" )
-        main.ONOSbench.getVersion( report=True )
-
-        # GRAPHS
-        # NOTE: important params here:
-        #       job = name of Jenkins job
-        #       Plot Name = Plot-HA, only can be used if multiple plots
-        #       index = The number of the graph under plot name
-        job = "HAfullNetPartition"
-        plotName = "Plot-HA"
-        index = "2"
-        graphs = '<ac:structured-macro ac:name="html">\n'
-        graphs += '<ac:plain-text-body><![CDATA[\n'
-        graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
-                  '/plot/' + plotName + '/getPlot?index=' + index +\
-                  '&width=500&height=300"' +\
-                  'noborder="0" width="500" height="300" scrolling="yes" ' +\
-                  'seamless="seamless"></iframe>\n'
-        graphs += ']]></ac:plain-text-body>\n'
-        graphs += '</ac:structured-macro>\n'
-        main.log.wiki( graphs )
-
-        main.step( "Creating ONOS package" )
-        # copy gen-partions file to ONOS
-        # NOTE: this assumes TestON and ONOS are on the same machine
-        srcFile = main.testDir + "/HA/dependencies/onos-gen-partitions"
-        dstDir = main.ONOSbench.home + "/tools/test/bin/onos-gen-partitions"
-        cpResult = main.ONOSbench.secureCopy( main.ONOSbench.user_name,
-                                              main.ONOSbench.ip_address,
-                                              srcFile,
-                                              dstDir,
-                                              pwd=main.ONOSbench.pwd,
-                                              direction="from" )
-        packageResult = main.ONOSbench.buckBuild()
-        utilities.assert_equals( expect=main.TRUE, actual=packageResult,
-                                 onpass="ONOS package successful",
-                                 onfail="ONOS package failed" )
-
-        main.step( "Installing ONOS package" )
-        onosInstallResult = main.TRUE
-        for node in main.nodes:
-            tmpResult = main.ONOSbench.onosInstall( options="-f",
-                                                    node=node.ip_address )
-            onosInstallResult = onosInstallResult and tmpResult
-        utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
-                                 onpass="ONOS install successful",
-                                 onfail="ONOS install failed" )
-        # clean up gen-partitions file
-        try:
-            main.ONOSbench.handle.sendline( "cd " + main.ONOSbench.home )
-            main.ONOSbench.handle.expect( main.ONOSbench.home + "\$" )
-            main.ONOSbench.handle.sendline( "git checkout -- tools/test/bin/onos-gen-partitions" )
-            main.ONOSbench.handle.expect( main.ONOSbench.home + "\$" )
-            main.log.info( " Cleaning custom gen partitions file, response was: \n" +
-                           str( main.ONOSbench.handle.before ) )
-        except ( pexpect.TIMEOUT, pexpect.EOF ):
-            main.log.exception( "ONOSbench: pexpect exception found:" +
-                                main.ONOSbench.handle.before )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.TRUE
-        for node in main.nodes:
-            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=node.ip_address )
-        utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        main.step( "Checking if ONOS is up yet" )
-        for i in range( 2 ):
-            onosIsupResult = main.TRUE
-            for node in main.nodes:
-                started = main.ONOSbench.isup( node.ip_address )
-                if not started:
-                    main.log.error( node.name + " hasn't started" )
-                onosIsupResult = onosIsupResult and started
-            if onosIsupResult == main.TRUE:
-                break
-        utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
-                                 onpass="ONOS startup successful",
-                                 onfail="ONOS startup failed" )
-
-        main.step( "Starting ONOS CLI sessions" )
-        cliResults = main.TRUE
-        threads = []
-        for i in range( main.numCtrls ):
-            t = main.Thread( target=main.CLIs[ i ].startOnosCli,
-                             name="startOnosCli-" + str( i ),
-                             args=[ main.nodes[ i ].ip_address ] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            cliResults = cliResults and t.result
-        utilities.assert_equals( expect=main.TRUE, actual=cliResults,
-                                 onpass="ONOS cli startup successful",
-                                 onfail="ONOS cli startup failed" )
-
-        # Create a list of active nodes for use when some nodes are stopped
-        main.activeNodes = [ i for i in range( 0, len( main.CLIs ) ) ]
-
-        if main.params[ 'tcpdump' ].lower() == "true":
-            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' ] )
-
-        main.step( "Checking ONOS nodes" )
-        nodeResults = utilities.retry( main.HA.nodesCheck,
-                                       False,
-                                       args=[ main.activeNodes ],
-                                       attempts=5 )
-
-        utilities.assert_equals( expect=True, actual=nodeResults,
-                                 onpass="Nodes check successful",
-                                 onfail="Nodes check NOT successful" )
-
-        if not nodeResults:
-            for i in main.activeNodes:
-                cli = main.CLIs[ i ]
-                main.log.debug( "{} components not ACTIVE: \n{}".format(
-                    cli.name,
-                    cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
-            main.log.error( "Failed to start ONOS, stopping test" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Activate apps defined in the params file" )
-        # get data from the params
-        apps = main.params.get( 'apps' )
-        if apps:
-            apps = apps.split( ',' )
-            main.log.warn( apps )
-            activateResult = True
-            for app in apps:
-                main.CLIs[ 0 ].app( app, "Activate" )
-            # TODO: check this worked
-            time.sleep( 10 )  # wait for apps to activate
-            for app in apps:
-                state = main.CLIs[ 0 ].appStatus( app )
-                if state == "ACTIVE":
-                    activateResult = activateResult and True
-                else:
-                    main.log.error( "{} is in {} state".format( app, state ) )
-                    activateResult = False
-            utilities.assert_equals( expect=True,
-                                     actual=activateResult,
-                                     onpass="Successfully activated apps",
-                                     onfail="Failed to activate apps" )
-        else:
-            main.log.warn( "No apps were specified to be loaded after startup" )
-
-        main.step( "Set ONOS configurations" )
-        config = main.params.get( 'ONOS_Configuration' )
-        if config:
-            main.log.debug( config )
-            checkResult = main.TRUE
-            for component in config:
-                for setting in config[ component ]:
-                    value = config[ component ][ setting ]
-                    check = main.CLIs[ 0 ].setCfg( component, setting, value )
-                    main.log.info( "Value was changed? {}".format( main.TRUE == check ) )
-                    checkResult = check and checkResult
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=checkResult,
-                                     onpass="Successfully set config",
-                                     onfail="Failed to set config" )
-        else:
-            main.log.warn( "No configurations were specified to be changed after startup" )
-
-        main.step( "App Ids check" )
-        appCheck = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
-                             name="appToIDCheck-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            appCheck = appCheck and t.result
-        if appCheck != main.TRUE:
-            node = main.activeNodes[ 0 ]
-            main.log.warn( main.CLIs[ node ].apps() )
-            main.log.warn( main.CLIs[ node ].appIDs() )
-        utilities.assert_equals( expect=main.TRUE, actual=appCheck,
-                                 onpass="App Ids seem to be correct",
-                                 onfail="Something is wrong with app Ids" )
 
     def CASE2( self, main ):
         """
         Assign devices to controllers
         """
-        import re
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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.case( "Assigning devices to controllers" )
-        main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
-                                "and check that an ONOS node becomes the " +\
-                                "master of the device."
-        main.step( "Assign switches to controllers" )
-
-        ipList = []
-        for i in range( main.numCtrls ):
-            ipList.append( main.nodes[ i ].ip_address )
-        swList = []
-        for i in range( 1, 29 ):
-            swList.append( "s" + str( i ) )
-        main.Mininet1.assignSwController( sw=swList, ip=ipList )
-
-        mastershipCheck = main.TRUE
-        for i in range( 1, 29 ):
-            response = main.Mininet1.getSwController( "s" + str( i ) )
-            try:
-                main.log.info( str( response ) )
-            except Exception:
-                main.log.info( repr( response ) )
-            for node in main.nodes:
-                if re.search( "tcp:" + node.ip_address, response ):
-                    mastershipCheck = mastershipCheck and main.TRUE
-                else:
-                    main.log.error( "Error, node " + node.ip_address + " is " +
-                                    "not in the list of controllers s" +
-                                    str( i ) + " is connecting to." )
-                    mastershipCheck = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=mastershipCheck,
-            onpass="Switch mastership assigned correctly",
-            onfail="Switches not assigned correctly to controllers" )
+        main.HA.assignDevices( main )
 
     def CASE21( self, main ):
         """
         Assign mastership to controllers
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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.case( "Assigning Controller roles for switches" )
-        main.caseExplanation = "Check that ONOS is connected to each " +\
-                                "device. Then manually assign" +\
-                                " mastership to specific ONOS nodes using" +\
-                                " 'device-role'"
-        main.step( "Assign mastership of switches to specific controllers" )
-        # Manually assign mastership to the controller we want
-        roleCall = main.TRUE
-
-        ipList = []
-        deviceList = []
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        try:
-            # Assign mastership to specific controllers. This assignment was
-            # determined for a 7 node cluser, but will work with any sized
-            # cluster
-            for i in range( 1, 29 ):  # switches 1 through 28
-                # set up correct variables:
-                if i == 1:
-                    c = 0
-                    ip = main.nodes[ c ].ip_address  # ONOS1
-                    deviceId = onosCli.getDevice( "1000" ).get( 'id' )
-                elif i == 2:
-                    c = 1 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS2
-                    deviceId = onosCli.getDevice( "2000" ).get( 'id' )
-                elif i == 3:
-                    c = 1 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS2
-                    deviceId = onosCli.getDevice( "3000" ).get( 'id' )
-                elif i == 4:
-                    c = 3 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS4
-                    deviceId = onosCli.getDevice( "3004" ).get( 'id' )
-                elif i == 5:
-                    c = 2 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS3
-                    deviceId = onosCli.getDevice( "5000" ).get( 'id' )
-                elif i == 6:
-                    c = 2 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS3
-                    deviceId = onosCli.getDevice( "6000" ).get( 'id' )
-                elif i == 7:
-                    c = 5 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS6
-                    deviceId = onosCli.getDevice( "6007" ).get( 'id' )
-                elif i >= 8 and i <= 17:
-                    c = 4 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS5
-                    dpid = '3' + str( i ).zfill( 3 )
-                    deviceId = onosCli.getDevice( dpid ).get( 'id' )
-                elif i >= 18 and i <= 27:
-                    c = 6 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS7
-                    dpid = '6' + str( i ).zfill( 3 )
-                    deviceId = onosCli.getDevice( dpid ).get( 'id' )
-                elif i == 28:
-                    c = 0
-                    ip = main.nodes[ c ].ip_address  # ONOS1
-                    deviceId = onosCli.getDevice( "2800" ).get( 'id' )
-                else:
-                    main.log.error( "You didn't write an else statement for " +
-                                    "switch s" + str( i ) )
-                    roleCall = main.FALSE
-                # Assign switch
-                assert deviceId, "No device id for s" + str( i ) + " in ONOS"
-                # TODO: make this controller dynamic
-                roleCall = roleCall and onosCli.deviceRole( deviceId, ip )
-                ipList.append( ip )
-                deviceList.append( deviceId )
-        except ( AttributeError, AssertionError ):
-            main.log.exception( "Something is wrong with ONOS device view" )
-            main.log.info( onosCli.devices() )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=roleCall,
-            onpass="Re-assigned switch mastership to designated controller",
-            onfail="Something wrong with deviceRole calls" )
-
-        main.step( "Check mastership was correctly assigned" )
-        roleCheck = main.TRUE
-        # NOTE: This is due to the fact that device mastership change is not
-        #       atomic and is actually a multi step process
-        time.sleep( 5 )
-        for i in range( len( ipList ) ):
-            ip = ipList[ i ]
-            deviceId = deviceList[ i ]
-            # Check assignment
-            master = onosCli.getRole( deviceId ).get( 'master' )
-            if ip in master:
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-                main.log.error( "Error, controller " + ip + " is not" +
-                                " master " + "of device " +
-                                str( deviceId ) + ". Master is " +
-                                repr( master ) + "." )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=roleCheck,
-            onpass="Switches were successfully reassigned to designated " +
-                   "controller",
-            onfail="Switches were not successfully reassigned" )
+        main.HA.assignMastership( main )
 
     def CASE3( self, main ):
         """
         Assign intents
         """
-        import time
-        import json
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-        main.case( "Adding host Intents" )
-        main.caseExplanation = "Discover hosts by using pingall then " +\
-                                "assign predetermined host-to-host intents." +\
-                                " After installation, check that the intent" +\
-                                " is distributed to all nodes and the state" +\
-                                " is INSTALLED"
-
-        # install onos-app-fwd
-        main.step( "Install reactive forwarding app" )
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        installResults = onosCli.activateApp( "org.onosproject.fwd" )
-        utilities.assert_equals( expect=main.TRUE, actual=installResults,
-                                 onpass="Install fwd successful",
-                                 onfail="Install fwd failed" )
-
-        main.step( "Check app ids" )
-        appCheck = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
-                             name="appToIDCheck-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            appCheck = appCheck and t.result
-        if appCheck != main.TRUE:
-            main.log.warn( onosCli.apps() )
-            main.log.warn( onosCli.appIDs() )
-        utilities.assert_equals( expect=main.TRUE, actual=appCheck,
-                                 onpass="App Ids seem to be correct",
-                                 onfail="Something is wrong with app Ids" )
-
-        main.step( "Discovering Hosts( Via pingall for now )" )
-        # FIXME: Once we have a host discovery mechanism, use that instead
-        # REACTIVE FWD test
-        pingResult = main.FALSE
-        passMsg = "Reactive Pingall test passed"
-        time1 = time.time()
-        pingResult = main.Mininet1.pingall()
-        time2 = time.time()
-        if not pingResult:
-            main.log.warn( "First pingall failed. Trying again..." )
-            pingResult = main.Mininet1.pingall()
-            passMsg += " on the second try"
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=pingResult,
-            onpass=passMsg,
-            onfail="Reactive Pingall failed, " +
-                   "one or more ping pairs failed" )
-        main.log.info( "Time for pingall: %2f seconds" %
-                       ( time2 - time1 ) )
-        # timeout for fwd flows
-        time.sleep( 11 )
-        # uninstall onos-app-fwd
-        main.step( "Uninstall reactive forwarding app" )
-        node = main.activeNodes[ 0 ]
-        uninstallResult = main.CLIs[ node ].deactivateApp( "org.onosproject.fwd" )
-        utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
-                                 onpass="Uninstall fwd successful",
-                                 onfail="Uninstall fwd failed" )
-
-        main.step( "Check app ids" )
-        threads = []
-        appCheck2 = main.TRUE
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
-                             name="appToIDCheck-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            appCheck2 = appCheck2 and t.result
-        if appCheck2 != main.TRUE:
-            node = main.activeNodes[ 0 ]
-            main.log.warn( main.CLIs[ node ].apps() )
-            main.log.warn( main.CLIs[ node ].appIDs() )
-        utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
-                                 onpass="App Ids seem to be correct",
-                                 onfail="Something is wrong with app Ids" )
-
-        main.step( "Add host intents via cli" )
-        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 ) )
-            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 = onosCli.getHost( host1 )
-            host2Dict = onosCli.getHost( host2 )
-            host1Id = None
-            host2Id = None
-            if host1Dict and host2Dict:
-                host1Id = host1Dict.get( 'id', None )
-                host2Id = host2Dict.get( 'id', None )
-            if host1Id and host2Id:
-                nodeNum = ( i % len( main.activeNodes ) )
-                node = main.activeNodes[ nodeNum ]
-                tmpId = main.CLIs[ node ].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 for h" + str( i ) +
-                                " and/or h" + str( i + 10 ) )
-                node = main.activeNodes[ 0 ]
-                hosts = main.CLIs[ node ].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
-        utilities.assert_equals( expect=main.TRUE, actual=hostResult,
-                                 onpass="Found a host id for each host",
-                                 onfail="Error looking up host ids" )
-
-        intentStart = time.time()
-        onosIds = onosCli.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
-        if intentAddResult:
-            intentStop = time.time()
-        else:
-            intentStop = None
-        # Print the intent states
-        intents = onosCli.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 = onosCli.leaders()
-        try:
-            missing = False
-            if leaders:
-                parsedLeaders = json.loads( leaders )
-                main.log.warn( json.dumps( parsedLeaders,
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-                # check for all intent partitions
-                topics = []
-                for i in range( 14 ):
-                    topics.append( "work-partition-" + str( i ) )
-                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" )
-                        missing = True
-            else:
-                main.log.error( "leaders() returned None" )
-        except ( ValueError, TypeError ):
-            main.log.exception( "Error parsing leaders" )
-            main.log.error( repr( leaders ) )
-        # Check all nodes
-        if missing:
-            for i in main.activeNodes:
-                response = main.CLIs[ i ].leaders( jsonFormat=False )
-                main.log.warn( str( main.CLIs[ i ].name ) + " leaders output: \n" +
-                               str( response ) )
-
-        partitions = onosCli.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 = onosCli.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( intentAddResult and not missingIntents and
-                                installedCheck )
-        if not intentAddResult:
-            main.log.error( "Error in pushing host intents to ONOS" )
-
-        main.step( "Intent Anti-Entropy dispersion" )
-        for j in range( 100 ):
-            correct = True
-            main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
-            for i in main.activeNodes:
-                onosIds = []
-                ids = main.CLIs[ i ].getAllIntentsId()
-                onosIds.append( ids )
-                main.log.debug( "Intents in " + main.CLIs[ i ].name + ": " +
-                                str( sorted( onosIds ) ) )
-                if sorted( ids ) != sorted( intentIds ):
-                    main.log.warn( "Set of intent IDs doesn't match" )
-                    correct = False
-                    break
-                else:
-                    intents = json.loads( main.CLIs[ i ].intents() )
-                    for intent in intents:
-                        if intent[ 'state' ] != "INSTALLED":
-                            main.log.warn( "Intent " + intent[ 'id' ] +
-                                           " is " + intent[ 'state' ] )
-                            correct = False
-                            break
-            if correct:
-                break
-            else:
-                time.sleep( 1 )
-        if not intentStop:
-            intentStop = time.time()
-        global gossipTime
-        gossipTime = intentStop - intentStart
-        main.log.info( "It took about " + str( gossipTime ) +
-                        " seconds for all intents to appear in each node" )
-        gossipPeriod = int( main.params[ 'timers' ][ 'gossip' ] )
-        maxGossipTime = gossipPeriod * len( main.activeNodes )
-        utilities.assert_greater_equals(
-                expect=maxGossipTime, actual=gossipTime,
-                onpass="ECM anti-entropy for intents worked within " +
-                       "expected time",
-                onfail="Intent ECM anti-entropy took too long. " +
-                       "Expected time:{}, Actual time:{}".format( maxGossipTime,
-                                                                  gossipTime ) )
-        if gossipTime <= maxGossipTime:
-            intentAddResult = True
-
-        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 = onosCli.getAllIntentsId()
-            main.log.info( "Submitted intents: " + str( intentIds ) )
-            main.log.info( "Intents in ONOS: " + str( onosIds ) )
-            # Print the intent states
-            intents = onosCli.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 = onosCli.leaders()
-            try:
-                missing = False
-                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( "work-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" )
-                            missing = True
-                else:
-                    main.log.error( "leaders() returned None" )
-            except ( ValueError, TypeError ):
-                main.log.exception( "Error parsing leaders" )
-                main.log.error( repr( leaders ) )
-            # Check all nodes
-            if missing:
-                for i in main.activeNodes:
-                    node = main.CLIs[ i ]
-                    response = node.leaders( jsonFormat=False )
-                    main.log.warn( str( node.name ) + " leaders output: \n" +
-                                   str( response ) )
-
-            partitions = onosCli.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 = onosCli.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 ) )
+        main.HA.assignIntents( main )
 
     def CASE4( self, main ):
         """
         Ping across added host intents
         """
-        import json
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-        main.case( "Verify connectivity by sending traffic across Intents" )
-        main.caseExplanation = "Ping across added host intents to check " +\
-                                "functionality and check the state of " +\
-                                "the intent"
-
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        main.step( "Check Intent state" )
-        installedCheck = False
-        loopCount = 0
-        while not installedCheck and loopCount < 40:
-            installedCheck = True
-            # Print the intent states
-            intents = onosCli.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." )
-            # Print states
-            intentStates.sort()
-            for i, s in intentStates:
-                count += 1
-                main.log.info( "%-6s%-15s%-15s" %
-                               ( str( count ), str( i ), str( s ) ) )
-            if not installedCheck:
-                time.sleep( 1 )
-                loopCount += 1
-        utilities.assert_equals( expect=True, actual=installedCheck,
-                                 onpass="Intents are all INSTALLED",
-                                 onfail="Intents are not all in " +
-                                        "INSTALLED state" )
-
-        main.step( "Ping across added host intents" )
-        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.error(
-                "Intents have not been installed correctly, pings failed." )
-            # TODO: pretty print
-            main.log.warn( "ONOS1 intents: " )
-            try:
-                tmpIntents = onosCli.intents()
-                main.log.warn( json.dumps( json.loads( tmpIntents ),
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-            except ( ValueError, TypeError ):
-                main.log.warn( repr( tmpIntents ) )
-        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." )
-
-        main.step( "Check leadership of topics" )
-        leaders = onosCli.leaders()
-        topicCheck = main.TRUE
-        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
-                # TODO: Look at Devices as topics now that it uses this system
-                topics = []
-                for i in range( 14 ):
-                    topics.append( "work-partition-" + str( i ) )
-                # FIXME: this should only be after we start the app
-                # FIXME: topics.append( "org.onosproject.election" )
-                # Print leaders output
-                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" )
-                        topicCheck = main.FALSE
-            else:
-                main.log.error( "leaders() returned None" )
-                topicCheck = main.FALSE
-        except ( ValueError, TypeError ):
-            topicCheck = main.FALSE
-            main.log.exception( "Error parsing leaders" )
-            main.log.error( repr( leaders ) )
-            # TODO: Check for a leader of these topics
-        # Check all nodes
-        if topicCheck:
-            for i in main.activeNodes:
-                node = main.CLIs[ i ]
-                response = node.leaders( jsonFormat=False )
-                main.log.warn( str( node.name ) + " leaders output: \n" +
-                               str( response ) )
-
-        utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
-                                 onpass="intent Partitions is in leaders",
-                                 onfail="Some topics were lost " )
-        # Print partitions
-        partitions = onosCli.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 ) )
-        # Print Pending Map
-        pendingMap = onosCli.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 = onosCli.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 = onosCli.leaders()
-            try:
-                missing = False
-                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( "work-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" )
-                            missing = True
-                else:
-                    main.log.error( "leaders() returned None" )
-            except ( ValueError, TypeError ):
-                main.log.exception( "Error parsing leaders" )
-                main.log.error( repr( leaders ) )
-            if missing:
-                for i in main.activeNodes:
-                    node = main.CLIs[ i ]
-                    response = node.leaders( jsonFormat=False )
-                    main.log.warn( str( node.name ) + " leaders output: \n" +
-                                   str( response ) )
-
-            partitions = onosCli.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 = onosCli.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 ) )
-        # Print flowrules
-        node = main.activeNodes[ 0 ]
-        main.log.debug( main.CLIs[ node ].flows( jsonFormat=False ) )
-        main.step( "Wait a minute then ping again" )
-        # the wait is above
-        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.error(
-                "Intents have not been installed correctly, pings failed." )
-            # TODO: pretty print
-            main.log.warn( "ONOS1 intents: " )
-            try:
-                tmpIntents = onosCli.intents()
-                main.log.warn( json.dumps( json.loads( tmpIntents ),
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-            except ( ValueError, TypeError ):
-                main.log.warn( repr( tmpIntents ) )
-        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." )
+        main.HA.pingAcrossHostIntent( main, True, True )
 
     def CASE5( self, main ):
         """
         Reading state of ONOS
         """
-        import json
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        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 each other and also with past states
-
-        main.step( "Check that each switch has a master" )
-        global mastershipState
-        mastershipState = '[]'
-
-        # Assert that each device has a master
-        rolesNotNull = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( "Get the Mastership of each switch from each controller" )
-        ONOSMastership = []
-        mastershipCheck = main.FALSE
-        consistentMastership = True
-        rolesResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSMastership ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSMastership[ i ] or "Error" in ONOSMastership[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " roles" )
-                main.log.warn( "ONOS" + node + " 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.info(
-                "Switch roles are consistent across all ONOS nodes" )
-        else:
-            consistentMastership = False
-        utilities.assert_equals(
-            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( len( main.activeNodes ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                try:
-                    main.log.warn(
-                        "ONOS" + node + " 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 = []
-        ONOSIntents = []
-        intentCheck = main.FALSE
-        consistentIntents = True
-        intentsResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSIntents ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " intents" )
-                main.log.warn( "ONOS" + node + " 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.info( "Intents are consistent across all ONOS " +
-                             "nodes" )
-        else:
-            consistentIntents = False
-            main.log.error( "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:
-            # Try to make it easy to figure out what is happening
-            #
-            # Intent      ONOS1      ONOS2    ...
-            #  0x01     INSTALLED  INSTALLING
-            #  ...        ...         ...
-            #  ...        ...         ...
-            title = "   Id"
-            for n in main.activeNodes:
-                title += " " * 10 + "ONOS" + str( n + 1 )
-            main.log.warn( title )
-            # get all intent keys in the cluster
-            keys = []
-            try:
-                # Get the set of all intent keys
-                for nodeStr in ONOSIntents:
-                    node = json.loads( nodeStr )
-                    for intent in node:
-                        keys.append( intent.get( 'id' ) )
-                keys = set( keys )
-                # For each intent key, print the state on each node
-                for key in keys:
-                    row = "%-13s" % key
-                    for nodeStr in ONOSIntents:
-                        node = json.loads( nodeStr )
-                        for intent in node:
-                            if intent.get( 'id', "Error" ) == key:
-                                row += "%-15s" % intent.get( 'state' )
-                    main.log.warn( row )
-                # End of intent state table
-            except ValueError as e:
-                main.log.exception( e )
-                main.log.debug( "nodeStr was: " + repr( nodeStr ) )
-
-        if intentsResults and not consistentIntents:
-            # print the json objects
-            n = str( main.activeNodes[ -1 ] + 1 )
-            main.log.debug( "ONOS" + n + " intents: " )
-            main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
-                                        sort_keys=True,
-                                        indent=4,
-                                        separators=( ',', ': ' ) ) )
-            for i in range( len( ONOSIntents ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
-                    main.log.debug( "ONOS" + node + " intents: " )
-                    main.log.debug( json.dumps( json.loads( ONOSIntents[ i ] ),
-                                                sort_keys=True,
-                                                indent=4,
-                                                separators=( ',', ': ' ) ) )
-                else:
-                    main.log.debug( "ONOS" + node + " intents match ONOS" +
-                                    n + " intents" )
-        elif intentsResults and consistentIntents:
-            intentCheck = main.TRUE
-            intentState = ONOSIntents[ 0 ]
-
-        main.step( "Get the flows from each controller" )
-        global flowState
-        flowState = []
-        ONOSFlows = []
-        ONOSFlowsJson = []
-        flowCheck = main.FALSE
-        consistentFlows = True
-        flowsResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].flows,
-                             name="flows-" + str( i ),
-                             args=[],
-                             kwargs={ 'jsonFormat': True } )
-            threads.append( t )
-            t.start()
-
-        # NOTE: Flows command can take some time to run
-        time.sleep( 30 )
-        for t in threads:
-            t.join()
-            result = t.result
-            ONOSFlows.append( result )
-
-        for i in range( len( ONOSFlows ) ):
-            num = str( main.activeNodes[ i ] + 1 )
-            if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
-                main.log.error( "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.info( "Flow count is consistent across all ONOS nodes" )
-        else:
-            consistentFlows = False
-        utilities.assert_equals(
-            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( len( ONOSFlows ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                try:
-                    main.log.warn(
-                        "ONOS" + node + " flows: " +
-                        json.dumps( json.loads( ONOSFlows[ i ] ), sort_keys=True,
-                                    indent=4, separators=( ',', ': ' ) ) )
-                except ( ValueError, TypeError ):
-                    main.log.warn( "ONOS" + node + " 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.Mininet1.getFlowTable( "s" + str( i ), version="1.3", debug=False ) )
-        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" )
-        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( "Collecting topology information from ONOS" )
-        devices = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].devices,
-                             name="devices-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            devices.append( t.result )
-        hosts = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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" )
-                main.log.warn( repr( t.result ) )
-                hosts.append( None )
-
-        ports = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].ports,
-                             name="ports-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            ports.append( t.result )
-        links = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].links,
-                             name="links-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            links.append( t.result )
-        clusters = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].clusters,
-                             name="clusters-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            clusters.append( t.result )
-        # Compare json objects for hosts and dataplane clusters
-
-        # hosts
-        main.step( "Host view is consistent across ONOS nodes" )
-        consistentHostsResult = main.TRUE
-        for controller in range( len( hosts ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if hosts[ controller ] and "Error" not in hosts[ controller ]:
-                if hosts[ controller ] == hosts[ 0 ]:
-                    continue
-                else:  # hosts not consistent
-                    main.log.error( "hosts from ONOS" +
-                                     controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    main.log.warn( repr( hosts[ controller ] ) )
-                    consistentHostsResult = main.FALSE
-
-            else:
-                main.log.error( "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" )
-
-        main.step( "Each host has an IP address" )
-        ipResult = main.TRUE
-        for controller in range( 0, len( hosts ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if hosts[ controller ]:
-                for host in hosts[ controller ]:
-                    if not host.get( 'ipAddresses', [] ):
-                        main.log.error( "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
-        main.step( "Cluster view is consistent across ONOS nodes" )
-        consistentClustersResult = main.TRUE
-        for controller in range( len( clusters ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if "Error" not in clusters[ controller ]:
-                if clusters[ controller ] == clusters[ 0 ]:
-                    continue
-                else:  # clusters not consistent
-                    main.log.error( "clusters from ONOS" + controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    consistentClustersResult = main.FALSE
-
-            else:
-                main.log.error( "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" )
-        if not consistentClustersResult:
-            main.log.debug( clusters )
-
-        # there should always only be one cluster
-        main.step( "Cluster view correct across ONOS nodes" )
-        try:
-            numClusters = len( json.loads( clusters[ 0 ] ) )
-        except ( ValueError, TypeError ):
-            main.log.exception( "Error parsing clusters[0]: " +
-                                repr( clusters[ 0 ] ) )
-            numClusters = "ERROR"
-        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
-        linksResults = main.TRUE
-        hostsResults = main.TRUE
-        mnSwitches = main.Mininet1.getSwitches()
-        mnLinks = main.Mininet1.getLinks()
-        mnHosts = main.Mininet1.getHosts()
-        for controller in main.activeNodes:
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if devices[ controller ] and ports[ controller ] and\
-                    "Error" not in devices[ controller ] and\
-                    "Error" not in ports[ controller ]:
-                currentDevicesResult = main.Mininet1.compareSwitches(
-                        mnSwitches,
-                        json.loads( devices[ controller ] ),
-                        json.loads( ports[ controller ] ) )
-            else:
-                currentDevicesResult = main.FALSE
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=currentDevicesResult,
-                                     onpass="ONOS" + controllerStr +
-                                     " Switches view is correct",
-                                     onfail="ONOS" + controllerStr +
-                                     " Switches view is incorrect" )
-            if links[ controller ] and "Error" not in links[ controller ]:
-                currentLinksResult = main.Mininet1.compareLinks(
-                        mnSwitches, mnLinks,
-                        json.loads( links[ controller ] ) )
-            else:
-                currentLinksResult = main.FALSE
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=currentLinksResult,
-                                     onpass="ONOS" + controllerStr +
-                                     " links view is correct",
-                                     onfail="ONOS" + controllerStr +
-                                     " links view is incorrect" )
-
-            if hosts[ controller ] and "Error" not in hosts[ controller ]:
-                currentHostsResult = main.Mininet1.compareHosts(
-                        mnHosts,
-                        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
-            linksResults = linksResults and currentLinksResult
-            hostsResults = hostsResults and currentHostsResult
-
-        main.step( "Device information is correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=devicesResults,
-            onpass="Device information is correct",
-            onfail="Device information is incorrect" )
-
-        main.step( "Links are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=linksResults,
-            onpass="Link are correct",
-            onfail="Links are incorrect" )
-
-        main.step( "Hosts are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=hostsResults,
-            onpass="Hosts are correct",
-            onfail="Hosts are incorrect" )
+        main.HA.readingState( main )
 
     def CASE61( self, main ):
         """
@@ -1891,284 +238,9 @@
         """
         Check state after ONOS failure
         """
-        import json
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-        try:
-            main.partition
-        except AttributeError:
-            main.partition = []
 
-        main.case( "Running ONOS Constant State Tests" )
+        main.HA.checkStateAfterONOS( main, afterWhich=0 )
 
-        main.step( "Check that each switch has a master" )
-        # Assert that each device has a master
-        rolesNotNull = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( "Read device roles from ONOS" )
-        ONOSMastership = []
-        mastershipCheck = main.FALSE
-        consistentMastership = True
-        rolesResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSMastership ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSMastership[ i ] or "Error" in ONOSMastership[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " roles" )
-                main.log.warn( "ONOS" + node + " 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.info(
-                "Switch roles are consistent across all ONOS nodes" )
-        else:
-            consistentMastership = False
-        utilities.assert_equals(
-            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( len( ONOSMastership ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                main.log.warn( "ONOS" + node + " roles: ",
-                               json.dumps( json.loads( ONOSMastership[ i ] ),
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-
-        # NOTE: we expect mastership to change on controller failure
-
-        main.step( "Get the intents and compare across all nodes" )
-        ONOSIntents = []
-        intentCheck = main.FALSE
-        consistentIntents = True
-        intentsResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSIntents ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " intents" )
-                main.log.warn( "ONOS" + node + " 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.info( "Intents are consistent across all ONOS " +
-                             "nodes" )
-        else:
-            consistentIntents = False
-
-        # Try to make it easy to figure out what is happening
-        #
-        # Intent      ONOS1      ONOS2    ...
-        #  0x01     INSTALLED  INSTALLING
-        #  ...        ...         ...
-        #  ...        ...         ...
-        title = "   ID"
-        for n in main.activeNodes:
-            title += " " * 10 + "ONOS" + str( n + 1 )
-        main.log.warn( title )
-        # get all intent keys in the cluster
-        keys = []
-        for nodeStr in ONOSIntents:
-            node = json.loads( nodeStr )
-            for intent in node:
-                keys.append( intent.get( 'id' ) )
-        keys = set( keys )
-        for key in keys:
-            row = "%-13s" % key
-            for nodeStr in ONOSIntents:
-                node = json.loads( nodeStr )
-                for intent in node:
-                    if intent.get( 'id' ) == key:
-                        row += "%-15s" % intent.get( 'state' )
-            main.log.warn( row )
-        # End table view
-
-        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' ] )
-            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( len( main.activeNodes ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                main.log.warn( "ONOS" + node + " 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?
-        sameIntents = main.FALSE
-        try:
-            intentState
-        except NameError:
-            main.log.warn( "No previous intent state was saved" )
-        else:
-            if intentState and intentState == ONOSIntents[ 0 ]:
-                sameIntents = main.TRUE
-                main.log.info( "Intents are consistent with before failure" )
-            # TODO: possibly the states have changed? we may need to figure out
-            #       what the acceptable states are
-            elif len( intentState ) == len( ONOSIntents[ 0 ] ):
-                sameIntents = main.TRUE
-                try:
-                    before = json.loads( intentState )
-                    after = json.loads( ONOSIntents[ 0 ] )
-                    for intent in before:
-                        if intent not in after:
-                            sameIntents = main.FALSE
-                            main.log.debug( "Intent is not currently in ONOS " +
-                                            "(at least in the same form):" )
-                            main.log.debug( json.dumps( intent ) )
-                except ( ValueError, TypeError ):
-                    main.log.exception( "Exception printing intents" )
-                    main.log.debug( repr( ONOSIntents[ 0 ] ) )
-                    main.log.debug( repr( intentState ) )
-            if sameIntents == main.FALSE:
-                try:
-                    main.log.debug( "ONOS intents before: " )
-                    main.log.debug( json.dumps( json.loads( intentState ),
-                                                sort_keys=True, indent=4,
-                                                separators=( ',', ': ' ) ) )
-                    main.log.debug( "Current ONOS intents: " )
-                    main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
-                                                sort_keys=True, indent=4,
-                                                separators=( ',', ': ' ) ) )
-                except ( ValueError, TypeError ):
-                    main.log.exception( "Exception printing intents" )
-                    main.log.debug( repr( ONOSIntents[ 0 ] ) )
-                    main.log.debug( repr( intentState ) )
-            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
-        for i in range( 28 ):
-            main.log.info( "Checking flow table on s" + str( i + 1 ) )
-            tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
-            curSwitch = main.Mininet1.flowTableComp( flows[ i ], tmpFlows )
-            FlowTables = FlowTables and curSwitch
-            if curSwitch == main.FALSE:
-                main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
-        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.Mininet2.pingLongKill()
-        """
-        main.step( "Check the continuous pings to ensure that no packets " +
-                   "were dropped during component failure" )
-        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.info( "No loss of dataplane connectivity" )
-        utilities.assert_equals(
-            expect=main.FALSE,
-            actual=LossInPings,
-            onpass="No Loss of connectivity",
-            onfail="Loss of dataplane connectivity detected" )
-        """
         main.step( "Leadership Election is still functional" )
         # Test of LeadershipElection
         leaderList = []
@@ -2213,680 +285,45 @@
         """
         Compare topo
         """
-        import json
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        main.case( "Compare ONOS Topology view to Mininet topology" )
-        main.caseExplanation = "Compare topology objects between Mininet" +\
-                                " and ONOS"
-        topoResult = main.FALSE
-        topoFailMsg = "ONOS topology don't match Mininet"
-        elapsed = 0
-        count = 0
-        main.step( "Comparing ONOS topology to MN topology" )
-        startTime = time.time()
-        # Give time for Gossip to work
-        while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
-            devicesResults = main.TRUE
-            linksResults = main.TRUE
-            hostsResults = main.TRUE
-            hostAttachmentResults = True
-            count += 1
-            cliStart = time.time()
-            devices = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="devices-" + str( i ),
-                                 args=[ main.CLIs[ i ].devices, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                devices.append( t.result )
-            hosts = []
-            ipResult = main.TRUE
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="hosts-" + str( i ),
-                                 args=[ main.CLIs[ i ].hosts, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                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 ) )
-                    hosts.append( None )
-            for controller in range( 0, len( hosts ) ):
-                controllerStr = str( main.activeNodes[ controller ] + 1 )
-                if hosts[ controller ]:
-                    for host in hosts[ controller ]:
-                        if host is None or host.get( 'ipAddresses', [] ) == []:
-                            main.log.error(
-                                "Error with host ipAddresses on controller" +
-                                controllerStr + ": " + str( host ) )
-                            ipResult = main.FALSE
-            ports = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="ports-" + str( i ),
-                                 args=[ main.CLIs[ i ].ports, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                ports.append( t.result )
-            links = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="links-" + str( i ),
-                                 args=[ main.CLIs[ i ].links, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                links.append( t.result )
-            clusters = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="clusters-" + str( i ),
-                                 args=[ main.CLIs[ i ].clusters, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                clusters.append( t.result )
-
-            elapsed = time.time() - startTime
-            cliTime = time.time() - cliStart
-            print "Elapsed time: " + str( elapsed )
-            print "CLI time: " + str( cliTime )
-
-            if all( e is None for e in devices ) and\
-               all( e is None for e in hosts ) and\
-               all( e is None for e in ports ) and\
-               all( e is None for e in links ) and\
-               all( e is None for e in clusters ):
-                topoFailMsg = "Could not get topology from ONOS"
-                main.log.error( topoFailMsg )
-                continue  # Try again, No use trying to compare
-
-            mnSwitches = main.Mininet1.getSwitches()
-            mnLinks = main.Mininet1.getLinks()
-            mnHosts = main.Mininet1.getHosts()
-            for controller in range( len( main.activeNodes ) ):
-                controllerStr = str( main.activeNodes[ controller ] + 1 )
-                if devices[ controller ] and ports[ controller ] and\
-                        "Error" not in devices[ controller ] and\
-                        "Error" not in ports[ controller ]:
-
-                    try:
-                        currentDevicesResult = main.Mininet1.compareSwitches(
-                                mnSwitches,
-                                json.loads( devices[ controller ] ),
-                                json.loads( ports[ controller ] ) )
-                    except ( TypeError, ValueError ) as e:
-                        main.log.exception( "Object not as expected; devices={!r}\nports={!r}".format(
-                            devices[ controller ], ports[ controller ] ) )
-                else:
-                    currentDevicesResult = main.FALSE
-                utilities.assert_equals( expect=main.TRUE,
-                                         actual=currentDevicesResult,
-                                         onpass="ONOS" + controllerStr +
-                                         " Switches view is correct",
-                                         onfail="ONOS" + controllerStr +
-                                         " Switches view is incorrect" )
-
-                if links[ controller ] and "Error" not in links[ controller ]:
-                    currentLinksResult = main.Mininet1.compareLinks(
-                            mnSwitches, mnLinks,
-                            json.loads( links[ controller ] ) )
-                else:
-                    currentLinksResult = main.FALSE
-                utilities.assert_equals( expect=main.TRUE,
-                                         actual=currentLinksResult,
-                                         onpass="ONOS" + controllerStr +
-                                         " links view is correct",
-                                         onfail="ONOS" + controllerStr +
-                                         " links view is incorrect" )
-                if hosts[ controller ] and "Error" not in hosts[ controller ]:
-                    currentHostsResult = main.Mininet1.compareHosts(
-                            mnHosts,
-                            hosts[ controller ] )
-                elif hosts[ controller ] == []:
-                    currentHostsResult = main.TRUE
-                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" )
-                # CHECKING HOST ATTACHMENT POINTS
-                hostAttachment = True
-                zeroHosts = False
-                # FIXME: topo-HA/obelisk specific mappings:
-                # key is mac and value is dpid
-                mappings = {}
-                for i in range( 1, 29 ):  # hosts 1 through 28
-                    # set up correct variables:
-                    macId = "00:" * 5 + hex( i ).split( "0x" )[ 1 ].upper().zfill( 2 )
-                    if i == 1:
-                        deviceId = "1000".zfill( 16 )
-                    elif i == 2:
-                        deviceId = "2000".zfill( 16 )
-                    elif i == 3:
-                        deviceId = "3000".zfill( 16 )
-                    elif i == 4:
-                        deviceId = "3004".zfill( 16 )
-                    elif i == 5:
-                        deviceId = "5000".zfill( 16 )
-                    elif i == 6:
-                        deviceId = "6000".zfill( 16 )
-                    elif i == 7:
-                        deviceId = "6007".zfill( 16 )
-                    elif i >= 8 and i <= 17:
-                        dpid = '3' + str( i ).zfill( 3 )
-                        deviceId = dpid.zfill( 16 )
-                    elif i >= 18 and i <= 27:
-                        dpid = '6' + str( i ).zfill( 3 )
-                        deviceId = dpid.zfill( 16 )
-                    elif i == 28:
-                        deviceId = "2800".zfill( 16 )
-                    mappings[ macId ] = deviceId
-                if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
-                    if hosts[ controller ] == []:
-                        main.log.warn( "There are no hosts discovered" )
-                        zeroHosts = True
-                    else:
-                        for host in hosts[ controller ]:
-                            mac = None
-                            location = None
-                            device = None
-                            port = None
-                            try:
-                                mac = host.get( 'mac' )
-                                assert mac, "mac field could not be found for this host object"
-
-                                location = host.get( 'locations' )[ 0 ]
-                                assert location, "location field could not be found for this host object"
-
-                                # Trim the protocol identifier off deviceId
-                                device = str( location.get( 'elementId' ) ).split( ':' )[ 1 ]
-                                assert device, "elementId field could not be found for this host location object"
-
-                                port = location.get( 'port' )
-                                assert port, "port field could not be found for this host location object"
-
-                                # Now check if this matches where they should be
-                                if mac and device and port:
-                                    if str( port ) != "1":
-                                        main.log.error( "The attachment port is incorrect for " +
-                                                        "host " + str( mac ) +
-                                                        ". Expected: 1 Actual: " + str( port ) )
-                                        hostAttachment = False
-                                    if device != mappings[ str( mac ) ]:
-                                        main.log.error( "The attachment device is incorrect for " +
-                                                        "host " + str( mac ) +
-                                                        ". Expected: " + mappings[ str( mac ) ] +
-                                                        " Actual: " + device )
-                                        hostAttachment = False
-                                else:
-                                    hostAttachment = False
-                            except AssertionError:
-                                main.log.exception( "Json object not as expected" )
-                                main.log.error( repr( host ) )
-                                hostAttachment = False
-                else:
-                    main.log.error( "No hosts json output or \"Error\"" +
-                                    " in output. hosts = " +
-                                    repr( hosts[ controller ] ) )
-                if zeroHosts is False:
-                    hostAttachment = True
-
-                # END CHECKING HOST ATTACHMENT POINTS
-                devicesResults = devicesResults and currentDevicesResult
-                linksResults = linksResults and currentLinksResult
-                hostsResults = hostsResults and currentHostsResult
-                hostAttachmentResults = hostAttachmentResults and\
-                                        hostAttachment
-                topoResult = ( devicesResults and linksResults
-                               and hostsResults and ipResult and
-                               hostAttachmentResults )
-        utilities.assert_equals( expect=True,
-                                 actual=topoResult,
-                                 onpass="ONOS topology matches Mininet",
-                                 onfail=topoFailMsg )
-        # End of While loop to pull ONOS state
-
-        # Compare json objects for hosts and dataplane clusters
-
-        # hosts
-        main.step( "Hosts view is consistent across all ONOS nodes" )
-        consistentHostsResult = main.TRUE
-        for controller in range( len( hosts ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
-                if hosts[ controller ] == hosts[ 0 ]:
-                    continue
-                else:  # hosts not consistent
-                    main.log.error( "hosts from ONOS" + controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    main.log.warn( repr( hosts[ controller ] ) )
-                    consistentHostsResult = main.FALSE
-
-            else:
-                main.log.error( "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" )
-
-        main.step( "Hosts information is correct" )
-        hostsResults = hostsResults and ipResult
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=hostsResults,
-            onpass="Host information is correct",
-            onfail="Host information is incorrect" )
-
-        main.step( "Host attachment points to the network" )
-        utilities.assert_equals(
-            expect=True,
-            actual=hostAttachmentResults,
-            onpass="Hosts are correctly attached to the network",
-            onfail="ONOS did not correctly attach hosts to the network" )
-
-        # Strongly connected clusters of devices
-        main.step( "Clusters view is consistent across all ONOS nodes" )
-        consistentClustersResult = main.TRUE
-        for controller in range( len( clusters ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if "Error" not in clusters[ controller ]:
-                if clusters[ controller ] == clusters[ 0 ]:
-                    continue
-                else:  # clusters not consistent
-                    main.log.error( "clusters from ONOS" +
-                                     controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    consistentClustersResult = main.FALSE
-            else:
-                main.log.error( "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" )
-        if not consistentClustersResult:
-            main.log.debug( clusters )
-
-        main.step( "There is only one SCC" )
-        # there should always only be one cluster
-        try:
-            numClusters = len( json.loads( clusters[ 0 ] ) )
-        except ( ValueError, TypeError ):
-            main.log.exception( "Error parsing clusters[0]: " +
-                                repr( clusters[ 0 ] ) )
-            numClusters = "ERROR"
-        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 linksResults
-                       and hostsResults and consistentHostsResult
-                       and consistentClustersResult and clusterResults
-                       and ipResult and hostAttachmentResults )
-
-        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" )
-
-        main.step( "Device information is correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=devicesResults,
-            onpass="Device information is correct",
-            onfail="Device information is incorrect" )
-
-        main.step( "Links are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=linksResults,
-            onpass="Link are correct",
-            onfail="Links are incorrect" )
-
-        main.step( "Hosts are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=hostsResults,
-            onpass="Hosts are correct",
-            onfail="Hosts are incorrect" )
-
-        # FIXME: move this to an ONOS state case
-        main.step( "Checking ONOS nodes" )
-        nodeResults = utilities.retry( main.HA.nodesCheck,
-                                       False,
-                                       args=[ main.activeNodes ],
-                                       attempts=5 )
-
-        utilities.assert_equals( expect=True, actual=nodeResults,
-                                 onpass="Nodes check successful",
-                                 onfail="Nodes check NOT successful" )
-        if not nodeResults:
-            for i in main.activeNodes:
-                main.log.debug( "{} components not ACTIVE: \n{}".format(
-                    main.CLIs[ i ].name,
-                    main.CLIs[ i ].sendline( "scr:list | grep -v ACTIVE" ) ) )
-
-        if not topoResult:
-            main.cleanup()
-            main.exit()
+        main.HA.compareTopo( main )
 
     def CASE9( self, main ):
         """
         Link s3-s28 down
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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"
-        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 successful",
-                                 onfail="Failed to bring link down" )
-        # TODO do some sort of check here
+        main.HA.linkDown( main )
 
     def CASE10( self, main ):
         """
         Link s3-s28 up
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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"
-        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 successful",
-                                 onfail="Failed to bring link up" )
-        # TODO do some sort of check here
+        main.HA.linkUp( main )
 
     def CASE11( self, main ):
         """
         Switch Down
         """
         # NOTE: You should probably run a topology check after this
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
-
-        description = "Killing a switch to ensure it is discovered correctly"
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        main.case( description )
-        switch = main.params[ 'kill' ][ 'switch' ]
-        switchDPID = main.params[ 'kill' ][ 'dpid' ]
-
-        # TODO: Make this switch parameterizable
-        main.step( "Kill " + switch )
-        main.log.info( "Deleting " + switch )
-        main.Mininet1.delSwitch( switch )
-        main.log.info( "Waiting " + str( switchSleep ) +
-                       " seconds for switch down to be discovered" )
-        time.sleep( switchSleep )
-        device = onosCli.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 successful",
-                                 onfail="Failed to kill switch?" )
+        main.HA.switchDown( main )
 
     def CASE12( self, main ):
         """
         Switch Up
         """
         # NOTE: You should probably run a topology check after this
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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' ]
-        switchDPID = main.params[ 'kill' ][ 'dpid' ]
-        links = main.params[ 'kill' ][ 'links' ].split()
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        description = "Adding a switch to ensure it is discovered correctly"
-        main.case( description )
-
-        main.step( "Add back " + switch )
-        main.Mininet1.addSwitch( switch, dpid=switchDPID )
-        for peer in links:
-            main.Mininet1.addLink( switch, peer )
-        ipList = [ node.ip_address for node in main.nodes ]
-        main.Mininet1.assignSwController( sw=switch, ip=ipList )
-        main.log.info( "Waiting " + str( switchSleep ) +
-                       " seconds for switch up to be discovered" )
-        time.sleep( switchSleep )
-        device = onosCli.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 successful",
-                                 onfail="Failed to add switch?" )
+        main.HA.switchUp( main )
 
     def CASE13( self, main ):
         """
         Clean up
         """
-        import os
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        # printing colors to terminal
-        colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
-                   'blue': '\033[94m', 'green': '\033[92m',
-                   'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
-        main.case( "Test Cleanup" )
-        main.step( "Killing tcpdumps" )
-        main.Mininet2.stopTcpdump()
-
-        testname = main.TEST
-        if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
-            main.step( "Copying MN pcap and ONOS log files to test station" )
-            teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
-            teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
-            # NOTE: MN Pcap file is being saved to logdir.
-            #       We scp this file as MN and TestON aren't necessarily the same vm
-
-            # FIXME: To be replaced with a Jenkin's post script
-            # TODO: Load these from params
-            # NOTE: must end in /
-            logFolder = "/opt/onos/log/"
-            logFiles = [ "karaf.log", "karaf.log.1" ]
-            # NOTE: must end in /
-            for f in logFiles:
-                for node in main.nodes:
-                    dstName = main.logdir + "/" + node.name + "-" + f
-                    main.ONOSbench.secureCopy( node.user_name, node.ip_address,
-                                               logFolder + f, dstName )
-            # std*.log's
-            # NOTE: must end in /
-            logFolder = "/opt/onos/var/"
-            logFiles = [ "stderr.log", "stdout.log" ]
-            # NOTE: must end in /
-            for f in logFiles:
-                for node in main.nodes:
-                    dstName = main.logdir + "/" + node.name + "-" + f
-                    main.ONOSbench.secureCopy( node.user_name, node.ip_address,
-                                               logFolder + f, dstName )
-        else:
-            main.log.debug( "skipping saving log files" )
-
-        main.step( "Stopping Mininet" )
-        mnResult = main.Mininet1.stopNet()
-        utilities.assert_equals( expect=main.TRUE, actual=mnResult,
-                                 onpass="Mininet stopped",
-                                 onfail="MN cleanup NOT successful" )
-
-        main.step( "Checking ONOS Logs for errors" )
-        for node in main.nodes:
-            main.log.debug( "Checking logs for errors on " + node.name + ":" )
-            main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
-
-        try:
-            timerLog = open( main.logdir + "/Timers.csv", 'w' )
-            # Overwrite with empty line and close
-            labels = "Gossip Intents"
-            data = str( gossipTime )
-            timerLog.write( labels + "\n" + data )
-            timerLog.close()
-        except NameError as e:
-            main.log.exception( e )
+        main.HA.cleanUp( main )
 
     def CASE14( self, main ):
         """
         start election app on all onos nodes
         """
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        main.case( "Start Leadership Election app" )
-        main.step( "Install leadership election app" )
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        appResult = onosCli.activateApp( "org.onosproject.election" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=appResult,
-            onpass="Election app installed",
-            onfail="Something went wrong with installing Leadership election" )
-
-        main.step( "Run for election on each node" )
-        for i in main.activeNodes:
-            main.CLIs[ i ].electionTestRun()
-        time.sleep( 5 )
-        activeCLIs = [ main.CLIs[ i ] for i in main.activeNodes ]
-        sameResult, leaders = main.HA.consistentLeaderboards( activeCLIs )
-        utilities.assert_equals(
-            expect=True,
-            actual=sameResult,
-            onpass="All nodes see the same leaderboards",
-            onfail="Inconsistent leaderboards" )
-
-        if sameResult:
-            leader = leaders[ 0 ][ 0 ]
-            if main.nodes[ main.activeNodes[ 0 ] ].ip_address in leader:
-                correctLeader = True
-            else:
-                correctLeader = False
-            main.step( "First node was elected leader" )
-            utilities.assert_equals(
-                expect=True,
-                actual=correctLeader,
-                onpass="Correct leader was elected",
-                onfail="Incorrect leader" )
+        main.HA.startElectionApp( main )
 
     def CASE15( self, main ):
         """
@@ -2903,196 +340,16 @@
             old and new variable prefixes refer to data from before vs after
                 withdrawl and later before withdrawl vs after re-election
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        description = "Check that Leadership Election is still functional"
-        main.case( description )
-        # NOTE: Need to re-run after restarts since being a canidate is not persistant
-
-        oldLeaders = []  # list of lists of each nodes' candidates before
-        newLeaders = []  # list of lists of each nodes' candidates after
-        oldLeader = ''  # the old leader from oldLeaders, None if not same
-        newLeader = ''  # the new leaders fron newLoeaders, None if not same
-        oldLeaderCLI = None  # the CLI of the old leader used for re-electing
-        expectNoLeader = False  # True when there is only one leader
-        if main.numCtrls == 1:
-            expectNoLeader = True
-
-        main.step( "Run for election on each node" )
-        electionResult = main.TRUE
-
-        for i in main.activeNodes:  # run test election on each node
-            if main.CLIs[ i ].electionTestRun() == main.FALSE:
-                electionResult = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=electionResult,
-            onpass="All nodes successfully ran for leadership",
-            onfail="At least one node failed to run for leadership" )
-
-        if electionResult == main.FALSE:
-            main.log.error(
-                "Skipping Test Case because Election Test App isn't loaded" )
-            main.skipCase()
-
-        main.step( "Check that each node shows the same leader and candidates" )
-        failMessage = "Nodes have different leaderboards"
-        activeCLIs = [ main.CLIs[ i ] for i in main.activeNodes ]
-        sameResult, oldLeaders = main.HA.consistentLeaderboards( activeCLIs )
-        if sameResult:
-            oldLeader = oldLeaders[ 0 ][ 0 ]
-            main.log.warn( oldLeader )
-        else:
-            oldLeader = None
-        utilities.assert_equals(
-            expect=True,
-            actual=sameResult,
-            onpass="Leaderboards are consistent for the election topic",
-            onfail=failMessage )
-
-        main.step( "Find current leader and withdraw" )
-        withdrawResult = main.TRUE
-        # do some sanity checking on leader before using it
-        if oldLeader is None:
-            main.log.error( "Leadership isn't consistent." )
-            withdrawResult = main.FALSE
-        # Get the CLI of the oldLeader
-        for i in main.activeNodes:
-            if oldLeader == main.nodes[ i ].ip_address:
-                oldLeaderCLI = main.CLIs[ i ]
-                break
-        else:  # FOR/ELSE statement
-            main.log.error( "Leader election, could not find current leader" )
-        if oldLeader:
-            withdrawResult = oldLeaderCLI.electionTestWithdraw()
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=withdrawResult,
-            onpass="Node was withdrawn from election",
-            onfail="Node was not withdrawn from election" )
-
-        main.step( "Check that a new node was elected leader" )
-        failMessage = "Nodes have different leaders"
-        # Get new leaders and candidates
-        newLeaderResult, newLeaders = main.HA.consistentLeaderboards( activeCLIs )
-        newLeader = None
-        if newLeaderResult:
-            if newLeaders[ 0 ][ 0 ] == 'none':
-                main.log.error( "No leader was elected on at least 1 node" )
-                if not expectNoLeader:
-                    newLeaderResult = False
-            newLeader = newLeaders[ 0 ][ 0 ]
-
-        # Check that the new leader is not the older leader, which was withdrawn
-        if newLeader == oldLeader:
-            newLeaderResult = False
-            main.log.error( "All nodes still see old leader: " + str( oldLeader ) +
-                            " as the current leader" )
-        utilities.assert_equals(
-            expect=True,
-            actual=newLeaderResult,
-            onpass="Leadership election passed",
-            onfail="Something went wrong with Leadership election" )
-
-        main.step( "Check that that new leader was the candidate of old leader" )
-        # candidates[ 2 ] should become the top candidate after withdrawl
-        correctCandidateResult = main.TRUE
-        if expectNoLeader:
-            if newLeader == 'none':
-                main.log.info( "No leader expected. None found. Pass" )
-                correctCandidateResult = main.TRUE
-            else:
-                main.log.info( "Expected no leader, got: " + str( newLeader ) )
-                correctCandidateResult = main.FALSE
-        elif len( oldLeaders[ 0 ] ) >= 3:
-            if newLeader == oldLeaders[ 0 ][ 2 ]:
-                # correct leader was elected
-                correctCandidateResult = main.TRUE
-            else:
-                correctCandidateResult = main.FALSE
-                main.log.error( "Candidate {} was elected. {} should have had priority.".format(
-                                    newLeader, oldLeaders[ 0 ][ 2 ] ) )
-        else:
-            main.log.warn( "Could not determine who should be the correct leader" )
-            main.log.debug( oldLeaders[ 0 ] )
-            correctCandidateResult = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=correctCandidateResult,
-            onpass="Correct Candidate Elected",
-            onfail="Incorrect Candidate Elected" )
-
-        main.step( "Run for election on old leader( just so everyone " +
-                   "is in the hat )" )
-        if oldLeaderCLI is not None:
-            runResult = oldLeaderCLI.electionTestRun()
-        else:
-            main.log.error( "No old leader to re-elect" )
-            runResult = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=runResult,
-            onpass="App re-ran for election",
-            onfail="App failed to run for election" )
-
-        main.step(
-            "Check that oldLeader is a candidate, and leader if only 1 node" )
-        # verify leader didn't just change
-        # Get new leaders and candidates
-        reRunLeaders = []
-        time.sleep( 5 )  # Paremterize
-        positionResult, reRunLeaders = main.HA.consistentLeaderboards( activeCLIs )
-
-        # Check that the re-elected node is last on the candidate List
-        if not reRunLeaders[ 0 ]:
-            positionResult = main.FALSE
-        elif oldLeader != reRunLeaders[ 0 ][ -1 ]:
-            main.log.error( "Old Leader ({}) not in the proper position: {} ".format( str( oldLeader ),
-                                                                                      str( reRunLeaders[ 0 ] ) ) )
-            positionResult = main.FALSE
-        utilities.assert_equals(
-            expect=True,
-            actual=positionResult,
-            onpass="Old leader successfully re-ran for election",
-            onfail="Something went wrong with Leadership election after " +
-                   "the old leader re-ran for election" )
+        main.HA.isElectionFunctional( main )
 
     def CASE16( self, main ):
         """
         Install Distributed Primitives app
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        # Variables for the distributed primitives tests
-        main.pCounterName = "TestON-Partitions"
-        main.pCounterValue = 0
-        main.onosSet = set( [] )
-        main.onosSetName = "TestON-set"
-
-        description = "Install Primitives app"
-        main.case( description )
-        main.step( "Install Primitives app" )
-        appName = "org.onosproject.distributedprimitives"
-        node = main.activeNodes[ 0 ]
-        appResults = main.CLIs[ node ].activateApp( appName )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=appResults,
-                                 onpass="Primitives app activated",
-                                 onfail="Primitives app not activated" )
-        time.sleep( 5 )  # To allow all nodes to activate
+        main.HA.installDistributedPrimitiveApp( main )
 
     def CASE17( self, main ):
         """
         Check for basic functionality with distributed primitives
         """
-        main.HA.CASE17( main )
+        main.HA.checkDistPrimitivesFunc( main )
diff --git a/TestON/tests/HA/HAkillNodes/HAkillNodes.params b/TestON/tests/HA/HAkillNodes/HAkillNodes.params
index 024b1c0..ebffe50 100644
--- a/TestON/tests/HA/HAkillNodes/HAkillNodes.params
+++ b/TestON/tests/HA/HAkillNodes/HAkillNodes.params
@@ -35,8 +35,10 @@
         <cellName>HA</cellName>
         <appString>drivers,openflow,proxyarp,mobility</appString>
     </ENV>
-    <Git> False </Git>
-    <branch> master </branch>
+    <GIT>
+        <pull>False</pull>
+        <branch>master</branch>
+    </GIT>
     <num_controllers> 7 </num_controllers>
     <tcpdump> False </tcpdump>
 
diff --git a/TestON/tests/HA/HAkillNodes/HAkillNodes.py b/TestON/tests/HA/HAkillNodes/HAkillNodes.py
index 4ef7001..b011fce 100644
--- a/TestON/tests/HA/HAkillNodes/HAkillNodes.py
+++ b/TestON/tests/HA/HAkillNodes/HAkillNodes.py
@@ -52,114 +52,33 @@
         import json
         main.log.info( "ONOS HA test: Restart a minority of ONOS nodes - " +
                          "initialization" )
-        main.case( "Setting up test environment" )
-        main.caseExplanation = "Setup the test environment including " +\
-                                "installing ONOS, starting Mininet and ONOS" +\
-                                "cli sessions."
-
-        # load some variables from the params file
-        PULLCODE = False
-        if main.params[ 'Git' ] == 'True':
-            PULLCODE = True
-        gitBranch = main.params[ 'branch' ]
-        cellName = main.params[ 'ENV' ][ 'cellName' ]
-
-        main.numCtrls = int( main.params[ 'num_controllers' ] )
-        if main.ONOSbench.maxNodes:
-            if main.ONOSbench.maxNodes < main.numCtrls:
-                main.numCtrls = int( main.ONOSbench.maxNodes )
-        # set global variables
-        global ONOS1Port
-        global ONOS2Port
-        global ONOS3Port
-        global ONOS4Port
-        global ONOS5Port
-        global ONOS6Port
-        global ONOS7Port
+                # set global variables
         # These are for csv plotting in jenkins
-        global labels
-        global data
-        labels = []
-        data = []
-
-        # 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' ]
-
+        main.HAlabels = []
+        main.HAdata = []
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        main.testSetUp.envSetupDescription()
         try:
             from tests.HA.dependencies.HA import HA
             main.HA = HA()
+            # load some variables from the params file
+            cellName = main.params[ 'ENV' ][ 'cellName' ]
+            main.apps = main.params[ 'ENV' ][ 'appString' ]
+            main.numCtrls = int( main.params[ 'num_controllers' ] )
+            if main.ONOSbench.maxNodes and\
+                        main.ONOSbench.maxNodes < main.numCtrls:
+                main.numCtrls = int( main.ONOSbench.maxNodes )
+            main.maxNodes = main.numCtrls
+            stepResult = main.testSetUp.envSetup( hasNode=True )
         except Exception as e:
-            main.log.exception( e )
-            main.cleanup()
-            main.exit()
-
-        main.CLIs = []
-        main.nodes = []
-        ipList = []
-        for i in range( 1, main.numCtrls + 1 ):
-            try:
-                main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
-                main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
-                ipList.append( main.nodes[ -1 ].ip_address )
-            except AttributeError:
-                break
-
-        main.step( "Create cell file" )
-        cellAppString = main.params[ 'ENV' ][ 'appString' ]
-        main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
-                                       main.Mininet1.ip_address,
-                                       cellAppString, ipList, main.ONOScli1.karafUser )
-        main.step( "Applying cell variable to environment" )
-        cellResult = main.ONOSbench.setCell( cellName )
-        verifyResult = main.ONOSbench.verifyCell()
-
-        # FIXME:this is short term fix
-        main.log.info( "Removing raft logs" )
-        main.ONOSbench.onosRemoveRaftLogs()
-
-        main.log.info( "Uninstalling ONOS" )
-        for node in main.nodes:
-            main.ONOSbench.onosUninstall( node.ip_address )
-
-        # Make sure ONOS is DEAD
-        main.log.info( "Killing any ONOS processes" )
-        killResults = main.TRUE
-        for node in main.nodes:
-            killed = main.ONOSbench.onosKill( node.ip_address )
-            killResults = killResults and killed
-
-        gitPullResult = main.TRUE
-
-        main.step( "Starting Mininet" )
-        # scp topo file to mininet
-        # TODO: move to params?
-        topoName = "obelisk.py"
-        filePath = main.ONOSbench.home + "/tools/test/topos/"
-        main.ONOSbench.scp( main.Mininet1,
-                            filePath + topoName,
-                            main.Mininet1.home,
-                            direction="to" )
-        mnResult = main.Mininet1.startNet()
-        utilities.assert_equals( expect=main.TRUE, actual=mnResult,
-                                 onpass="Mininet Started",
-                                 onfail="Error starting Mininet" )
-
-        main.step( "Git checkout and pull " + gitBranch )
-        if PULLCODE:
-            main.ONOSbench.gitCheckout( gitBranch )
-            gitPullResult = main.ONOSbench.gitPull()
-            # values of 1 or 3 are good
-            utilities.assert_lesser( expect=0, actual=gitPullResult,
-                                      onpass="Git pull successful",
-                                      onfail="Git pull failed" )
-        main.ONOSbench.getVersion( report=True )
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
+        main.HA.generateGraph( "HAkillNodes" )
 
         main.step( "Make sure ONOS service doesn't automatically respawn" )
         handle = main.ONOSbench.handle
@@ -169,1628 +88,41 @@
         handle.expect( "\$" )  # $ from the command
         handle.expect( "\$" )  # $ from the prompt
 
-        # GRAPHS
-        # NOTE: important params here:
-        #       job = name of Jenkins job
-        #       Plot Name = Plot-HA, only can be used if multiple plots
-        #       index = The number of the graph under plot name
-        job = "HAkillNodes"
-        plotName = "Plot-HA"
-        index = "2"
-        graphs = '<ac:structured-macro ac:name="html">\n'
-        graphs += '<ac:plain-text-body><![CDATA[\n'
-        graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
-                  '/plot/' + plotName + '/getPlot?index=' + index +\
-                  '&width=500&height=300"' +\
-                  'noborder="0" width="500" height="300" scrolling="yes" ' +\
-                  'seamless="seamless"></iframe>\n'
-        graphs += ']]></ac:plain-text-body>\n'
-        graphs += '</ac:structured-macro>\n'
-        main.log.wiki( graphs )
+        main.testSetUp.ONOSSetUp( main.Mininet1, cellName=cellName, removeLog=True,
+                                 extraApply=main.HA.customizeOnosGenPartitions,
+                                 extraClean=main.HA.cleanUpGenPartition )
 
-        main.step( "Creating ONOS package" )
-        # copy gen-partions file to ONOS
-        # NOTE: this assumes TestON and ONOS are on the same machine
-        srcFile = main.testDir + "/HA/dependencies/onos-gen-partitions"
-        dstDir = main.ONOSbench.home + "/tools/test/bin/onos-gen-partitions"
-        cpResult = main.ONOSbench.secureCopy( main.ONOSbench.user_name,
-                                              main.ONOSbench.ip_address,
-                                              srcFile,
-                                              dstDir,
-                                              pwd=main.ONOSbench.pwd,
-                                              direction="from" )
-        packageResult = main.ONOSbench.buckBuild()
-        utilities.assert_equals( expect=main.TRUE, actual=packageResult,
-                                 onpass="ONOS package successful",
-                                 onfail="ONOS package failed" )
-
-        main.step( "Installing ONOS package" )
-        onosInstallResult = main.TRUE
-        for node in main.nodes:
-            tmpResult = main.ONOSbench.onosInstall( options="-f",
-                                                    node=node.ip_address )
-            onosInstallResult = onosInstallResult and tmpResult
-        utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
-                                 onpass="ONOS install successful",
-                                 onfail="ONOS install failed" )
-        # clean up gen-partitions file
-        try:
-            main.ONOSbench.handle.sendline( "cd " + main.ONOSbench.home )
-            main.ONOSbench.handle.expect( main.ONOSbench.home + "\$" )
-            main.ONOSbench.handle.sendline( "git checkout -- tools/test/bin/onos-gen-partitions" )
-            main.ONOSbench.handle.expect( main.ONOSbench.home + "\$" )
-            main.log.info( " Cleaning custom gen partitions file, response was: \n" +
-                           str( main.ONOSbench.handle.before ) )
-        except ( pexpect.TIMEOUT, pexpect.EOF ):
-            main.log.exception( "ONOSbench: pexpect exception found:" +
-                                main.ONOSbench.handle.before )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.TRUE
-        for node in main.nodes:
-            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=node.ip_address )
-        utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        main.step( "Checking if ONOS is up yet" )
-        for i in range( 2 ):
-            onosIsupResult = main.TRUE
-            for node in main.nodes:
-                started = main.ONOSbench.isup( node.ip_address )
-                if not started:
-                    main.log.error( node.name + " hasn't started" )
-                onosIsupResult = onosIsupResult and started
-            if onosIsupResult == main.TRUE:
-                break
-        utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
-                                 onpass="ONOS startup successful",
-                                 onfail="ONOS startup failed" )
-
-        main.step( "Starting ONOS CLI sessions" )
-        cliResults = main.TRUE
-        threads = []
-        for i in range( main.numCtrls ):
-            t = main.Thread( target=main.CLIs[ i ].startOnosCli,
-                             name="startOnosCli-" + str( i ),
-                             args=[ main.nodes[ i ].ip_address ] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            cliResults = cliResults and t.result
-        utilities.assert_equals( expect=main.TRUE, actual=cliResults,
-                                 onpass="ONOS cli startup successful",
-                                 onfail="ONOS cli startup failed" )
-
-        # Create a list of active nodes for use when some nodes are stopped
-        main.activeNodes = [ i for i in range( 0, len( main.CLIs ) ) ]
-
-        if main.params[ 'tcpdump' ].lower() == "true":
-            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' ] )
-
-        main.step( "Clean up ONOS service changes" )
-        handle.sendline( "git checkout -- tools/package/init/onos.conf" )
-        handle.sendline( "git checkout -- tools/package/init/onos.service" )
-        handle.expect( "\$" )
-
-        main.step( "Checking ONOS nodes" )
-        nodeResults = utilities.retry( main.HA.nodesCheck,
-                                       False,
-                                       args=[ main.activeNodes ],
-                                       attempts=5 )
-
-        utilities.assert_equals( expect=True, actual=nodeResults,
-                                 onpass="Nodes check successful",
-                                 onfail="Nodes check NOT successful" )
-
-        if not nodeResults:
-            for i in main.activeNodes:
-                cli = main.CLIs[ i ]
-                main.log.debug( "{} components not ACTIVE: \n{}".format(
-                    cli.name,
-                    cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
-            main.log.error( "Failed to start ONOS, stopping test" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Activate apps defined in the params file" )
-        # get data from the params
-        apps = main.params.get( 'apps' )
-        if apps:
-            apps = apps.split( ',' )
-            main.log.warn( apps )
-            activateResult = True
-            for app in apps:
-                main.CLIs[ 0 ].app( app, "Activate" )
-            # TODO: check this worked
-            time.sleep( 10 )  # wait for apps to activate
-            for app in apps:
-                state = main.CLIs[ 0 ].appStatus( app )
-                if state == "ACTIVE":
-                    activateResult = activateResult and True
-                else:
-                    main.log.error( "{} is in {} state".format( app, state ) )
-                    activateResult = False
-            utilities.assert_equals( expect=True,
-                                     actual=activateResult,
-                                     onpass="Successfully activated apps",
-                                     onfail="Failed to activate apps" )
-        else:
-            main.log.warn( "No apps were specified to be loaded after startup" )
-
-        main.step( "Set ONOS configurations" )
-        config = main.params.get( 'ONOS_Configuration' )
-        if config:
-            main.log.debug( config )
-            checkResult = main.TRUE
-            for component in config:
-                for setting in config[ component ]:
-                    value = config[ component ][ setting ]
-                    check = main.CLIs[ 0 ].setCfg( component, setting, value )
-                    main.log.info( "Value was changed? {}".format( main.TRUE == check ) )
-                    checkResult = check and checkResult
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=checkResult,
-                                     onpass="Successfully set config",
-                                     onfail="Failed to set config" )
-        else:
-            main.log.warn( "No configurations were specified to be changed after startup" )
-
-        main.step( "App Ids check" )
-        appCheck = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
-                             name="appToIDCheck-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            appCheck = appCheck and t.result
-        if appCheck != main.TRUE:
-            node = main.activeNodes[ 0 ]
-            main.log.warn( main.CLIs[ node ].apps() )
-            main.log.warn( main.CLIs[ node ].appIDs() )
-        utilities.assert_equals( expect=main.TRUE, actual=appCheck,
-                                 onpass="App Ids seem to be correct",
-                                 onfail="Something is wrong with app Ids" )
+        main.HA.initialSetUp()
 
     def CASE2( self, main ):
         """
         Assign devices to controllers
         """
-        import re
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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.case( "Assigning devices to controllers" )
-        main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
-                                "and check that an ONOS node becomes the " +\
-                                "master of the device."
-        main.step( "Assign switches to controllers" )
-
-        ipList = []
-        for i in range( main.numCtrls ):
-            ipList.append( main.nodes[ i ].ip_address )
-        swList = []
-        for i in range( 1, 29 ):
-            swList.append( "s" + str( i ) )
-        main.Mininet1.assignSwController( sw=swList, ip=ipList )
-
-        mastershipCheck = main.TRUE
-        for i in range( 1, 29 ):
-            response = main.Mininet1.getSwController( "s" + str( i ) )
-            try:
-                main.log.info( str( response ) )
-            except Exception:
-                main.log.info( repr( response ) )
-            for node in main.nodes:
-                if re.search( "tcp:" + node.ip_address, response ):
-                    mastershipCheck = mastershipCheck and main.TRUE
-                else:
-                    main.log.error( "Error, node " + node.ip_address + " is " +
-                                    "not in the list of controllers s" +
-                                    str( i ) + " is connecting to." )
-                    mastershipCheck = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=mastershipCheck,
-            onpass="Switch mastership assigned correctly",
-            onfail="Switches not assigned correctly to controllers" )
+        main.HA.assignDevices( main )
 
     def CASE21( self, main ):
         """
         Assign mastership to controllers
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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.case( "Assigning Controller roles for switches" )
-        main.caseExplanation = "Check that ONOS is connected to each " +\
-                                "device. Then manually assign" +\
-                                " mastership to specific ONOS nodes using" +\
-                                " 'device-role'"
-        main.step( "Assign mastership of switches to specific controllers" )
-        # Manually assign mastership to the controller we want
-        roleCall = main.TRUE
-
-        ipList = []
-        deviceList = []
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        try:
-            # Assign mastership to specific controllers. This assignment was
-            # determined for a 7 node cluser, but will work with any sized
-            # cluster
-            for i in range( 1, 29 ):  # switches 1 through 28
-                # set up correct variables:
-                if i == 1:
-                    c = 0
-                    ip = main.nodes[ c ].ip_address  # ONOS1
-                    deviceId = onosCli.getDevice( "1000" ).get( 'id' )
-                elif i == 2:
-                    c = 1 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS2
-                    deviceId = onosCli.getDevice( "2000" ).get( 'id' )
-                elif i == 3:
-                    c = 1 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS2
-                    deviceId = onosCli.getDevice( "3000" ).get( 'id' )
-                elif i == 4:
-                    c = 3 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS4
-                    deviceId = onosCli.getDevice( "3004" ).get( 'id' )
-                elif i == 5:
-                    c = 2 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS3
-                    deviceId = onosCli.getDevice( "5000" ).get( 'id' )
-                elif i == 6:
-                    c = 2 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS3
-                    deviceId = onosCli.getDevice( "6000" ).get( 'id' )
-                elif i == 7:
-                    c = 5 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS6
-                    deviceId = onosCli.getDevice( "6007" ).get( 'id' )
-                elif i >= 8 and i <= 17:
-                    c = 4 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS5
-                    dpid = '3' + str( i ).zfill( 3 )
-                    deviceId = onosCli.getDevice( dpid ).get( 'id' )
-                elif i >= 18 and i <= 27:
-                    c = 6 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS7
-                    dpid = '6' + str( i ).zfill( 3 )
-                    deviceId = onosCli.getDevice( dpid ).get( 'id' )
-                elif i == 28:
-                    c = 0
-                    ip = main.nodes[ c ].ip_address  # ONOS1
-                    deviceId = onosCli.getDevice( "2800" ).get( 'id' )
-                else:
-                    main.log.error( "You didn't write an else statement for " +
-                                    "switch s" + str( i ) )
-                    roleCall = main.FALSE
-                # Assign switch
-                assert deviceId, "No device id for s" + str( i ) + " in ONOS"
-                # TODO: make this controller dynamic
-                roleCall = roleCall and onosCli.deviceRole( deviceId, ip )
-                ipList.append( ip )
-                deviceList.append( deviceId )
-        except ( AttributeError, AssertionError ):
-            main.log.exception( "Something is wrong with ONOS device view" )
-            main.log.info( onosCli.devices() )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=roleCall,
-            onpass="Re-assigned switch mastership to designated controller",
-            onfail="Something wrong with deviceRole calls" )
-
-        main.step( "Check mastership was correctly assigned" )
-        roleCheck = main.TRUE
-        # NOTE: This is due to the fact that device mastership change is not
-        #       atomic and is actually a multi step process
-        time.sleep( 5 )
-        for i in range( len( ipList ) ):
-            ip = ipList[ i ]
-            deviceId = deviceList[ i ]
-            # Check assignment
-            master = onosCli.getRole( deviceId ).get( 'master' )
-            if ip in master:
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-                main.log.error( "Error, controller " + ip + " is not" +
-                                " master " + "of device " +
-                                str( deviceId ) + ". Master is " +
-                                repr( master ) + "." )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=roleCheck,
-            onpass="Switches were successfully reassigned to designated " +
-                   "controller",
-            onfail="Switches were not successfully reassigned" )
+        main.HA.assignMastership( main )
 
     def CASE3( self, main ):
         """
         Assign intents
         """
-        import time
-        import json
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-        try:
-            labels
-        except NameError:
-            main.log.error( "labels not defined, setting to []" )
-            labels = []
-        try:
-            data
-        except NameError:
-            main.log.error( "data not defined, setting to []" )
-            data = []
-        main.case( "Adding host Intents" )
-        main.caseExplanation = "Discover hosts by using pingall then " +\
-                                "assign predetermined host-to-host intents." +\
-                                " After installation, check that the intent" +\
-                                " is distributed to all nodes and the state" +\
-                                " is INSTALLED"
-
-        # install onos-app-fwd
-        main.step( "Install reactive forwarding app" )
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        installResults = onosCli.activateApp( "org.onosproject.fwd" )
-        utilities.assert_equals( expect=main.TRUE, actual=installResults,
-                                 onpass="Install fwd successful",
-                                 onfail="Install fwd failed" )
-
-        main.step( "Check app ids" )
-        appCheck = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
-                             name="appToIDCheck-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            appCheck = appCheck and t.result
-        if appCheck != main.TRUE:
-            main.log.warn( onosCli.apps() )
-            main.log.warn( onosCli.appIDs() )
-        utilities.assert_equals( expect=main.TRUE, actual=appCheck,
-                                 onpass="App Ids seem to be correct",
-                                 onfail="Something is wrong with app Ids" )
-
-        main.step( "Discovering Hosts( Via pingall for now )" )
-        # FIXME: Once we have a host discovery mechanism, use that instead
-        # REACTIVE FWD test
-        pingResult = main.FALSE
-        passMsg = "Reactive Pingall test passed"
-        time1 = time.time()
-        pingResult = main.Mininet1.pingall()
-        time2 = time.time()
-        if not pingResult:
-            main.log.warn( "First pingall failed. Trying again..." )
-            pingResult = main.Mininet1.pingall()
-            passMsg += " on the second try"
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=pingResult,
-            onpass=passMsg,
-            onfail="Reactive Pingall failed, " +
-                   "one or more ping pairs failed" )
-        main.log.info( "Time for pingall: %2f seconds" %
-                       ( time2 - time1 ) )
-        # timeout for fwd flows
-        time.sleep( 11 )
-        # uninstall onos-app-fwd
-        main.step( "Uninstall reactive forwarding app" )
-        node = main.activeNodes[ 0 ]
-        uninstallResult = main.CLIs[ node ].deactivateApp( "org.onosproject.fwd" )
-        utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
-                                 onpass="Uninstall fwd successful",
-                                 onfail="Uninstall fwd failed" )
-
-        main.step( "Check app ids" )
-        threads = []
-        appCheck2 = main.TRUE
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
-                             name="appToIDCheck-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            appCheck2 = appCheck2 and t.result
-        if appCheck2 != main.TRUE:
-            node = main.activeNodes[ 0 ]
-            main.log.warn( main.CLIs[ node ].apps() )
-            main.log.warn( main.CLIs[ node ].appIDs() )
-        utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
-                                 onpass="App Ids seem to be correct",
-                                 onfail="Something is wrong with app Ids" )
-
-        main.step( "Add host intents via cli" )
-        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 ) )
-            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 = onosCli.getHost( host1 )
-            host2Dict = onosCli.getHost( host2 )
-            host1Id = None
-            host2Id = None
-            if host1Dict and host2Dict:
-                host1Id = host1Dict.get( 'id', None )
-                host2Id = host2Dict.get( 'id', None )
-            if host1Id and host2Id:
-                nodeNum = ( i % len( main.activeNodes ) )
-                node = main.activeNodes[ nodeNum ]
-                tmpId = main.CLIs[ node ].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 for h" + str( i ) +
-                                " and/or h" + str( i + 10 ) )
-                node = main.activeNodes[ 0 ]
-                hosts = main.CLIs[ node ].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
-        utilities.assert_equals( expect=main.TRUE, actual=hostResult,
-                                 onpass="Found a host id for each host",
-                                 onfail="Error looking up host ids" )
-
-        intentStart = time.time()
-        onosIds = onosCli.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
-        if intentAddResult:
-            intentStop = time.time()
-        else:
-            intentStop = None
-        # Print the intent states
-        intents = onosCli.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 = onosCli.leaders()
-        try:
-            missing = False
-            if leaders:
-                parsedLeaders = json.loads( leaders )
-                main.log.warn( json.dumps( parsedLeaders,
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-                # check for all intent partitions
-                topics = []
-                for i in range( 14 ):
-                    topics.append( "work-partition-" + str( i ) )
-                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" )
-                        missing = True
-            else:
-                main.log.error( "leaders() returned None" )
-        except ( ValueError, TypeError ):
-            main.log.exception( "Error parsing leaders" )
-            main.log.error( repr( leaders ) )
-        # Check all nodes
-        if missing:
-            for i in main.activeNodes:
-                response = main.CLIs[ i ].leaders( jsonFormat=False )
-                main.log.warn( str( main.CLIs[ i ].name ) + " leaders output: \n" +
-                               str( response ) )
-
-        partitions = onosCli.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 = onosCli.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( intentAddResult and not missingIntents and
-                                installedCheck )
-        if not intentAddResult:
-            main.log.error( "Error in pushing host intents to ONOS" )
-
-        main.step( "Intent Anti-Entropy dispersion" )
-        for j in range( 100 ):
-            correct = True
-            main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
-            for i in main.activeNodes:
-                onosIds = []
-                ids = main.CLIs[ i ].getAllIntentsId()
-                onosIds.append( ids )
-                main.log.debug( "Intents in " + main.CLIs[ i ].name + ": " +
-                                str( sorted( onosIds ) ) )
-                if sorted( ids ) != sorted( intentIds ):
-                    main.log.warn( "Set of intent IDs doesn't match" )
-                    correct = False
-                    break
-                else:
-                    intents = json.loads( main.CLIs[ i ].intents() )
-                    for intent in intents:
-                        if intent[ 'state' ] != "INSTALLED":
-                            main.log.warn( "Intent " + intent[ 'id' ] +
-                                           " is " + intent[ 'state' ] )
-                            correct = False
-                            break
-            if correct:
-                break
-            else:
-                time.sleep( 1 )
-        if not intentStop:
-            intentStop = time.time()
-        global gossipTime
-        gossipTime = intentStop - intentStart
-        main.log.info( "It took about " + str( gossipTime ) +
-                        " seconds for all intents to appear in each node" )
-        gossipPeriod = int( main.params[ 'timers' ][ 'gossip' ] )
-        maxGossipTime = gossipPeriod * len( main.activeNodes )
-        utilities.assert_greater_equals(
-                expect=maxGossipTime, actual=gossipTime,
-                onpass="ECM anti-entropy for intents worked within " +
-                       "expected time",
-                onfail="Intent ECM anti-entropy took too long. " +
-                       "Expected time:{}, Actual time:{}".format( maxGossipTime,
-                                                                  gossipTime ) )
-        if gossipTime <= maxGossipTime:
-            intentAddResult = True
-
-        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 = onosCli.getAllIntentsId()
-            main.log.info( "Submitted intents: " + str( intentIds ) )
-            main.log.info( "Intents in ONOS: " + str( onosIds ) )
-            # Print the intent states
-            intents = onosCli.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 = onosCli.leaders()
-            try:
-                missing = False
-                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( "work-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" )
-                            missing = True
-                else:
-                    main.log.error( "leaders() returned None" )
-            except ( ValueError, TypeError ):
-                main.log.exception( "Error parsing leaders" )
-                main.log.error( repr( leaders ) )
-            # Check all nodes
-            if missing:
-                for i in main.activeNodes:
-                    node = main.CLIs[ i ]
-                    response = node.leaders( jsonFormat=False )
-                    main.log.warn( str( node.name ) + " leaders output: \n" +
-                                   str( response ) )
-
-            partitions = onosCli.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 = onosCli.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 ) )
+        main.HA.assignIntents( main )
 
     def CASE4( self, main ):
         """
         Ping across added host intents
         """
-        import json
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-        main.case( "Verify connectivity by sending traffic across Intents" )
-        main.caseExplanation = "Ping across added host intents to check " +\
-                                "functionality and check the state of " +\
-                                "the intent"
-
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        main.step( "Check Intent state" )
-        installedCheck = False
-        loopCount = 0
-        while not installedCheck and loopCount < 40:
-            installedCheck = True
-            # Print the intent states
-            intents = onosCli.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." )
-            # Print states
-            intentStates.sort()
-            for i, s in intentStates:
-                count += 1
-                main.log.info( "%-6s%-15s%-15s" %
-                               ( str( count ), str( i ), str( s ) ) )
-            if not installedCheck:
-                time.sleep( 1 )
-                loopCount += 1
-        utilities.assert_equals( expect=True, actual=installedCheck,
-                                 onpass="Intents are all INSTALLED",
-                                 onfail="Intents are not all in " +
-                                        "INSTALLED state" )
-
-        main.step( "Ping across added host intents" )
-        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.error(
-                "Intents have not been installed correctly, pings failed." )
-            # TODO: pretty print
-            main.log.warn( "ONOS1 intents: " )
-            try:
-                tmpIntents = onosCli.intents()
-                main.log.warn( json.dumps( json.loads( tmpIntents ),
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-            except ( ValueError, TypeError ):
-                main.log.warn( repr( tmpIntents ) )
-        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." )
-
-        main.step( "Check leadership of topics" )
-        leaders = onosCli.leaders()
-        topicCheck = main.TRUE
-        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
-                # TODO: Look at Devices as topics now that it uses this system
-                topics = []
-                for i in range( 14 ):
-                    topics.append( "work-partition-" + str( i ) )
-                # FIXME: this should only be after we start the app
-                # FIXME: topics.append( "org.onosproject.election" )
-                # Print leaders output
-                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" )
-                        topicCheck = main.FALSE
-            else:
-                main.log.error( "leaders() returned None" )
-                topicCheck = main.FALSE
-        except ( ValueError, TypeError ):
-            topicCheck = main.FALSE
-            main.log.exception( "Error parsing leaders" )
-            main.log.error( repr( leaders ) )
-            # TODO: Check for a leader of these topics
-        # Check all nodes
-        if topicCheck:
-            for i in main.activeNodes:
-                node = main.CLIs[ i ]
-                response = node.leaders( jsonFormat=False )
-                main.log.warn( str( node.name ) + " leaders output: \n" +
-                               str( response ) )
-
-        utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
-                                 onpass="intent Partitions is in leaders",
-                                 onfail="Some topics were lost " )
-        # Print partitions
-        partitions = onosCli.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 ) )
-        # Print Pending Map
-        pendingMap = onosCli.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 = onosCli.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 = onosCli.leaders()
-            try:
-                missing = False
-                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( "work-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" )
-                            missing = True
-                else:
-                    main.log.error( "leaders() returned None" )
-            except ( ValueError, TypeError ):
-                main.log.exception( "Error parsing leaders" )
-                main.log.error( repr( leaders ) )
-            if missing:
-                for i in main.activeNodes:
-                    node = main.CLIs[ i ]
-                    response = node.leaders( jsonFormat=False )
-                    main.log.warn( str( node.name ) + " leaders output: \n" +
-                                   str( response ) )
-
-            partitions = onosCli.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 = onosCli.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 ) )
-        # Print flowrules
-        main.log.debug( onosCli.flows( jsonFormat=False ) )
-        main.step( "Wait a minute then ping again" )
-        # the wait is above
-        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.error(
-                "Intents have not been installed correctly, pings failed." )
-            # TODO: pretty print
-            main.log.warn( "ONOS1 intents: " )
-            try:
-                tmpIntents = onosCli.intents()
-                main.log.warn( json.dumps( json.loads( tmpIntents ),
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-            except ( ValueError, TypeError ):
-                main.log.warn( repr( tmpIntents ) )
-        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." )
+        main.HA.pingAcrossHostIntent( main, True, False )
 
     def CASE5( self, main ):
         """
         Reading state of ONOS
         """
-        import json
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        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 each other and also with past states
-
-        main.step( "Check that each switch has a master" )
-        global mastershipState
-        mastershipState = '[]'
-
-        # Assert that each device has a master
-        rolesNotNull = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( "Get the Mastership of each switch from each controller" )
-        ONOSMastership = []
-        mastershipCheck = main.FALSE
-        consistentMastership = True
-        rolesResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSMastership ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSMastership[ i ] or "Error" in ONOSMastership[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " roles" )
-                main.log.warn( "ONOS" + node + " 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.info(
-                "Switch roles are consistent across all ONOS nodes" )
-        else:
-            consistentMastership = False
-        utilities.assert_equals(
-            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( len( main.activeNodes ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                try:
-                    main.log.warn(
-                        "ONOS" + node + " 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 = []
-        ONOSIntents = []
-        intentCheck = main.FALSE
-        consistentIntents = True
-        intentsResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSIntents ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " intents" )
-                main.log.warn( "ONOS" + node + " 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.info( "Intents are consistent across all ONOS " +
-                             "nodes" )
-        else:
-            consistentIntents = False
-            main.log.error( "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:
-            # Try to make it easy to figure out what is happening
-            #
-            # Intent      ONOS1      ONOS2    ...
-            #  0x01     INSTALLED  INSTALLING
-            #  ...        ...         ...
-            #  ...        ...         ...
-            title = "   Id"
-            for n in main.activeNodes:
-                title += " " * 10 + "ONOS" + str( n + 1 )
-            main.log.warn( title )
-            # get all intent keys in the cluster
-            keys = []
-            try:
-                # Get the set of all intent keys
-                for nodeStr in ONOSIntents:
-                    node = json.loads( nodeStr )
-                    for intent in node:
-                        keys.append( intent.get( 'id' ) )
-                keys = set( keys )
-                # For each intent key, print the state on each node
-                for key in keys:
-                    row = "%-13s" % key
-                    for nodeStr in ONOSIntents:
-                        node = json.loads( nodeStr )
-                        for intent in node:
-                            if intent.get( 'id', "Error" ) == key:
-                                row += "%-15s" % intent.get( 'state' )
-                    main.log.warn( row )
-                # End of intent state table
-            except ValueError as e:
-                main.log.exception( e )
-                main.log.debug( "nodeStr was: " + repr( nodeStr ) )
-
-        if intentsResults and not consistentIntents:
-            # print the json objects
-            n = str( main.activeNodes[ -1 ] + 1 )
-            main.log.debug( "ONOS" + n + " intents: " )
-            main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
-                                        sort_keys=True,
-                                        indent=4,
-                                        separators=( ',', ': ' ) ) )
-            for i in range( len( ONOSIntents ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
-                    main.log.debug( "ONOS" + node + " intents: " )
-                    main.log.debug( json.dumps( json.loads( ONOSIntents[ i ] ),
-                                                sort_keys=True,
-                                                indent=4,
-                                                separators=( ',', ': ' ) ) )
-                else:
-                    main.log.debug( "ONOS" + node + " intents match ONOS" +
-                                    n + " intents" )
-        elif intentsResults and consistentIntents:
-            intentCheck = main.TRUE
-            intentState = ONOSIntents[ 0 ]
-
-        main.step( "Get the flows from each controller" )
-        global flowState
-        flowState = []
-        ONOSFlows = []
-        ONOSFlowsJson = []
-        flowCheck = main.FALSE
-        consistentFlows = True
-        flowsResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].flows,
-                             name="flows-" + str( i ),
-                             args=[],
-                             kwargs={ 'jsonFormat': True } )
-            threads.append( t )
-            t.start()
-
-        # NOTE: Flows command can take some time to run
-        time.sleep( 30 )
-        for t in threads:
-            t.join()
-            result = t.result
-            ONOSFlows.append( result )
-
-        for i in range( len( ONOSFlows ) ):
-            num = str( main.activeNodes[ i ] + 1 )
-            if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
-                main.log.error( "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.info( "Flow count is consistent across all ONOS nodes" )
-        else:
-            consistentFlows = False
-        utilities.assert_equals(
-            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( len( ONOSFlows ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                try:
-                    main.log.warn(
-                        "ONOS" + node + " flows: " +
-                        json.dumps( json.loads( ONOSFlows[ i ] ), sort_keys=True,
-                                    indent=4, separators=( ',', ': ' ) ) )
-                except ( ValueError, TypeError ):
-                    main.log.warn( "ONOS" + node + " 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.Mininet1.getFlowTable( "s" + str( i ), version="1.3", debug=False ) )
-        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" )
-        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( "Collecting topology information from ONOS" )
-        devices = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].devices,
-                             name="devices-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            devices.append( t.result )
-        hosts = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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" )
-                main.log.warn( repr( t.result ) )
-                hosts.append( None )
-
-        ports = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].ports,
-                             name="ports-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            ports.append( t.result )
-        links = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].links,
-                             name="links-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            links.append( t.result )
-        clusters = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].clusters,
-                             name="clusters-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            clusters.append( t.result )
-        # Compare json objects for hosts and dataplane clusters
-
-        # hosts
-        main.step( "Host view is consistent across ONOS nodes" )
-        consistentHostsResult = main.TRUE
-        for controller in range( len( hosts ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if hosts[ controller ] and "Error" not in hosts[ controller ]:
-                if hosts[ controller ] == hosts[ 0 ]:
-                    continue
-                else:  # hosts not consistent
-                    main.log.error( "hosts from ONOS" +
-                                     controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    main.log.warn( repr( hosts[ controller ] ) )
-                    consistentHostsResult = main.FALSE
-
-            else:
-                main.log.error( "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" )
-
-        main.step( "Each host has an IP address" )
-        ipResult = main.TRUE
-        for controller in range( 0, len( hosts ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if hosts[ controller ]:
-                for host in hosts[ controller ]:
-                    if not host.get( 'ipAddresses', [] ):
-                        main.log.error( "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
-        main.step( "Cluster view is consistent across ONOS nodes" )
-        consistentClustersResult = main.TRUE
-        for controller in range( len( clusters ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if "Error" not in clusters[ controller ]:
-                if clusters[ controller ] == clusters[ 0 ]:
-                    continue
-                else:  # clusters not consistent
-                    main.log.error( "clusters from ONOS" + controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    consistentClustersResult = main.FALSE
-
-            else:
-                main.log.error( "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" )
-        if not consistentClustersResult:
-            main.log.debug( clusters )
-
-        # there should always only be one cluster
-        main.step( "Cluster view correct across ONOS nodes" )
-        try:
-            numClusters = len( json.loads( clusters[ 0 ] ) )
-        except ( ValueError, TypeError ):
-            main.log.exception( "Error parsing clusters[0]: " +
-                                repr( clusters[ 0 ] ) )
-            numClusters = "ERROR"
-        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
-        linksResults = main.TRUE
-        hostsResults = main.TRUE
-        mnSwitches = main.Mininet1.getSwitches()
-        mnLinks = main.Mininet1.getLinks()
-        mnHosts = main.Mininet1.getHosts()
-        for controller in main.activeNodes:
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if devices[ controller ] and ports[ controller ] and\
-                    "Error" not in devices[ controller ] and\
-                    "Error" not in ports[ controller ]:
-                currentDevicesResult = main.Mininet1.compareSwitches(
-                        mnSwitches,
-                        json.loads( devices[ controller ] ),
-                        json.loads( ports[ controller ] ) )
-            else:
-                currentDevicesResult = main.FALSE
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=currentDevicesResult,
-                                     onpass="ONOS" + controllerStr +
-                                     " Switches view is correct",
-                                     onfail="ONOS" + controllerStr +
-                                     " Switches view is incorrect" )
-            if links[ controller ] and "Error" not in links[ controller ]:
-                currentLinksResult = main.Mininet1.compareLinks(
-                        mnSwitches, mnLinks,
-                        json.loads( links[ controller ] ) )
-            else:
-                currentLinksResult = main.FALSE
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=currentLinksResult,
-                                     onpass="ONOS" + controllerStr +
-                                     " links view is correct",
-                                     onfail="ONOS" + controllerStr +
-                                     " links view is incorrect" )
-
-            if hosts[ controller ] and "Error" not in hosts[ controller ]:
-                currentHostsResult = main.Mininet1.compareHosts(
-                        mnHosts,
-                        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
-            linksResults = linksResults and currentLinksResult
-            hostsResults = hostsResults and currentHostsResult
-
-        main.step( "Device information is correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=devicesResults,
-            onpass="Device information is correct",
-            onfail="Device information is incorrect" )
-
-        main.step( "Links are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=linksResults,
-            onpass="Link are correct",
-            onfail="Links are incorrect" )
-
-        main.step( "Hosts are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=hostsResults,
-            onpass="Hosts are correct",
-            onfail="Hosts are incorrect" )
+        main.HA.readingState( main )
 
     def CASE61( self, main ):
         """
@@ -1850,380 +182,19 @@
         """
         The bring up stopped nodes
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-        assert main.kill, "main.kill not defined"
-        main.case( "Restart minority of ONOS nodes" )
 
-        main.step( "Restarting " + str( len( main.kill ) ) + " ONOS nodes" )
-        startResults = main.TRUE
-        restartTime = time.time()
-        for i in main.kill:
-            startResults = startResults and\
-                           main.ONOSbench.onosStart( main.nodes[ i ].ip_address )
-        utilities.assert_equals( expect=main.TRUE, actual=startResults,
-                                 onpass="ONOS nodes started successfully",
-                                 onfail="ONOS nodes NOT successfully started" )
-
-        main.step( "Checking if ONOS is up yet" )
-        count = 0
-        onosIsupResult = main.FALSE
-        while onosIsupResult == main.FALSE and count < 10:
-            onosIsupResult = main.TRUE
-            for i in main.kill:
-                onosIsupResult = onosIsupResult and\
-                                 main.ONOSbench.isup( main.nodes[ i ].ip_address )
-            count = count + 1
-        utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
-                                 onpass="ONOS restarted successfully",
-                                 onfail="ONOS restart NOT successful" )
-
-        main.step( "Restarting ONOS main.CLIs" )
-        cliResults = main.TRUE
-        for i in main.kill:
-            cliResults = cliResults and\
-                         main.CLIs[ i ].startOnosCli( main.nodes[ i ].ip_address )
-            main.activeNodes.append( i )
-        utilities.assert_equals( expect=main.TRUE, actual=cliResults,
-                                 onpass="ONOS cli restarted",
-                                 onfail="ONOS cli did not restart" )
-        main.activeNodes.sort()
-        try:
-            assert list( set( main.activeNodes ) ) == main.activeNodes,\
-                   "List of active nodes has duplicates, this likely indicates something was run out of order"
-        except AssertionError:
-            main.log.exception( "" )
-            main.cleanup()
-            main.exit()
-
-        # Grab the time of restart so we chan check how long the gossip
-        # protocol has had time to work
-        main.restartTime = time.time() - restartTime
-        main.log.debug( "Restart time: " + str( main.restartTime ) )
-        # TODO: MAke this configurable. Also, we are breaking the above timer
-        main.step( "Checking ONOS nodes" )
-        nodeResults = utilities.retry( main.HA.nodesCheck,
-                                       False,
-                                       args=[ main.activeNodes ],
-                                       sleep=15,
-                                       attempts=5 )
-
-        utilities.assert_equals( expect=True, actual=nodeResults,
-                                 onpass="Nodes check successful",
-                                 onfail="Nodes check NOT successful" )
-
-        if not nodeResults:
-            for i in main.activeNodes:
-                cli = main.CLIs[ i ]
-                main.log.debug( "{} components not ACTIVE: \n{}".format(
-                    cli.name,
-                    cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
-            main.log.error( "Failed to start ONOS, stopping test" )
-            main.cleanup()
-            main.exit()
-
-        node = main.activeNodes[ 0 ]
-        main.log.debug( main.CLIs[ node ].nodes( jsonFormat=False ) )
-        main.log.debug( main.CLIs[ node ].leaders( jsonFormat=False ) )
-        main.log.debug( main.CLIs[ node ].partitions( jsonFormat=False ) )
-
-        main.step( "Rerun for election on the node(s) that were killed" )
-        runResults = main.TRUE
-        for i in main.kill:
-            runResults = runResults and\
-                         main.CLIs[ i ].electionTestRun()
-        utilities.assert_equals( expect=main.TRUE, actual=runResults,
-                                 onpass="ONOS nodes reran for election topic",
-                                 onfail="Errror rerunning for election" )
+        main.HA.bringUpStoppedNode( main )
 
     def CASE7( self, main ):
         """
         Check state after ONOS failure
         """
-        import json
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
         try:
             main.kill
         except AttributeError:
             main.kill = []
 
-        main.case( "Running ONOS Constant State Tests" )
-
-        main.step( "Check that each switch has a master" )
-        # Assert that each device has a master
-        rolesNotNull = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( "Read device roles from ONOS" )
-        ONOSMastership = []
-        mastershipCheck = main.FALSE
-        consistentMastership = True
-        rolesResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSMastership ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSMastership[ i ] or "Error" in ONOSMastership[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " roles" )
-                main.log.warn( "ONOS" + node + " 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.info(
-                "Switch roles are consistent across all ONOS nodes" )
-        else:
-            consistentMastership = False
-        utilities.assert_equals(
-            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( len( ONOSMastership ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                main.log.warn( "ONOS" + node + " roles: ",
-                               json.dumps( json.loads( ONOSMastership[ i ] ),
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-        elif rolesResults and consistentMastership:
-            mastershipCheck = main.TRUE
-
-        # NOTE: we expect mastership to change on controller failure
-
-        main.step( "Get the intents and compare across all nodes" )
-        ONOSIntents = []
-        intentCheck = main.FALSE
-        consistentIntents = True
-        intentsResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSIntents ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " intents" )
-                main.log.warn( "ONOS" + node + " 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.info( "Intents are consistent across all ONOS " +
-                             "nodes" )
-        else:
-            consistentIntents = False
-
-        # Try to make it easy to figure out what is happening
-        #
-        # Intent      ONOS1      ONOS2    ...
-        #  0x01     INSTALLED  INSTALLING
-        #  ...        ...         ...
-        #  ...        ...         ...
-        title = "   ID"
-        for n in main.activeNodes:
-            title += " " * 10 + "ONOS" + str( n + 1 )
-        main.log.warn( title )
-        # get all intent keys in the cluster
-        keys = []
-        for nodeStr in ONOSIntents:
-            node = json.loads( nodeStr )
-            for intent in node:
-                keys.append( intent.get( 'id' ) )
-        keys = set( keys )
-        for key in keys:
-            row = "%-13s" % key
-            for nodeStr in ONOSIntents:
-                node = json.loads( nodeStr )
-                for intent in node:
-                    if intent.get( 'id' ) == key:
-                        row += "%-15s" % intent.get( 'state' )
-            main.log.warn( row )
-        # End table view
-
-        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' ] )
-            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( len( main.activeNodes ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                main.log.warn( "ONOS" + node + " 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?
-        sameIntents = main.FALSE
-        try:
-            intentState
-        except NameError:
-            main.log.warn( "No previous intent state was saved" )
-        else:
-            if intentState and intentState == ONOSIntents[ 0 ]:
-                sameIntents = main.TRUE
-                main.log.info( "Intents are consistent with before failure" )
-            # TODO: possibly the states have changed? we may need to figure out
-            #       what the acceptable states are
-            elif len( intentState ) == len( ONOSIntents[ 0 ] ):
-                sameIntents = main.TRUE
-                try:
-                    before = json.loads( intentState )
-                    after = json.loads( ONOSIntents[ 0 ] )
-                    for intent in before:
-                        if intent not in after:
-                            sameIntents = main.FALSE
-                            main.log.debug( "Intent is not currently in ONOS " +
-                                            "(at least in the same form):" )
-                            main.log.debug( json.dumps( intent ) )
-                except ( ValueError, TypeError ):
-                    main.log.exception( "Exception printing intents" )
-                    main.log.debug( repr( ONOSIntents[ 0 ] ) )
-                    main.log.debug( repr( intentState ) )
-            if sameIntents == main.FALSE:
-                try:
-                    main.log.debug( "ONOS intents before: " )
-                    main.log.debug( json.dumps( json.loads( intentState ),
-                                                sort_keys=True, indent=4,
-                                                separators=( ',', ': ' ) ) )
-                    main.log.debug( "Current ONOS intents: " )
-                    main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
-                                                sort_keys=True, indent=4,
-                                                separators=( ',', ': ' ) ) )
-                except ( ValueError, TypeError ):
-                    main.log.exception( "Exception printing intents" )
-                    main.log.debug( repr( ONOSIntents[ 0 ] ) )
-                    main.log.debug( repr( intentState ) )
-            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
-        for i in range( 28 ):
-            main.log.info( "Checking flow table on s" + str( i + 1 ) )
-            tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
-            curSwitch = main.Mininet1.flowTableComp( flows[ i ], tmpFlows )
-            FlowTables = FlowTables and curSwitch
-            if curSwitch == main.FALSE:
-                main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
-        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.Mininet2.pingLongKill()
-        """
-        main.step( "Check the continuous pings to ensure that no packets " +
-                   "were dropped during component failure" )
-        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.info( "No loss of dataplane connectivity" )
-        utilities.assert_equals(
-            expect=main.FALSE,
-            actual=LossInPings,
-            onpass="No Loss of connectivity",
-            onfail="Loss of dataplane connectivity detected" )
-        """
+        main.HA.checkStateAfterONOS( main, afterWhich=0 )
         main.step( "Leadership Election is still functional" )
         # Test of LeadershipElection
         leaderList = []
@@ -2268,680 +239,47 @@
         """
         Compare topo
         """
-        import json
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        main.case( "Compare ONOS Topology view to Mininet topology" )
-        main.caseExplanation = "Compare topology objects between Mininet" +\
-                                " and ONOS"
-        topoResult = main.FALSE
-        topoFailMsg = "ONOS topology don't match Mininet"
-        elapsed = 0
-        count = 0
-        main.step( "Comparing ONOS topology to MN topology" )
-        startTime = time.time()
-        # Give time for Gossip to work
-        while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
-            devicesResults = main.TRUE
-            linksResults = main.TRUE
-            hostsResults = main.TRUE
-            hostAttachmentResults = True
-            count += 1
-            cliStart = time.time()
-            devices = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="devices-" + str( i ),
-                                 args=[ main.CLIs[ i ].devices, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                devices.append( t.result )
-            hosts = []
-            ipResult = main.TRUE
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="hosts-" + str( i ),
-                                 args=[ main.CLIs[ i ].hosts, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                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 ) )
-                    hosts.append( None )
-            for controller in range( 0, len( hosts ) ):
-                controllerStr = str( main.activeNodes[ controller ] + 1 )
-                if hosts[ controller ]:
-                    for host in hosts[ controller ]:
-                        if host is None or host.get( 'ipAddresses', [] ) == []:
-                            main.log.error(
-                                "Error with host ipAddresses on controller" +
-                                controllerStr + ": " + str( host ) )
-                            ipResult = main.FALSE
-            ports = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="ports-" + str( i ),
-                                 args=[ main.CLIs[ i ].ports, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                ports.append( t.result )
-            links = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="links-" + str( i ),
-                                 args=[ main.CLIs[ i ].links, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                links.append( t.result )
-            clusters = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="clusters-" + str( i ),
-                                 args=[ main.CLIs[ i ].clusters, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                clusters.append( t.result )
-
-            elapsed = time.time() - startTime
-            cliTime = time.time() - cliStart
-            print "Elapsed time: " + str( elapsed )
-            print "CLI time: " + str( cliTime )
-
-            if all( e is None for e in devices ) and\
-               all( e is None for e in hosts ) and\
-               all( e is None for e in ports ) and\
-               all( e is None for e in links ) and\
-               all( e is None for e in clusters ):
-                topoFailMsg = "Could not get topology from ONOS"
-                main.log.error( topoFailMsg )
-                continue  # Try again, No use trying to compare
-
-            mnSwitches = main.Mininet1.getSwitches()
-            mnLinks = main.Mininet1.getLinks()
-            mnHosts = main.Mininet1.getHosts()
-            for controller in range( len( main.activeNodes ) ):
-                controllerStr = str( main.activeNodes[ controller ] + 1 )
-                if devices[ controller ] and ports[ controller ] and\
-                        "Error" not in devices[ controller ] and\
-                        "Error" not in ports[ controller ]:
-
-                    try:
-                        currentDevicesResult = main.Mininet1.compareSwitches(
-                                mnSwitches,
-                                json.loads( devices[ controller ] ),
-                                json.loads( ports[ controller ] ) )
-                    except ( TypeError, ValueError ) as e:
-                        main.log.exception( "Object not as expected; devices={!r}\nports={!r}".format(
-                            devices[ controller ], ports[ controller ] ) )
-                else:
-                    currentDevicesResult = main.FALSE
-                utilities.assert_equals( expect=main.TRUE,
-                                         actual=currentDevicesResult,
-                                         onpass="ONOS" + controllerStr +
-                                         " Switches view is correct",
-                                         onfail="ONOS" + controllerStr +
-                                         " Switches view is incorrect" )
-
-                if links[ controller ] and "Error" not in links[ controller ]:
-                    currentLinksResult = main.Mininet1.compareLinks(
-                            mnSwitches, mnLinks,
-                            json.loads( links[ controller ] ) )
-                else:
-                    currentLinksResult = main.FALSE
-                utilities.assert_equals( expect=main.TRUE,
-                                         actual=currentLinksResult,
-                                         onpass="ONOS" + controllerStr +
-                                         " links view is correct",
-                                         onfail="ONOS" + controllerStr +
-                                         " links view is incorrect" )
-                if hosts[ controller ] and "Error" not in hosts[ controller ]:
-                    currentHostsResult = main.Mininet1.compareHosts(
-                            mnHosts,
-                            hosts[ controller ] )
-                elif hosts[ controller ] == []:
-                    currentHostsResult = main.TRUE
-                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" )
-                # CHECKING HOST ATTACHMENT POINTS
-                hostAttachment = True
-                zeroHosts = False
-                # FIXME: topo-HA/obelisk specific mappings:
-                # key is mac and value is dpid
-                mappings = {}
-                for i in range( 1, 29 ):  # hosts 1 through 28
-                    # set up correct variables:
-                    macId = "00:" * 5 + hex( i ).split( "0x" )[ 1 ].upper().zfill( 2 )
-                    if i == 1:
-                        deviceId = "1000".zfill( 16 )
-                    elif i == 2:
-                        deviceId = "2000".zfill( 16 )
-                    elif i == 3:
-                        deviceId = "3000".zfill( 16 )
-                    elif i == 4:
-                        deviceId = "3004".zfill( 16 )
-                    elif i == 5:
-                        deviceId = "5000".zfill( 16 )
-                    elif i == 6:
-                        deviceId = "6000".zfill( 16 )
-                    elif i == 7:
-                        deviceId = "6007".zfill( 16 )
-                    elif i >= 8 and i <= 17:
-                        dpid = '3' + str( i ).zfill( 3 )
-                        deviceId = dpid.zfill( 16 )
-                    elif i >= 18 and i <= 27:
-                        dpid = '6' + str( i ).zfill( 3 )
-                        deviceId = dpid.zfill( 16 )
-                    elif i == 28:
-                        deviceId = "2800".zfill( 16 )
-                    mappings[ macId ] = deviceId
-                if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
-                    if hosts[ controller ] == []:
-                        main.log.warn( "There are no hosts discovered" )
-                        zeroHosts = True
-                    else:
-                        for host in hosts[ controller ]:
-                            mac = None
-                            location = None
-                            device = None
-                            port = None
-                            try:
-                                mac = host.get( 'mac' )
-                                assert mac, "mac field could not be found for this host object"
-
-                                location = host.get( 'locations' )[ 0 ]
-                                assert location, "location field could not be found for this host object"
-
-                                # Trim the protocol identifier off deviceId
-                                device = str( location.get( 'elementId' ) ).split( ':' )[ 1 ]
-                                assert device, "elementId field could not be found for this host location object"
-
-                                port = location.get( 'port' )
-                                assert port, "port field could not be found for this host location object"
-
-                                # Now check if this matches where they should be
-                                if mac and device and port:
-                                    if str( port ) != "1":
-                                        main.log.error( "The attachment port is incorrect for " +
-                                                        "host " + str( mac ) +
-                                                        ". Expected: 1 Actual: " + str( port ) )
-                                        hostAttachment = False
-                                    if device != mappings[ str( mac ) ]:
-                                        main.log.error( "The attachment device is incorrect for " +
-                                                        "host " + str( mac ) +
-                                                        ". Expected: " + mappings[ str( mac ) ] +
-                                                        " Actual: " + device )
-                                        hostAttachment = False
-                                else:
-                                    hostAttachment = False
-                            except AssertionError:
-                                main.log.exception( "Json object not as expected" )
-                                main.log.error( repr( host ) )
-                                hostAttachment = False
-                else:
-                    main.log.error( "No hosts json output or \"Error\"" +
-                                    " in output. hosts = " +
-                                    repr( hosts[ controller ] ) )
-                if zeroHosts is False:
-                    hostAttachment = True
-
-                # END CHECKING HOST ATTACHMENT POINTS
-                devicesResults = devicesResults and currentDevicesResult
-                linksResults = linksResults and currentLinksResult
-                hostsResults = hostsResults and currentHostsResult
-                hostAttachmentResults = hostAttachmentResults and\
-                                        hostAttachment
-                topoResult = ( devicesResults and linksResults
-                               and hostsResults and ipResult and
-                               hostAttachmentResults )
-        utilities.assert_equals( expect=True,
-                                 actual=topoResult,
-                                 onpass="ONOS topology matches Mininet",
-                                 onfail=topoFailMsg )
-        # End of While loop to pull ONOS state
-
-        # Compare json objects for hosts and dataplane clusters
-
-        # hosts
-        main.step( "Hosts view is consistent across all ONOS nodes" )
-        consistentHostsResult = main.TRUE
-        for controller in range( len( hosts ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
-                if hosts[ controller ] == hosts[ 0 ]:
-                    continue
-                else:  # hosts not consistent
-                    main.log.error( "hosts from ONOS" + controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    main.log.warn( repr( hosts[ controller ] ) )
-                    consistentHostsResult = main.FALSE
-
-            else:
-                main.log.error( "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" )
-
-        main.step( "Hosts information is correct" )
-        hostsResults = hostsResults and ipResult
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=hostsResults,
-            onpass="Host information is correct",
-            onfail="Host information is incorrect" )
-
-        main.step( "Host attachment points to the network" )
-        utilities.assert_equals(
-            expect=True,
-            actual=hostAttachmentResults,
-            onpass="Hosts are correctly attached to the network",
-            onfail="ONOS did not correctly attach hosts to the network" )
-
-        # Strongly connected clusters of devices
-        main.step( "Clusters view is consistent across all ONOS nodes" )
-        consistentClustersResult = main.TRUE
-        for controller in range( len( clusters ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if "Error" not in clusters[ controller ]:
-                if clusters[ controller ] == clusters[ 0 ]:
-                    continue
-                else:  # clusters not consistent
-                    main.log.error( "clusters from ONOS" +
-                                     controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    consistentClustersResult = main.FALSE
-            else:
-                main.log.error( "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" )
-        if not consistentClustersResult:
-            main.log.debug( clusters )
-
-        main.step( "There is only one SCC" )
-        # there should always only be one cluster
-        try:
-            numClusters = len( json.loads( clusters[ 0 ] ) )
-        except ( ValueError, TypeError ):
-            main.log.exception( "Error parsing clusters[0]: " +
-                                repr( clusters[ 0 ] ) )
-            numClusters = "ERROR"
-        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 linksResults
-                       and hostsResults and consistentHostsResult
-                       and consistentClustersResult and clusterResults
-                       and ipResult and hostAttachmentResults )
-
-        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" )
-
-        main.step( "Device information is correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=devicesResults,
-            onpass="Device information is correct",
-            onfail="Device information is incorrect" )
-
-        main.step( "Links are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=linksResults,
-            onpass="Link are correct",
-            onfail="Links are incorrect" )
-
-        main.step( "Hosts are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=hostsResults,
-            onpass="Hosts are correct",
-            onfail="Hosts are incorrect" )
-
-        # FIXME: move this to an ONOS state case
-        main.step( "Checking ONOS nodes" )
-        nodeResults = utilities.retry( main.HA.nodesCheck,
-                                       False,
-                                       args=[ main.activeNodes ],
-                                       attempts=5 )
-
-        utilities.assert_equals( expect=True, actual=nodeResults,
-                                 onpass="Nodes check successful",
-                                 onfail="Nodes check NOT successful" )
-        if not nodeResults:
-            for i in main.activeNodes:
-                main.log.debug( "{} components not ACTIVE: \n{}".format(
-                    main.CLIs[ i ].name,
-                    main.CLIs[ i ].sendline( "scr:list | grep -v ACTIVE" ) ) )
-
-        if not topoResult:
-            main.cleanup()
-            main.exit()
+        main.HA.compareTopo( main )
 
     def CASE9( self, main ):
         """
         Link s3-s28 down
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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"
-        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 successful",
-                                 onfail="Failed to bring link down" )
-        # TODO do some sort of check here
+        main.HA.linkDown( main )
 
     def CASE10( self, main ):
         """
         Link s3-s28 up
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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"
-        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 successful",
-                                 onfail="Failed to bring link up" )
-        # TODO do some sort of check here
+        main.HA.linkUp( main )
 
     def CASE11( self, main ):
         """
         Switch Down
         """
         # NOTE: You should probably run a topology check after this
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
-
-        description = "Killing a switch to ensure it is discovered correctly"
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        main.case( description )
-        switch = main.params[ 'kill' ][ 'switch' ]
-        switchDPID = main.params[ 'kill' ][ 'dpid' ]
-
-        # TODO: Make this switch parameterizable
-        main.step( "Kill " + switch )
-        main.log.info( "Deleting " + switch )
-        main.Mininet1.delSwitch( switch )
-        main.log.info( "Waiting " + str( switchSleep ) +
-                       " seconds for switch down to be discovered" )
-        time.sleep( switchSleep )
-        device = onosCli.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 successful",
-                                 onfail="Failed to kill switch?" )
+        main.HA.switchDown( main )
 
     def CASE12( self, main ):
         """
         Switch Up
         """
         # NOTE: You should probably run a topology check after this
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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' ]
-        switchDPID = main.params[ 'kill' ][ 'dpid' ]
-        links = main.params[ 'kill' ][ 'links' ].split()
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        description = "Adding a switch to ensure it is discovered correctly"
-        main.case( description )
-
-        main.step( "Add back " + switch )
-        main.Mininet1.addSwitch( switch, dpid=switchDPID )
-        for peer in links:
-            main.Mininet1.addLink( switch, peer )
-        ipList = [ node.ip_address for node in main.nodes ]
-        main.Mininet1.assignSwController( sw=switch, ip=ipList )
-        main.log.info( "Waiting " + str( switchSleep ) +
-                       " seconds for switch up to be discovered" )
-        time.sleep( switchSleep )
-        device = onosCli.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 successful",
-                                 onfail="Failed to add switch?" )
+        main.HA.switchUp( main )
 
     def CASE13( self, main ):
         """
         Clean up
         """
-        import os
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        # printing colors to terminal
-        colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
-                   'blue': '\033[94m', 'green': '\033[92m',
-                   'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
-        main.case( "Test Cleanup" )
-        main.step( "Killing tcpdumps" )
-        main.Mininet2.stopTcpdump()
-
-        testname = main.TEST
-        if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
-            main.step( "Copying MN pcap and ONOS log files to test station" )
-            teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
-            teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
-            # NOTE: MN Pcap file is being saved to logdir.
-            #       We scp this file as MN and TestON aren't necessarily the same vm
-
-            # FIXME: To be replaced with a Jenkin's post script
-            # TODO: Load these from params
-            # NOTE: must end in /
-            logFolder = "/opt/onos/log/"
-            logFiles = [ "karaf.log", "karaf.log.1" ]
-            # NOTE: must end in /
-            for f in logFiles:
-                for node in main.nodes:
-                    dstName = main.logdir + "/" + node.name + "-" + f
-                    main.ONOSbench.secureCopy( node.user_name, node.ip_address,
-                                               logFolder + f, dstName )
-            # std*.log's
-            # NOTE: must end in /
-            logFolder = "/opt/onos/var/"
-            logFiles = [ "stderr.log", "stdout.log" ]
-            # NOTE: must end in /
-            for f in logFiles:
-                for node in main.nodes:
-                    dstName = main.logdir + "/" + node.name + "-" + f
-                    main.ONOSbench.secureCopy( node.user_name, node.ip_address,
-                                               logFolder + f, dstName )
-        else:
-            main.log.debug( "skipping saving log files" )
-
-        main.step( "Stopping Mininet" )
-        mnResult = main.Mininet1.stopNet()
-        utilities.assert_equals( expect=main.TRUE, actual=mnResult,
-                                 onpass="Mininet stopped",
-                                 onfail="MN cleanup NOT successful" )
-
-        main.step( "Checking ONOS Logs for errors" )
-        for node in main.nodes:
-            main.log.debug( "Checking logs for errors on " + node.name + ":" )
-            main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
-
-        try:
-            timerLog = open( main.logdir + "/Timers.csv", 'w' )
-            # Overwrite with empty line and close
-            labels = "Gossip Intents, Restart"
-            data = str( gossipTime ) + ", " + str( main.restartTime )
-            timerLog.write( labels + "\n" + data )
-            timerLog.close()
-        except NameError as e:
-            main.log.exception( e )
+        main.HAlabels.append( "Restart" )
+        main.HAdata.append( str( main.restartTime ) )
+        main.HA.cleanUp( main )
 
     def CASE14( self, main ):
         """
         start election app on all onos nodes
         """
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        main.case( "Start Leadership Election app" )
-        main.step( "Install leadership election app" )
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        appResult = onosCli.activateApp( "org.onosproject.election" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=appResult,
-            onpass="Election app installed",
-            onfail="Something went wrong with installing Leadership election" )
-
-        main.step( "Run for election on each node" )
-        for i in main.activeNodes:
-            main.CLIs[ i ].electionTestRun()
-        time.sleep( 5 )
-        activeCLIs = [ main.CLIs[ i ] for i in main.activeNodes ]
-        sameResult, leaders = main.HA.consistentLeaderboards( activeCLIs )
-        utilities.assert_equals(
-            expect=True,
-            actual=sameResult,
-            onpass="All nodes see the same leaderboards",
-            onfail="Inconsistent leaderboards" )
-
-        if sameResult:
-            leader = leaders[ 0 ][ 0 ]
-            if main.nodes[ main.activeNodes[ 0 ] ].ip_address in leader:
-                correctLeader = True
-            else:
-                correctLeader = False
-            main.step( "First node was elected leader" )
-            utilities.assert_equals(
-                expect=True,
-                actual=correctLeader,
-                onpass="Correct leader was elected",
-                onfail="Incorrect leader" )
+        main.HA.startElectionApp( main )
 
     def CASE15( self, main ):
         """
@@ -2958,196 +296,16 @@
             old and new variable prefixes refer to data from before vs after
                 withdrawl and later before withdrawl vs after re-election
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        description = "Check that Leadership Election is still functional"
-        main.case( description )
-        # NOTE: Need to re-run after restarts since being a canidate is not persistant
-
-        oldLeaders = []  # list of lists of each nodes' candidates before
-        newLeaders = []  # list of lists of each nodes' candidates after
-        oldLeader = ''  # the old leader from oldLeaders, None if not same
-        newLeader = ''  # the new leaders fron newLoeaders, None if not same
-        oldLeaderCLI = None  # the CLI of the old leader used for re-electing
-        expectNoLeader = False  # True when there is only one leader
-        if main.numCtrls == 1:
-            expectNoLeader = True
-
-        main.step( "Run for election on each node" )
-        electionResult = main.TRUE
-
-        for i in main.activeNodes:  # run test election on each node
-            if main.CLIs[ i ].electionTestRun() == main.FALSE:
-                electionResult = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=electionResult,
-            onpass="All nodes successfully ran for leadership",
-            onfail="At least one node failed to run for leadership" )
-
-        if electionResult == main.FALSE:
-            main.log.error(
-                "Skipping Test Case because Election Test App isn't loaded" )
-            main.skipCase()
-
-        main.step( "Check that each node shows the same leader and candidates" )
-        failMessage = "Nodes have different leaderboards"
-        activeCLIs = [ main.CLIs[ i ] for i in main.activeNodes ]
-        sameResult, oldLeaders = main.HA.consistentLeaderboards( activeCLIs )
-        if sameResult:
-            oldLeader = oldLeaders[ 0 ][ 0 ]
-            main.log.warn( oldLeader )
-        else:
-            oldLeader = None
-        utilities.assert_equals(
-            expect=True,
-            actual=sameResult,
-            onpass="Leaderboards are consistent for the election topic",
-            onfail=failMessage )
-
-        main.step( "Find current leader and withdraw" )
-        withdrawResult = main.TRUE
-        # do some sanity checking on leader before using it
-        if oldLeader is None:
-            main.log.error( "Leadership isn't consistent." )
-            withdrawResult = main.FALSE
-        # Get the CLI of the oldLeader
-        for i in main.activeNodes:
-            if oldLeader == main.nodes[ i ].ip_address:
-                oldLeaderCLI = main.CLIs[ i ]
-                break
-        else:  # FOR/ELSE statement
-            main.log.error( "Leader election, could not find current leader" )
-        if oldLeader:
-            withdrawResult = oldLeaderCLI.electionTestWithdraw()
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=withdrawResult,
-            onpass="Node was withdrawn from election",
-            onfail="Node was not withdrawn from election" )
-
-        main.step( "Check that a new node was elected leader" )
-        failMessage = "Nodes have different leaders"
-        # Get new leaders and candidates
-        newLeaderResult, newLeaders = main.HA.consistentLeaderboards( activeCLIs )
-        newLeader = None
-        if newLeaderResult:
-            if newLeaders[ 0 ][ 0 ] == 'none':
-                main.log.error( "No leader was elected on at least 1 node" )
-                if not expectNoLeader:
-                    newLeaderResult = False
-            newLeader = newLeaders[ 0 ][ 0 ]
-
-        # Check that the new leader is not the older leader, which was withdrawn
-        if newLeader == oldLeader:
-            newLeaderResult = False
-            main.log.error( "All nodes still see old leader: " + str( oldLeader ) +
-                            " as the current leader" )
-        utilities.assert_equals(
-            expect=True,
-            actual=newLeaderResult,
-            onpass="Leadership election passed",
-            onfail="Something went wrong with Leadership election" )
-
-        main.step( "Check that that new leader was the candidate of old leader" )
-        # candidates[ 2 ] should become the top candidate after withdrawl
-        correctCandidateResult = main.TRUE
-        if expectNoLeader:
-            if newLeader == 'none':
-                main.log.info( "No leader expected. None found. Pass" )
-                correctCandidateResult = main.TRUE
-            else:
-                main.log.info( "Expected no leader, got: " + str( newLeader ) )
-                correctCandidateResult = main.FALSE
-        elif len( oldLeaders[ 0 ] ) >= 3:
-            if newLeader == oldLeaders[ 0 ][ 2 ]:
-                # correct leader was elected
-                correctCandidateResult = main.TRUE
-            else:
-                correctCandidateResult = main.FALSE
-                main.log.error( "Candidate {} was elected. {} should have had priority.".format(
-                                    newLeader, oldLeaders[ 0 ][ 2 ] ) )
-        else:
-            main.log.warn( "Could not determine who should be the correct leader" )
-            main.log.debug( oldLeaders[ 0 ] )
-            correctCandidateResult = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=correctCandidateResult,
-            onpass="Correct Candidate Elected",
-            onfail="Incorrect Candidate Elected" )
-
-        main.step( "Run for election on old leader( just so everyone " +
-                   "is in the hat )" )
-        if oldLeaderCLI is not None:
-            runResult = oldLeaderCLI.electionTestRun()
-        else:
-            main.log.error( "No old leader to re-elect" )
-            runResult = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=runResult,
-            onpass="App re-ran for election",
-            onfail="App failed to run for election" )
-
-        main.step(
-            "Check that oldLeader is a candidate, and leader if only 1 node" )
-        # verify leader didn't just change
-        # Get new leaders and candidates
-        reRunLeaders = []
-        time.sleep( 5 )  # Paremterize
-        positionResult, reRunLeaders = main.HA.consistentLeaderboards( activeCLIs )
-
-        # Check that the re-elected node is last on the candidate List
-        if not reRunLeaders[ 0 ]:
-            positionResult = main.FALSE
-        elif oldLeader != reRunLeaders[ 0 ][ -1 ]:
-            main.log.error( "Old Leader ({}) not in the proper position: {} ".format( str( oldLeader ),
-                                                                                      str( reRunLeaders[ 0 ] ) ) )
-            positionResult = main.FALSE
-        utilities.assert_equals(
-            expect=True,
-            actual=positionResult,
-            onpass="Old leader successfully re-ran for election",
-            onfail="Something went wrong with Leadership election after " +
-                   "the old leader re-ran for election" )
+        main.HA.isElectionFunctional( main )
 
     def CASE16( self, main ):
         """
         Install Distributed Primitives app
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        # Variables for the distributed primitives tests
-        main.pCounterName = "TestON-Partitions"
-        main.pCounterValue = 0
-        main.onosSet = set( [] )
-        main.onosSetName = "TestON-set"
-
-        description = "Install Primitives app"
-        main.case( description )
-        main.step( "Install Primitives app" )
-        appName = "org.onosproject.distributedprimitives"
-        node = main.activeNodes[ 0 ]
-        appResults = main.CLIs[ node ].activateApp( appName )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=appResults,
-                                 onpass="Primitives app activated",
-                                 onfail="Primitives app not activated" )
-        time.sleep( 5 )  # To allow all nodes to activate
+        main.HA.installDistributedPrimitiveApp( main )
 
     def CASE17( self, main ):
         """
         Check for basic functionality with distributed primitives
         """
-        main.HA.CASE17( main )
+        main.HA.checkDistPrimitivesFunc( main )
diff --git a/TestON/tests/HA/HAsanity/HAsanity.params b/TestON/tests/HA/HAsanity/HAsanity.params
index 166c559..edd6bfb 100644
--- a/TestON/tests/HA/HAsanity/HAsanity.params
+++ b/TestON/tests/HA/HAsanity/HAsanity.params
@@ -34,8 +34,10 @@
         <cellName>HA</cellName>
         <appString>drivers,openflow,proxyarp,mobility</appString>
     </ENV>
-    <Git> False </Git>
-    <branch> master </branch>
+    <GIT>
+        <pull>False</pull>
+        <branch>master</branch>
+    </GIT>
     <num_controllers> 7 </num_controllers>
     <tcpdump> False </tcpdump>
 
diff --git a/TestON/tests/HA/HAsanity/HAsanity.py b/TestON/tests/HA/HAsanity/HAsanity.py
index 9505cb5..c40c785 100644
--- a/TestON/tests/HA/HAsanity/HAsanity.py
+++ b/TestON/tests/HA/HAsanity/HAsanity.py
@@ -50,1714 +50,68 @@
         import time
         import json
         main.log.info( "ONOS HA Sanity test - initialization" )
-        main.case( "Setting up test environment" )
-        main.caseExplanation = "Setup the test environment including " +\
-                                "installing ONOS, starting Mininet and ONOS" +\
-                                "cli sessions."
-
-        # load some variables from the params file
-        PULLCODE = False
-        if main.params[ 'Git' ] == 'True':
-            PULLCODE = True
-        gitBranch = main.params[ 'branch' ]
-        cellName = main.params[ 'ENV' ][ 'cellName' ]
-
-        main.numCtrls = int( main.params[ 'num_controllers' ] )
-        if main.ONOSbench.maxNodes:
-            if main.ONOSbench.maxNodes < main.numCtrls:
-                main.numCtrls = int( main.ONOSbench.maxNodes )
-        # TODO: refactor how to get onos port, maybe put into component tag?
-        # set global variables
-        global ONOS1Port
-        global ONOS2Port
-        global ONOS3Port
-        global ONOS4Port
-        global ONOS5Port
-        global ONOS6Port
-        global ONOS7Port
         # These are for csv plotting in jenkins
-        global labels
-        global data
-        labels = []
-        data = []
-
-        # 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' ]
-
+        main.HAlabels = []
+        main.HAdata = []
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found exiting the test" )
+            main.exit()
+        main.testSetUp.envSetupDescription()
         try:
             from tests.HA.dependencies.HA import HA
             main.HA = HA()
+            # load some variables from the params file
+            cellName = main.params[ 'ENV' ][ 'cellName' ]
+            main.apps = main.params[ 'ENV' ][ 'appString' ]
+            main.numCtrls = int( main.params[ 'num_controllers' ] )
+            if main.ONOSbench.maxNodes and \
+                            main.ONOSbench.maxNodes < main.numCtrls:
+                main.numCtrls = int( main.ONOSbench.maxNodes )
+            main.maxNodes = main.numCtrls
+            stepResult = main.testSetUp.envSetup( hasNode=True )
         except Exception as e:
-            main.log.exception( e )
-            main.cleanup()
-            main.exit()
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
+        main.HA.generateGraph( "HAsanity" )
 
-        main.CLIs = []
-        main.nodes = []
-        ipList = []
-        for i in range( 1, main.numCtrls + 1 ):
-            try:
-                main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
-                main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
-                ipList.append( main.nodes[ -1 ].ip_address )
-            except AttributeError:
-                break
+        main.testSetUp.ONOSSetUp( main.Mininet1, cellName=cellName, removeLog=True,
+                                  extraApply=main.HA.startingMininet )
 
-        main.step( "Create cell file" )
-        cellAppString = main.params[ 'ENV' ][ 'appString' ]
-        main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
-                                       main.Mininet1.ip_address,
-                                       cellAppString, ipList, main.ONOScli1.karafUser )
-        main.step( "Applying cell variable to environment" )
-        cellResult = main.ONOSbench.setCell( cellName )
-        verifyResult = main.ONOSbench.verifyCell()
-
-        # FIXME:this is short term fix
-        main.log.info( "Removing raft logs" )
-        main.ONOSbench.onosRemoveRaftLogs()
-
-        main.log.info( "Uninstalling ONOS" )
-        for node in main.nodes:
-            main.ONOSbench.onosUninstall( node.ip_address )
-
-        # Make sure ONOS is DEAD
-        main.log.info( "Killing any ONOS processes" )
-        killResults = main.TRUE
-        for node in main.nodes:
-            killed = main.ONOSbench.onosKill( node.ip_address )
-            killResults = killResults and killed
-
-        gitPullResult = main.TRUE
-
-        main.step( "Starting Mininet" )
-        # scp topo file to mininet
-        # TODO: move to params?
-        topoName = "obelisk.py"
-        filePath = main.ONOSbench.home + "/tools/test/topos/"
-        main.ONOSbench.scp( main.Mininet1,
-                            filePath + topoName,
-                            main.Mininet1.home,
-                            direction="to" )
-        mnResult = main.Mininet1.startNet()
-        utilities.assert_equals( expect=main.TRUE, actual=mnResult,
-                                 onpass="Mininet Started",
-                                 onfail="Error starting Mininet" )
-
-        main.step( "Git checkout and pull " + gitBranch )
-        if PULLCODE:
-            main.ONOSbench.gitCheckout( gitBranch )
-            gitPullResult = main.ONOSbench.gitPull()
-            # values of 1 or 3 are good
-            utilities.assert_lesser( expect=0, actual=gitPullResult,
-                                      onpass="Git pull successful",
-                                      onfail="Git pull failed" )
-        main.ONOSbench.getVersion( report=True )
-
-        # GRAPHS
-        # NOTE: important params here:
-        #       job = name of Jenkins job
-        #       Plot Name = Plot-HA, only can be used if multiple plots
-        #       index = The number of the graph under plot name
-        job = "HAsanity"
-        plotName = "Plot-HA"
-        index = "2"
-        graphs = '<ac:structured-macro ac:name="html">\n'
-        graphs += '<ac:plain-text-body><![CDATA[\n'
-        graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
-                  '/plot/' + plotName + '/getPlot?index=' + index +\
-                  '&width=500&height=300"' +\
-                  'noborder="0" width="500" height="300" scrolling="yes" ' +\
-                  'seamless="seamless"></iframe>\n'
-        graphs += ']]></ac:plain-text-body>\n'
-        graphs += '</ac:structured-macro>\n'
-        main.log.wiki( graphs )
-
-        main.step( "Creating ONOS package" )
-        packageResult = main.ONOSbench.buckBuild()
-        utilities.assert_equals( expect=main.TRUE, actual=packageResult,
-                                 onpass="ONOS package successful",
-                                 onfail="ONOS package failed" )
-
-        main.step( "Installing ONOS package" )
-        onosInstallResult = main.TRUE
-        for node in main.nodes:
-            tmpResult = main.ONOSbench.onosInstall( options="-f",
-                                                    node=node.ip_address )
-            onosInstallResult = onosInstallResult and tmpResult
-        utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
-                                 onpass="ONOS install successful",
-                                 onfail="ONOS install failed" )
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.TRUE
-        for node in main.nodes:
-            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=node.ip_address )
-        utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        main.step( "Checking if ONOS is up yet" )
-        for i in range( 2 ):
-            onosIsupResult = main.TRUE
-            for node in main.nodes:
-                started = main.ONOSbench.isup( node.ip_address )
-                if not started:
-                    main.log.error( node.name + " hasn't started" )
-                onosIsupResult = onosIsupResult and started
-            if onosIsupResult == main.TRUE:
-                break
-        utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
-                                 onpass="ONOS startup successful",
-                                 onfail="ONOS startup failed" )
-
-        main.step( "Starting ONOS CLI sessions" )
-        cliResults = main.TRUE
-        threads = []
-        for i in range( main.numCtrls ):
-            t = main.Thread( target=main.CLIs[ i ].startOnosCli,
-                             name="startOnosCli-" + str( i ),
-                             args=[ main.nodes[ i ].ip_address ] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            cliResults = cliResults and t.result
-        utilities.assert_equals( expect=main.TRUE, actual=cliResults,
-                                 onpass="ONOS cli startup successful",
-                                 onfail="ONOS cli startup failed" )
-
-        # Create a list of active nodes for use when some nodes are stopped
-        main.activeNodes = [ i for i in range( 0, len( main.CLIs ) ) ]
-
-        if main.params[ 'tcpdump' ].lower() == "true":
-            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' ] )
-
-        main.step( "Checking ONOS nodes" )
-        nodeResults = utilities.retry( main.HA.nodesCheck,
-                                       False,
-                                       args=[ main.activeNodes ],
-                                       attempts=5 )
-
-        utilities.assert_equals( expect=True, actual=nodeResults,
-                                 onpass="Nodes check successful",
-                                 onfail="Nodes check NOT successful" )
-
-        if not nodeResults:
-            for i in main.activeNodes:
-                cli = main.CLIs[ i ]
-                main.log.debug( "{} components not ACTIVE: \n{}".format(
-                    cli.name,
-                    cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
-            main.log.error( "Failed to start ONOS, stopping test" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Activate apps defined in the params file" )
-        # get data from the params
-        apps = main.params.get( 'apps' )
-        if apps:
-            apps = apps.split( ',' )
-            main.log.warn( apps )
-            activateResult = True
-            for app in apps:
-                main.CLIs[ 0 ].app( app, "Activate" )
-            # TODO: check this worked
-            time.sleep( 10 )  # wait for apps to activate
-            for app in apps:
-                state = main.CLIs[ 0 ].appStatus( app )
-                if state == "ACTIVE":
-                    activateResult = activateResult and True
-                else:
-                    main.log.error( "{} is in {} state".format( app, state ) )
-                    activateResult = False
-            utilities.assert_equals( expect=True,
-                                     actual=activateResult,
-                                     onpass="Successfully activated apps",
-                                     onfail="Failed to activate apps" )
-        else:
-            main.log.warn( "No apps were specified to be loaded after startup" )
-
-        main.step( "Set ONOS configurations" )
-        config = main.params.get( 'ONOS_Configuration' )
-        if config:
-            main.log.debug( config )
-            checkResult = main.TRUE
-            for component in config:
-                for setting in config[ component ]:
-                    value = config[ component ][ setting ]
-                    check = main.CLIs[ 0 ].setCfg( component, setting, value )
-                    main.log.info( "Value was changed? {}".format( main.TRUE == check ) )
-                    checkResult = check and checkResult
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=checkResult,
-                                     onpass="Successfully set config",
-                                     onfail="Failed to set config" )
-        else:
-            main.log.warn( "No configurations were specified to be changed after startup" )
-
-        main.step( "App Ids check" )
-        appCheck = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
-                             name="appToIDCheck-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            appCheck = appCheck and t.result
-        if appCheck != main.TRUE:
-            node = main.activeNodes[ 0 ]
-            main.log.warn( main.CLIs[ node ].apps() )
-            main.log.warn( main.CLIs[ node ].appIDs() )
-        utilities.assert_equals( expect=main.TRUE, actual=appCheck,
-                                 onpass="App Ids seem to be correct",
-                                 onfail="Something is wrong with app Ids" )
+        main.HA.initialSetUp()
 
     def CASE2( self, main ):
         """
         Assign devices to controllers
         """
-        import re
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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.case( "Assigning devices to controllers" )
-        main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
-                                "and check that an ONOS node becomes the " +\
-                                "master of the device."
-        main.step( "Assign switches to controllers" )
-
-        ipList = []
-        for i in range( main.numCtrls ):
-            ipList.append( main.nodes[ i ].ip_address )
-        swList = []
-        for i in range( 1, 29 ):
-            swList.append( "s" + str( i ) )
-        main.Mininet1.assignSwController( sw=swList, ip=ipList )
-
-        mastershipCheck = main.TRUE
-        for i in range( 1, 29 ):
-            response = main.Mininet1.getSwController( "s" + str( i ) )
-            try:
-                main.log.info( str( response ) )
-            except Exception:
-                main.log.info( repr( response ) )
-            for node in main.nodes:
-                if re.search( "tcp:" + node.ip_address, response ):
-                    mastershipCheck = mastershipCheck and main.TRUE
-                else:
-                    main.log.error( "Error, node " + node.ip_address + " is " +
-                                    "not in the list of controllers s" +
-                                    str( i ) + " is connecting to." )
-                    mastershipCheck = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=mastershipCheck,
-            onpass="Switch mastership assigned correctly",
-            onfail="Switches not assigned correctly to controllers" )
+        main.HA.assignDevices( main )
 
     def CASE21( self, main ):
         """
         Assign mastership to controllers
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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.case( "Assigning Controller roles for switches" )
-        main.caseExplanation = "Check that ONOS is connected to each " +\
-                                "device. Then manually assign" +\
-                                " mastership to specific ONOS nodes using" +\
-                                " 'device-role'"
-        main.step( "Assign mastership of switches to specific controllers" )
-        # Manually assign mastership to the controller we want
-        roleCall = main.TRUE
-
-        ipList = []
-        deviceList = []
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        try:
-            # Assign mastership to specific controllers. This assignment was
-            # determined for a 7 node cluser, but will work with any sized
-            # cluster
-            for i in range( 1, 29 ):  # switches 1 through 28
-                # set up correct variables:
-                if i == 1:
-                    c = 0
-                    ip = main.nodes[ c ].ip_address  # ONOS1
-                    deviceId = onosCli.getDevice( "1000" ).get( 'id' )
-                elif i == 2:
-                    c = 1 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS2
-                    deviceId = onosCli.getDevice( "2000" ).get( 'id' )
-                elif i == 3:
-                    c = 1 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS2
-                    deviceId = onosCli.getDevice( "3000" ).get( 'id' )
-                elif i == 4:
-                    c = 3 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS4
-                    deviceId = onosCli.getDevice( "3004" ).get( 'id' )
-                elif i == 5:
-                    c = 2 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS3
-                    deviceId = onosCli.getDevice( "5000" ).get( 'id' )
-                elif i == 6:
-                    c = 2 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS3
-                    deviceId = onosCli.getDevice( "6000" ).get( 'id' )
-                elif i == 7:
-                    c = 5 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS6
-                    deviceId = onosCli.getDevice( "6007" ).get( 'id' )
-                elif i >= 8 and i <= 17:
-                    c = 4 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS5
-                    dpid = '3' + str( i ).zfill( 3 )
-                    deviceId = onosCli.getDevice( dpid ).get( 'id' )
-                elif i >= 18 and i <= 27:
-                    c = 6 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS7
-                    dpid = '6' + str( i ).zfill( 3 )
-                    deviceId = onosCli.getDevice( dpid ).get( 'id' )
-                elif i == 28:
-                    c = 0
-                    ip = main.nodes[ c ].ip_address  # ONOS1
-                    deviceId = onosCli.getDevice( "2800" ).get( 'id' )
-                else:
-                    main.log.error( "You didn't write an else statement for " +
-                                    "switch s" + str( i ) )
-                    roleCall = main.FALSE
-                # Assign switch
-                assert deviceId, "No device id for s" + str( i ) + " in ONOS"
-                # TODO: make this controller dynamic
-                roleCall = roleCall and onosCli.deviceRole( deviceId, ip )
-                ipList.append( ip )
-                deviceList.append( deviceId )
-        except ( AttributeError, AssertionError ):
-            main.log.exception( "Something is wrong with ONOS device view" )
-            main.log.info( onosCli.devices() )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=roleCall,
-            onpass="Re-assigned switch mastership to designated controller",
-            onfail="Something wrong with deviceRole calls" )
-
-        main.step( "Check mastership was correctly assigned" )
-        roleCheck = main.TRUE
-        # NOTE: This is due to the fact that device mastership change is not
-        #       atomic and is actually a multi step process
-        time.sleep( 5 )
-        for i in range( len( ipList ) ):
-            ip = ipList[ i ]
-            deviceId = deviceList[ i ]
-            # Check assignment
-            master = onosCli.getRole( deviceId ).get( 'master' )
-            if ip in master:
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-                main.log.error( "Error, controller " + ip + " is not" +
-                                " master " + "of device " +
-                                str( deviceId ) + ". Master is " +
-                                repr( master ) + "." )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=roleCheck,
-            onpass="Switches were successfully reassigned to designated " +
-                   "controller",
-            onfail="Switches were not successfully reassigned" )
+        main.HA.assignMastership( main )
 
     def CASE3( self, main ):
         """
         Assign intents
         """
-        import time
-        import json
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-        try:
-            labels
-        except NameError:
-            main.log.error( "labels not defined, setting to []" )
-            labels = []
-        try:
-            data
-        except NameError:
-            main.log.error( "data not defined, setting to []" )
-            data = []
-        main.case( "Adding host Intents" )
-        main.caseExplanation = "Discover hosts by using pingall then " +\
-                                "assign predetermined host-to-host intents." +\
-                                " After installation, check that the intent" +\
-                                " is distributed to all nodes and the state" +\
-                                " is INSTALLED"
-
-        # install onos-app-fwd
-        main.step( "Install reactive forwarding app" )
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        installResults = onosCli.activateApp( "org.onosproject.fwd" )
-        utilities.assert_equals( expect=main.TRUE, actual=installResults,
-                                 onpass="Install fwd successful",
-                                 onfail="Install fwd failed" )
-
-        main.step( "Check app ids" )
-        appCheck = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
-                             name="appToIDCheck-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            appCheck = appCheck and t.result
-        if appCheck != main.TRUE:
-            main.log.warn( onosCli.apps() )
-            main.log.warn( onosCli.appIDs() )
-        utilities.assert_equals( expect=main.TRUE, actual=appCheck,
-                                 onpass="App Ids seem to be correct",
-                                 onfail="Something is wrong with app Ids" )
-
-        main.step( "Discovering Hosts( Via pingall for now )" )
-        # FIXME: Once we have a host discovery mechanism, use that instead
-        # REACTIVE FWD test
-        pingResult = main.FALSE
-        passMsg = "Reactive Pingall test passed"
-        time1 = time.time()
-        pingResult = main.Mininet1.pingall()
-        time2 = time.time()
-        if not pingResult:
-            main.log.warn( "First pingall failed. Trying again..." )
-            pingResult = main.Mininet1.pingall()
-            passMsg += " on the second try"
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=pingResult,
-            onpass=passMsg,
-            onfail="Reactive Pingall failed, " +
-                   "one or more ping pairs failed" )
-        main.log.info( "Time for pingall: %2f seconds" %
-                       ( time2 - time1 ) )
-        if not pingResult:
-            main.cleanup()
-            main.exit()
-        # timeout for fwd flows
-        time.sleep( 11 )
-        # uninstall onos-app-fwd
-        main.step( "Uninstall reactive forwarding app" )
-        node = main.activeNodes[ 0 ]
-        uninstallResult = main.CLIs[ node ].deactivateApp( "org.onosproject.fwd" )
-        utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
-                                 onpass="Uninstall fwd successful",
-                                 onfail="Uninstall fwd failed" )
-
-        main.step( "Check app ids" )
-        threads = []
-        appCheck2 = main.TRUE
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
-                             name="appToIDCheck-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            appCheck2 = appCheck2 and t.result
-        if appCheck2 != main.TRUE:
-            node = main.activeNodes[ 0 ]
-            main.log.warn( main.CLIs[ node ].apps() )
-            main.log.warn( main.CLIs[ node ].appIDs() )
-        utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
-                                 onpass="App Ids seem to be correct",
-                                 onfail="Something is wrong with app Ids" )
-
-        main.step( "Add host intents via cli" )
-        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 ) )
-            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 = onosCli.getHost( host1 )
-            host2Dict = onosCli.getHost( host2 )
-            host1Id = None
-            host2Id = None
-            if host1Dict and host2Dict:
-                host1Id = host1Dict.get( 'id', None )
-                host2Id = host2Dict.get( 'id', None )
-            if host1Id and host2Id:
-                nodeNum = ( i % len( main.activeNodes ) )
-                node = main.activeNodes[ nodeNum ]
-                tmpId = main.CLIs[ node ].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 for h" + str( i ) +
-                                " and/or h" + str( i + 10 ) )
-                node = main.activeNodes[ 0 ]
-                hosts = main.CLIs[ node ].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
-        utilities.assert_equals( expect=main.TRUE, actual=hostResult,
-                                 onpass="Found a host id for each host",
-                                 onfail="Error looking up host ids" )
-
-        intentStart = time.time()
-        onosIds = onosCli.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
-        if intentAddResult:
-            intentStop = time.time()
-        else:
-            intentStop = None
-        # Print the intent states
-        intents = onosCli.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 = onosCli.leaders()
-        try:
-            missing = False
-            if leaders:
-                parsedLeaders = json.loads( leaders )
-                main.log.warn( json.dumps( parsedLeaders,
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-                # check for all intent partitions
-                topics = []
-                for i in range( 14 ):
-                    topics.append( "work-partition-" + str( i ) )
-                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" )
-                        missing = True
-            else:
-                main.log.error( "leaders() returned None" )
-        except ( ValueError, TypeError ):
-            main.log.exception( "Error parsing leaders" )
-            main.log.error( repr( leaders ) )
-        # Check all nodes
-        if missing:
-            for i in main.activeNodes:
-                response = main.CLIs[ i ].leaders( jsonFormat=False )
-                main.log.warn( str( main.CLIs[ i ].name ) + " leaders output: \n" +
-                               str( response ) )
-
-        partitions = onosCli.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 = onosCli.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( intentAddResult and not missingIntents and
-                                installedCheck )
-        if not intentAddResult:
-            main.log.error( "Error in pushing host intents to ONOS" )
-
-        main.step( "Intent Anti-Entropy dispersion" )
-        for j in range( 100 ):
-            correct = True
-            main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
-            for i in main.activeNodes:
-                onosIds = []
-                ids = main.CLIs[ i ].getAllIntentsId()
-                onosIds.append( ids )
-                main.log.debug( "Intents in " + main.CLIs[ i ].name + ": " +
-                                str( sorted( onosIds ) ) )
-                if sorted( ids ) != sorted( intentIds ):
-                    main.log.warn( "Set of intent IDs doesn't match" )
-                    correct = False
-                    break
-                else:
-                    intents = json.loads( main.CLIs[ i ].intents() )
-                    for intent in intents:
-                        if intent[ 'state' ] != "INSTALLED":
-                            main.log.warn( "Intent " + intent[ 'id' ] +
-                                           " is " + intent[ 'state' ] )
-                            correct = False
-                            break
-            if correct:
-                break
-            else:
-                time.sleep( 1 )
-        if not intentStop:
-            intentStop = time.time()
-        global gossipTime
-        gossipTime = intentStop - intentStart
-        main.log.info( "It took about " + str( gossipTime ) +
-                        " seconds for all intents to appear in each node" )
-        gossipPeriod = int( main.params[ 'timers' ][ 'gossip' ] )
-        maxGossipTime = gossipPeriod * len( main.activeNodes )
-        utilities.assert_greater_equals(
-                expect=maxGossipTime, actual=gossipTime,
-                onpass="ECM anti-entropy for intents worked within " +
-                       "expected time",
-                onfail="Intent ECM anti-entropy took too long. " +
-                       "Expected time:{}, Actual time:{}".format( maxGossipTime,
-                                                                  gossipTime ) )
-        if gossipTime <= maxGossipTime:
-            intentAddResult = True
-
-        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 = onosCli.getAllIntentsId()
-            main.log.info( "Submitted intents: " + str( intentIds ) )
-            main.log.info( "Intents in ONOS: " + str( onosIds ) )
-            # Print the intent states
-            intents = onosCli.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 = onosCli.leaders()
-            try:
-                missing = False
-                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( "work-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" )
-                            missing = True
-                else:
-                    main.log.error( "leaders() returned None" )
-            except ( ValueError, TypeError ):
-                main.log.exception( "Error parsing leaders" )
-                main.log.error( repr( leaders ) )
-            # Check all nodes
-            if missing:
-                for i in main.activeNodes:
-                    node = main.CLIs[ i ]
-                    response = node.leaders( jsonFormat=False )
-                    main.log.warn( str( node.name ) + " leaders output: \n" +
-                                   str( response ) )
-
-            partitions = onosCli.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 = onosCli.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 ) )
+        main.HA.assignIntents( main )
 
     def CASE4( self, main ):
         """
         Ping across added host intents
         """
-        import json
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-        main.case( "Verify connectivity by sending traffic across Intents" )
-        main.caseExplanation = "Ping across added host intents to check " +\
-                                "functionality and check the state of " +\
-                                "the intent"
 
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        main.step( "Check Intent state" )
-        installedCheck = False
-        loopCount = 0
-        while not installedCheck and loopCount < 40:
-            installedCheck = True
-            # Print the intent states
-            intents = onosCli.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." )
-            # Print states
-            intentStates.sort()
-            for i, s in intentStates:
-                count += 1
-                main.log.info( "%-6s%-15s%-15s" %
-                               ( str( count ), str( i ), str( s ) ) )
-            if not installedCheck:
-                time.sleep( 1 )
-                loopCount += 1
-        utilities.assert_equals( expect=True, actual=installedCheck,
-                                 onpass="Intents are all INSTALLED",
-                                 onfail="Intents are not all in " +
-                                        "INSTALLED state" )
-
-        main.step( "Ping across added host intents" )
-        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.error(
-                "Intents have not been installed correctly, pings failed." )
-            # TODO: pretty print
-            main.log.warn( "ONOS1 intents: " )
-            try:
-                tmpIntents = onosCli.intents()
-                main.log.warn( json.dumps( json.loads( tmpIntents ),
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-            except ( ValueError, TypeError ):
-                main.log.warn( repr( tmpIntents ) )
-        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." )
-
-        main.step( "Check leadership of topics" )
-        leaders = onosCli.leaders()
-        topicCheck = main.TRUE
-        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
-                # TODO: Look at Devices as topics now that it uses this system
-                topics = []
-                for i in range( 14 ):
-                    topics.append( "work-partition-" + str( i ) )
-                # FIXME: this should only be after we start the app
-                # FIXME: topics.append( "org.onosproject.election" )
-                # Print leaders output
-                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" )
-                        topicCheck = main.FALSE
-            else:
-                main.log.error( "leaders() returned None" )
-                topicCheck = main.FALSE
-        except ( ValueError, TypeError ):
-            topicCheck = main.FALSE
-            main.log.exception( "Error parsing leaders" )
-            main.log.error( repr( leaders ) )
-            # TODO: Check for a leader of these topics
-        # Check all nodes
-        if topicCheck:
-            for i in main.activeNodes:
-                node = main.CLIs[ i ]
-                response = node.leaders( jsonFormat=False )
-                main.log.warn( str( node.name ) + " leaders output: \n" +
-                               str( response ) )
-
-        utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
-                                 onpass="intent Partitions is in leaders",
-                                 onfail="Some topics were lost " )
-        # Print partitions
-        partitions = onosCli.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 ) )
-        # Print Pending Map
-        pendingMap = onosCli.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 = onosCli.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 = onosCli.leaders()
-            try:
-                missing = False
-                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( "work-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" )
-                            missing = True
-                else:
-                    main.log.error( "leaders() returned None" )
-            except ( ValueError, TypeError ):
-                main.log.exception( "Error parsing leaders" )
-                main.log.error( repr( leaders ) )
-            if missing:
-                for i in main.activeNodes:
-                    node = main.CLIs[ i ]
-                    response = node.leaders( jsonFormat=False )
-                    main.log.warn( str( node.name ) + " leaders output: \n" +
-                                   str( response ) )
-
-            partitions = onosCli.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 = onosCli.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 ) )
-        # Print flowrules
-        node = main.activeNodes[ 0 ]
-        main.log.debug( main.CLIs[ node ].flows( jsonFormat=False ) )
-        main.step( "Wait a minute then ping again" )
-        # the wait is above
-        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.error(
-                "Intents have not been installed correctly, pings failed." )
-            # TODO: pretty print
-            main.log.warn( "ONOS1 intents: " )
-            try:
-                tmpIntents = onosCli.intents()
-                main.log.warn( json.dumps( json.loads( tmpIntents ),
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-            except ( ValueError, TypeError ):
-                main.log.warn( repr( tmpIntents ) )
-        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." )
+        main.HA.pingAcrossHostIntent( main, True, True )
 
     def CASE5( self, main ):
         """
         Reading state of ONOS
         """
-        import json
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        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 each other and also with past states
-
-        main.step( "Check that each switch has a master" )
-        global mastershipState
-        mastershipState = '[]'
-
-        # Assert that each device has a master
-        rolesNotNull = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( "Get the Mastership of each switch from each controller" )
-        ONOSMastership = []
-        mastershipCheck = main.FALSE
-        consistentMastership = True
-        rolesResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSMastership ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSMastership[ i ] or "Error" in ONOSMastership[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " roles" )
-                main.log.warn( "ONOS" + node + " 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.info(
-                "Switch roles are consistent across all ONOS nodes" )
-        else:
-            consistentMastership = False
-        utilities.assert_equals(
-            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( len( main.activeNodes ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                try:
-                    main.log.warn(
-                        "ONOS" + node + " 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 = []
-        ONOSIntents = []
-        intentCheck = main.FALSE
-        consistentIntents = True
-        intentsResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSIntents ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " intents" )
-                main.log.warn( "ONOS" + node + " 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.info( "Intents are consistent across all ONOS " +
-                             "nodes" )
-        else:
-            consistentIntents = False
-            main.log.error( "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:
-            # Try to make it easy to figure out what is happening
-            #
-            # Intent      ONOS1      ONOS2    ...
-            #  0x01     INSTALLED  INSTALLING
-            #  ...        ...         ...
-            #  ...        ...         ...
-            title = "   Id"
-            for n in main.activeNodes:
-                title += " " * 10 + "ONOS" + str( n + 1 )
-            main.log.warn( title )
-            # get all intent keys in the cluster
-            keys = []
-            try:
-                # Get the set of all intent keys
-                for nodeStr in ONOSIntents:
-                    node = json.loads( nodeStr )
-                    for intent in node:
-                        keys.append( intent.get( 'id' ) )
-                keys = set( keys )
-                # For each intent key, print the state on each node
-                for key in keys:
-                    row = "%-13s" % key
-                    for nodeStr in ONOSIntents:
-                        node = json.loads( nodeStr )
-                        for intent in node:
-                            if intent.get( 'id', "Error" ) == key:
-                                row += "%-15s" % intent.get( 'state' )
-                    main.log.warn( row )
-                # End of intent state table
-            except ValueError as e:
-                main.log.exception( e )
-                main.log.debug( "nodeStr was: " + repr( nodeStr ) )
-
-        if intentsResults and not consistentIntents:
-            # print the json objects
-            n = str( main.activeNodes[ -1 ] + 1 )
-            main.log.debug( "ONOS" + n + " intents: " )
-            main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
-                                        sort_keys=True,
-                                        indent=4,
-                                        separators=( ',', ': ' ) ) )
-            for i in range( len( ONOSIntents ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
-                    main.log.debug( "ONOS" + node + " intents: " )
-                    main.log.debug( json.dumps( json.loads( ONOSIntents[ i ] ),
-                                                sort_keys=True,
-                                                indent=4,
-                                                separators=( ',', ': ' ) ) )
-                else:
-                    main.log.debug( "ONOS" + node + " intents match ONOS" +
-                                    n + " intents" )
-        elif intentsResults and consistentIntents:
-            intentCheck = main.TRUE
-            intentState = ONOSIntents[ 0 ]
-
-        main.step( "Get the flows from each controller" )
-        global flowState
-        flowState = []
-        ONOSFlows = []
-        ONOSFlowsJson = []
-        flowCheck = main.FALSE
-        consistentFlows = True
-        flowsResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].flows,
-                             name="flows-" + str( i ),
-                             args=[],
-                             kwargs={ 'jsonFormat': True } )
-            threads.append( t )
-            t.start()
-
-        # NOTE: Flows command can take some time to run
-        time.sleep( 30 )
-        for t in threads:
-            t.join()
-            result = t.result
-            ONOSFlows.append( result )
-
-        for i in range( len( ONOSFlows ) ):
-            num = str( main.activeNodes[ i ] + 1 )
-            if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
-                main.log.error( "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.info( "Flow count is consistent across all ONOS nodes" )
-        else:
-            consistentFlows = False
-        utilities.assert_equals(
-            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( len( ONOSFlows ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                try:
-                    main.log.warn(
-                        "ONOS" + node + " flows: " +
-                        json.dumps( json.loads( ONOSFlows[ i ] ), sort_keys=True,
-                                    indent=4, separators=( ',', ': ' ) ) )
-                except ( ValueError, TypeError ):
-                    main.log.warn( "ONOS" + node + " 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.Mininet1.getFlowTable( "s" + str( i ), version="1.3", debug=False ) )
-        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" )
-        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( "Collecting topology information from ONOS" )
-        devices = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].devices,
-                             name="devices-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            devices.append( t.result )
-        hosts = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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" )
-                main.log.warn( repr( t.result ) )
-                hosts.append( None )
-
-        ports = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].ports,
-                             name="ports-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            ports.append( t.result )
-        links = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].links,
-                             name="links-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            links.append( t.result )
-        clusters = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].clusters,
-                             name="clusters-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            clusters.append( t.result )
-        # Compare json objects for hosts and dataplane clusters
-
-        # hosts
-        main.step( "Host view is consistent across ONOS nodes" )
-        consistentHostsResult = main.TRUE
-        for controller in range( len( hosts ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if hosts[ controller ] and "Error" not in hosts[ controller ]:
-                if hosts[ controller ] == hosts[ 0 ]:
-                    continue
-                else:  # hosts not consistent
-                    main.log.error( "hosts from ONOS" +
-                                     controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    main.log.warn( repr( hosts[ controller ] ) )
-                    consistentHostsResult = main.FALSE
-
-            else:
-                main.log.error( "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" )
-
-        main.step( "Each host has an IP address" )
-        ipResult = main.TRUE
-        for controller in range( 0, len( hosts ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if hosts[ controller ]:
-                for host in hosts[ controller ]:
-                    if not host.get( 'ipAddresses', [] ):
-                        main.log.error( "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
-        main.step( "Cluster view is consistent across ONOS nodes" )
-        consistentClustersResult = main.TRUE
-        for controller in range( len( clusters ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if "Error" not in clusters[ controller ]:
-                if clusters[ controller ] == clusters[ 0 ]:
-                    continue
-                else:  # clusters not consistent
-                    main.log.error( "clusters from ONOS" + controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    consistentClustersResult = main.FALSE
-
-            else:
-                main.log.error( "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" )
-        if not consistentClustersResult:
-            main.log.debug( clusters )
-
-        # there should always only be one cluster
-        main.step( "Cluster view correct across ONOS nodes" )
-        try:
-            numClusters = len( json.loads( clusters[ 0 ] ) )
-        except ( ValueError, TypeError ):
-            main.log.exception( "Error parsing clusters[0]: " +
-                                repr( clusters[ 0 ] ) )
-            numClusters = "ERROR"
-        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
-        linksResults = main.TRUE
-        hostsResults = main.TRUE
-        mnSwitches = main.Mininet1.getSwitches()
-        mnLinks = main.Mininet1.getLinks()
-        mnHosts = main.Mininet1.getHosts()
-        for controller in main.activeNodes:
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if devices[ controller ] and ports[ controller ] and\
-                    "Error" not in devices[ controller ] and\
-                    "Error" not in ports[ controller ]:
-                currentDevicesResult = main.Mininet1.compareSwitches(
-                        mnSwitches,
-                        json.loads( devices[ controller ] ),
-                        json.loads( ports[ controller ] ) )
-            else:
-                currentDevicesResult = main.FALSE
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=currentDevicesResult,
-                                     onpass="ONOS" + controllerStr +
-                                     " Switches view is correct",
-                                     onfail="ONOS" + controllerStr +
-                                     " Switches view is incorrect" )
-            if links[ controller ] and "Error" not in links[ controller ]:
-                currentLinksResult = main.Mininet1.compareLinks(
-                        mnSwitches, mnLinks,
-                        json.loads( links[ controller ] ) )
-            else:
-                currentLinksResult = main.FALSE
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=currentLinksResult,
-                                     onpass="ONOS" + controllerStr +
-                                     " links view is correct",
-                                     onfail="ONOS" + controllerStr +
-                                     " links view is incorrect" )
-
-            if hosts[ controller ] and "Error" not in hosts[ controller ]:
-                currentHostsResult = main.Mininet1.compareHosts(
-                        mnHosts,
-                        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
-            linksResults = linksResults and currentLinksResult
-            hostsResults = hostsResults and currentHostsResult
-
-        main.step( "Device information is correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=devicesResults,
-            onpass="Device information is correct",
-            onfail="Device information is incorrect" )
-
-        main.step( "Links are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=linksResults,
-            onpass="Link are correct",
-            onfail="Links are incorrect" )
-
-        main.step( "Hosts are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=hostsResults,
-            onpass="Hosts are correct",
-            onfail="Hosts are incorrect" )
+        main.HA.readingState( main )
 
     def CASE6( self, main ):
         """
@@ -1781,309 +135,8 @@
         """
         Check state after ONOS failure
         """
-        import json
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-        main.case( "Running ONOS Constant State Tests" )
+        main.HA.checkStateAfterONOS( main, afterWhich=0, compareSwitch=True )
 
-        main.step( "Check that each switch has a master" )
-        # Assert that each device has a master
-        rolesNotNull = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( "Read device roles from ONOS" )
-        ONOSMastership = []
-        mastershipCheck = main.FALSE
-        consistentMastership = True
-        rolesResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSMastership ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSMastership[ i ] or "Error" in ONOSMastership[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " roles" )
-                main.log.warn( "ONOS" + node + " 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.info(
-                "Switch roles are consistent across all ONOS nodes" )
-        else:
-            consistentMastership = False
-        utilities.assert_equals(
-            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( len( ONOSMastership ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                main.log.warn( "ONOS" + node + " roles: ",
-                               json.dumps( json.loads( ONOSMastership[ i ] ),
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-
-        description2 = "Compare switch roles from before failure"
-        main.step( description2 )
-        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 ) ) )
-            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
-        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" )
-        ONOSIntents = []
-        intentCheck = main.FALSE
-        consistentIntents = True
-        intentsResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSIntents ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " intents" )
-                main.log.warn( "ONOS" + node + " 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.info( "Intents are consistent across all ONOS " +
-                             "nodes" )
-        else:
-            consistentIntents = False
-
-        # Try to make it easy to figure out what is happening
-        #
-        # Intent      ONOS1      ONOS2    ...
-        #  0x01     INSTALLED  INSTALLING
-        #  ...        ...         ...
-        #  ...        ...         ...
-        title = "   ID"
-        for n in main.activeNodes:
-            title += " " * 10 + "ONOS" + str( n + 1 )
-        main.log.warn( title )
-        # get all intent keys in the cluster
-        keys = []
-        for nodeStr in ONOSIntents:
-            node = json.loads( nodeStr )
-            for intent in node:
-                keys.append( intent.get( 'id' ) )
-        keys = set( keys )
-        for key in keys:
-            row = "%-13s" % key
-            for nodeStr in ONOSIntents:
-                node = json.loads( nodeStr )
-                for intent in node:
-                    if intent.get( 'id' ) == key:
-                        row += "%-15s" % intent.get( 'state' )
-            main.log.warn( row )
-        # End table view
-
-        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' ] )
-            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( len( main.activeNodes ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                main.log.warn( "ONOS" + node + " 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?
-        sameIntents = main.FALSE
-        try:
-            intentState
-        except NameError:
-            main.log.warn( "No previous intent state was saved" )
-        else:
-            if intentState and intentState == ONOSIntents[ 0 ]:
-                sameIntents = main.TRUE
-                main.log.info( "Intents are consistent with before failure" )
-            # TODO: possibly the states have changed? we may need to figure out
-            #       what the acceptable states are
-            elif len( intentState ) == len( ONOSIntents[ 0 ] ):
-                sameIntents = main.TRUE
-                try:
-                    before = json.loads( intentState )
-                    after = json.loads( ONOSIntents[ 0 ] )
-                    for intent in before:
-                        if intent not in after:
-                            sameIntents = main.FALSE
-                            main.log.debug( "Intent is not currently in ONOS " +
-                                            "(at least in the same form):" )
-                            main.log.debug( json.dumps( intent ) )
-                except ( ValueError, TypeError ):
-                    main.log.exception( "Exception printing intents" )
-                    main.log.debug( repr( ONOSIntents[ 0 ] ) )
-                    main.log.debug( repr( intentState ) )
-            if sameIntents == main.FALSE:
-                try:
-                    main.log.debug( "ONOS intents before: " )
-                    main.log.debug( json.dumps( json.loads( intentState ),
-                                                sort_keys=True, indent=4,
-                                                separators=( ',', ': ' ) ) )
-                    main.log.debug( "Current ONOS intents: " )
-                    main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
-                                                sort_keys=True, indent=4,
-                                                separators=( ',', ': ' ) ) )
-                except ( ValueError, TypeError ):
-                    main.log.exception( "Exception printing intents" )
-                    main.log.debug( repr( ONOSIntents[ 0 ] ) )
-                    main.log.debug( repr( intentState ) )
-            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
-        for i in range( 28 ):
-            main.log.info( "Checking flow table on s" + str( i + 1 ) )
-            tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
-            curSwitch = main.Mininet1.flowTableComp( flows[ i ], tmpFlows )
-            FlowTables = FlowTables and curSwitch
-            if curSwitch == main.FALSE:
-                main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
-        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.Mininet2.pingLongKill()
-        """
-        main.step( "Check the continuous pings to ensure that no packets " +
-                   "were dropped during component failure" )
-        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.info( "No loss of dataplane connectivity" )
-        utilities.assert_equals(
-            expect=main.FALSE,
-            actual=LossInPings,
-            onpass="No Loss of connectivity",
-            onfail="Loss of dataplane connectivity detected" )
-        """
         main.step( "Leadership Election is still functional" )
         # Test of LeadershipElection
         leaderList = []
@@ -2129,680 +182,45 @@
         """
         Compare topo
         """
-        import json
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        main.case( "Compare ONOS Topology view to Mininet topology" )
-        main.caseExplanation = "Compare topology objects between Mininet" +\
-                                " and ONOS"
-        topoResult = main.FALSE
-        topoFailMsg = "ONOS topology don't match Mininet"
-        elapsed = 0
-        count = 0
-        main.step( "Comparing ONOS topology to MN topology" )
-        startTime = time.time()
-        # Give time for Gossip to work
-        while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
-            devicesResults = main.TRUE
-            linksResults = main.TRUE
-            hostsResults = main.TRUE
-            hostAttachmentResults = True
-            count += 1
-            cliStart = time.time()
-            devices = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="devices-" + str( i ),
-                                 args=[ main.CLIs[ i ].devices, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                devices.append( t.result )
-            hosts = []
-            ipResult = main.TRUE
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="hosts-" + str( i ),
-                                 args=[ main.CLIs[ i ].hosts, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                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 ) )
-                    hosts.append( None )
-            for controller in range( 0, len( hosts ) ):
-                controllerStr = str( main.activeNodes[ controller ] + 1 )
-                if hosts[ controller ]:
-                    for host in hosts[ controller ]:
-                        if host is None or host.get( 'ipAddresses', [] ) == []:
-                            main.log.error(
-                                "Error with host ipAddresses on controller" +
-                                controllerStr + ": " + str( host ) )
-                            ipResult = main.FALSE
-            ports = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="ports-" + str( i ),
-                                 args=[ main.CLIs[ i ].ports, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                ports.append( t.result )
-            links = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="links-" + str( i ),
-                                 args=[ main.CLIs[ i ].links, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                links.append( t.result )
-            clusters = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="clusters-" + str( i ),
-                                 args=[ main.CLIs[ i ].clusters, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                clusters.append( t.result )
-
-            elapsed = time.time() - startTime
-            cliTime = time.time() - cliStart
-            print "Elapsed time: " + str( elapsed )
-            print "CLI time: " + str( cliTime )
-
-            if all( e is None for e in devices ) and\
-               all( e is None for e in hosts ) and\
-               all( e is None for e in ports ) and\
-               all( e is None for e in links ) and\
-               all( e is None for e in clusters ):
-                topoFailMsg = "Could not get topology from ONOS"
-                main.log.error( topoFailMsg )
-                continue  # Try again, No use trying to compare
-
-            mnSwitches = main.Mininet1.getSwitches()
-            mnLinks = main.Mininet1.getLinks()
-            mnHosts = main.Mininet1.getHosts()
-            for controller in range( len( main.activeNodes ) ):
-                controllerStr = str( main.activeNodes[ controller ] + 1 )
-                if devices[ controller ] and ports[ controller ] and\
-                        "Error" not in devices[ controller ] and\
-                        "Error" not in ports[ controller ]:
-
-                    try:
-                        currentDevicesResult = main.Mininet1.compareSwitches(
-                                mnSwitches,
-                                json.loads( devices[ controller ] ),
-                                json.loads( ports[ controller ] ) )
-                    except ( TypeError, ValueError ) as e:
-                        main.log.exception( "Object not as expected; devices={!r}\nports={!r}".format(
-                            devices[ controller ], ports[ controller ] ) )
-                else:
-                    currentDevicesResult = main.FALSE
-                utilities.assert_equals( expect=main.TRUE,
-                                         actual=currentDevicesResult,
-                                         onpass="ONOS" + controllerStr +
-                                         " Switches view is correct",
-                                         onfail="ONOS" + controllerStr +
-                                         " Switches view is incorrect" )
-
-                if links[ controller ] and "Error" not in links[ controller ]:
-                    currentLinksResult = main.Mininet1.compareLinks(
-                            mnSwitches, mnLinks,
-                            json.loads( links[ controller ] ) )
-                else:
-                    currentLinksResult = main.FALSE
-                utilities.assert_equals( expect=main.TRUE,
-                                         actual=currentLinksResult,
-                                         onpass="ONOS" + controllerStr +
-                                         " links view is correct",
-                                         onfail="ONOS" + controllerStr +
-                                         " links view is incorrect" )
-                if hosts[ controller ] and "Error" not in hosts[ controller ]:
-                    currentHostsResult = main.Mininet1.compareHosts(
-                            mnHosts,
-                            hosts[ controller ] )
-                elif hosts[ controller ] == []:
-                    currentHostsResult = main.TRUE
-                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" )
-                # CHECKING HOST ATTACHMENT POINTS
-                hostAttachment = True
-                zeroHosts = False
-                # FIXME: topo-HA/obelisk specific mappings:
-                # key is mac and value is dpid
-                mappings = {}
-                for i in range( 1, 29 ):  # hosts 1 through 28
-                    # set up correct variables:
-                    macId = "00:" * 5 + hex( i ).split( "0x" )[ 1 ].upper().zfill( 2 )
-                    if i == 1:
-                        deviceId = "1000".zfill( 16 )
-                    elif i == 2:
-                        deviceId = "2000".zfill( 16 )
-                    elif i == 3:
-                        deviceId = "3000".zfill( 16 )
-                    elif i == 4:
-                        deviceId = "3004".zfill( 16 )
-                    elif i == 5:
-                        deviceId = "5000".zfill( 16 )
-                    elif i == 6:
-                        deviceId = "6000".zfill( 16 )
-                    elif i == 7:
-                        deviceId = "6007".zfill( 16 )
-                    elif i >= 8 and i <= 17:
-                        dpid = '3' + str( i ).zfill( 3 )
-                        deviceId = dpid.zfill( 16 )
-                    elif i >= 18 and i <= 27:
-                        dpid = '6' + str( i ).zfill( 3 )
-                        deviceId = dpid.zfill( 16 )
-                    elif i == 28:
-                        deviceId = "2800".zfill( 16 )
-                    mappings[ macId ] = deviceId
-                if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
-                    if hosts[ controller ] == []:
-                        main.log.warn( "There are no hosts discovered" )
-                        zeroHosts = True
-                    else:
-                        for host in hosts[ controller ]:
-                            mac = None
-                            location = None
-                            device = None
-                            port = None
-                            try:
-                                mac = host.get( 'mac' )
-                                assert mac, "mac field could not be found for this host object"
-
-                                location = host.get( 'locations' )[ 0 ]
-                                assert location, "location field could not be found for this host object"
-
-                                # Trim the protocol identifier off deviceId
-                                device = str( location.get( 'elementId' ) ).split( ':' )[ 1 ]
-                                assert device, "elementId field could not be found for this host location object"
-
-                                port = location.get( 'port' )
-                                assert port, "port field could not be found for this host location object"
-
-                                # Now check if this matches where they should be
-                                if mac and device and port:
-                                    if str( port ) != "1":
-                                        main.log.error( "The attachment port is incorrect for " +
-                                                        "host " + str( mac ) +
-                                                        ". Expected: 1 Actual: " + str( port ) )
-                                        hostAttachment = False
-                                    if device != mappings[ str( mac ) ]:
-                                        main.log.error( "The attachment device is incorrect for " +
-                                                        "host " + str( mac ) +
-                                                        ". Expected: " + mappings[ str( mac ) ] +
-                                                        " Actual: " + device )
-                                        hostAttachment = False
-                                else:
-                                    hostAttachment = False
-                            except AssertionError:
-                                main.log.exception( "Json object not as expected" )
-                                main.log.error( repr( host ) )
-                                hostAttachment = False
-                else:
-                    main.log.error( "No hosts json output or \"Error\"" +
-                                    " in output. hosts = " +
-                                    repr( hosts[ controller ] ) )
-                if zeroHosts is False:
-                    hostAttachment = True
-
-                # END CHECKING HOST ATTACHMENT POINTS
-                devicesResults = devicesResults and currentDevicesResult
-                linksResults = linksResults and currentLinksResult
-                hostsResults = hostsResults and currentHostsResult
-                hostAttachmentResults = hostAttachmentResults and\
-                                        hostAttachment
-                topoResult = ( devicesResults and linksResults
-                               and hostsResults and ipResult and
-                               hostAttachmentResults )
-        utilities.assert_equals( expect=True,
-                                 actual=topoResult,
-                                 onpass="ONOS topology matches Mininet",
-                                 onfail=topoFailMsg )
-        # End of While loop to pull ONOS state
-
-        # Compare json objects for hosts and dataplane clusters
-
-        # hosts
-        main.step( "Hosts view is consistent across all ONOS nodes" )
-        consistentHostsResult = main.TRUE
-        for controller in range( len( hosts ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
-                if hosts[ controller ] == hosts[ 0 ]:
-                    continue
-                else:  # hosts not consistent
-                    main.log.error( "hosts from ONOS" + controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    main.log.warn( repr( hosts[ controller ] ) )
-                    consistentHostsResult = main.FALSE
-
-            else:
-                main.log.error( "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" )
-
-        main.step( "Hosts information is correct" )
-        hostsResults = hostsResults and ipResult
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=hostsResults,
-            onpass="Host information is correct",
-            onfail="Host information is incorrect" )
-
-        main.step( "Host attachment points to the network" )
-        utilities.assert_equals(
-            expect=True,
-            actual=hostAttachmentResults,
-            onpass="Hosts are correctly attached to the network",
-            onfail="ONOS did not correctly attach hosts to the network" )
-
-        # Strongly connected clusters of devices
-        main.step( "Clusters view is consistent across all ONOS nodes" )
-        consistentClustersResult = main.TRUE
-        for controller in range( len( clusters ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if "Error" not in clusters[ controller ]:
-                if clusters[ controller ] == clusters[ 0 ]:
-                    continue
-                else:  # clusters not consistent
-                    main.log.error( "clusters from ONOS" +
-                                     controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    consistentClustersResult = main.FALSE
-            else:
-                main.log.error( "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" )
-        if not consistentClustersResult:
-            main.log.debug( clusters )
-
-        main.step( "There is only one SCC" )
-        # there should always only be one cluster
-        try:
-            numClusters = len( json.loads( clusters[ 0 ] ) )
-        except ( ValueError, TypeError ):
-            main.log.exception( "Error parsing clusters[0]: " +
-                                repr( clusters[ 0 ] ) )
-            numClusters = "ERROR"
-        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 linksResults
-                       and hostsResults and consistentHostsResult
-                       and consistentClustersResult and clusterResults
-                       and ipResult and hostAttachmentResults )
-
-        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" )
-
-        main.step( "Device information is correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=devicesResults,
-            onpass="Device information is correct",
-            onfail="Device information is incorrect" )
-
-        main.step( "Links are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=linksResults,
-            onpass="Link are correct",
-            onfail="Links are incorrect" )
-
-        main.step( "Hosts are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=hostsResults,
-            onpass="Hosts are correct",
-            onfail="Hosts are incorrect" )
-
-        # FIXME: move this to an ONOS state case
-        main.step( "Checking ONOS nodes" )
-        nodeResults = utilities.retry( main.HA.nodesCheck,
-                                       False,
-                                       args=[ main.activeNodes ],
-                                       attempts=5 )
-
-        utilities.assert_equals( expect=True, actual=nodeResults,
-                                 onpass="Nodes check successful",
-                                 onfail="Nodes check NOT successful" )
-        if not nodeResults:
-            for i in main.activeNodes:
-                main.log.debug( "{} components not ACTIVE: \n{}".format(
-                    main.CLIs[ i ].name,
-                    main.CLIs[ i ].sendline( "scr:list | grep -v ACTIVE" ) ) )
-
-        if not topoResult:
-            main.cleanup()
-            main.exit()
+        main.HA.compareTopo( main )
 
     def CASE9( self, main ):
         """
         Link s3-s28 down
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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"
-        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 successful",
-                                 onfail="Failed to bring link down" )
-        # TODO do some sort of check here
+        main.HA.linkDown( main )
 
     def CASE10( self, main ):
         """
         Link s3-s28 up
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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"
-        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 successful",
-                                 onfail="Failed to bring link up" )
-        # TODO do some sort of check here
+        main.HA.linkUp( main )
 
     def CASE11( self, main ):
         """
         Switch Down
         """
         # NOTE: You should probably run a topology check after this
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
-
-        description = "Killing a switch to ensure it is discovered correctly"
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        main.case( description )
-        switch = main.params[ 'kill' ][ 'switch' ]
-        switchDPID = main.params[ 'kill' ][ 'dpid' ]
-
-        # TODO: Make this switch parameterizable
-        main.step( "Kill " + switch )
-        main.log.info( "Deleting " + switch )
-        main.Mininet1.delSwitch( switch )
-        main.log.info( "Waiting " + str( switchSleep ) +
-                       " seconds for switch down to be discovered" )
-        time.sleep( switchSleep )
-        device = onosCli.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 successful",
-                                 onfail="Failed to kill switch?" )
+        main.HA.switchDown( main )
 
     def CASE12( self, main ):
         """
         Switch Up
         """
         # NOTE: You should probably run a topology check after this
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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' ]
-        switchDPID = main.params[ 'kill' ][ 'dpid' ]
-        links = main.params[ 'kill' ][ 'links' ].split()
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        description = "Adding a switch to ensure it is discovered correctly"
-        main.case( description )
-
-        main.step( "Add back " + switch )
-        main.Mininet1.addSwitch( switch, dpid=switchDPID )
-        for peer in links:
-            main.Mininet1.addLink( switch, peer )
-        ipList = [ node.ip_address for node in main.nodes ]
-        main.Mininet1.assignSwController( sw=switch, ip=ipList )
-        main.log.info( "Waiting " + str( switchSleep ) +
-                       " seconds for switch up to be discovered" )
-        time.sleep( switchSleep )
-        device = onosCli.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 successful",
-                                 onfail="Failed to add switch?" )
+        main.HA.switchUp( main )
 
     def CASE13( self, main ):
         """
         Clean up
         """
-        import os
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        # printing colors to terminal
-        colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
-                   'blue': '\033[94m', 'green': '\033[92m',
-                   'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
-        main.case( "Test Cleanup" )
-        main.step( "Killing tcpdumps" )
-        main.Mininet2.stopTcpdump()
-
-        testname = main.TEST
-        if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
-            main.step( "Copying MN pcap and ONOS log files to test station" )
-            teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
-            teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
-            # NOTE: MN Pcap file is being saved to logdir.
-            #       We scp this file as MN and TestON aren't necessarily the same vm
-
-            # FIXME: To be replaced with a Jenkin's post script
-            # TODO: Load these from params
-            # NOTE: must end in /
-            logFolder = "/opt/onos/log/"
-            logFiles = [ "karaf.log", "karaf.log.1" ]
-            # NOTE: must end in /
-            for f in logFiles:
-                for node in main.nodes:
-                    dstName = main.logdir + "/" + node.name + "-" + f
-                    main.ONOSbench.secureCopy( node.user_name, node.ip_address,
-                                               logFolder + f, dstName )
-            # std*.log's
-            # NOTE: must end in /
-            logFolder = "/opt/onos/var/"
-            logFiles = [ "stderr.log", "stdout.log" ]
-            # NOTE: must end in /
-            for f in logFiles:
-                for node in main.nodes:
-                    dstName = main.logdir + "/" + node.name + "-" + f
-                    main.ONOSbench.secureCopy( node.user_name, node.ip_address,
-                                               logFolder + f, dstName )
-        else:
-            main.log.debug( "skipping saving log files" )
-
-        main.step( "Stopping Mininet" )
-        mnResult = main.Mininet1.stopNet()
-        utilities.assert_equals( expect=main.TRUE, actual=mnResult,
-                                 onpass="Mininet stopped",
-                                 onfail="MN cleanup NOT successful" )
-
-        main.step( "Checking ONOS Logs for errors" )
-        for node in main.nodes:
-            main.log.debug( "Checking logs for errors on " + node.name + ":" )
-            main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
-
-        try:
-            timerLog = open( main.logdir + "/Timers.csv", 'w' )
-            # Overwrite with empty line and close
-            labels = "Gossip Intents"
-            data = str( gossipTime )
-            timerLog.write( labels + "\n" + data )
-            timerLog.close()
-        except NameError as e:
-            main.log.exception( e )
+        main.HA.cleanUp( main )
 
     def CASE14( self, main ):
         """
         start election app on all onos nodes
         """
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        main.case( "Start Leadership Election app" )
-        main.step( "Install leadership election app" )
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        appResult = onosCli.activateApp( "org.onosproject.election" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=appResult,
-            onpass="Election app installed",
-            onfail="Something went wrong with installing Leadership election" )
-
-        main.step( "Run for election on each node" )
-        for i in main.activeNodes:
-            main.CLIs[ i ].electionTestRun()
-        time.sleep( 5 )
-        activeCLIs = [ main.CLIs[ i ] for i in main.activeNodes ]
-        sameResult, leaders = main.HA.consistentLeaderboards( activeCLIs )
-        utilities.assert_equals(
-            expect=True,
-            actual=sameResult,
-            onpass="All nodes see the same leaderboards",
-            onfail="Inconsistent leaderboards" )
-
-        if sameResult:
-            leader = leaders[ 0 ][ 0 ]
-            if main.nodes[ main.activeNodes[ 0 ] ].ip_address in leader:
-                correctLeader = True
-            else:
-                correctLeader = False
-            main.step( "First node was elected leader" )
-            utilities.assert_equals(
-                expect=True,
-                actual=correctLeader,
-                onpass="Correct leader was elected",
-                onfail="Incorrect leader" )
+        main.HA.startElectionApp( main )
 
     def CASE15( self, main ):
         """
@@ -2819,196 +237,16 @@
             old and new variable prefixes refer to data from before vs after
                 withdrawl and later before withdrawl vs after re-election
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        description = "Check that Leadership Election is still functional"
-        main.case( description )
-        # NOTE: Need to re-run after restarts since being a canidate is not persistant
-
-        oldLeaders = []  # list of lists of each nodes' candidates before
-        newLeaders = []  # list of lists of each nodes' candidates after
-        oldLeader = ''  # the old leader from oldLeaders, None if not same
-        newLeader = ''  # the new leaders fron newLoeaders, None if not same
-        oldLeaderCLI = None  # the CLI of the old leader used for re-electing
-        expectNoLeader = False  # True when there is only one leader
-        if main.numCtrls == 1:
-            expectNoLeader = True
-
-        main.step( "Run for election on each node" )
-        electionResult = main.TRUE
-
-        for i in main.activeNodes:  # run test election on each node
-            if main.CLIs[ i ].electionTestRun() == main.FALSE:
-                electionResult = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=electionResult,
-            onpass="All nodes successfully ran for leadership",
-            onfail="At least one node failed to run for leadership" )
-
-        if electionResult == main.FALSE:
-            main.log.error(
-                "Skipping Test Case because Election Test App isn't loaded" )
-            main.skipCase()
-
-        main.step( "Check that each node shows the same leader and candidates" )
-        failMessage = "Nodes have different leaderboards"
-        activeCLIs = [ main.CLIs[ i ] for i in main.activeNodes ]
-        sameResult, oldLeaders = main.HA.consistentLeaderboards( activeCLIs )
-        if sameResult:
-            oldLeader = oldLeaders[ 0 ][ 0 ]
-            main.log.warn( oldLeader )
-        else:
-            oldLeader = None
-        utilities.assert_equals(
-            expect=True,
-            actual=sameResult,
-            onpass="Leaderboards are consistent for the election topic",
-            onfail=failMessage )
-
-        main.step( "Find current leader and withdraw" )
-        withdrawResult = main.TRUE
-        # do some sanity checking on leader before using it
-        if oldLeader is None:
-            main.log.error( "Leadership isn't consistent." )
-            withdrawResult = main.FALSE
-        # Get the CLI of the oldLeader
-        for i in main.activeNodes:
-            if oldLeader == main.nodes[ i ].ip_address:
-                oldLeaderCLI = main.CLIs[ i ]
-                break
-        else:  # FOR/ELSE statement
-            main.log.error( "Leader election, could not find current leader" )
-        if oldLeader:
-            withdrawResult = oldLeaderCLI.electionTestWithdraw()
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=withdrawResult,
-            onpass="Node was withdrawn from election",
-            onfail="Node was not withdrawn from election" )
-
-        main.step( "Check that a new node was elected leader" )
-        failMessage = "Nodes have different leaders"
-        # Get new leaders and candidates
-        newLeaderResult, newLeaders = main.HA.consistentLeaderboards( activeCLIs )
-        newLeader = None
-        if newLeaderResult:
-            if newLeaders[ 0 ][ 0 ] == 'none':
-                main.log.error( "No leader was elected on at least 1 node" )
-                if not expectNoLeader:
-                    newLeaderResult = False
-            newLeader = newLeaders[ 0 ][ 0 ]
-
-        # Check that the new leader is not the older leader, which was withdrawn
-        if newLeader == oldLeader:
-            newLeaderResult = False
-            main.log.error( "All nodes still see old leader: " + str( oldLeader ) +
-                            " as the current leader" )
-        utilities.assert_equals(
-            expect=True,
-            actual=newLeaderResult,
-            onpass="Leadership election passed",
-            onfail="Something went wrong with Leadership election" )
-
-        main.step( "Check that that new leader was the candidate of old leader" )
-        # candidates[ 2 ] should become the top candidate after withdrawl
-        correctCandidateResult = main.TRUE
-        if expectNoLeader:
-            if newLeader == 'none':
-                main.log.info( "No leader expected. None found. Pass" )
-                correctCandidateResult = main.TRUE
-            else:
-                main.log.info( "Expected no leader, got: " + str( newLeader ) )
-                correctCandidateResult = main.FALSE
-        elif len( oldLeaders[ 0 ] ) >= 3:
-            if newLeader == oldLeaders[ 0 ][ 2 ]:
-                # correct leader was elected
-                correctCandidateResult = main.TRUE
-            else:
-                correctCandidateResult = main.FALSE
-                main.log.error( "Candidate {} was elected. {} should have had priority.".format(
-                                    newLeader, oldLeaders[ 0 ][ 2 ] ) )
-        else:
-            main.log.warn( "Could not determine who should be the correct leader" )
-            main.log.debug( oldLeaders[ 0 ] )
-            correctCandidateResult = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=correctCandidateResult,
-            onpass="Correct Candidate Elected",
-            onfail="Incorrect Candidate Elected" )
-
-        main.step( "Run for election on old leader( just so everyone " +
-                   "is in the hat )" )
-        if oldLeaderCLI is not None:
-            runResult = oldLeaderCLI.electionTestRun()
-        else:
-            main.log.error( "No old leader to re-elect" )
-            runResult = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=runResult,
-            onpass="App re-ran for election",
-            onfail="App failed to run for election" )
-
-        main.step(
-            "Check that oldLeader is a candidate, and leader if only 1 node" )
-        # verify leader didn't just change
-        # Get new leaders and candidates
-        reRunLeaders = []
-        time.sleep( 5 )  # Paremterize
-        positionResult, reRunLeaders = main.HA.consistentLeaderboards( activeCLIs )
-
-        # Check that the re-elected node is last on the candidate List
-        if not reRunLeaders[ 0 ]:
-            positionResult = main.FALSE
-        elif oldLeader != reRunLeaders[ 0 ][ -1 ]:
-            main.log.error( "Old Leader ({}) not in the proper position: {} ".format( str( oldLeader ),
-                                                                                      str( reRunLeaders[ 0 ] ) ) )
-            positionResult = main.FALSE
-        utilities.assert_equals(
-            expect=True,
-            actual=positionResult,
-            onpass="Old leader successfully re-ran for election",
-            onfail="Something went wrong with Leadership election after " +
-                   "the old leader re-ran for election" )
+        main.HA.isElectionFunctional( main )
 
     def CASE16( self, main ):
         """
         Install Distributed Primitives app
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        # Variables for the distributed primitives tests
-        main.pCounterName = "TestON-Partitions"
-        main.pCounterValue = 0
-        main.onosSet = set( [] )
-        main.onosSetName = "TestON-set"
-
-        description = "Install Primitives app"
-        main.case( description )
-        main.step( "Install Primitives app" )
-        appName = "org.onosproject.distributedprimitives"
-        node = main.activeNodes[ 0 ]
-        appResults = main.CLIs[ node ].activateApp( appName )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=appResults,
-                                 onpass="Primitives app activated",
-                                 onfail="Primitives app not activated" )
-        time.sleep( 5 )  # To allow all nodes to activate
+        main.HA.installDistributedPrimitiveApp( main )
 
     def CASE17( self, main ):
         """
         Check for basic functionality with distributed primitives
         """
-        main.HA.CASE17( main )
+        main.HA.checkDistPrimitivesFunc( main )
diff --git a/TestON/tests/HA/HAscaling/HAscaling.params b/TestON/tests/HA/HAscaling/HAscaling.params
index 49b244d..6bcb87d 100644
--- a/TestON/tests/HA/HAscaling/HAscaling.params
+++ b/TestON/tests/HA/HAscaling/HAscaling.params
@@ -38,8 +38,10 @@
         <cellName>HA</cellName>
         <appString>drivers,openflow,proxyarp,mobility</appString>
     </ENV>
-    <Git> False </Git>
-    <branch> master </branch>
+    <GIT>
+        <pull>False</pull>
+        <branch>master</branch>
+    </GIT>
     <num_controllers> 7 </num_controllers>
     <tcpdump> False </tcpdump>
 
diff --git a/TestON/tests/HA/HAscaling/HAscaling.py b/TestON/tests/HA/HAscaling/HAscaling.py
index 0ac38a2..ab63b5d 100644
--- a/TestON/tests/HA/HAscaling/HAscaling.py
+++ b/TestON/tests/HA/HAscaling/HAscaling.py
@@ -50,1768 +50,75 @@
         import re
         main.log.info( "ONOS HA test: Restart all ONOS nodes - " +
                          "initialization" )
-        main.case( "Setting up test environment" )
-        main.caseExplanation = "Setup the test environment including " +\
-                                "installing ONOS, starting Mininet and ONOS" +\
-                                "cli sessions."
-
-        # load some variables from the params file
-        PULLCODE = False
-        if main.params[ 'Git' ] == 'True':
-            PULLCODE = True
-        gitBranch = main.params[ 'branch' ]
-        cellName = main.params[ 'ENV' ][ 'cellName' ]
-
-        main.numCtrls = int( main.params[ 'num_controllers' ] )
-        if main.ONOSbench.maxNodes:
-            if main.ONOSbench.maxNodes < main.numCtrls:
-                main.numCtrls = int( main.ONOSbench.maxNodes )
         # set global variables
         # These are for csv plotting in jenkins
-        global labels
-        global data
-        labels = []
-        data = []
+        main.HAlabels = []
+        main.HAdata = []
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found exiting the test" )
+            main.exit()
 
+        main.testSetUp.envSetupDescription()
         try:
             from tests.HA.dependencies.HA import HA
             main.HA = HA()
-            from tests.HA.HAscaling.dependencies.Server import Server
+            from tests.HA.HAswapNodes.dependencies.Server import Server
             main.Server = Server()
+
+            # load some variables from the params file
+            cellName = main.params[ 'ENV' ][ 'cellName' ]
+            main.apps = main.params[ 'ENV' ][ 'appString' ]
+            main.numCtrls = int( main.params[ 'num_controllers' ] )
+            if main.ONOSbench.maxNodes and\
+                        main.ONOSbench.maxNodes < main.numCtrls:
+                main.numCtrls = int( main.ONOSbench.maxNodes )
+            main.maxNodes = main.numCtrls
+            stepResult = main.testSetUp.envSetup( hasNode=True )
         except Exception as e:
-            main.log.exception( e )
-            main.cleanup()
-            main.exit()
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
+        main.HA.generateGraph( "HAscaling", index=1 )
 
-        main.CLIs = []
-        main.nodes = []
-        ipList = []
-        for i in range( 1, main.numCtrls + 1 ):
-            try:
-                main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
-                main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
-                ipList.append( main.nodes[ -1 ].ip_address )
-            except AttributeError:
-                break
+        main.testSetUp.ONOSSetUp( main.Mininet1, cellName=cellName, removeLog=True,
+                                 extraApply=main.HA.customizeOnosService,
+                                 arg=main.HA.scalingMetadata,
+                                 extraClean=main.HA.cleanUpOnosService,
+                                 installMax=True )
 
-        main.step( "Create cell file" )
-        cellAppString = main.params[ 'ENV' ][ 'appString' ]
-        main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
-                                       main.Mininet1.ip_address,
-                                       cellAppString, ipList, main.ONOScli1.karafUser )
-
-        main.step( "Applying cell variable to environment" )
-        cellResult = main.ONOSbench.setCell( cellName )
-        utilities.assert_equals( expect=main.TRUE, actual=cellResult,
-                                 onpass="Set cell successfull",
-                                 onfail="Failled to set cell" )
-
-        main.step( "Verify connectivity to cell" )
-        verifyResult = main.ONOSbench.verifyCell()
-        utilities.assert_equals( expect=main.TRUE, actual=verifyResult,
-                                 onpass="Verify cell passed",
-                                 onfail="Failled to verify cell" )
-
-        # FIXME:this is short term fix
-        main.log.info( "Removing raft logs" )
-        main.ONOSbench.onosRemoveRaftLogs()
-
-        main.log.info( "Uninstalling ONOS" )
-        for node in main.nodes:
-            main.ONOSbench.onosUninstall( node.ip_address )
-
-        # Make sure ONOS is DEAD
-        main.log.info( "Killing any ONOS processes" )
-        killResults = main.TRUE
-        for node in main.nodes:
-            killed = main.ONOSbench.onosKill( node.ip_address )
-            killResults = killResults and killed
-
-        main.step( "Setup server for cluster metadata file" )
-        port = main.params[ 'server' ][ 'port' ]
-        rootDir = os.path.dirname( main.testFile ) + "/dependencies"
-        main.log.debug( "Root dir: {}".format( rootDir ) )
-        status = main.Server.start( main.ONOSbench,
-                                    rootDir,
-                                    port=port,
-                                    logDir=main.logdir + "/server.log" )
-        utilities.assert_equals( expect=main.TRUE, actual=status,
-                                 onpass="Server started",
-                                 onfail="Failled to start SimpleHTTPServer" )
-
-        main.step( "Generate initial metadata file" )
-        main.scaling = main.params[ 'scaling' ].split( "," )
-        main.log.debug( main.scaling )
-        scale = main.scaling.pop( 0 )
-        main.log.debug( scale )
-        if "e" in scale:
-            equal = True
-        else:
-            equal = False
-        main.log.debug( equal )
-        main.numCtrls = int( re.search( "\d+", scale ).group( 0 ) )
-        genResult = main.Server.generateFile( main.numCtrls, equal=equal )
-        utilities.assert_equals( expect=main.TRUE, actual=genResult,
-                                 onpass="New cluster metadata file generated",
-                                 onfail="Failled to generate new metadata file" )
-
-        gitPullResult = main.TRUE
-
-        main.step( "Starting Mininet" )
-        # scp topo file to mininet
-        # TODO: move to params?
-        topoName = "obelisk.py"
-        filePath = main.ONOSbench.home + "/tools/test/topos/"
-        main.ONOSbench.scp( main.Mininet1,
-                            filePath + topoName,
-                            main.Mininet1.home,
-                            direction="to" )
-        mnResult = main.Mininet1.startNet()
-        utilities.assert_equals( expect=main.TRUE, actual=mnResult,
-                                 onpass="Mininet Started",
-                                 onfail="Error starting Mininet" )
-
-        main.step( "Git checkout and pull " + gitBranch )
-        if PULLCODE:
-            main.ONOSbench.gitCheckout( gitBranch )
-            gitPullResult = main.ONOSbench.gitPull()
-            # values of 1 or 3 are good
-            utilities.assert_lesser( expect=0, actual=gitPullResult,
-                                      onpass="Git pull successful",
-                                      onfail="Git pull failed" )
-        main.ONOSbench.getVersion( report=True )
-
-        # GRAPHS
-        # NOTE: important params here:
-        #       job = name of Jenkins job
-        #       Plot Name = Plot-HA, only can be used if multiple plots
-        #       index = The number of the graph under plot name
-        job = "HAscaling"
-        plotName = "Plot-HA"
-        index = "1"
-        graphs = '<ac:structured-macro ac:name="html">\n'
-        graphs += '<ac:plain-text-body><![CDATA[\n'
-        graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
-                  '/plot/' + plotName + '/getPlot?index=' + index +\
-                  '&width=500&height=300"' +\
-                  'noborder="0" width="500" height="300" scrolling="yes" ' +\
-                  'seamless="seamless"></iframe>\n'
-        graphs += ']]></ac:plain-text-body>\n'
-        graphs += '</ac:structured-macro>\n'
-        main.log.wiki( graphs )
-
-        main.step( "Copying backup config files" )
-        path = "~/onos/tools/package/bin/onos-service"
-        cp = main.ONOSbench.scp( main.ONOSbench,
-                                     path,
-                                     path + ".backup",
-                                     direction="to" )
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=cp,
-                                 onpass="Copy backup config file succeeded",
-                                 onfail="Copy backup config file failed" )
-        # we need to modify the onos-service file to use remote metadata file
-        # url for cluster metadata file
-        iface = main.params[ 'server' ].get( 'interface' )
-        ip = main.ONOSbench.getIpAddr( iface=iface )
-        metaFile = "cluster.json"
-        javaArgs = r"-Donos.cluster.metadata.uri=http:\/\/{}:{}\/{}".format( ip, port, metaFile )
-        main.log.warn( javaArgs )
-        main.log.warn( repr( javaArgs ) )
-        handle = main.ONOSbench.handle
-        sed = r"sed -i 's/bash/bash\nexport JAVA_OPTS=${{JAVA_OPTS:-{}}}\n/' {}".format( javaArgs, path )
-        main.log.warn( sed )
-        main.log.warn( repr( sed ) )
-        handle.sendline( sed )
-        handle.expect( metaFile )
-        output = handle.before
-        handle.expect( "\$" )
-        output += handle.before
-        main.log.debug( repr( output ) )
-
-        main.step( "Creating ONOS package" )
-        packageResult = main.ONOSbench.buckBuild()
-        utilities.assert_equals( expect=main.TRUE, actual=packageResult,
-                                 onpass="ONOS package successful",
-                                 onfail="ONOS package failed" )
-        if not packageResult:
-            main.cleanup()
-            main.exit()
-
-        main.step( "Installing ONOS package" )
-        onosInstallResult = main.TRUE
-        for i in range( main.ONOSbench.maxNodes ):
-            node = main.nodes[ i ]
-            options = "-f"
-            if i >= main.numCtrls:
-                options = "-nf"  # Don't start more than the current scale
-            tmpResult = main.ONOSbench.onosInstall( options=options,
-                                                    node=node.ip_address )
-            onosInstallResult = onosInstallResult and tmpResult
-        utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
-                                 onpass="ONOS install successful",
-                                 onfail="ONOS install failed" )
-
-        # Cleanup custom onos-service file
-        main.ONOSbench.scp( main.ONOSbench,
-                            path + ".backup",
-                            path,
-                            direction="to" )
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.TRUE
-        for i in range( main.numCtrls ):
-            node = main.nodes[ i ]
-            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=node.ip_address )
-        utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        main.step( "Checking if ONOS is up yet" )
-        for i in range( 2 ):
-            onosIsupResult = main.TRUE
-            for i in range( main.numCtrls ):
-                node = main.nodes[ i ]
-                started = main.ONOSbench.isup( node.ip_address )
-                if not started:
-                    main.log.error( node.name + " hasn't started" )
-                onosIsupResult = onosIsupResult and started
-            if onosIsupResult == main.TRUE:
-                break
-        utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
-                                 onpass="ONOS startup successful",
-                                 onfail="ONOS startup failed" )
-
-        main.step( "Starting ONOS CLI sessions" )
-        cliResults = main.TRUE
-        threads = []
-        for i in range( main.numCtrls ):
-            t = main.Thread( target=main.CLIs[ i ].startOnosCli,
-                             name="startOnosCli-" + str( i ),
-                             args=[ main.nodes[ i ].ip_address ] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            cliResults = cliResults and t.result
-        utilities.assert_equals( expect=main.TRUE, actual=cliResults,
-                                 onpass="ONOS cli startup successful",
-                                 onfail="ONOS cli startup failed" )
-
-        # Create a list of active nodes for use when some nodes are stopped
-        main.activeNodes = [ i for i in range( 0, main.numCtrls ) ]
-
-        if main.params[ 'tcpdump' ].lower() == "true":
-            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' ] )
-
-        main.step( "Checking ONOS nodes" )
-        nodeResults = utilities.retry( main.HA.nodesCheck,
-                                       False,
-                                       args=[ main.activeNodes ],
-                                       attempts=5 )
-        utilities.assert_equals( expect=True, actual=nodeResults,
-                                 onpass="Nodes check successful",
-                                 onfail="Nodes check NOT successful" )
-
-        if not nodeResults:
-            for i in main.activeNodes:
-                cli = main.CLIs[ i ]
-                main.log.debug( "{} components not ACTIVE: \n{}".format(
-                    cli.name,
-                    cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
-            main.log.error( "Failed to start ONOS, stopping test" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Activate apps defined in the params file" )
-        # get data from the params
-        apps = main.params.get( 'apps' )
-        if apps:
-            apps = apps.split( ',' )
-            main.log.warn( apps )
-            activateResult = True
-            for app in apps:
-                main.CLIs[ 0 ].app( app, "Activate" )
-            # TODO: check this worked
-            time.sleep( 10 )  # wait for apps to activate
-            for app in apps:
-                state = main.CLIs[ 0 ].appStatus( app )
-                if state == "ACTIVE":
-                    activateResult = activateResult and True
-                else:
-                    main.log.error( "{} is in {} state".format( app, state ) )
-                    activateResult = False
-            utilities.assert_equals( expect=True,
-                                     actual=activateResult,
-                                     onpass="Successfully activated apps",
-                                     onfail="Failed to activate apps" )
-        else:
-            main.log.warn( "No apps were specified to be loaded after startup" )
-
-        main.step( "Set ONOS configurations" )
-        config = main.params.get( 'ONOS_Configuration' )
-        if config:
-            main.log.debug( config )
-            checkResult = main.TRUE
-            for component in config:
-                for setting in config[ component ]:
-                    value = config[ component ][ setting ]
-                    check = main.CLIs[ 0 ].setCfg( component, setting, value )
-                    main.log.info( "Value was changed? {}".format( main.TRUE == check ) )
-                    checkResult = check and checkResult
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=checkResult,
-                                     onpass="Successfully set config",
-                                     onfail="Failed to set config" )
-        else:
-            main.log.warn( "No configurations were specified to be changed after startup" )
-
-        main.step( "App Ids check" )
-        appCheck = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
-                             name="appToIDCheck-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            appCheck = appCheck and t.result
-        if appCheck != main.TRUE:
-            node = main.activeNodes[ 0 ]
-            main.log.warn( main.CLIs[ node ].apps() )
-            main.log.warn( main.CLIs[ node ].appIDs() )
-        utilities.assert_equals( expect=main.TRUE, actual=appCheck,
-                                 onpass="App Ids seem to be correct",
-                                 onfail="Something is wrong with app Ids" )
+        main.HA.initialSetUp( True )
 
     def CASE2( self, main ):
         """
         Assign devices to controllers
         """
-        import re
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        main.case( "Assigning devices to controllers" )
-        main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
-                                "and check that an ONOS node becomes the " +\
-                                "master of the device."
-        main.step( "Assign switches to controllers" )
-
-        ipList = []
-        for i in range( main.ONOSbench.maxNodes ):
-            ipList.append( main.nodes[ i ].ip_address )
-        swList = []
-        for i in range( 1, 29 ):
-            swList.append( "s" + str( i ) )
-        main.Mininet1.assignSwController( sw=swList, ip=ipList )
-
-        mastershipCheck = main.TRUE
-        for i in range( 1, 29 ):
-            response = main.Mininet1.getSwController( "s" + str( i ) )
-            try:
-                main.log.info( str( response ) )
-            except Exception:
-                main.log.info( repr( response ) )
-            for node in main.nodes:
-                if re.search( "tcp:" + node.ip_address, response ):
-                    mastershipCheck = mastershipCheck and main.TRUE
-                else:
-                    main.log.error( "Error, node " + node.ip_address + " is " +
-                                    "not in the list of controllers s" +
-                                    str( i ) + " is connecting to." )
-                    mastershipCheck = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=mastershipCheck,
-            onpass="Switch mastership assigned correctly",
-            onfail="Switches not assigned correctly to controllers" )
+        main.HA.assignDevices( main )
 
     def CASE21( self, main ):
         """
         Assign mastership to controllers
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        main.case( "Assigning Controller roles for switches" )
-        main.caseExplanation = "Check that ONOS is connected to each " +\
-                                "device. Then manually assign" +\
-                                " mastership to specific ONOS nodes using" +\
-                                " 'device-role'"
-        main.step( "Assign mastership of switches to specific controllers" )
-        # Manually assign mastership to the controller we want
-        roleCall = main.TRUE
-
-        ipList = []
-        deviceList = []
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        try:
-            # Assign mastership to specific controllers. This assignment was
-            # determined for a 7 node cluser, but will work with any sized
-            # cluster
-            for i in range( 1, 29 ):  # switches 1 through 28
-                # set up correct variables:
-                if i == 1:
-                    c = 0
-                    ip = main.nodes[ c ].ip_address  # ONOS1
-                    deviceId = onosCli.getDevice( "1000" ).get( 'id' )
-                elif i == 2:
-                    c = 1 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS2
-                    deviceId = onosCli.getDevice( "2000" ).get( 'id' )
-                elif i == 3:
-                    c = 1 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS2
-                    deviceId = onosCli.getDevice( "3000" ).get( 'id' )
-                elif i == 4:
-                    c = 3 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS4
-                    deviceId = onosCli.getDevice( "3004" ).get( 'id' )
-                elif i == 5:
-                    c = 2 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS3
-                    deviceId = onosCli.getDevice( "5000" ).get( 'id' )
-                elif i == 6:
-                    c = 2 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS3
-                    deviceId = onosCli.getDevice( "6000" ).get( 'id' )
-                elif i == 7:
-                    c = 5 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS6
-                    deviceId = onosCli.getDevice( "6007" ).get( 'id' )
-                elif i >= 8 and i <= 17:
-                    c = 4 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS5
-                    dpid = '3' + str( i ).zfill( 3 )
-                    deviceId = onosCli.getDevice( dpid ).get( 'id' )
-                elif i >= 18 and i <= 27:
-                    c = 6 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS7
-                    dpid = '6' + str( i ).zfill( 3 )
-                    deviceId = onosCli.getDevice( dpid ).get( 'id' )
-                elif i == 28:
-                    c = 0
-                    ip = main.nodes[ c ].ip_address  # ONOS1
-                    deviceId = onosCli.getDevice( "2800" ).get( 'id' )
-                else:
-                    main.log.error( "You didn't write an else statement for " +
-                                    "switch s" + str( i ) )
-                    roleCall = main.FALSE
-                # Assign switch
-                assert deviceId, "No device id for s" + str( i ) + " in ONOS"
-                # TODO: make this controller dynamic
-                roleCall = roleCall and onosCli.deviceRole( deviceId, ip )
-                ipList.append( ip )
-                deviceList.append( deviceId )
-        except ( AttributeError, AssertionError ):
-            main.log.exception( "Something is wrong with ONOS device view" )
-            main.log.info( onosCli.devices() )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=roleCall,
-            onpass="Re-assigned switch mastership to designated controller",
-            onfail="Something wrong with deviceRole calls" )
-
-        main.step( "Check mastership was correctly assigned" )
-        roleCheck = main.TRUE
-        # NOTE: This is due to the fact that device mastership change is not
-        #       atomic and is actually a multi step process
-        time.sleep( 5 )
-        for i in range( len( ipList ) ):
-            ip = ipList[ i ]
-            deviceId = deviceList[ i ]
-            # Check assignment
-            master = onosCli.getRole( deviceId ).get( 'master' )
-            if ip in master:
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-                main.log.error( "Error, controller " + ip + " is not" +
-                                " master " + "of device " +
-                                str( deviceId ) + ". Master is " +
-                                repr( master ) + "." )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=roleCheck,
-            onpass="Switches were successfully reassigned to designated " +
-                   "controller",
-            onfail="Switches were not successfully reassigned" )
+        main.HA.assignMastership( main )
 
     def CASE3( self, main ):
         """
         Assign intents
         """
-        import time
-        import json
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-        try:
-            labels
-        except NameError:
-            main.log.error( "labels not defined, setting to []" )
-            labels = []
-        try:
-            data
-        except NameError:
-            main.log.error( "data not defined, setting to []" )
-            data = []
-        # NOTE: we must reinstall intents until we have a persistant intent
-        #        datastore!
-        main.case( "Adding host Intents" )
-        main.caseExplanation = "Discover hosts by using pingall then " +\
-                                "assign predetermined host-to-host intents." +\
-                                " After installation, check that the intent" +\
-                                " is distributed to all nodes and the state" +\
-                                " is INSTALLED"
-
-        # install onos-app-fwd
-        main.step( "Install reactive forwarding app" )
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        installResults = onosCli.activateApp( "org.onosproject.fwd" )
-        utilities.assert_equals( expect=main.TRUE, actual=installResults,
-                                 onpass="Install fwd successful",
-                                 onfail="Install fwd failed" )
-
-        main.step( "Check app ids" )
-        appCheck = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
-                             name="appToIDCheck-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            appCheck = appCheck and t.result
-        if appCheck != main.TRUE:
-            main.log.warn( onosCli.apps() )
-            main.log.warn( onosCli.appIDs() )
-        utilities.assert_equals( expect=main.TRUE, actual=appCheck,
-                                 onpass="App Ids seem to be correct",
-                                 onfail="Something is wrong with app Ids" )
-
-        main.step( "Discovering Hosts( Via pingall for now )" )
-        # FIXME: Once we have a host discovery mechanism, use that instead
-        # REACTIVE FWD test
-        pingResult = main.FALSE
-        passMsg = "Reactive Pingall test passed"
-        time1 = time.time()
-        pingResult = main.Mininet1.pingall()
-        time2 = time.time()
-        if not pingResult:
-            main.log.warn( "First pingall failed. Trying again..." )
-            pingResult = main.Mininet1.pingall()
-            passMsg += " on the second try"
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=pingResult,
-            onpass=passMsg,
-            onfail="Reactive Pingall failed, " +
-                   "one or more ping pairs failed" )
-        main.log.info( "Time for pingall: %2f seconds" %
-                       ( time2 - time1 ) )
-        # timeout for fwd flows
-        time.sleep( 11 )
-        # uninstall onos-app-fwd
-        main.step( "Uninstall reactive forwarding app" )
-        node = main.activeNodes[ 0 ]
-        uninstallResult = main.CLIs[ node ].deactivateApp( "org.onosproject.fwd" )
-        utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
-                                 onpass="Uninstall fwd successful",
-                                 onfail="Uninstall fwd failed" )
-
-        main.step( "Check app ids" )
-        threads = []
-        appCheck2 = main.TRUE
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
-                             name="appToIDCheck-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            appCheck2 = appCheck2 and t.result
-        if appCheck2 != main.TRUE:
-            node = main.activeNodes[ 0 ]
-            main.log.warn( main.CLIs[ node ].apps() )
-            main.log.warn( main.CLIs[ node ].appIDs() )
-        utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
-                                 onpass="App Ids seem to be correct",
-                                 onfail="Something is wrong with app Ids" )
-
-        main.step( "Add host intents via cli" )
-        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 ) )
-            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 = onosCli.getHost( host1 )
-            host2Dict = onosCli.getHost( host2 )
-            host1Id = None
-            host2Id = None
-            if host1Dict and host2Dict:
-                host1Id = host1Dict.get( 'id', None )
-                host2Id = host2Dict.get( 'id', None )
-            if host1Id and host2Id:
-                nodeNum = ( i % len( main.activeNodes ) )
-                node = main.activeNodes[ nodeNum ]
-                tmpId = main.CLIs[ node ].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 for h" + str( i ) +
-                                " and/or h" + str( i + 10 ) )
-                node = main.activeNodes[ 0 ]
-                hosts = main.CLIs[ node ].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
-        utilities.assert_equals( expect=main.TRUE, actual=hostResult,
-                                 onpass="Found a host id for each host",
-                                 onfail="Error looking up host ids" )
-
-        intentStart = time.time()
-        onosIds = onosCli.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
-        if intentAddResult:
-            intentStop = time.time()
-        else:
-            intentStop = None
-        # Print the intent states
-        intents = onosCli.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 = onosCli.leaders()
-        try:
-            missing = False
-            if leaders:
-                parsedLeaders = json.loads( leaders )
-                main.log.warn( json.dumps( parsedLeaders,
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-                # check for all intent partitions
-                topics = []
-                for i in range( 14 ):
-                    topics.append( "work-partition-" + str( i ) )
-                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" )
-                        missing = True
-            else:
-                main.log.error( "leaders() returned None" )
-        except ( ValueError, TypeError ):
-            main.log.exception( "Error parsing leaders" )
-            main.log.error( repr( leaders ) )
-        # Check all nodes
-        if missing:
-            for i in main.activeNodes:
-                response = main.CLIs[ i ].leaders( jsonFormat=False )
-                main.log.warn( str( main.CLIs[ i ].name ) + " leaders output: \n" +
-                               str( response ) )
-
-        partitions = onosCli.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 = onosCli.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( intentAddResult and not missingIntents and
-                                installedCheck )
-        if not intentAddResult:
-            main.log.error( "Error in pushing host intents to ONOS" )
-
-        main.step( "Intent Anti-Entropy dispersion" )
-        for j in range( 100 ):
-            correct = True
-            main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
-            for i in main.activeNodes:
-                onosIds = []
-                ids = main.CLIs[ i ].getAllIntentsId()
-                onosIds.append( ids )
-                main.log.debug( "Intents in " + main.CLIs[ i ].name + ": " +
-                                str( sorted( onosIds ) ) )
-                if sorted( ids ) != sorted( intentIds ):
-                    main.log.warn( "Set of intent IDs doesn't match" )
-                    correct = False
-                    break
-                else:
-                    intents = json.loads( main.CLIs[ i ].intents() )
-                    for intent in intents:
-                        if intent[ 'state' ] != "INSTALLED":
-                            main.log.warn( "Intent " + intent[ 'id' ] +
-                                           " is " + intent[ 'state' ] )
-                            correct = False
-                            break
-            if correct:
-                break
-            else:
-                time.sleep( 1 )
-        if not intentStop:
-            intentStop = time.time()
-        global gossipTime
-        gossipTime = intentStop - intentStart
-        main.log.info( "It took about " + str( gossipTime ) +
-                        " seconds for all intents to appear in each node" )
-        append = False
-        title = "Gossip Intents"
-        count = 1
-        while append is False:
-            curTitle = title + str( count )
-            if curTitle not in labels:
-                labels.append( curTitle )
-                data.append( str( gossipTime ) )
-                append = True
-            else:
-                count += 1
-        gossipPeriod = int( main.params[ 'timers' ][ 'gossip' ] )
-        maxGossipTime = gossipPeriod * len( main.activeNodes )
-        utilities.assert_greater_equals(
-                expect=maxGossipTime, actual=gossipTime,
-                onpass="ECM anti-entropy for intents worked within " +
-                       "expected time",
-                onfail="Intent ECM anti-entropy took too long. " +
-                       "Expected time:{}, Actual time:{}".format( maxGossipTime,
-                                                                  gossipTime ) )
-        if gossipTime <= maxGossipTime:
-            intentAddResult = True
-
-        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 = onosCli.getAllIntentsId()
-            main.log.info( "Submitted intents: " + str( intentIds ) )
-            main.log.info( "Intents in ONOS: " + str( onosIds ) )
-            # Print the intent states
-            intents = onosCli.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 = onosCli.leaders()
-            try:
-                missing = False
-                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( "work-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" )
-                            missing = True
-                else:
-                    main.log.error( "leaders() returned None" )
-            except ( ValueError, TypeError ):
-                main.log.exception( "Error parsing leaders" )
-                main.log.error( repr( leaders ) )
-            # Check all nodes
-            if missing:
-                for i in main.activeNodes:
-                    node = main.CLIs[ i ]
-                    response = node.leaders( jsonFormat=False )
-                    main.log.warn( str( node.name ) + " leaders output: \n" +
-                                   str( response ) )
-
-            partitions = onosCli.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 = onosCli.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 ) )
+        main.HA.assignIntents( main )
 
     def CASE4( self, main ):
         """
         Ping across added host intents
         """
-        import json
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-        main.case( "Verify connectivity by sending traffic across Intents" )
-        main.caseExplanation = "Ping across added host intents to check " +\
-                                "functionality and check the state of " +\
-                                "the intent"
-
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        main.step( "Check Intent state" )
-        installedCheck = False
-        loopCount = 0
-        while not installedCheck and loopCount < 40:
-            installedCheck = True
-            # Print the intent states
-            intents = onosCli.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." )
-            # Print states
-            intentStates.sort()
-            for i, s in intentStates:
-                count += 1
-                main.log.info( "%-6s%-15s%-15s" %
-                               ( str( count ), str( i ), str( s ) ) )
-            if not installedCheck:
-                time.sleep( 1 )
-                loopCount += 1
-        utilities.assert_equals( expect=True, actual=installedCheck,
-                                 onpass="Intents are all INSTALLED",
-                                 onfail="Intents are not all in " +
-                                        "INSTALLED state" )
-
-        main.step( "Ping across added host intents" )
-        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.error(
-                "Intents have not been installed correctly, pings failed." )
-            # TODO: pretty print
-            main.log.warn( "ONOS1 intents: " )
-            try:
-                tmpIntents = onosCli.intents()
-                main.log.warn( json.dumps( json.loads( tmpIntents ),
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-            except ( ValueError, TypeError ):
-                main.log.warn( repr( tmpIntents ) )
-        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." )
-
-        main.step( "Check leadership of topics" )
-        leaders = onosCli.leaders()
-        topicCheck = main.TRUE
-        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
-                # TODO: Look at Devices as topics now that it uses this system
-                topics = []
-                for i in range( 14 ):
-                    topics.append( "work-partition-" + str( i ) )
-                # FIXME: this should only be after we start the app
-                # FIXME: topics.append( "org.onosproject.election" )
-                # Print leaders output
-                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" )
-                        topicCheck = main.FALSE
-            else:
-                main.log.error( "leaders() returned None" )
-                topicCheck = main.FALSE
-        except ( ValueError, TypeError ):
-            topicCheck = main.FALSE
-            main.log.exception( "Error parsing leaders" )
-            main.log.error( repr( leaders ) )
-            # TODO: Check for a leader of these topics
-        # Check all nodes
-        if topicCheck:
-            for i in main.activeNodes:
-                node = main.CLIs[ i ]
-                response = node.leaders( jsonFormat=False )
-                main.log.warn( str( node.name ) + " leaders output: \n" +
-                               str( response ) )
-
-        utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
-                                 onpass="intent Partitions is in leaders",
-                                 onfail="Some topics were lost " )
-        # Print partitions
-        partitions = onosCli.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 ) )
-        # Print Pending Map
-        pendingMap = onosCli.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 = onosCli.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 = onosCli.leaders()
-            try:
-                missing = False
-                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( "work-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" )
-                            missing = True
-                else:
-                    main.log.error( "leaders() returned None" )
-            except ( ValueError, TypeError ):
-                main.log.exception( "Error parsing leaders" )
-                main.log.error( repr( leaders ) )
-            if missing:
-                for i in main.activeNodes:
-                    node = main.CLIs[ i ]
-                    response = node.leaders( jsonFormat=False )
-                    main.log.warn( str( node.name ) + " leaders output: \n" +
-                                   str( response ) )
-
-            partitions = onosCli.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 = onosCli.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 ) )
-        # Print flowrules
-        node = main.activeNodes[ 0 ]
-        main.log.debug( main.CLIs[ node ].flows( jsonFormat=False ) )
-        main.step( "Wait a minute then ping again" )
-        # the wait is above
-        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.error(
-                "Intents have not been installed correctly, pings failed." )
-            # TODO: pretty print
-            main.log.warn( "ONOS1 intents: " )
-            try:
-                tmpIntents = onosCli.intents()
-                main.log.warn( json.dumps( json.loads( tmpIntents ),
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-            except ( ValueError, TypeError ):
-                main.log.warn( repr( tmpIntents ) )
-        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." )
+        main.HA.pingAcrossHostIntent( main, True, True )
 
     def CASE5( self, main ):
         """
         Reading state of ONOS
         """
-        import json
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        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 each other and also with past states
-
-        main.step( "Check that each switch has a master" )
-        global mastershipState
-        mastershipState = '[]'
-
-        # Assert that each device has a master
-        rolesNotNull = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( "Get the Mastership of each switch from each controller" )
-        ONOSMastership = []
-        consistentMastership = True
-        rolesResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSMastership ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSMastership[ i ] or "Error" in ONOSMastership[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " roles" )
-                main.log.warn( "ONOS" + node + " 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.info(
-                "Switch roles are consistent across all ONOS nodes" )
-        else:
-            consistentMastership = False
-        utilities.assert_equals(
-            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( len( main.activeNodes ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                try:
-                    main.log.warn(
-                        "ONOS" + node + " 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:
-            mastershipState = ONOSMastership[ 0 ]
-
-        main.step( "Get the intents from each controller" )
-        global intentState
-        intentState = []
-        ONOSIntents = []
-        consistentIntents = True  # Are Intents consistent across nodes?
-        intentsResults = True  # Could we read Intents from ONOS?
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSIntents ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " intents" )
-                main.log.warn( "ONOS" + node + " 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.info( "Intents are consistent across all ONOS " +
-                             "nodes" )
-        else:
-            consistentIntents = False
-            main.log.error( "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:
-            # Try to make it easy to figure out what is happening
-            #
-            # Intent      ONOS1      ONOS2    ...
-            #  0x01     INSTALLED  INSTALLING
-            #  ...        ...         ...
-            #  ...        ...         ...
-            title = "   Id"
-            for n in main.activeNodes:
-                title += " " * 10 + "ONOS" + str( n + 1 )
-            main.log.warn( title )
-            # get all intent keys in the cluster
-            keys = []
-            try:
-                # Get the set of all intent keys
-                for nodeStr in ONOSIntents:
-                    node = json.loads( nodeStr )
-                    for intent in node:
-                        keys.append( intent.get( 'id' ) )
-                keys = set( keys )
-                # For each intent key, print the state on each node
-                for key in keys:
-                    row = "%-13s" % key
-                    for nodeStr in ONOSIntents:
-                        node = json.loads( nodeStr )
-                        for intent in node:
-                            if intent.get( 'id', "Error" ) == key:
-                                row += "%-15s" % intent.get( 'state' )
-                    main.log.warn( row )
-                # End of intent state table
-            except ValueError as e:
-                main.log.exception( e )
-                main.log.debug( "nodeStr was: " + repr( nodeStr ) )
-
-        if intentsResults and not consistentIntents:
-            # print the json objects
-            n = str( main.activeNodes[ -1 ] + 1 )
-            main.log.debug( "ONOS" + n + " intents: " )
-            main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
-                                        sort_keys=True,
-                                        indent=4,
-                                        separators=( ',', ': ' ) ) )
-            for i in range( len( ONOSIntents ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
-                    main.log.debug( "ONOS" + node + " intents: " )
-                    main.log.debug( json.dumps( json.loads( ONOSIntents[ i ] ),
-                                                sort_keys=True,
-                                                indent=4,
-                                                separators=( ',', ': ' ) ) )
-                else:
-                    main.log.debug( "ONOS" + node + " intents match ONOS" +
-                                    n + " intents" )
-        elif intentsResults and consistentIntents:
-            intentState = ONOSIntents[ 0 ]
-
-        main.step( "Get the flows from each controller" )
-        global flowState
-        flowState = []
-        ONOSFlows = []
-        ONOSFlowsJson = []
-        flowCheck = main.FALSE
-        consistentFlows = True
-        flowsResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].flows,
-                             name="flows-" + str( i ),
-                             args=[],
-                             kwargs={ 'jsonFormat': True } )
-            threads.append( t )
-            t.start()
-
-        # NOTE: Flows command can take some time to run
-        time.sleep( 30 )
-        for t in threads:
-            t.join()
-            result = t.result
-            ONOSFlows.append( result )
-
-        for i in range( len( ONOSFlows ) ):
-            num = str( main.activeNodes[ i ] + 1 )
-            if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
-                main.log.error( "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.info( "Flow count is consistent across all ONOS nodes" )
-        else:
-            consistentFlows = False
-        utilities.assert_equals(
-            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( len( ONOSFlows ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                try:
-                    main.log.warn(
-                        "ONOS" + node + " flows: " +
-                        json.dumps( json.loads( ONOSFlows[ i ] ), sort_keys=True,
-                                    indent=4, separators=( ',', ': ' ) ) )
-                except ( ValueError, TypeError ):
-                    main.log.warn( "ONOS" + node + " 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.Mininet1.getFlowTable( "s" + str( i ), version="1.3", debug=False ) )
-        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" )
-        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( "Collecting topology information from ONOS" )
-        devices = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].devices,
-                             name="devices-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            devices.append( t.result )
-        hosts = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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" )
-                main.log.warn( repr( t.result ) )
-                hosts.append( None )
-
-        ports = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].ports,
-                             name="ports-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            ports.append( t.result )
-        links = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].links,
-                             name="links-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            links.append( t.result )
-        clusters = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].clusters,
-                             name="clusters-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            clusters.append( t.result )
-        # Compare json objects for hosts and dataplane clusters
-
-        # hosts
-        main.step( "Host view is consistent across ONOS nodes" )
-        consistentHostsResult = main.TRUE
-        for controller in range( len( hosts ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if hosts[ controller ] and "Error" not in hosts[ controller ]:
-                if hosts[ controller ] == hosts[ 0 ]:
-                    continue
-                else:  # hosts not consistent
-                    main.log.error( "hosts from ONOS" +
-                                     controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    main.log.warn( repr( hosts[ controller ] ) )
-                    consistentHostsResult = main.FALSE
-
-            else:
-                main.log.error( "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" )
-
-        main.step( "Each host has an IP address" )
-        ipResult = main.TRUE
-        for controller in range( 0, len( hosts ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if hosts[ controller ]:
-                for host in hosts[ controller ]:
-                    if not host.get( 'ipAddresses', [] ):
-                        main.log.error( "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
-        main.step( "Cluster view is consistent across ONOS nodes" )
-        consistentClustersResult = main.TRUE
-        for controller in range( len( clusters ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if "Error" not in clusters[ controller ]:
-                if clusters[ controller ] == clusters[ 0 ]:
-                    continue
-                else:  # clusters not consistent
-                    main.log.error( "clusters from ONOS" + controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    consistentClustersResult = main.FALSE
-
-            else:
-                main.log.error( "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" )
-        if not consistentClustersResult:
-            main.log.debug( clusters )
-
-        # there should always only be one cluster
-        main.step( "Cluster view correct across ONOS nodes" )
-        try:
-            numClusters = len( json.loads( clusters[ 0 ] ) )
-        except ( ValueError, TypeError ):
-            main.log.exception( "Error parsing clusters[0]: " +
-                                repr( clusters[ 0 ] ) )
-            numClusters = "ERROR"
-        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
-        linksResults = main.TRUE
-        hostsResults = main.TRUE
-        mnSwitches = main.Mininet1.getSwitches()
-        mnLinks = main.Mininet1.getLinks()
-        mnHosts = main.Mininet1.getHosts()
-        for controller in main.activeNodes:
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if devices[ controller ] and ports[ controller ] and\
-                    "Error" not in devices[ controller ] and\
-                    "Error" not in ports[ controller ]:
-                currentDevicesResult = main.Mininet1.compareSwitches(
-                        mnSwitches,
-                        json.loads( devices[ controller ] ),
-                        json.loads( ports[ controller ] ) )
-            else:
-                currentDevicesResult = main.FALSE
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=currentDevicesResult,
-                                     onpass="ONOS" + controllerStr +
-                                     " Switches view is correct",
-                                     onfail="ONOS" + controllerStr +
-                                     " Switches view is incorrect" )
-            if links[ controller ] and "Error" not in links[ controller ]:
-                currentLinksResult = main.Mininet1.compareLinks(
-                        mnSwitches, mnLinks,
-                        json.loads( links[ controller ] ) )
-            else:
-                currentLinksResult = main.FALSE
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=currentLinksResult,
-                                     onpass="ONOS" + controllerStr +
-                                     " links view is correct",
-                                     onfail="ONOS" + controllerStr +
-                                     " links view is incorrect" )
-
-            if hosts[ controller ] and "Error" not in hosts[ controller ]:
-                currentHostsResult = main.Mininet1.compareHosts(
-                        mnHosts,
-                        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
-            linksResults = linksResults and currentLinksResult
-            hostsResults = hostsResults and currentHostsResult
-
-        main.step( "Device information is correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=devicesResults,
-            onpass="Device information is correct",
-            onfail="Device information is incorrect" )
-
-        main.step( "Links are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=linksResults,
-            onpass="Link are correct",
-            onfail="Links are incorrect" )
-
-        main.step( "Hosts are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=hostsResults,
-            onpass="Hosts are correct",
-            onfail="Hosts are incorrect" )
+        main.HA.readingState( main )
 
     def CASE6( self, main ):
         """
@@ -1825,17 +132,15 @@
         assert main.CLIs, "main.CLIs not defined"
         assert main.nodes, "main.nodes not defined"
         try:
-            labels
-        except NameError:
-            main.log.error( "labels not defined, setting to []" )
-            global labels
-            labels = []
+            main.HAlabels
+        except ( NameError, AttributeError ):
+            main.log.error( "main.HAlabels not defined, setting to []" )
+            main.HAlabels = []
         try:
-            data
-        except NameError:
-            main.log.error( "data not defined, setting to []" )
-            global data
-            data = []
+            main.HAdata
+        except ( NameError, AttributeError ):
+            main.log.error( "main.HAdata not defined, setting to []" )
+            main.HAdata = []
 
         main.case( "Scale the number of nodes in the ONOS cluster" )
 
@@ -1963,280 +268,9 @@
         """
         Check state after ONOS scaling
         """
-        import json
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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
-        rolesNotNull = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].rolesNotNull,
-                             name="rolesNotNull-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
+        main.HA.checkStateAfterONOS( main, afterWhich=1 )
 
-        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( "Read device roles from ONOS" )
-        ONOSMastership = []
-        consistentMastership = True
-        rolesResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSMastership ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSMastership[ i ] or "Error" in ONOSMastership[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " roles" )
-                main.log.warn( "ONOS" + node + " 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.info(
-                "Switch roles are consistent across all ONOS nodes" )
-        else:
-            consistentMastership = False
-        utilities.assert_equals(
-            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( len( ONOSMastership ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                main.log.warn( "ONOS" + node + " roles: ",
-                               json.dumps( json.loads( ONOSMastership[ i ] ),
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-
-        # NOTE: we expect mastership to change on controller scaling down
-
-        main.step( "Get the intents and compare across all nodes" )
-        ONOSIntents = []
-        intentCheck = main.FALSE
-        consistentIntents = True
-        intentsResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSIntents ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " intents" )
-                main.log.warn( "ONOS" + node + " 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.info( "Intents are consistent across all ONOS " +
-                             "nodes" )
-        else:
-            consistentIntents = False
-
-        # Try to make it easy to figure out what is happening
-        #
-        # Intent      ONOS1      ONOS2    ...
-        #  0x01     INSTALLED  INSTALLING
-        #  ...        ...         ...
-        #  ...        ...         ...
-        title = "   ID"
-        for n in main.activeNodes:
-            title += " " * 10 + "ONOS" + str( n + 1 )
-        main.log.warn( title )
-        # get all intent keys in the cluster
-        keys = []
-        for nodeStr in ONOSIntents:
-            node = json.loads( nodeStr )
-            for intent in node:
-                keys.append( intent.get( 'id' ) )
-        keys = set( keys )
-        for key in keys:
-            row = "%-13s" % key
-            for nodeStr in ONOSIntents:
-                node = json.loads( nodeStr )
-                for intent in node:
-                    if intent.get( 'id' ) == key:
-                        row += "%-15s" % intent.get( 'state' )
-            main.log.warn( row )
-        # End table view
-
-        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' ] )
-            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( len( main.activeNodes ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                main.log.warn( "ONOS" + node + " intents: " )
-                main.log.warn( json.dumps(
-                    json.loads( ONOSIntents[ i ] ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=( ',', ': ' ) ) )
-        elif intentsResults and consistentIntents:
-            intentCheck = main.TRUE
-
-        main.step( "Compare current intents with intents before the scaling" )
-        # NOTE: this requires case 5 to pass for intentState to be set.
-        #      maybe we should stop the test if that fails?
-        sameIntents = main.FALSE
-        try:
-            intentState
-        except NameError:
-            main.log.warn( "No previous intent state was saved" )
-        else:
-            if intentState and intentState == ONOSIntents[ 0 ]:
-                sameIntents = main.TRUE
-                main.log.info( "Intents are consistent with before scaling" )
-            # TODO: possibly the states have changed? we may need to figure out
-            #       what the acceptable states are
-            elif len( intentState ) == len( ONOSIntents[ 0 ] ):
-                sameIntents = main.TRUE
-                try:
-                    before = json.loads( intentState )
-                    after = json.loads( ONOSIntents[ 0 ] )
-                    for intent in before:
-                        if intent not in after:
-                            sameIntents = main.FALSE
-                            main.log.debug( "Intent is not currently in ONOS " +
-                                            "(at least in the same form):" )
-                            main.log.debug( json.dumps( intent ) )
-                except ( ValueError, TypeError ):
-                    main.log.exception( "Exception printing intents" )
-                    main.log.debug( repr( ONOSIntents[ 0 ] ) )
-                    main.log.debug( repr( intentState ) )
-            if sameIntents == main.FALSE:
-                try:
-                    main.log.debug( "ONOS intents before: " )
-                    main.log.debug( json.dumps( json.loads( intentState ),
-                                                sort_keys=True, indent=4,
-                                                separators=( ',', ': ' ) ) )
-                    main.log.debug( "Current ONOS intents: " )
-                    main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
-                                                sort_keys=True, indent=4,
-                                                separators=( ',', ': ' ) ) )
-                except ( ValueError, TypeError ):
-                    main.log.exception( "Exception printing intents" )
-                    main.log.debug( repr( ONOSIntents[ 0 ] ) )
-                    main.log.debug( repr( intentState ) )
-            utilities.assert_equals(
-                expect=main.TRUE,
-                actual=sameIntents,
-                onpass="Intents are consistent with before scaling",
-                onfail="The Intents changed during scaling" )
-        intentCheck = intentCheck and sameIntents
-
-        main.step( "Get the OF Table entries and compare to before " +
-                   "component scaling" )
-        FlowTables = main.TRUE
-        for i in range( 28 ):
-            main.log.info( "Checking flow table on s" + str( i + 1 ) )
-            tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
-            curSwitch = main.Mininet1.flowTableComp( flows[ i ], tmpFlows )
-            FlowTables = FlowTables and curSwitch
-            if curSwitch == main.FALSE:
-                main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
-        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.Mininet2.pingLongKill()
-        """
-        # main.step( "Check the continuous pings to ensure that no packets " +
-        #            "were dropped during component failure" )
-        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.info( "No loss of dataplane connectivity" )
-        # utilities.assert_equals(
-        #     expect=main.FALSE,
-        #     actual=LossInPings,
-        #     onpass="No Loss of connectivity",
-        #     onfail="Loss of dataplane connectivity detected" )
-
-        # NOTE: Since intents are not persisted with IntnentStore,
-        #       we expect loss in dataplane connectivity
-        LossInPings = main.FALSE
-        """
         main.step( "Leadership Election is still functional" )
         # Test of LeadershipElection
         leaderList = []
@@ -2271,618 +305,39 @@
         """
         Compare topo
         """
-        import json
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        main.case( "Compare ONOS Topology view to Mininet topology" )
-        main.caseExplanation = "Compare topology objects between Mininet" +\
-                                " and ONOS"
-        topoResult = main.FALSE
-        topoFailMsg = "ONOS topology don't match Mininet"
-        elapsed = 0
-        count = 0
-        main.step( "Comparing ONOS topology to MN topology" )
-        startTime = time.time()
-        # Give time for Gossip to work
-        while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
-            devicesResults = main.TRUE
-            linksResults = main.TRUE
-            hostsResults = main.TRUE
-            hostAttachmentResults = True
-            count += 1
-            cliStart = time.time()
-            devices = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="devices-" + str( i ),
-                                 args=[ main.CLIs[ i ].devices, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                devices.append( t.result )
-            hosts = []
-            ipResult = main.TRUE
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="hosts-" + str( i ),
-                                 args=[ main.CLIs[ i ].hosts, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                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 ) )
-                    hosts.append( None )
-            for controller in range( 0, len( hosts ) ):
-                controllerStr = str( main.activeNodes[ controller ] + 1 )
-                if hosts[ controller ]:
-                    for host in hosts[ controller ]:
-                        if host is None or host.get( 'ipAddresses', [] ) == []:
-                            main.log.error(
-                                "Error with host ipAddresses on controller" +
-                                controllerStr + ": " + str( host ) )
-                            ipResult = main.FALSE
-            ports = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="ports-" + str( i ),
-                                 args=[ main.CLIs[ i ].ports, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                ports.append( t.result )
-            links = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="links-" + str( i ),
-                                 args=[ main.CLIs[ i ].links, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                links.append( t.result )
-            clusters = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="clusters-" + str( i ),
-                                 args=[ main.CLIs[ i ].clusters, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                clusters.append( t.result )
-
-            elapsed = time.time() - startTime
-            cliTime = time.time() - cliStart
-            print "Elapsed time: " + str( elapsed )
-            print "CLI time: " + str( cliTime )
-
-            if all( e is None for e in devices ) and\
-               all( e is None for e in hosts ) and\
-               all( e is None for e in ports ) and\
-               all( e is None for e in links ) and\
-               all( e is None for e in clusters ):
-                topoFailMsg = "Could not get topology from ONOS"
-                main.log.error( topoFailMsg )
-                continue  # Try again, No use trying to compare
-
-            mnSwitches = main.Mininet1.getSwitches()
-            mnLinks = main.Mininet1.getLinks()
-            mnHosts = main.Mininet1.getHosts()
-            for controller in range( len( main.activeNodes ) ):
-                controllerStr = str( main.activeNodes[ controller ] + 1 )
-                if devices[ controller ] and ports[ controller ] and\
-                        "Error" not in devices[ controller ] and\
-                        "Error" not in ports[ controller ]:
-
-                    try:
-                        currentDevicesResult = main.Mininet1.compareSwitches(
-                                mnSwitches,
-                                json.loads( devices[ controller ] ),
-                                json.loads( ports[ controller ] ) )
-                    except ( TypeError, ValueError ):
-                        main.log.exception( "Object not as expected; devices={!r}\nports={!r}".format(
-                            devices[ controller ], ports[ controller ] ) )
-                else:
-                    currentDevicesResult = main.FALSE
-                utilities.assert_equals( expect=main.TRUE,
-                                         actual=currentDevicesResult,
-                                         onpass="ONOS" + controllerStr +
-                                         " Switches view is correct",
-                                         onfail="ONOS" + controllerStr +
-                                         " Switches view is incorrect" )
-
-                if links[ controller ] and "Error" not in links[ controller ]:
-                    currentLinksResult = main.Mininet1.compareLinks(
-                            mnSwitches, mnLinks,
-                            json.loads( links[ controller ] ) )
-                else:
-                    currentLinksResult = main.FALSE
-                utilities.assert_equals( expect=main.TRUE,
-                                         actual=currentLinksResult,
-                                         onpass="ONOS" + controllerStr +
-                                         " links view is correct",
-                                         onfail="ONOS" + controllerStr +
-                                         " links view is incorrect" )
-                if hosts[ controller ] and "Error" not in hosts[ controller ]:
-                    currentHostsResult = main.Mininet1.compareHosts(
-                            mnHosts,
-                            hosts[ controller ] )
-                elif hosts[ controller ] == []:
-                    currentHostsResult = main.TRUE
-                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" )
-                # CHECKING HOST ATTACHMENT POINTS
-                hostAttachment = True
-                zeroHosts = False
-                # FIXME: topo-HA/obelisk specific mappings:
-                # key is mac and value is dpid
-                mappings = {}
-                for i in range( 1, 29 ):  # hosts 1 through 28
-                    # set up correct variables:
-                    macId = "00:" * 5 + hex( i ).split( "0x" )[ 1 ].upper().zfill( 2 )
-                    if i == 1:
-                        deviceId = "1000".zfill( 16 )
-                    elif i == 2:
-                        deviceId = "2000".zfill( 16 )
-                    elif i == 3:
-                        deviceId = "3000".zfill( 16 )
-                    elif i == 4:
-                        deviceId = "3004".zfill( 16 )
-                    elif i == 5:
-                        deviceId = "5000".zfill( 16 )
-                    elif i == 6:
-                        deviceId = "6000".zfill( 16 )
-                    elif i == 7:
-                        deviceId = "6007".zfill( 16 )
-                    elif i >= 8 and i <= 17:
-                        dpid = '3' + str( i ).zfill( 3 )
-                        deviceId = dpid.zfill( 16 )
-                    elif i >= 18 and i <= 27:
-                        dpid = '6' + str( i ).zfill( 3 )
-                        deviceId = dpid.zfill( 16 )
-                    elif i == 28:
-                        deviceId = "2800".zfill( 16 )
-                    mappings[ macId ] = deviceId
-                if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
-                    if hosts[ controller ] == []:
-                        main.log.warn( "There are no hosts discovered" )
-                        zeroHosts = True
-                    else:
-                        for host in hosts[ controller ]:
-                            mac = None
-                            location = None
-                            device = None
-                            port = None
-                            try:
-                                mac = host.get( 'mac' )
-                                assert mac, "mac field could not be found for this host object"
-
-                                location = host.get( 'locations' )[ 0 ]
-                                assert location, "location field could not be found for this host object"
-
-                                # Trim the protocol identifier off deviceId
-                                device = str( location.get( 'elementId' ) ).split( ':' )[ 1 ]
-                                assert device, "elementId field could not be found for this host location object"
-
-                                port = location.get( 'port' )
-                                assert port, "port field could not be found for this host location object"
-
-                                # Now check if this matches where they should be
-                                if mac and device and port:
-                                    if str( port ) != "1":
-                                        main.log.error( "The attachment port is incorrect for " +
-                                                        "host " + str( mac ) +
-                                                        ". Expected: 1 Actual: " + str( port ) )
-                                        hostAttachment = False
-                                    if device != mappings[ str( mac ) ]:
-                                        main.log.error( "The attachment device is incorrect for " +
-                                                        "host " + str( mac ) +
-                                                        ". Expected: " + mappings[ str( mac ) ] +
-                                                        " Actual: " + device )
-                                        hostAttachment = False
-                                else:
-                                    hostAttachment = False
-                            except AssertionError:
-                                main.log.exception( "Json object not as expected" )
-                                main.log.error( repr( host ) )
-                                hostAttachment = False
-                else:
-                    main.log.error( "No hosts json output or \"Error\"" +
-                                    " in output. hosts = " +
-                                    repr( hosts[ controller ] ) )
-                if zeroHosts is False:
-                    # TODO: Find a way to know if there should be hosts in a
-                    #       given point of the test
-                    hostAttachment = True
-
-                # END CHECKING HOST ATTACHMENT POINTS
-                devicesResults = devicesResults and currentDevicesResult
-                linksResults = linksResults and currentLinksResult
-                hostsResults = hostsResults and currentHostsResult
-                hostAttachmentResults = hostAttachmentResults and\
-                                        hostAttachment
-                topoResult = ( devicesResults and linksResults
-                               and hostsResults and ipResult and
-                               hostAttachmentResults )
-        utilities.assert_equals( expect=True,
-                                 actual=topoResult,
-                                 onpass="ONOS topology matches Mininet",
-                                 onfail=topoFailMsg )
-        # End of While loop to pull ONOS state
-
-        # Compare json objects for hosts and dataplane clusters
-
-        # hosts
-        main.step( "Hosts view is consistent across all ONOS nodes" )
-        consistentHostsResult = main.TRUE
-        for controller in range( len( hosts ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
-                if hosts[ controller ] == hosts[ 0 ]:
-                    continue
-                else:  # hosts not consistent
-                    main.log.error( "hosts from ONOS" + controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    main.log.warn( repr( hosts[ controller ] ) )
-                    consistentHostsResult = main.FALSE
-
-            else:
-                main.log.error( "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" )
-
-        main.step( "Hosts information is correct" )
-        hostsResults = hostsResults and ipResult
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=hostsResults,
-            onpass="Host information is correct",
-            onfail="Host information is incorrect" )
-
-        main.step( "Host attachment points to the network" )
-        utilities.assert_equals(
-            expect=True,
-            actual=hostAttachmentResults,
-            onpass="Hosts are correctly attached to the network",
-            onfail="ONOS did not correctly attach hosts to the network" )
-
-        # Strongly connected clusters of devices
-        main.step( "Clusters view is consistent across all ONOS nodes" )
-        consistentClustersResult = main.TRUE
-        for controller in range( len( clusters ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if "Error" not in clusters[ controller ]:
-                if clusters[ controller ] == clusters[ 0 ]:
-                    continue
-                else:  # clusters not consistent
-                    main.log.error( "clusters from ONOS" +
-                                     controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    consistentClustersResult = main.FALSE
-            else:
-                main.log.error( "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" )
-        if not consistentClustersResult:
-            main.log.debug( clusters )
-
-        main.step( "There is only one SCC" )
-        # there should always only be one cluster
-        try:
-            numClusters = len( json.loads( clusters[ 0 ] ) )
-        except ( ValueError, TypeError ):
-            main.log.exception( "Error parsing clusters[0]: " +
-                                repr( clusters[ 0 ] ) )
-            numClusters = "ERROR"
-        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 linksResults
-                       and hostsResults and consistentHostsResult
-                       and consistentClustersResult and clusterResults
-                       and ipResult and hostAttachmentResults )
-
-        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" )
-
-        main.step( "Device information is correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=devicesResults,
-            onpass="Device information is correct",
-            onfail="Device information is incorrect" )
-
-        main.step( "Links are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=linksResults,
-            onpass="Link are correct",
-            onfail="Links are incorrect" )
-
-        main.step( "Hosts are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=hostsResults,
-            onpass="Hosts are correct",
-            onfail="Hosts are incorrect" )
-
-        # FIXME: move this to an ONOS state case
-        main.step( "Checking ONOS nodes" )
-        nodeResults = utilities.retry( main.HA.nodesCheck,
-                                       False,
-                                       args=[ main.activeNodes ],
-                                       attempts=5 )
-        utilities.assert_equals( expect=True, actual=nodeResults,
-                                 onpass="Nodes check successful",
-                                 onfail="Nodes check NOT successful" )
-        if not nodeResults:
-            for i in main.activeNodes:
-                main.log.debug( "{} components not ACTIVE: \n{}".format(
-                    main.CLIs[ i ].name,
-                    main.CLIs[ i ].sendline( "scr:list | grep -v ACTIVE" ) ) )
-
-        if not topoResult:
-            main.cleanup()
-            main.exit()
+        main.HA.compareTopo( main )
 
     def CASE9( self, main ):
         """
         Link s3-s28 down
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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"
-        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 successful",
-                                 onfail="Failed to bring link down" )
-        # TODO do some sort of check here
+        main.HA.linkDown( main )
 
     def CASE10( self, main ):
         """
         Link s3-s28 up
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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"
-        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 successful",
-                                 onfail="Failed to bring link up" )
-        # TODO do some sort of check here
+        main.HA.linkUp( main )
 
     def CASE11( self, main ):
         """
         Switch Down
         """
         # NOTE: You should probably run a topology check after this
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
-
-        description = "Killing a switch to ensure it is discovered correctly"
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        main.case( description )
-        switch = main.params[ 'kill' ][ 'switch' ]
-        switchDPID = main.params[ 'kill' ][ 'dpid' ]
-
-        # TODO: Make this switch parameterizable
-        main.step( "Kill " + switch )
-        main.log.info( "Deleting " + switch )
-        main.Mininet1.delSwitch( switch )
-        main.log.info( "Waiting " + str( switchSleep ) +
-                       " seconds for switch down to be discovered" )
-        time.sleep( switchSleep )
-        device = onosCli.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 successful",
-                                 onfail="Failed to kill switch?" )
+        main.HA.switchDown( main )
 
     def CASE12( self, main ):
         """
         Switch Up
         """
         # NOTE: You should probably run a topology check after this
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
-        switch = main.params[ 'kill' ][ 'switch' ]
-        switchDPID = main.params[ 'kill' ][ 'dpid' ]
-        links = main.params[ 'kill' ][ 'links' ].split()
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        description = "Adding a switch to ensure it is discovered correctly"
-        main.case( description )
-
-        main.step( "Add back " + switch )
-        main.Mininet1.addSwitch( switch, dpid=switchDPID )
-        for peer in links:
-            main.Mininet1.addLink( switch, peer )
-        ipList = [ node.ip_address for node in main.nodes ]
-        main.Mininet1.assignSwController( sw=switch, ip=ipList )
-        main.log.info( "Waiting " + str( switchSleep ) +
-                       " seconds for switch up to be discovered" )
-        time.sleep( switchSleep )
-        device = onosCli.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 successful",
-                                 onfail="Failed to add switch?" )
+        main.HA.switchUp( main )
 
     def CASE13( self, main ):
         """
         Clean up
         """
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        main.case( "Test Cleanup" )
-        main.step( "Killing tcpdumps" )
-        main.Mininet2.stopTcpdump()
-
-        if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
-            main.step( "Copying MN pcap and ONOS log files to test station" )
-            # NOTE: MN Pcap file is being saved to logdir.
-            #       We scp this file as MN and TestON aren't necessarily the same vm
-
-            # FIXME: To be replaced with a Jenkin's post script
-            # TODO: Load these from params
-            # NOTE: must end in /
-            logFolder = "/opt/onos/log/"
-            logFiles = [ "karaf.log", "karaf.log.1" ]
-            # NOTE: must end in /
-            for f in logFiles:
-                for node in main.nodes:
-                    dstName = main.logdir + "/" + node.name + "-" + f
-                    main.ONOSbench.secureCopy( node.user_name, node.ip_address,
-                                               logFolder + f, dstName )
-            # std*.log's
-            # NOTE: must end in /
-            logFolder = "/opt/onos/var/"
-            logFiles = [ "stderr.log", "stdout.log" ]
-            # NOTE: must end in /
-            for f in logFiles:
-                for node in main.nodes:
-                    dstName = main.logdir + "/" + node.name + "-" + f
-                    main.ONOSbench.secureCopy( node.user_name, node.ip_address,
-                                               logFolder + f, dstName )
-        else:
-            main.log.debug( "skipping saving log files" )
-
-        main.step( "Stopping Mininet" )
-        mnResult = main.Mininet1.stopNet()
-        utilities.assert_equals( expect=main.TRUE, actual=mnResult,
-                                 onpass="Mininet stopped",
-                                 onfail="MN cleanup NOT successful" )
-
-        main.step( "Checking ONOS Logs for errors" )
-        for node in main.nodes:
-            main.log.debug( "Checking logs for errors on " + node.name + ":" )
-            main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
-
-        try:
-            timerLog = open( main.logdir + "/Timers.csv", 'w' )
-            main.log.error( ", ".join( labels ) + "\n" + ", ".join( data ) )
-            timerLog.write( ", ".join( labels ) + "\n" + ", ".join( data ) )
-            timerLog.close()
-        except NameError as e:
-            main.log.exception( e )
+        main.HA.cleanUp( main )
 
         main.step( "Stopping webserver" )
         status = main.Server.stop()
@@ -2895,47 +350,7 @@
         """
         start election app on all onos nodes
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        main.case( "Start Leadership Election app" )
-        main.step( "Install leadership election app" )
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        appResult = onosCli.activateApp( "org.onosproject.election" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=appResult,
-            onpass="Election app installed",
-            onfail="Something went wrong with installing Leadership election" )
-
-        main.step( "Run for election on each node" )
-        for i in main.activeNodes:
-            main.CLIs[ i ].electionTestRun()
-        time.sleep( 5 )
-        activeCLIs = [ main.CLIs[ i ] for i in main.activeNodes ]
-        sameResult, leaders = main.HA.consistentLeaderboards( activeCLIs )
-        utilities.assert_equals(
-            expect=True,
-            actual=sameResult,
-            onpass="All nodes see the same leaderboards",
-            onfail="Inconsistent leaderboards" )
-
-        if sameResult:
-            leader = leaders[ 0 ][ 0 ]
-            if main.nodes[ main.activeNodes[ 0 ] ].ip_address in leader:
-                correctLeader = True
-            else:
-                correctLeader = False
-            main.step( "First node was elected leader" )
-            utilities.assert_equals(
-                expect=True,
-                actual=correctLeader,
-                onpass="Correct leader was elected",
-                onfail="Incorrect leader" )
+        main.HA.startElectionApp( main )
 
     def CASE15( self, main ):
         """
@@ -2952,196 +367,16 @@
             old and new variable prefixes refer to data from before vs after
                 withdrawl and later before withdrawl vs after re-election
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        description = "Check that Leadership Election is still functional"
-        main.case( description )
-        # NOTE: Need to re-run after restarts since being a canidate is not persistant
-
-        oldLeaders = []  # list of lists of each nodes' candidates before
-        newLeaders = []  # list of lists of each nodes' candidates after
-        oldLeader = ''  # the old leader from oldLeaders, None if not same
-        newLeader = ''  # the new leaders fron newLoeaders, None if not same
-        oldLeaderCLI = None  # the CLI of the old leader used for re-electing
-        expectNoLeader = False  # True when there is only one leader
-        if main.numCtrls == 1:
-            expectNoLeader = True
-
-        main.step( "Run for election on each node" )
-        electionResult = main.TRUE
-
-        for i in main.activeNodes:  # run test election on each node
-            if main.CLIs[ i ].electionTestRun() == main.FALSE:
-                electionResult = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=electionResult,
-            onpass="All nodes successfully ran for leadership",
-            onfail="At least one node failed to run for leadership" )
-
-        if electionResult == main.FALSE:
-            main.log.error(
-                "Skipping Test Case because Election Test App isn't loaded" )
-            main.skipCase()
-
-        main.step( "Check that each node shows the same leader and candidates" )
-        failMessage = "Nodes have different leaderboards"
-        activeCLIs = [ main.CLIs[ i ] for i in main.activeNodes ]
-        sameResult, oldLeaders = main.HA.consistentLeaderboards( activeCLIs )
-        if sameResult:
-            oldLeader = oldLeaders[ 0 ][ 0 ]
-            main.log.warn( oldLeader )
-        else:
-            oldLeader = None
-        utilities.assert_equals(
-            expect=True,
-            actual=sameResult,
-            onpass="Leaderboards are consistent for the election topic",
-            onfail=failMessage )
-
-        main.step( "Find current leader and withdraw" )
-        withdrawResult = main.TRUE
-        # do some sanity checking on leader before using it
-        if oldLeader is None:
-            main.log.error( "Leadership isn't consistent." )
-            withdrawResult = main.FALSE
-        # Get the CLI of the oldLeader
-        for i in main.activeNodes:
-            if oldLeader == main.nodes[ i ].ip_address:
-                oldLeaderCLI = main.CLIs[ i ]
-                break
-        else:  # FOR/ELSE statement
-            main.log.error( "Leader election, could not find current leader" )
-        if oldLeader:
-            withdrawResult = oldLeaderCLI.electionTestWithdraw()
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=withdrawResult,
-            onpass="Node was withdrawn from election",
-            onfail="Node was not withdrawn from election" )
-
-        main.step( "Check that a new node was elected leader" )
-        failMessage = "Nodes have different leaders"
-        # Get new leaders and candidates
-        newLeaderResult, newLeaders = main.HA.consistentLeaderboards( activeCLIs )
-        newLeader = None
-        if newLeaderResult:
-            if newLeaders[ 0 ][ 0 ] == 'none':
-                main.log.error( "No leader was elected on at least 1 node" )
-                if not expectNoLeader:
-                    newLeaderResult = False
-            newLeader = newLeaders[ 0 ][ 0 ]
-
-        # Check that the new leader is not the older leader, which was withdrawn
-        if newLeader == oldLeader:
-            newLeaderResult = False
-            main.log.error( "All nodes still see old leader: " + str( oldLeader ) +
-                            " as the current leader" )
-        utilities.assert_equals(
-            expect=True,
-            actual=newLeaderResult,
-            onpass="Leadership election passed",
-            onfail="Something went wrong with Leadership election" )
-
-        main.step( "Check that that new leader was the candidate of old leader" )
-        # candidates[ 2 ] should become the top candidate after withdrawl
-        correctCandidateResult = main.TRUE
-        if expectNoLeader:
-            if newLeader == 'none':
-                main.log.info( "No leader expected. None found. Pass" )
-                correctCandidateResult = main.TRUE
-            else:
-                main.log.info( "Expected no leader, got: " + str( newLeader ) )
-                correctCandidateResult = main.FALSE
-        elif len( oldLeaders[ 0 ] ) >= 3:
-            if newLeader == oldLeaders[ 0 ][ 2 ]:
-                # correct leader was elected
-                correctCandidateResult = main.TRUE
-            else:
-                correctCandidateResult = main.FALSE
-                main.log.error( "Candidate {} was elected. {} should have had priority.".format(
-                                    newLeader, oldLeaders[ 0 ][ 2 ] ) )
-        else:
-            main.log.warn( "Could not determine who should be the correct leader" )
-            main.log.debug( oldLeaders[ 0 ] )
-            correctCandidateResult = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=correctCandidateResult,
-            onpass="Correct Candidate Elected",
-            onfail="Incorrect Candidate Elected" )
-
-        main.step( "Run for election on old leader( just so everyone " +
-                   "is in the hat )" )
-        if oldLeaderCLI is not None:
-            runResult = oldLeaderCLI.electionTestRun()
-        else:
-            main.log.error( "No old leader to re-elect" )
-            runResult = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=runResult,
-            onpass="App re-ran for election",
-            onfail="App failed to run for election" )
-
-        main.step(
-            "Check that oldLeader is a candidate, and leader if only 1 node" )
-        # verify leader didn't just change
-        # Get new leaders and candidates
-        reRunLeaders = []
-        time.sleep( 5 )  # Paremterize
-        positionResult, reRunLeaders = main.HA.consistentLeaderboards( activeCLIs )
-
-        # Check that the re-elected node is last on the candidate List
-        if not reRunLeaders[ 0 ]:
-            positionResult = main.FALSE
-        elif oldLeader != reRunLeaders[ 0 ][ -1 ]:
-            main.log.error( "Old Leader ({}) not in the proper position: {} ".format( str( oldLeader ),
-                                                                                      str( reRunLeaders[ 0 ] ) ) )
-            positionResult = main.FALSE
-        utilities.assert_equals(
-            expect=True,
-            actual=positionResult,
-            onpass="Old leader successfully re-ran for election",
-            onfail="Something went wrong with Leadership election after " +
-                   "the old leader re-ran for election" )
+        main.HA.isElectionFunctional( main )
 
     def CASE16( self, main ):
         """
         Install Distributed Primitives app
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        # Variables for the distributed primitives tests
-        main.pCounterName = "TestON-Partitions"
-        main.pCounterValue = 0
-        main.onosSet = set( [] )
-        main.onosSetName = "TestON-set"
-
-        description = "Install Primitives app"
-        main.case( description )
-        main.step( "Install Primitives app" )
-        appName = "org.onosproject.distributedprimitives"
-        node = main.activeNodes[ 0 ]
-        appResults = main.CLIs[ node ].activateApp( appName )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=appResults,
-                                 onpass="Primitives app activated",
-                                 onfail="Primitives app not activated" )
-        time.sleep( 5 )  # To allow all nodes to activate
+        main.HA.installDistributedPrimitiveApp( main )
 
     def CASE17( self, main ):
         """
         Check for basic functionality with distributed primitives
         """
-        main.HA.CASE17( main )
+        main.HA.checkDistPrimitivesFunc( main )
diff --git a/TestON/tests/HA/HAsingleInstanceRestart/HAsingleInstanceRestart.params b/TestON/tests/HA/HAsingleInstanceRestart/HAsingleInstanceRestart.params
index 9e02df9..65ec6c6 100644
--- a/TestON/tests/HA/HAsingleInstanceRestart/HAsingleInstanceRestart.params
+++ b/TestON/tests/HA/HAsingleInstanceRestart/HAsingleInstanceRestart.params
@@ -32,8 +32,10 @@
         <cellName>HA</cellName>
         <appString>drivers,openflow,proxyarp,mobility</appString>
     </ENV>
-    <Git> False </Git>
-    <branch> master </branch>
+    <GIT>
+        <pull>False</pull>
+        <branch>master</branch>
+    </GIT>
     <num_controllers> 1 </num_controllers>
     <tcpdump> False </tcpdump>
 
diff --git a/TestON/tests/HA/HAsingleInstanceRestart/HAsingleInstanceRestart.py b/TestON/tests/HA/HAsingleInstanceRestart/HAsingleInstanceRestart.py
index 73ec921..3af5a66 100644
--- a/TestON/tests/HA/HAsingleInstanceRestart/HAsingleInstanceRestart.py
+++ b/TestON/tests/HA/HAsingleInstanceRestart/HAsingleInstanceRestart.py
@@ -57,20 +57,22 @@
 
         # load some variables from the params file
         PULLCODE = False
-        if main.params[ 'Git' ] == 'True':
+        if main.params[ 'GIT' ][ 'pull' ] == 'True':
             PULLCODE = True
-        gitBranch = main.params[ 'branch' ]
+        gitBranch = main.params[ 'GIT' ][ 'branch' ]
         cellName = main.params[ 'ENV' ][ 'cellName' ]
 
         main.numCtrls = int( main.params[ 'num_controllers' ] )
         if main.ONOSbench.maxNodes:
             if main.ONOSbench.maxNodes < main.numCtrls:
                 main.numCtrls = int( main.ONOSbench.maxNodes )
-
+        # These are for csv plotting in jenkins
+        main.HAlabels = []
+        main.HAdata = []
         try:
             from tests.HA.dependencies.HA import HA
             main.HA = HA()
-        except Exception as e:
+        except ImportError as e:
             main.log.exception( e )
             main.cleanup()
             main.exit()
@@ -112,19 +114,7 @@
 
         gitPullResult = main.TRUE
 
-        main.step( "Starting Mininet" )
-        # scp topo file to mininet
-        # TODO: move to params?
-        topoName = "obelisk.py"
-        filePath = main.ONOSbench.home + "/tools/test/topos/"
-        main.ONOSbench.scp( main.Mininet1,
-                            filePath + topoName,
-                            main.Mininet1.home,
-                            direction="to" )
-        mnResult = main.Mininet1.startNet()
-        utilities.assert_equals( expect=main.TRUE, actual=mnResult,
-                                 onpass="Mininet Started",
-                                 onfail="Error starting Mininet" )
+        main.HA.startingMininet()
 
         main.step( "Git checkout and pull " + gitBranch )
         if PULLCODE:
@@ -136,24 +126,7 @@
                                       onfail="Git pull failed" )
         main.ONOSbench.getVersion( report=True )
 
-        # GRAPHS
-        # NOTE: important params here:
-        #       job = name of Jenkins job
-        #       Plot Name = Plot-HA, only can be used if multiple plots
-        #       index = The number of the graph under plot name
-        job = "HAsingleInstanceRestart"
-        plotName = "Plot-HA"
-        index = "2"
-        graphs = '<ac:structured-macro ac:name="html">\n'
-        graphs += '<ac:plain-text-body><![CDATA[\n'
-        graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
-                  '/plot/' + plotName + '/getPlot?index=' + index +\
-                  '&width=500&height=300"' +\
-                  'noborder="0" width="500" height="300" scrolling="yes" ' +\
-                  'seamless="seamless"></iframe>\n'
-        graphs += ']]></ac:plain-text-body>\n'
-        graphs += '</ac:structured-macro>\n'
-        main.log.wiki( graphs )
+        main.HA.generateGraph( "HAsingleInstanceRestart" )
 
         main.CLIs = []
         main.nodes = []
@@ -223,928 +196,31 @@
                                  onpass="ONOS cli startup successful",
                                  onfail="ONOS cli startup failed" )
 
-        # Create a list of active nodes for use when some nodes are stopped
-        main.activeNodes = [ i for i in range( 0, len( main.CLIs ) ) ]
-
-        if main.params[ 'tcpdump' ].lower() == "true":
-            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' ] )
-
-        main.step( "Checking ONOS nodes" )
-        nodeResults = utilities.retry( main.HA.nodesCheck,
-                                       False,
-                                       args=[ main.activeNodes ],
-                                       attempts=5 )
-
-        utilities.assert_equals( expect=True, actual=nodeResults,
-                                 onpass="Nodes check successful",
-                                 onfail="Nodes check NOT successful" )
-
-        if not nodeResults:
-            for i in main.activeNodes:
-                cli = main.CLIs[ i ]
-                main.log.debug( "{} components not ACTIVE: \n{}".format(
-                    cli.name,
-                    cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
-            main.log.error( "Failed to start ONOS, stopping test" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Activate apps defined in the params file" )
-        # get data from the params
-        apps = main.params.get( 'apps' )
-        if apps:
-            apps = apps.split( ',' )
-            main.log.warn( apps )
-            activateResult = True
-            for app in apps:
-                main.CLIs[ 0 ].app( app, "Activate" )
-            # TODO: check this worked
-            time.sleep( 10 )  # wait for apps to activate
-            for app in apps:
-                state = main.CLIs[ 0 ].appStatus( app )
-                if state == "ACTIVE":
-                    activateResult = activateResult and True
-                else:
-                    main.log.error( "{} is in {} state".format( app, state ) )
-                    activateResult = False
-            utilities.assert_equals( expect=True,
-                                     actual=activateResult,
-                                     onpass="Successfully activated apps",
-                                     onfail="Failed to activate apps" )
-        else:
-            main.log.warn( "No apps were specified to be loaded after startup" )
-
-        main.step( "Set ONOS configurations" )
-        config = main.params.get( 'ONOS_Configuration' )
-        if config:
-            main.log.debug( config )
-            checkResult = main.TRUE
-            for component in config:
-                for setting in config[ component ]:
-                    value = config[ component ][ setting ]
-                    check = main.CLIs[ 0 ].setCfg( component, setting, value )
-                    main.log.info( "Value was changed? {}".format( main.TRUE == check ) )
-                    checkResult = check and checkResult
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=checkResult,
-                                     onpass="Successfully set config",
-                                     onfail="Failed to set config" )
-        else:
-            main.log.warn( "No configurations were specified to be changed after startup" )
-
-        main.step( "App Ids check" )
-        appCheck = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
-                             name="appToIDCheck-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            appCheck = appCheck and t.result
-        if appCheck != main.TRUE:
-            node = main.activeNodes[ 0 ]
-            main.log.warn( main.CLIs[ node ].apps() )
-            main.log.warn( main.CLIs[ node ].appIDs() )
-        utilities.assert_equals( expect=main.TRUE, actual=appCheck,
-                                 onpass="App Ids seem to be correct",
-                                 onfail="Something is wrong with app Ids" )
+        main.HA.initialSetUp()
 
     def CASE2( self, main ):
         """
         Assign devices to controllers
         """
-        import re
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-
-        main.case( "Assigning devices to controllers" )
-        main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
-                                "and check that an ONOS node becomes the " +\
-                                "master of the device."
-        main.step( "Assign switches to controllers" )
-
-        ipList = []
-        for i in range( main.numCtrls ):
-            ipList.append( main.nodes[ i ].ip_address )
-        swList = []
-        for i in range( 1, 29 ):
-            swList.append( "s" + str( i ) )
-        main.Mininet1.assignSwController( sw=swList, ip=ipList )
-
-        mastershipCheck = main.TRUE
-        for i in range( 1, 29 ):
-            response = main.Mininet1.getSwController( "s" + str( i ) )
-            try:
-                main.log.info( str( response ) )
-            except Exception:
-                main.log.info( repr( response ) )
-            for node in main.nodes:
-                if re.search( "tcp:" + node.ip_address, response ):
-                    mastershipCheck = mastershipCheck and main.TRUE
-                else:
-                    main.log.error( "Error, node " + node.ip_address + " is " +
-                                    "not in the list of controllers s" +
-                                    str( i ) + " is connecting to." )
-                    mastershipCheck = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=mastershipCheck,
-            onpass="Switch mastership assigned correctly",
-            onfail="Switches not assigned correctly to controllers" )
+        main.HA.assignDevices( main )
 
     def CASE21( self, main ):
         """
         Assign mastership to controllers
         """
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        main.case( "Assigning Controller roles for switches" )
-        main.caseExplanation = "Check that ONOS is connected to each " +\
-                                "device. Then manually assign" +\
-                                " mastership to specific ONOS nodes using" +\
-                                " 'device-role'"
-        main.step( "Assign mastership of switches to specific controllers" )
-        # Manually assign mastership to the controller we want
-        roleCall = main.TRUE
-
-        ipList = []
-        deviceList = []
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        try:
-            # Assign mastership to specific controllers. This assignment was
-            # determined for a 7 node cluser, but will work with any sized
-            # cluster
-            for i in range( 1, 29 ):  # switches 1 through 28
-                # set up correct variables:
-                if i == 1:
-                    c = 0
-                    ip = main.nodes[ c ].ip_address  # ONOS1
-                    deviceId = onosCli.getDevice( "1000" ).get( 'id' )
-                elif i == 2:
-                    c = 1 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS2
-                    deviceId = onosCli.getDevice( "2000" ).get( 'id' )
-                elif i == 3:
-                    c = 1 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS2
-                    deviceId = onosCli.getDevice( "3000" ).get( 'id' )
-                elif i == 4:
-                    c = 3 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS4
-                    deviceId = onosCli.getDevice( "3004" ).get( 'id' )
-                elif i == 5:
-                    c = 2 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS3
-                    deviceId = onosCli.getDevice( "5000" ).get( 'id' )
-                elif i == 6:
-                    c = 2 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS3
-                    deviceId = onosCli.getDevice( "6000" ).get( 'id' )
-                elif i == 7:
-                    c = 5 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS6
-                    deviceId = onosCli.getDevice( "6007" ).get( 'id' )
-                elif i >= 8 and i <= 17:
-                    c = 4 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS5
-                    dpid = '3' + str( i ).zfill( 3 )
-                    deviceId = onosCli.getDevice( dpid ).get( 'id' )
-                elif i >= 18 and i <= 27:
-                    c = 6 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS7
-                    dpid = '6' + str( i ).zfill( 3 )
-                    deviceId = onosCli.getDevice( dpid ).get( 'id' )
-                elif i == 28:
-                    c = 0
-                    ip = main.nodes[ c ].ip_address  # ONOS1
-                    deviceId = onosCli.getDevice( "2800" ).get( 'id' )
-                else:
-                    main.log.error( "You didn't write an else statement for " +
-                                    "switch s" + str( i ) )
-                    roleCall = main.FALSE
-                # Assign switch
-                assert deviceId, "No device id for s" + str( i ) + " in ONOS"
-                # TODO: make this controller dynamic
-                roleCall = roleCall and onosCli.deviceRole( deviceId, ip )
-                ipList.append( ip )
-                deviceList.append( deviceId )
-        except ( AttributeError, AssertionError ):
-            main.log.exception( "Something is wrong with ONOS device view" )
-            main.log.info( onosCli.devices() )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=roleCall,
-            onpass="Re-assigned switch mastership to designated controller",
-            onfail="Something wrong with deviceRole calls" )
-
-        main.step( "Check mastership was correctly assigned" )
-        roleCheck = main.TRUE
-        # NOTE: This is due to the fact that device mastership change is not
-        #       atomic and is actually a multi step process
-        time.sleep( 5 )
-        for i in range( len( ipList ) ):
-            ip = ipList[ i ]
-            deviceId = deviceList[ i ]
-            # Check assignment
-            master = onosCli.getRole( deviceId ).get( 'master' )
-            if ip in master:
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-                main.log.error( "Error, controller " + ip + " is not" +
-                                " master " + "of device " +
-                                str( deviceId ) + ". Master is " +
-                                repr( master ) + "." )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=roleCheck,
-            onpass="Switches were successfully reassigned to designated " +
-                   "controller",
-            onfail="Switches were not successfully reassigned" )
+        main.HA.assignMastership( main )
 
     def CASE3( self, main ):
         """
         Assign intents
         """
-        import time
-        import json
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        # NOTE: we must reinstall intents until we have a persistant intent
-        #        datastore!
-        main.case( "Adding host Intents" )
-        main.caseExplanation = "Discover hosts by using pingall then " +\
-                                "assign predetermined host-to-host intents." +\
-                                " After installation, check that the intent" +\
-                                " is distributed to all nodes and the state" +\
-                                " is INSTALLED"
-
-        # install onos-app-fwd
-        main.step( "Install reactive forwarding app" )
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        installResults = onosCli.activateApp( "org.onosproject.fwd" )
-        utilities.assert_equals( expect=main.TRUE, actual=installResults,
-                                 onpass="Install fwd successful",
-                                 onfail="Install fwd failed" )
-
-        main.step( "Check app ids" )
-        appCheck = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
-                             name="appToIDCheck-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            appCheck = appCheck and t.result
-        if appCheck != main.TRUE:
-            main.log.warn( onosCli.apps() )
-            main.log.warn( onosCli.appIDs() )
-        utilities.assert_equals( expect=main.TRUE, actual=appCheck,
-                                 onpass="App Ids seem to be correct",
-                                 onfail="Something is wrong with app Ids" )
-
-        main.step( "Discovering Hosts( Via pingall for now )" )
-        # FIXME: Once we have a host discovery mechanism, use that instead
-        # REACTIVE FWD test
-        pingResult = main.FALSE
-        passMsg = "Reactive Pingall test passed"
-        time1 = time.time()
-        pingResult = main.Mininet1.pingall()
-        time2 = time.time()
-        if not pingResult:
-            main.log.warn( "First pingall failed. Trying again..." )
-            pingResult = main.Mininet1.pingall()
-            passMsg += " on the second try"
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=pingResult,
-            onpass=passMsg,
-            onfail="Reactive Pingall failed, " +
-                   "one or more ping pairs failed" )
-        main.log.info( "Time for pingall: %2f seconds" %
-                       ( time2 - time1 ) )
-        # timeout for fwd flows
-        time.sleep( 11 )
-        # uninstall onos-app-fwd
-        main.step( "Uninstall reactive forwarding app" )
-        node = main.activeNodes[ 0 ]
-        uninstallResult = main.CLIs[ node ].deactivateApp( "org.onosproject.fwd" )
-        utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
-                                 onpass="Uninstall fwd successful",
-                                 onfail="Uninstall fwd failed" )
-
-        main.step( "Check app ids" )
-        threads = []
-        appCheck2 = main.TRUE
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
-                             name="appToIDCheck-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            appCheck2 = appCheck2 and t.result
-        if appCheck2 != main.TRUE:
-            node = main.activeNodes[ 0 ]
-            main.log.warn( main.CLIs[ node ].apps() )
-            main.log.warn( main.CLIs[ node ].appIDs() )
-        utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
-                                 onpass="App Ids seem to be correct",
-                                 onfail="Something is wrong with app Ids" )
-
-        main.step( "Add host intents via cli" )
-        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 ) )
-            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 = onosCli.getHost( host1 )
-            host2Dict = onosCli.getHost( host2 )
-            host1Id = None
-            host2Id = None
-            if host1Dict and host2Dict:
-                host1Id = host1Dict.get( 'id', None )
-                host2Id = host2Dict.get( 'id', None )
-            if host1Id and host2Id:
-                nodeNum = ( i % len( main.activeNodes ) )
-                node = main.activeNodes[ nodeNum ]
-                tmpId = main.CLIs[ node ].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 for h" + str( i ) +
-                                " and/or h" + str( i + 10 ) )
-                node = main.activeNodes[ 0 ]
-                hosts = main.CLIs[ node ].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
-        utilities.assert_equals( expect=main.TRUE, actual=hostResult,
-                                 onpass="Found a host id for each host",
-                                 onfail="Error looking up host ids" )
-
-        intentStart = time.time()
-        onosIds = onosCli.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
-        if intentAddResult:
-            intentStop = time.time()
-        else:
-            intentStop = None
-        # Print the intent states
-        intents = onosCli.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 = onosCli.leaders()
-        try:
-            missing = False
-            if leaders:
-                parsedLeaders = json.loads( leaders )
-                main.log.warn( json.dumps( parsedLeaders,
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-                # check for all intent partitions
-                topics = []
-                for i in range( 14 ):
-                    topics.append( "work-partition-" + str( i ) )
-                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" )
-                        missing = True
-            else:
-                main.log.error( "leaders() returned None" )
-        except ( ValueError, TypeError ):
-            main.log.exception( "Error parsing leaders" )
-            main.log.error( repr( leaders ) )
-        # Check all nodes
-        if missing:
-            for i in main.activeNodes:
-                response = main.CLIs[ i ].leaders( jsonFormat=False )
-                main.log.warn( str( main.CLIs[ i ].name ) + " leaders output: \n" +
-                               str( response ) )
-
-        partitions = onosCli.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 = onosCli.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( intentAddResult and not missingIntents and
-                                installedCheck )
-        if not intentAddResult:
-            main.log.error( "Error in pushing host intents to ONOS" )
-
-        main.step( "Intent Anti-Entropy dispersion" )
-        for j in range( 100 ):
-            correct = True
-            main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
-            for i in main.activeNodes:
-                onosIds = []
-                ids = main.CLIs[ i ].getAllIntentsId()
-                onosIds.append( ids )
-                main.log.debug( "Intents in " + main.CLIs[ i ].name + ": " +
-                                str( sorted( onosIds ) ) )
-                if sorted( ids ) != sorted( intentIds ):
-                    main.log.warn( "Set of intent IDs doesn't match" )
-                    correct = False
-                    break
-                else:
-                    intents = json.loads( main.CLIs[ i ].intents() )
-                    for intent in intents:
-                        if intent[ 'state' ] != "INSTALLED":
-                            main.log.warn( "Intent " + intent[ 'id' ] +
-                                           " is " + intent[ 'state' ] )
-                            correct = False
-                            break
-            if correct:
-                break
-            else:
-                time.sleep( 1 )
-        if not intentStop:
-            intentStop = time.time()
-        global gossipTime
-        gossipTime = intentStop - intentStart
-        main.log.info( "It took about " + str( gossipTime ) +
-                        " seconds for all intents to appear in each node" )
-        gossipPeriod = int( main.params[ 'timers' ][ 'gossip' ] )
-        maxGossipTime = gossipPeriod * len( main.activeNodes )
-        utilities.assert_greater_equals(
-                expect=maxGossipTime, actual=gossipTime,
-                onpass="ECM anti-entropy for intents worked within " +
-                       "expected time",
-                onfail="Intent ECM anti-entropy took too long. " +
-                       "Expected time:{}, Actual time:{}".format( maxGossipTime,
-                                                                  gossipTime ) )
-        if gossipTime <= maxGossipTime:
-            intentAddResult = True
-
-        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 = onosCli.getAllIntentsId()
-            main.log.info( "Submitted intents: " + str( intentIds ) )
-            main.log.info( "Intents in ONOS: " + str( onosIds ) )
-            # Print the intent states
-            intents = onosCli.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 = onosCli.leaders()
-            try:
-                missing = False
-                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( "work-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" )
-                            missing = True
-                else:
-                    main.log.error( "leaders() returned None" )
-            except ( ValueError, TypeError ):
-                main.log.exception( "Error parsing leaders" )
-                main.log.error( repr( leaders ) )
-            # Check all nodes
-            if missing:
-                for i in main.activeNodes:
-                    node = main.CLIs[ i ]
-                    response = node.leaders( jsonFormat=False )
-                    main.log.warn( str( node.name ) + " leaders output: \n" +
-                                   str( response ) )
-
-            partitions = onosCli.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 = onosCli.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 ) )
+        main.HA.assignIntents( main )
 
     def CASE4( self, main ):
         """
         Ping across added host intents
         """
-        import json
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        main.case( "Verify connectivity by sending traffic across Intents" )
-        main.caseExplanation = "Ping across added host intents to check " +\
-                                "functionality and check the state of " +\
-                                "the intent"
-
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        main.step( "Check Intent state" )
-        installedCheck = 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." )
-        # Print states
-        intentStates.sort()
-        for i, s in intentStates:
-            count += 1
-            main.log.info( "%-6s%-15s%-15s" %
-                           ( str( count ), str( i ), str( s ) ) )
-        utilities.assert_equals( expect=True, actual=installedCheck,
-                                 onpass="Intents are all INSTALLED",
-                                 onfail="Intents are not all in " +
-                                        "INSTALLED state" )
-
-        main.step( "Ping across added host intents" )
-        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.error(
-                "Intents have not been installed correctly, pings failed." )
-            # TODO: pretty print
-            main.log.warn( "ONOS1 intents: " )
-            try:
-                tmpIntents = onosCli.intents()
-                main.log.warn( json.dumps( json.loads( tmpIntents ),
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-            except ( ValueError, TypeError ):
-                main.log.warn( repr( tmpIntents ) )
-        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." )
-
-        main.step( "Check leadership of topics" )
-        leaders = onosCli.leaders()
-        topicCheck = main.TRUE
-        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
-                # TODO: Look at Devices as topics now that it uses this system
-                topics = []
-                for i in range( 14 ):
-                    topics.append( "work-partition-" + str( i ) )
-                # FIXME: this should only be after we start the app
-                # FIXME: topics.append( "org.onosproject.election" )
-                # Print leaders output
-                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" )
-                        topicCheck = main.FALSE
-            else:
-                main.log.error( "leaders() returned None" )
-                topicCheck = main.FALSE
-        except ( ValueError, TypeError ):
-            topicCheck = main.FALSE
-            main.log.exception( "Error parsing leaders" )
-            main.log.error( repr( leaders ) )
-            # TODO: Check for a leader of these topics
-        # Check all nodes
-        if topicCheck:
-            for i in main.activeNodes:
-                node = main.CLIs[ i ]
-                response = node.leaders( jsonFormat=False )
-                main.log.warn( str( node.name ) + " leaders output: \n" +
-                               str( response ) )
-
-        utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
-                                 onpass="intent Partitions is in leaders",
-                                 onfail="Some topics were lost " )
-        # Print partitions
-        partitions = onosCli.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 ) )
-        # Print Pending Map
-        pendingMap = onosCli.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 = onosCli.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 = onosCli.leaders()
-            try:
-                missing = False
-                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( "work-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" )
-                            missing = True
-                else:
-                    main.log.error( "leaders() returned None" )
-            except ( ValueError, TypeError ):
-                main.log.exception( "Error parsing leaders" )
-                main.log.error( repr( leaders ) )
-            if missing:
-                for i in main.activeNodes:
-                    node = main.CLIs[ i ]
-                    response = node.leaders( jsonFormat=False )
-                    main.log.warn( str( node.name ) + " leaders output: \n" +
-                                   str( response ) )
-
-            partitions = onosCli.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 = onosCli.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 ) )
-        # Print flowrules
-        node = main.activeNodes[ 0 ]
-        main.log.debug( main.CLIs[ node ].flows( jsonFormat=False ) )
-        main.step( "Wait a minute then ping again" )
-        # the wait is above
-        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.error(
-                "Intents have not been installed correctly, pings failed." )
-            # TODO: pretty print
-            main.log.warn( "ONOS1 intents: " )
-            try:
-                tmpIntents = onosCli.intents()
-                main.log.warn( json.dumps( json.loads( tmpIntents ),
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-            except ( ValueError, TypeError ):
-                main.log.warn( repr( tmpIntents ) )
-        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." )
+        main.HA.pingAcrossHostIntent( main, False, True )
 
     def CASE5( self, main ):
         """
@@ -1856,238 +932,41 @@
         """
         Link s3-s28 down
         """
-        import time
-        assert main.numCtrls, "main.numCtrls 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"
-        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 successful",
-                                 onfail="Failed to bring link down" )
-        # TODO do some sort of check here
+        main.HA.linkDown( main )
 
     def CASE10( self, main ):
         """
         Link s3-s28 up
         """
-        import time
-        assert main.numCtrls, "main.numCtrls 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"
-        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 successful",
-                                 onfail="Failed to bring link up" )
-        # TODO do some sort of check here
+        main.HA.linkUp( main )
 
     def CASE11( self, main ):
         """
         Switch Down
         """
         # NOTE: You should probably run a topology check after this
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-
-        switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
-
-        description = "Killing a switch to ensure it is discovered correctly"
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        main.case( description )
-        switch = main.params[ 'kill' ][ 'switch' ]
-        switchDPID = main.params[ 'kill' ][ 'dpid' ]
-
-        # TODO: Make this switch parameterizable
-        main.step( "Kill " + switch )
-        main.log.info( "Deleting " + switch )
-        main.Mininet1.delSwitch( switch )
-        main.log.info( "Waiting " + str( switchSleep ) +
-                       " seconds for switch down to be discovered" )
-        time.sleep( switchSleep )
-        device = onosCli.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 successful",
-                                 onfail="Failed to kill switch?" )
+        main.HA.switchDown( main )
 
     def CASE12( self, main ):
         """
         Switch Up
         """
         # NOTE: You should probably run a topology check after this
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-
-        switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
-        switch = main.params[ 'kill' ][ 'switch' ]
-        switchDPID = main.params[ 'kill' ][ 'dpid' ]
-        links = main.params[ 'kill' ][ 'links' ].split()
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        description = "Adding a switch to ensure it is discovered correctly"
-        main.case( description )
-
-        main.step( "Add back " + switch )
-        main.Mininet1.addSwitch( switch, dpid=switchDPID )
-        for peer in links:
-            main.Mininet1.addLink( switch, peer )
-        ipList = [ node.ip_address for node in main.nodes ]
-        main.Mininet1.assignSwController( sw=switch, ip=ipList )
-        main.log.info( "Waiting " + str( switchSleep ) +
-                       " seconds for switch up to be discovered" )
-        time.sleep( switchSleep )
-        device = onosCli.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 successful",
-                                 onfail="Failed to add switch?" )
+        main.HA.switchUp( main )
 
     def CASE13( self, main ):
         """
         Clean up
         """
-        import os
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        # printing colors to terminal
-        colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
-                   'blue': '\033[94m', 'green': '\033[92m',
-                   'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
-        main.case( "Test Cleanup" )
-        main.step( "Killing tcpdumps" )
-        main.Mininet2.stopTcpdump()
-
-        testname = main.TEST
-        if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
-            main.step( "Copying MN pcap and ONOS log files to test station" )
-            teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
-            teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
-            # NOTE: MN Pcap file is being saved to logdir.
-            #       We scp this file as MN and TestON aren't necessarily the same vm
-
-            # FIXME: To be replaced with a Jenkin's post script
-            # TODO: Load these from params
-            # NOTE: must end in /
-            logFolder = "/opt/onos/log/"
-            logFiles = [ "karaf.log", "karaf.log.1" ]
-            # NOTE: must end in /
-            for f in logFiles:
-                for node in main.nodes:
-                    dstName = main.logdir + "/" + node.name + "-" + f
-                    main.ONOSbench.secureCopy( node.user_name, node.ip_address,
-                                               logFolder + f, dstName )
-            # std*.log's
-            # NOTE: must end in /
-            logFolder = "/opt/onos/var/"
-            logFiles = [ "stderr.log", "stdout.log" ]
-            # NOTE: must end in /
-            for f in logFiles:
-                for node in main.nodes:
-                    dstName = main.logdir + "/" + node.name + "-" + f
-                    main.ONOSbench.secureCopy( node.user_name, node.ip_address,
-                                               logFolder + f, dstName )
-        else:
-            main.log.debug( "skipping saving log files" )
-
-        main.step( "Stopping Mininet" )
-        mnResult = main.Mininet1.stopNet()
-        utilities.assert_equals( expect=main.TRUE, actual=mnResult,
-                                 onpass="Mininet stopped",
-                                 onfail="MN cleanup NOT successful" )
-
-        main.step( "Checking ONOS Logs for errors" )
-        for node in main.nodes:
-            main.log.debug( "Checking logs for errors on " + node.name + ":" )
-            main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
-
-        try:
-            timerLog = open( main.logdir + "/Timers.csv", 'w' )
-            # Overwrite with empty line and close
-            labels = "Gossip Intents, Restart"
-            data = str( gossipTime ) + ", " + str( main.restartTime )
-            timerLog.write( labels + "\n" + data )
-            timerLog.close()
-        except NameError as e:
-            main.log.exception( e )
+        main.HAlabels.append( "Restart" )
+        main.HAdata.append( str( main.restartTime ) )
+        main.HA.cleanUp( main )
 
     def CASE14( self, main ):
         """
         start election app on all onos nodes
         """
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-
-        main.case( "Start Leadership Election app" )
-        main.step( "Install leadership election app" )
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        appResult = onosCli.activateApp( "org.onosproject.election" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=appResult,
-            onpass="Election app installed",
-            onfail="Something went wrong with installing Leadership election" )
-
-        main.step( "Run for election on each node" )
-        for i in main.activeNodes:
-            main.CLIs[ i ].electionTestRun()
-        time.sleep( 5 )
-        activeCLIs = [ main.CLIs[ i ] for i in main.activeNodes ]
-        sameResult, leaders = main.HA.consistentLeaderboards( activeCLIs )
-        utilities.assert_equals(
-            expect=True,
-            actual=sameResult,
-            onpass="All nodes see the same leaderboards",
-            onfail="Inconsistent leaderboards" )
-
-        if sameResult:
-            leader = leaders[ 0 ][ 0 ]
-            if main.nodes[ main.activeNodes[ 0 ] ].ip_address in leader:
-                correctLeader = True
-            else:
-                correctLeader = False
-            main.step( "First node was elected leader" )
-            utilities.assert_equals(
-                expect=True,
-                actual=correctLeader,
-                onpass="Correct leader was elected",
-                onfail="Incorrect leader" )
+        main.HA.startElectionApp( main )
 
     def CASE15( self, main ):
         """
@@ -2104,197 +983,16 @@
             old and new variable prefixes refer to data from before vs after
                 withdrawl and later before withdrawl vs after re-election
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        description = "Check that Leadership Election is still functional"
-        main.case( description )
-        # NOTE: Need to re-run after restarts since being a canidate is not persistant
-
-        oldLeaders = []  # list of lists of each nodes' candidates before
-        newLeaders = []  # list of lists of each nodes' candidates after
-        oldLeader = ''  # the old leader from oldLeaders, None if not same
-        newLeader = ''  # the new leaders fron newLoeaders, None if not same
-        oldLeaderCLI = None  # the CLI of the old leader used for re-electing
-        expectNoLeader = False  # True when there is only one leader
-        if main.numCtrls == 1:
-            expectNoLeader = True
-
-        main.step( "Run for election on each node" )
-        electionResult = main.TRUE
-
-        for i in main.activeNodes:  # run test election on each node
-            if main.CLIs[ i ].electionTestRun() == main.FALSE:
-                electionResult = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=electionResult,
-            onpass="All nodes successfully ran for leadership",
-            onfail="At least one node failed to run for leadership" )
-
-        if electionResult == main.FALSE:
-            main.log.error(
-                "Skipping Test Case because Election Test App isn't loaded" )
-            main.skipCase()
-
-        main.step( "Check that each node shows the same leader and candidates" )
-        failMessage = "Nodes have different leaderboards"
-        activeCLIs = [ main.CLIs[ i ] for i in main.activeNodes ]
-        sameResult, oldLeaders = main.HA.consistentLeaderboards( activeCLIs )
-        if sameResult:
-            oldLeader = oldLeaders[ 0 ][ 0 ]
-            main.log.warn( oldLeader )
-        else:
-            oldLeader = None
-        utilities.assert_equals(
-            expect=True,
-            actual=sameResult,
-            onpass="Leaderboards are consistent for the election topic",
-            onfail=failMessage )
-
-        main.step( "Find current leader and withdraw" )
-        withdrawResult = main.TRUE
-        # do some sanity checking on leader before using it
-        if oldLeader is None:
-            main.log.error( "Leadership isn't consistent." )
-            withdrawResult = main.FALSE
-        # Get the CLI of the oldLeader
-        for i in main.activeNodes:
-            if oldLeader == main.nodes[ i ].ip_address:
-                oldLeaderCLI = main.CLIs[ i ]
-                break
-        else:  # FOR/ELSE statement
-            main.log.error( "Leader election, could not find current leader" )
-        if oldLeader:
-            withdrawResult = oldLeaderCLI.electionTestWithdraw()
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=withdrawResult,
-            onpass="Node was withdrawn from election",
-            onfail="Node was not withdrawn from election" )
-
-        main.step( "Check that a new node was elected leader" )
-        failMessage = "Nodes have different leaders"
-        # Get new leaders and candidates
-        newLeaderResult, newLeaders = main.HA.consistentLeaderboards( activeCLIs )
-        newLeader = None
-        if newLeaderResult:
-            if newLeaders[ 0 ][ 0 ] == 'none':
-                main.log.error( "No leader was elected on at least 1 node" )
-                if not expectNoLeader:
-                    newLeaderResult = False
-            newLeader = newLeaders[ 0 ][ 0 ]
-
-        # Check that the new leader is not the older leader, which was withdrawn
-        if newLeader == oldLeader:
-            newLeaderResult = False
-            main.log.error( "All nodes still see old leader: " + str( oldLeader ) +
-                            " as the current leader" )
-        utilities.assert_equals(
-            expect=True,
-            actual=newLeaderResult,
-            onpass="Leadership election passed",
-            onfail="Something went wrong with Leadership election" )
-
-        main.step( "Check that that new leader was the candidate of old leader" )
-        # candidates[ 2 ] should become the top candidate after withdrawl
-        correctCandidateResult = main.TRUE
-        if expectNoLeader:
-            if newLeader == 'none':
-                main.log.info( "No leader expected. None found. Pass" )
-                correctCandidateResult = main.TRUE
-            else:
-                main.log.info( "Expected no leader, got: " + str( newLeader ) )
-                correctCandidateResult = main.FALSE
-        elif len( oldLeaders[ 0 ] ) >= 3:
-            if newLeader == oldLeaders[ 0 ][ 2 ]:
-                # correct leader was elected
-                correctCandidateResult = main.TRUE
-            else:
-                correctCandidateResult = main.FALSE
-                main.log.error( "Candidate {} was elected. {} should have had priority.".format(
-                                    newLeader, oldLeaders[ 0 ][ 2 ] ) )
-        else:
-            main.log.warn( "Could not determine who should be the correct leader" )
-            main.log.debug( oldLeaders[ 0 ] )
-            correctCandidateResult = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=correctCandidateResult,
-            onpass="Correct Candidate Elected",
-            onfail="Incorrect Candidate Elected" )
-
-        main.step( "Run for election on old leader( just so everyone " +
-                   "is in the hat )" )
-        if oldLeaderCLI is not None:
-            runResult = oldLeaderCLI.electionTestRun()
-        else:
-            main.log.error( "No old leader to re-elect" )
-            runResult = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=runResult,
-            onpass="App re-ran for election",
-            onfail="App failed to run for election" )
-
-        main.step(
-            "Check that oldLeader is a candidate, and leader if only 1 node" )
-        # verify leader didn't just change
-        # Get new leaders and candidates
-        reRunLeaders = []
-        time.sleep( 5 )  # Paremterize
-        positionResult, reRunLeaders = main.HA.consistentLeaderboards( activeCLIs )
-
-        # Check that the re-elected node is last on the candidate List
-        if not reRunLeaders[ 0 ]:
-            positionResult = main.FALSE
-        elif oldLeader != reRunLeaders[ 0 ][ -1 ]:
-            main.log.error( "Old Leader ({}) not in the proper position: {} ".format( str( oldLeader ),
-                                                                                      str( reRunLeaders[ 0 ] ) ) )
-            positionResult = main.FALSE
-        utilities.assert_equals(
-            expect=True,
-            actual=positionResult,
-            onpass="Old leader successfully re-ran for election",
-            onfail="Something went wrong with Leadership election after " +
-                   "the old leader re-ran for election" )
+        main.HA.isElectionFunctional( main )
 
     def CASE16( self, main ):
         """
         Install Distributed Primitives app
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        # Variables for the distributed primitives tests
-        main.pCounterName = "TestON-Partitions"
-        main.pCounterValue = 0
-        main.onosSet = set( [] )
-        main.onosSetName = "TestON-set"
-
-        description = "Install Primitives app"
-        main.case( description )
-        main.step( "Install Primitives app" )
-        appName = "org.onosproject.distributedprimitives"
-        node = main.activeNodes[ 0 ]
-        appResults = main.CLIs[ node ].activateApp( appName )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=appResults,
-                                 onpass="Primitives app activated",
-                                 onfail="Primitives app not activated" )
-        # TODO check on all nodes instead of sleeping
-        time.sleep( 5 )  # To allow all nodes to activate
+        main.HA.installDistributedPrimitiveApp( main )
 
     def CASE17( self, main ):
         """
         Check for basic functionality with distributed primitives
         """
-        main.HA.CASE17( main )
+        main.HA.checkDistPrimitivesFunc( main )
diff --git a/TestON/tests/HA/HAstopNodes/HAstopNodes.params b/TestON/tests/HA/HAstopNodes/HAstopNodes.params
index 024b1c0..ebffe50 100644
--- a/TestON/tests/HA/HAstopNodes/HAstopNodes.params
+++ b/TestON/tests/HA/HAstopNodes/HAstopNodes.params
@@ -35,8 +35,10 @@
         <cellName>HA</cellName>
         <appString>drivers,openflow,proxyarp,mobility</appString>
     </ENV>
-    <Git> False </Git>
-    <branch> master </branch>
+    <GIT>
+        <pull>False</pull>
+        <branch>master</branch>
+    </GIT>
     <num_controllers> 7 </num_controllers>
     <tcpdump> False </tcpdump>
 
diff --git a/TestON/tests/HA/HAstopNodes/HAstopNodes.py b/TestON/tests/HA/HAstopNodes/HAstopNodes.py
index 46fc032..50fb721 100644
--- a/TestON/tests/HA/HAstopNodes/HAstopNodes.py
+++ b/TestON/tests/HA/HAstopNodes/HAstopNodes.py
@@ -52,1722 +52,72 @@
         import json
         main.log.info( "ONOS HA test: Stop a minority of ONOS nodes - " +
                          "initialization" )
-        main.case( "Setting up test environment" )
-        main.caseExplanation = "Setup the test environment including " +\
-                                "installing ONOS, starting Mininet and ONOS" +\
-                                "cli sessions."
-
-        # load some variables from the params file
-        PULLCODE = False
-        if main.params[ 'Git' ] == 'True':
-            PULLCODE = True
-        gitBranch = main.params[ 'branch' ]
-        cellName = main.params[ 'ENV' ][ 'cellName' ]
-
-        main.numCtrls = int( main.params[ 'num_controllers' ] )
-        if main.ONOSbench.maxNodes:
-            if main.ONOSbench.maxNodes < main.numCtrls:
-                main.numCtrls = int( main.ONOSbench.maxNodes )
         # set global variables
-        global ONOS1Port
-        global ONOS2Port
-        global ONOS3Port
-        global ONOS4Port
-        global ONOS5Port
-        global ONOS6Port
-        global ONOS7Port
         # These are for csv plotting in jenkins
-        global labels
-        global data
-        labels = []
-        data = []
-
-        # 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' ]
-
+        main.HAlabels = []
+        main.HAdata = []
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        main.testSetUp.envSetupDescription()
         try:
             from tests.HA.dependencies.HA import HA
             main.HA = HA()
+            # load some variables from the params file
+            cellName = main.params[ 'ENV' ][ 'cellName' ]
+            main.apps = main.params[ 'ENV' ][ 'appString' ]
+            main.numCtrls = int( main.params[ 'num_controllers' ] )
+            if main.ONOSbench.maxNodes and\
+                        main.ONOSbench.maxNodes < main.numCtrls:
+                main.numCtrls = int( main.ONOSbench.maxNodes )
+            main.maxNodes = main.numCtrls
+            stepResult = main.testSetUp.envSetup( hasNode=True )
         except Exception as e:
-            main.log.exception( e )
-            main.cleanup()
-            main.exit()
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
+        main.HA.generateGraph( "HAstopNodes" )
 
-        main.CLIs = []
-        main.nodes = []
-        ipList = []
-        for i in range( 1, main.numCtrls + 1 ):
-            try:
-                main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
-                main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
-                ipList.append( main.nodes[ -1 ].ip_address )
-            except AttributeError:
-                break
+        main.testSetUp.ONOSSetUp( main.Mininet1, cellName=cellName, removeLog=True,
+                                 extraApply=main.HA.customizeOnosGenPartitions,
+                                 extraClean=main.HA.cleanUpGenPartition )
 
-        main.step( "Create cell file" )
-        cellAppString = main.params[ 'ENV' ][ 'appString' ]
-        main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
-                                       main.Mininet1.ip_address,
-                                       cellAppString, ipList, main.ONOScli1.karafUser )
-        main.step( "Applying cell variable to environment" )
-        cellResult = main.ONOSbench.setCell( cellName )
-        verifyResult = main.ONOSbench.verifyCell()
-
-        # FIXME:this is short term fix
-        main.log.info( "Removing raft logs" )
-        main.ONOSbench.onosRemoveRaftLogs()
-
-        main.log.info( "Uninstalling ONOS" )
-        for node in main.nodes:
-            main.ONOSbench.onosUninstall( node.ip_address )
-
-        # Make sure ONOS is DEAD
-        main.log.info( "Killing any ONOS processes" )
-        killResults = main.TRUE
-        for node in main.nodes:
-            killed = main.ONOSbench.onosKill( node.ip_address )
-            killResults = killResults and killed
-
-        gitPullResult = main.TRUE
-
-        main.step( "Starting Mininet" )
-        # scp topo file to mininet
-        # TODO: move to params?
-        topoName = "obelisk.py"
-        filePath = main.ONOSbench.home + "/tools/test/topos/"
-        main.ONOSbench.scp( main.Mininet1,
-                            filePath + topoName,
-                            main.Mininet1.home,
-                            direction="to" )
-        mnResult = main.Mininet1.startNet()
-        utilities.assert_equals( expect=main.TRUE, actual=mnResult,
-                                 onpass="Mininet Started",
-                                 onfail="Error starting Mininet" )
-
-        main.step( "Git checkout and pull " + gitBranch )
-        if PULLCODE:
-            main.ONOSbench.gitCheckout( gitBranch )
-            gitPullResult = main.ONOSbench.gitPull()
-            # values of 1 or 3 are good
-            utilities.assert_lesser( expect=0, actual=gitPullResult,
-                                      onpass="Git pull successful",
-                                      onfail="Git pull failed" )
-        main.ONOSbench.getVersion( report=True )
-
-        # GRAPHS
-        # NOTE: important params here:
-        #       job = name of Jenkins job
-        #       Plot Name = Plot-HA, only can be used if multiple plots
-        #       index = The number of the graph under plot name
-        job = "HAstopNodes"
-        plotName = "Plot-HA"
-        index = "2"
-        graphs = '<ac:structured-macro ac:name="html">\n'
-        graphs += '<ac:plain-text-body><![CDATA[\n'
-        graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
-                  '/plot/' + plotName + '/getPlot?index=' + index +\
-                  '&width=500&height=300"' +\
-                  'noborder="0" width="500" height="300" scrolling="yes" ' +\
-                  'seamless="seamless"></iframe>\n'
-        graphs += ']]></ac:plain-text-body>\n'
-        graphs += '</ac:structured-macro>\n'
-        main.log.wiki( graphs )
-
-        main.step( "Creating ONOS package" )
-        # copy gen-partions file to ONOS
-        # NOTE: this assumes TestON and ONOS are on the same machine
-        srcFile = main.testDir + "/HA/dependencies/onos-gen-partitions"
-        dstDir = main.ONOSbench.home + "/tools/test/bin/onos-gen-partitions"
-        cpResult = main.ONOSbench.secureCopy( main.ONOSbench.user_name,
-                                              main.ONOSbench.ip_address,
-                                              srcFile,
-                                              dstDir,
-                                              pwd=main.ONOSbench.pwd,
-                                              direction="from" )
-        packageResult = main.ONOSbench.buckBuild()
-        utilities.assert_equals( expect=main.TRUE, actual=packageResult,
-                                 onpass="ONOS package successful",
-                                 onfail="ONOS package failed" )
-
-        main.step( "Installing ONOS package" )
-        onosInstallResult = main.TRUE
-        for node in main.nodes:
-            tmpResult = main.ONOSbench.onosInstall( options="-f",
-                                                    node=node.ip_address )
-            onosInstallResult = onosInstallResult and tmpResult
-        utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
-                                 onpass="ONOS install successful",
-                                 onfail="ONOS install failed" )
-        # clean up gen-partitions file
-        try:
-            main.ONOSbench.handle.sendline( "cd " + main.ONOSbench.home )
-            main.ONOSbench.handle.expect( main.ONOSbench.home + "\$" )
-            main.ONOSbench.handle.sendline( "git checkout -- tools/test/bin/onos-gen-partitions" )
-            main.ONOSbench.handle.expect( main.ONOSbench.home + "\$" )
-            main.log.info( " Cleaning custom gen partitions file, response was: \n" +
-                           str( main.ONOSbench.handle.before ) )
-        except ( pexpect.TIMEOUT, pexpect.EOF ):
-            main.log.exception( "ONOSbench: pexpect exception found:" +
-                                main.ONOSbench.handle.before )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.TRUE
-        for node in main.nodes:
-            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=node.ip_address )
-        utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        main.step( "Checking if ONOS is up yet" )
-        for i in range( 2 ):
-            onosIsupResult = main.TRUE
-            for node in main.nodes:
-                started = main.ONOSbench.isup( node.ip_address )
-                if not started:
-                    main.log.error( node.name + " hasn't started" )
-                onosIsupResult = onosIsupResult and started
-            if onosIsupResult == main.TRUE:
-                break
-        utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
-                                 onpass="ONOS startup successful",
-                                 onfail="ONOS startup failed" )
-
-        main.step( "Starting ONOS CLI sessions" )
-        cliResults = main.TRUE
-        threads = []
-        for i in range( main.numCtrls ):
-            t = main.Thread( target=main.CLIs[ i ].startOnosCli,
-                             name="startOnosCli-" + str( i ),
-                             args=[ main.nodes[ i ].ip_address ] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            cliResults = cliResults and t.result
-        utilities.assert_equals( expect=main.TRUE, actual=cliResults,
-                                 onpass="ONOS cli startup successful",
-                                 onfail="ONOS cli startup failed" )
-
-        # Create a list of active nodes for use when some nodes are stopped
-        main.activeNodes = [ i for i in range( 0, len( main.CLIs ) ) ]
-
-        if main.params[ 'tcpdump' ].lower() == "true":
-            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' ] )
-
-        main.step( "Checking ONOS nodes" )
-        nodeResults = utilities.retry( main.HA.nodesCheck,
-                                       False,
-                                       args=[ main.activeNodes ],
-                                       attempts=5 )
-
-        utilities.assert_equals( expect=True, actual=nodeResults,
-                                 onpass="Nodes check successful",
-                                 onfail="Nodes check NOT successful" )
-
-        if not nodeResults:
-            for i in main.activeNodes:
-                cli = main.CLIs[ i ]
-                main.log.debug( "{} components not ACTIVE: \n{}".format(
-                    cli.name,
-                    cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
-            main.log.error( "Failed to start ONOS, stopping test" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Activate apps defined in the params file" )
-        # get data from the params
-        apps = main.params.get( 'apps' )
-        if apps:
-            apps = apps.split( ',' )
-            main.log.warn( apps )
-            activateResult = True
-            for app in apps:
-                main.CLIs[ 0 ].app( app, "Activate" )
-            # TODO: check this worked
-            time.sleep( 10 )  # wait for apps to activate
-            for app in apps:
-                state = main.CLIs[ 0 ].appStatus( app )
-                if state == "ACTIVE":
-                    activateResult = activateResult and True
-                else:
-                    main.log.error( "{} is in {} state".format( app, state ) )
-                    activateResult = False
-            utilities.assert_equals( expect=True,
-                                     actual=activateResult,
-                                     onpass="Successfully activated apps",
-                                     onfail="Failed to activate apps" )
-        else:
-            main.log.warn( "No apps were specified to be loaded after startup" )
-
-        main.step( "Set ONOS configurations" )
-        config = main.params.get( 'ONOS_Configuration' )
-        if config:
-            main.log.debug( config )
-            checkResult = main.TRUE
-            for component in config:
-                for setting in config[ component ]:
-                    value = config[ component ][ setting ]
-                    check = main.CLIs[ 0 ].setCfg( component, setting, value )
-                    main.log.info( "Value was changed? {}".format( main.TRUE == check ) )
-                    checkResult = check and checkResult
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=checkResult,
-                                     onpass="Successfully set config",
-                                     onfail="Failed to set config" )
-        else:
-            main.log.warn( "No configurations were specified to be changed after startup" )
-
-        main.step( "App Ids check" )
-        appCheck = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
-                             name="appToIDCheck-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            appCheck = appCheck and t.result
-        if appCheck != main.TRUE:
-            node = main.activeNodes[ 0 ]
-            main.log.warn( main.CLIs[ node ].apps() )
-            main.log.warn( main.CLIs[ node ].appIDs() )
-        utilities.assert_equals( expect=main.TRUE, actual=appCheck,
-                                 onpass="App Ids seem to be correct",
-                                 onfail="Something is wrong with app Ids" )
+        main.HA.initialSetUp()
 
     def CASE2( self, main ):
         """
         Assign devices to controllers
         """
-        import re
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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.case( "Assigning devices to controllers" )
-        main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
-                                "and check that an ONOS node becomes the " +\
-                                "master of the device."
-        main.step( "Assign switches to controllers" )
-
-        ipList = []
-        for i in range( main.numCtrls ):
-            ipList.append( main.nodes[ i ].ip_address )
-        swList = []
-        for i in range( 1, 29 ):
-            swList.append( "s" + str( i ) )
-        main.Mininet1.assignSwController( sw=swList, ip=ipList )
-
-        mastershipCheck = main.TRUE
-        for i in range( 1, 29 ):
-            response = main.Mininet1.getSwController( "s" + str( i ) )
-            try:
-                main.log.info( str( response ) )
-            except Exception:
-                main.log.info( repr( response ) )
-            for node in main.nodes:
-                if re.search( "tcp:" + node.ip_address, response ):
-                    mastershipCheck = mastershipCheck and main.TRUE
-                else:
-                    main.log.error( "Error, node " + node.ip_address + " is " +
-                                    "not in the list of controllers s" +
-                                    str( i ) + " is connecting to." )
-                    mastershipCheck = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=mastershipCheck,
-            onpass="Switch mastership assigned correctly",
-            onfail="Switches not assigned correctly to controllers" )
+        main.HA.assignDevices( main )
 
     def CASE21( self, main ):
         """
         Assign mastership to controllers
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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.HA.assignMastership( main )
 
-        main.case( "Assigning Controller roles for switches" )
-        main.caseExplanation = "Check that ONOS is connected to each " +\
-                                "device. Then manually assign" +\
-                                " mastership to specific ONOS nodes using" +\
-                                " 'device-role'"
-        main.step( "Assign mastership of switches to specific controllers" )
-        # Manually assign mastership to the controller we want
-        roleCall = main.TRUE
-
-        ipList = []
-        deviceList = []
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        try:
-            # Assign mastership to specific controllers. This assignment was
-            # determined for a 7 node cluser, but will work with any sized
-            # cluster
-            for i in range( 1, 29 ):  # switches 1 through 28
-                # set up correct variables:
-                if i == 1:
-                    c = 0
-                    ip = main.nodes[ c ].ip_address  # ONOS1
-                    deviceId = onosCli.getDevice( "1000" ).get( 'id' )
-                elif i == 2:
-                    c = 1 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS2
-                    deviceId = onosCli.getDevice( "2000" ).get( 'id' )
-                elif i == 3:
-                    c = 1 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS2
-                    deviceId = onosCli.getDevice( "3000" ).get( 'id' )
-                elif i == 4:
-                    c = 3 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS4
-                    deviceId = onosCli.getDevice( "3004" ).get( 'id' )
-                elif i == 5:
-                    c = 2 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS3
-                    deviceId = onosCli.getDevice( "5000" ).get( 'id' )
-                elif i == 6:
-                    c = 2 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS3
-                    deviceId = onosCli.getDevice( "6000" ).get( 'id' )
-                elif i == 7:
-                    c = 5 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS6
-                    deviceId = onosCli.getDevice( "6007" ).get( 'id' )
-                elif i >= 8 and i <= 17:
-                    c = 4 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS5
-                    dpid = '3' + str( i ).zfill( 3 )
-                    deviceId = onosCli.getDevice( dpid ).get( 'id' )
-                elif i >= 18 and i <= 27:
-                    c = 6 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS7
-                    dpid = '6' + str( i ).zfill( 3 )
-                    deviceId = onosCli.getDevice( dpid ).get( 'id' )
-                elif i == 28:
-                    c = 0
-                    ip = main.nodes[ c ].ip_address  # ONOS1
-                    deviceId = onosCli.getDevice( "2800" ).get( 'id' )
-                else:
-                    main.log.error( "You didn't write an else statement for " +
-                                    "switch s" + str( i ) )
-                    roleCall = main.FALSE
-                # Assign switch
-                assert deviceId, "No device id for s" + str( i ) + " in ONOS"
-                # TODO: make this controller dynamic
-                roleCall = roleCall and onosCli.deviceRole( deviceId, ip )
-                ipList.append( ip )
-                deviceList.append( deviceId )
-        except ( AttributeError, AssertionError ):
-            main.log.exception( "Something is wrong with ONOS device view" )
-            main.log.info( onosCli.devices() )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=roleCall,
-            onpass="Re-assigned switch mastership to designated controller",
-            onfail="Something wrong with deviceRole calls" )
-
-        main.step( "Check mastership was correctly assigned" )
-        roleCheck = main.TRUE
-        # NOTE: This is due to the fact that device mastership change is not
-        #       atomic and is actually a multi step process
-        time.sleep( 5 )
-        for i in range( len( ipList ) ):
-            ip = ipList[ i ]
-            deviceId = deviceList[ i ]
-            # Check assignment
-            master = onosCli.getRole( deviceId ).get( 'master' )
-            if ip in master:
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-                main.log.error( "Error, controller " + ip + " is not" +
-                                " master " + "of device " +
-                                str( deviceId ) + ". Master is " +
-                                repr( master ) + "." )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=roleCheck,
-            onpass="Switches were successfully reassigned to designated " +
-                   "controller",
-            onfail="Switches were not successfully reassigned" )
 
     def CASE3( self, main ):
         """
         Assign intents
         """
-        import time
-        import json
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-        main.case( "Adding host Intents" )
-        main.caseExplanation = "Discover hosts by using pingall then " +\
-                                "assign predetermined host-to-host intents." +\
-                                " After installation, check that the intent" +\
-                                " is distributed to all nodes and the state" +\
-                                " is INSTALLED"
+        main.HA.assignIntents( main )
 
-        # install onos-app-fwd
-        main.step( "Install reactive forwarding app" )
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        installResults = onosCli.activateApp( "org.onosproject.fwd" )
-        utilities.assert_equals( expect=main.TRUE, actual=installResults,
-                                 onpass="Install fwd successful",
-                                 onfail="Install fwd failed" )
 
-        main.step( "Check app ids" )
-        appCheck = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
-                             name="appToIDCheck-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            appCheck = appCheck and t.result
-        if appCheck != main.TRUE:
-            main.log.warn( onosCli.apps() )
-            main.log.warn( onosCli.appIDs() )
-        utilities.assert_equals( expect=main.TRUE, actual=appCheck,
-                                 onpass="App Ids seem to be correct",
-                                 onfail="Something is wrong with app Ids" )
-
-        main.step( "Discovering Hosts( Via pingall for now )" )
-        # FIXME: Once we have a host discovery mechanism, use that instead
-        # REACTIVE FWD test
-        pingResult = main.FALSE
-        passMsg = "Reactive Pingall test passed"
-        time1 = time.time()
-        pingResult = main.Mininet1.pingall()
-        time2 = time.time()
-        if not pingResult:
-            main.log.warn( "First pingall failed. Trying again..." )
-            pingResult = main.Mininet1.pingall()
-            passMsg += " on the second try"
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=pingResult,
-            onpass=passMsg,
-            onfail="Reactive Pingall failed, " +
-                   "one or more ping pairs failed" )
-        main.log.info( "Time for pingall: %2f seconds" %
-                       ( time2 - time1 ) )
-        # timeout for fwd flows
-        time.sleep( 11 )
-        # uninstall onos-app-fwd
-        main.step( "Uninstall reactive forwarding app" )
-        node = main.activeNodes[ 0 ]
-        uninstallResult = main.CLIs[ node ].deactivateApp( "org.onosproject.fwd" )
-        utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
-                                 onpass="Uninstall fwd successful",
-                                 onfail="Uninstall fwd failed" )
-
-        main.step( "Check app ids" )
-        threads = []
-        appCheck2 = main.TRUE
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
-                             name="appToIDCheck-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            appCheck2 = appCheck2 and t.result
-        if appCheck2 != main.TRUE:
-            node = main.activeNodes[ 0 ]
-            main.log.warn( main.CLIs[ node ].apps() )
-            main.log.warn( main.CLIs[ node ].appIDs() )
-        utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
-                                 onpass="App Ids seem to be correct",
-                                 onfail="Something is wrong with app Ids" )
-
-        main.step( "Add host intents via cli" )
-        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 ) )
-            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 = onosCli.getHost( host1 )
-            host2Dict = onosCli.getHost( host2 )
-            host1Id = None
-            host2Id = None
-            if host1Dict and host2Dict:
-                host1Id = host1Dict.get( 'id', None )
-                host2Id = host2Dict.get( 'id', None )
-            if host1Id and host2Id:
-                nodeNum = ( i % len( main.activeNodes ) )
-                node = main.activeNodes[ nodeNum ]
-                tmpId = main.CLIs[ node ].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 for h" + str( i ) +
-                                " and/or h" + str( i + 10 ) )
-                node = main.activeNodes[ 0 ]
-                hosts = main.CLIs[ node ].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
-        utilities.assert_equals( expect=main.TRUE, actual=hostResult,
-                                 onpass="Found a host id for each host",
-                                 onfail="Error looking up host ids" )
-
-        intentStart = time.time()
-        onosIds = onosCli.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
-        if intentAddResult:
-            intentStop = time.time()
-        else:
-            intentStop = None
-        # Print the intent states
-        intents = onosCli.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 = onosCli.leaders()
-        try:
-            missing = False
-            if leaders:
-                parsedLeaders = json.loads( leaders )
-                main.log.warn( json.dumps( parsedLeaders,
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-                # check for all intent partitions
-                topics = []
-                for i in range( 14 ):
-                    topics.append( "work-partition-" + str( i ) )
-                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" )
-                        missing = True
-            else:
-                main.log.error( "leaders() returned None" )
-        except ( ValueError, TypeError ):
-            main.log.exception( "Error parsing leaders" )
-            main.log.error( repr( leaders ) )
-        # Check all nodes
-        if missing:
-            for i in main.activeNodes:
-                response = main.CLIs[ i ].leaders( jsonFormat=False )
-                main.log.warn( str( main.CLIs[ i ].name ) + " leaders output: \n" +
-                               str( response ) )
-
-        partitions = onosCli.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 = onosCli.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( intentAddResult and not missingIntents and
-                                installedCheck )
-        if not intentAddResult:
-            main.log.error( "Error in pushing host intents to ONOS" )
-
-        main.step( "Intent Anti-Entropy dispersion" )
-        for j in range( 100 ):
-            correct = True
-            main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
-            for i in main.activeNodes:
-                onosIds = []
-                ids = main.CLIs[ i ].getAllIntentsId()
-                onosIds.append( ids )
-                main.log.debug( "Intents in " + main.CLIs[ i ].name + ": " +
-                                str( sorted( onosIds ) ) )
-                if sorted( ids ) != sorted( intentIds ):
-                    main.log.warn( "Set of intent IDs doesn't match" )
-                    correct = False
-                    break
-                else:
-                    intents = json.loads( main.CLIs[ i ].intents() )
-                    for intent in intents:
-                        if intent[ 'state' ] != "INSTALLED":
-                            main.log.warn( "Intent " + intent[ 'id' ] +
-                                           " is " + intent[ 'state' ] )
-                            correct = False
-                            break
-            if correct:
-                break
-            else:
-                time.sleep( 1 )
-        if not intentStop:
-            intentStop = time.time()
-        global gossipTime
-        gossipTime = intentStop - intentStart
-        main.log.info( "It took about " + str( gossipTime ) +
-                        " seconds for all intents to appear in each node" )
-        gossipPeriod = int( main.params[ 'timers' ][ 'gossip' ] )
-        maxGossipTime = gossipPeriod * len( main.activeNodes )
-        utilities.assert_greater_equals(
-                expect=maxGossipTime, actual=gossipTime,
-                onpass="ECM anti-entropy for intents worked within " +
-                       "expected time",
-                onfail="Intent ECM anti-entropy took too long. " +
-                       "Expected time:{}, Actual time:{}".format( maxGossipTime,
-                                                                  gossipTime ) )
-        if gossipTime <= maxGossipTime:
-            intentAddResult = True
-
-        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 = onosCli.getAllIntentsId()
-            main.log.info( "Submitted intents: " + str( intentIds ) )
-            main.log.info( "Intents in ONOS: " + str( onosIds ) )
-            # Print the intent states
-            intents = onosCli.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 = onosCli.leaders()
-            try:
-                missing = False
-                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( "work-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" )
-                            missing = True
-                else:
-                    main.log.error( "leaders() returned None" )
-            except ( ValueError, TypeError ):
-                main.log.exception( "Error parsing leaders" )
-                main.log.error( repr( leaders ) )
-            # Check all nodes
-            if missing:
-                for i in main.activeNodes:
-                    node = main.CLIs[ i ]
-                    response = node.leaders( jsonFormat=False )
-                    main.log.warn( str( node.name ) + " leaders output: \n" +
-                                   str( response ) )
-
-            partitions = onosCli.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 = onosCli.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 main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-        main.case( "Verify connectivity by sending traffic across Intents" )
-        main.caseExplanation = "Ping across added host intents to check " +\
-                                "functionality and check the state of " +\
-                                "the intent"
-
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        main.step( "Check Intent state" )
-        installedCheck = False
-        loopCount = 0
-        while not installedCheck and loopCount < 40:
-            installedCheck = True
-            # Print the intent states
-            intents = onosCli.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." )
-            # Print states
-            intentStates.sort()
-            for i, s in intentStates:
-                count += 1
-                main.log.info( "%-6s%-15s%-15s" %
-                               ( str( count ), str( i ), str( s ) ) )
-            if not installedCheck:
-                time.sleep( 1 )
-                loopCount += 1
-        utilities.assert_equals( expect=True, actual=installedCheck,
-                                 onpass="Intents are all INSTALLED",
-                                 onfail="Intents are not all in " +
-                                        "INSTALLED state" )
-
-        main.step( "Ping across added host intents" )
-        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.error(
-                "Intents have not been installed correctly, pings failed." )
-            # TODO: pretty print
-            main.log.warn( "ONOS1 intents: " )
-            try:
-                tmpIntents = onosCli.intents()
-                main.log.warn( json.dumps( json.loads( tmpIntents ),
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-            except ( ValueError, TypeError ):
-                main.log.warn( repr( tmpIntents ) )
-        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." )
-
-        main.step( "Check leadership of topics" )
-        leaders = onosCli.leaders()
-        topicCheck = main.TRUE
-        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
-                # TODO: Look at Devices as topics now that it uses this system
-                topics = []
-                for i in range( 14 ):
-                    topics.append( "work-partition-" + str( i ) )
-                # FIXME: this should only be after we start the app
-                # FIXME: topics.append( "org.onosproject.election" )
-                # Print leaders output
-                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" )
-                        topicCheck = main.FALSE
-            else:
-                main.log.error( "leaders() returned None" )
-                topicCheck = main.FALSE
-        except ( ValueError, TypeError ):
-            topicCheck = main.FALSE
-            main.log.exception( "Error parsing leaders" )
-            main.log.error( repr( leaders ) )
-            # TODO: Check for a leader of these topics
-        # Check all nodes
-        if topicCheck:
-            for i in main.activeNodes:
-                node = main.CLIs[ i ]
-                response = node.leaders( jsonFormat=False )
-                main.log.warn( str( node.name ) + " leaders output: \n" +
-                               str( response ) )
-
-        utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
-                                 onpass="intent Partitions is in leaders",
-                                 onfail="Some topics were lost " )
-        # Print partitions
-        partitions = onosCli.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 ) )
-        # Print Pending Map
-        pendingMap = onosCli.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 = onosCli.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 = onosCli.leaders()
-            try:
-                missing = False
-                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( "work-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" )
-                            missing = True
-                else:
-                    main.log.error( "leaders() returned None" )
-            except ( ValueError, TypeError ):
-                main.log.exception( "Error parsing leaders" )
-                main.log.error( repr( leaders ) )
-            if missing:
-                for i in main.activeNodes:
-                    node = main.CLIs[ i ]
-                    response = node.leaders( jsonFormat=False )
-                    main.log.warn( str( node.name ) + " leaders output: \n" +
-                                   str( response ) )
-
-            partitions = onosCli.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 = onosCli.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 ) )
-        # Print flowrules
-        main.log.debug( onosCli.flows( jsonFormat=False ) )
-        main.step( "Wait a minute then ping again" )
-        # the wait is above
-        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.error(
-                "Intents have not been installed correctly, pings failed." )
-            # TODO: pretty print
-            main.log.warn( "ONOS1 intents: " )
-            try:
-                tmpIntents = onosCli.intents()
-                main.log.warn( json.dumps( json.loads( tmpIntents ),
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-            except ( ValueError, TypeError ):
-                main.log.warn( repr( tmpIntents ) )
-        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." )
+        main.HA.pingAcrossHostIntent( main, True, False )
 
     def CASE5( self, main ):
         """
         Reading state of ONOS
         """
-        import json
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        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 each other and also with past states
-
-        main.step( "Check that each switch has a master" )
-        global mastershipState
-        mastershipState = '[]'
-
-        # Assert that each device has a master
-        rolesNotNull = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( "Get the Mastership of each switch from each controller" )
-        ONOSMastership = []
-        mastershipCheck = main.FALSE
-        consistentMastership = True
-        rolesResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSMastership ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSMastership[ i ] or "Error" in ONOSMastership[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " roles" )
-                main.log.warn( "ONOS" + node + " 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.info(
-                "Switch roles are consistent across all ONOS nodes" )
-        else:
-            consistentMastership = False
-        utilities.assert_equals(
-            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( len( main.activeNodes ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                try:
-                    main.log.warn(
-                        "ONOS" + node + " 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 = []
-        ONOSIntents = []
-        intentCheck = main.FALSE
-        consistentIntents = True
-        intentsResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSIntents ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " intents" )
-                main.log.warn( "ONOS" + node + " 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.info( "Intents are consistent across all ONOS " +
-                             "nodes" )
-        else:
-            consistentIntents = False
-            main.log.error( "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:
-            # Try to make it easy to figure out what is happening
-            #
-            # Intent      ONOS1      ONOS2    ...
-            #  0x01     INSTALLED  INSTALLING
-            #  ...        ...         ...
-            #  ...        ...         ...
-            title = "   Id"
-            for n in main.activeNodes:
-                title += " " * 10 + "ONOS" + str( n + 1 )
-            main.log.warn( title )
-            # get all intent keys in the cluster
-            keys = []
-            try:
-                # Get the set of all intent keys
-                for nodeStr in ONOSIntents:
-                    node = json.loads( nodeStr )
-                    for intent in node:
-                        keys.append( intent.get( 'id' ) )
-                keys = set( keys )
-                # For each intent key, print the state on each node
-                for key in keys:
-                    row = "%-13s" % key
-                    for nodeStr in ONOSIntents:
-                        node = json.loads( nodeStr )
-                        for intent in node:
-                            if intent.get( 'id', "Error" ) == key:
-                                row += "%-15s" % intent.get( 'state' )
-                    main.log.warn( row )
-                # End of intent state table
-            except ValueError as e:
-                main.log.exception( e )
-                main.log.debug( "nodeStr was: " + repr( nodeStr ) )
-
-        if intentsResults and not consistentIntents:
-            # print the json objects
-            n = str( main.activeNodes[ -1 ] + 1 )
-            main.log.debug( "ONOS" + n + " intents: " )
-            main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
-                                        sort_keys=True,
-                                        indent=4,
-                                        separators=( ',', ': ' ) ) )
-            for i in range( len( ONOSIntents ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
-                    main.log.debug( "ONOS" + node + " intents: " )
-                    main.log.debug( json.dumps( json.loads( ONOSIntents[ i ] ),
-                                                sort_keys=True,
-                                                indent=4,
-                                                separators=( ',', ': ' ) ) )
-                else:
-                    main.log.debug( "ONOS" + node + " intents match ONOS" +
-                                    n + " intents" )
-        elif intentsResults and consistentIntents:
-            intentCheck = main.TRUE
-            intentState = ONOSIntents[ 0 ]
-
-        main.step( "Get the flows from each controller" )
-        global flowState
-        flowState = []
-        ONOSFlows = []
-        ONOSFlowsJson = []
-        flowCheck = main.FALSE
-        consistentFlows = True
-        flowsResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].flows,
-                             name="flows-" + str( i ),
-                             args=[],
-                             kwargs={ 'jsonFormat': True } )
-            threads.append( t )
-            t.start()
-
-        # NOTE: Flows command can take some time to run
-        time.sleep( 30 )
-        for t in threads:
-            t.join()
-            result = t.result
-            ONOSFlows.append( result )
-
-        for i in range( len( ONOSFlows ) ):
-            num = str( main.activeNodes[ i ] + 1 )
-            if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
-                main.log.error( "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.info( "Flow count is consistent across all ONOS nodes" )
-        else:
-            consistentFlows = False
-        utilities.assert_equals(
-            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( len( ONOSFlows ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                try:
-                    main.log.warn(
-                        "ONOS" + node + " flows: " +
-                        json.dumps( json.loads( ONOSFlows[ i ] ), sort_keys=True,
-                                    indent=4, separators=( ',', ': ' ) ) )
-                except ( ValueError, TypeError ):
-                    main.log.warn( "ONOS" + node + " 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.Mininet1.getFlowTable( "s" + str( i ), version="1.3", debug=False ) )
-        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" )
-        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( "Collecting topology information from ONOS" )
-        devices = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].devices,
-                             name="devices-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            devices.append( t.result )
-        hosts = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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" )
-                main.log.warn( repr( t.result ) )
-                hosts.append( None )
-
-        ports = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].ports,
-                             name="ports-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            ports.append( t.result )
-        links = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].links,
-                             name="links-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            links.append( t.result )
-        clusters = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].clusters,
-                             name="clusters-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            clusters.append( t.result )
-        # Compare json objects for hosts and dataplane clusters
-
-        # hosts
-        main.step( "Host view is consistent across ONOS nodes" )
-        consistentHostsResult = main.TRUE
-        for controller in range( len( hosts ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if hosts[ controller ] and "Error" not in hosts[ controller ]:
-                if hosts[ controller ] == hosts[ 0 ]:
-                    continue
-                else:  # hosts not consistent
-                    main.log.error( "hosts from ONOS" +
-                                     controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    main.log.warn( repr( hosts[ controller ] ) )
-                    consistentHostsResult = main.FALSE
-
-            else:
-                main.log.error( "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" )
-
-        main.step( "Each host has an IP address" )
-        ipResult = main.TRUE
-        for controller in range( 0, len( hosts ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if hosts[ controller ]:
-                for host in hosts[ controller ]:
-                    if not host.get( 'ipAddresses', [] ):
-                        main.log.error( "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
-        main.step( "Cluster view is consistent across ONOS nodes" )
-        consistentClustersResult = main.TRUE
-        for controller in range( len( clusters ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if "Error" not in clusters[ controller ]:
-                if clusters[ controller ] == clusters[ 0 ]:
-                    continue
-                else:  # clusters not consistent
-                    main.log.error( "clusters from ONOS" + controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    consistentClustersResult = main.FALSE
-
-            else:
-                main.log.error( "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" )
-        if not consistentClustersResult:
-            main.log.debug( clusters )
-
-        # there should always only be one cluster
-        main.step( "Cluster view correct across ONOS nodes" )
-        try:
-            numClusters = len( json.loads( clusters[ 0 ] ) )
-        except ( ValueError, TypeError ):
-            main.log.exception( "Error parsing clusters[0]: " +
-                                repr( clusters[ 0 ] ) )
-            numClusters = "ERROR"
-        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
-        linksResults = main.TRUE
-        hostsResults = main.TRUE
-        mnSwitches = main.Mininet1.getSwitches()
-        mnLinks = main.Mininet1.getLinks()
-        mnHosts = main.Mininet1.getHosts()
-        for controller in main.activeNodes:
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if devices[ controller ] and ports[ controller ] and\
-                    "Error" not in devices[ controller ] and\
-                    "Error" not in ports[ controller ]:
-                currentDevicesResult = main.Mininet1.compareSwitches(
-                        mnSwitches,
-                        json.loads( devices[ controller ] ),
-                        json.loads( ports[ controller ] ) )
-            else:
-                currentDevicesResult = main.FALSE
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=currentDevicesResult,
-                                     onpass="ONOS" + controllerStr +
-                                     " Switches view is correct",
-                                     onfail="ONOS" + controllerStr +
-                                     " Switches view is incorrect" )
-            if links[ controller ] and "Error" not in links[ controller ]:
-                currentLinksResult = main.Mininet1.compareLinks(
-                        mnSwitches, mnLinks,
-                        json.loads( links[ controller ] ) )
-            else:
-                currentLinksResult = main.FALSE
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=currentLinksResult,
-                                     onpass="ONOS" + controllerStr +
-                                     " links view is correct",
-                                     onfail="ONOS" + controllerStr +
-                                     " links view is incorrect" )
-
-            if hosts[ controller ] and "Error" not in hosts[ controller ]:
-                currentHostsResult = main.Mininet1.compareHosts(
-                        mnHosts,
-                        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
-            linksResults = linksResults and currentLinksResult
-            hostsResults = hostsResults and currentHostsResult
-
-        main.step( "Device information is correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=devicesResults,
-            onpass="Device information is correct",
-            onfail="Device information is incorrect" )
-
-        main.step( "Links are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=linksResults,
-            onpass="Link are correct",
-            onfail="Links are incorrect" )
-
-        main.step( "Hosts are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=hostsResults,
-            onpass="Hosts are correct",
-            onfail="Hosts are incorrect" )
+        main.HA.readingState( main )
 
     def CASE61( self, main ):
         """
@@ -1827,377 +177,20 @@
         """
         The bring up stopped nodes
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-        assert main.kill, "main.kill not defined"
-        main.case( "Restart minority of ONOS nodes" )
-
-        main.step( "Restarting " + str( len( main.kill ) ) + " ONOS nodes" )
-        startResults = main.TRUE
-        restartTime = time.time()
-        for i in main.kill:
-            startResults = startResults and\
-                           main.ONOSbench.onosStart( main.nodes[ i ].ip_address )
-        utilities.assert_equals( expect=main.TRUE, actual=startResults,
-                                 onpass="ONOS nodes started successfully",
-                                 onfail="ONOS nodes NOT successfully started" )
-
-        main.step( "Checking if ONOS is up yet" )
-        count = 0
-        onosIsupResult = main.FALSE
-        while onosIsupResult == main.FALSE and count < 10:
-            onosIsupResult = main.TRUE
-            for i in main.kill:
-                onosIsupResult = onosIsupResult and\
-                                 main.ONOSbench.isup( main.nodes[ i ].ip_address )
-            count = count + 1
-        utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
-                                 onpass="ONOS restarted successfully",
-                                 onfail="ONOS restart NOT successful" )
-
-        main.step( "Restarting ONOS main.CLIs" )
-        cliResults = main.TRUE
-        for i in main.kill:
-            cliResults = cliResults and\
-                         main.CLIs[ i ].startOnosCli( main.nodes[ i ].ip_address )
-            main.activeNodes.append( i )
-        utilities.assert_equals( expect=main.TRUE, actual=cliResults,
-                                 onpass="ONOS cli restarted",
-                                 onfail="ONOS cli did not restart" )
-        main.activeNodes.sort()
-        try:
-            assert list( set( main.activeNodes ) ) == main.activeNodes,\
-                   "List of active nodes has duplicates, this likely indicates something was run out of order"
-        except AssertionError:
-            main.log.exception( "" )
-            main.cleanup()
-            main.exit()
-
-        # Grab the time of restart so we chan check how long the gossip
-        # protocol has had time to work
-        main.restartTime = time.time() - restartTime
-        main.log.debug( "Restart time: " + str( main.restartTime ) )
-
-        main.step( "Checking ONOS nodes" )
-        nodeResults = utilities.retry( main.HA.nodesCheck,
-                                       False,
-                                       args=[ main.activeNodes ],
-                                       sleep=15,
-                                       attempts=5 )
-
-        utilities.assert_equals( expect=True, actual=nodeResults,
-                                 onpass="Nodes check successful",
-                                 onfail="Nodes check NOT successful" )
-
-        if not nodeResults:
-            for i in main.activeNodes:
-                cli = main.CLIs[ i ]
-                main.log.debug( "{} components not ACTIVE: \n{}".format(
-                    cli.name,
-                    cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
-            main.log.error( "Failed to start ONOS, stopping test" )
-            main.cleanup()
-            main.exit()
-        node = main.activeNodes[ 0 ]
-        main.log.debug( main.CLIs[ node ].nodes( jsonFormat=False ) )
-        main.log.debug( main.CLIs[ node ].leaders( jsonFormat=False ) )
-        main.log.debug( main.CLIs[ node ].partitions( jsonFormat=False ) )
-
-        main.step( "Rerun for election on the node(s) that were killed" )
-        runResults = main.TRUE
-        for i in main.kill:
-            runResults = runResults and\
-                         main.CLIs[ i ].electionTestRun()
-        utilities.assert_equals( expect=main.TRUE, actual=runResults,
-                                 onpass="ONOS nodes reran for election topic",
-                                 onfail="Errror rerunning for election" )
+        main.HA.bringUpStoppedNode( main )
 
     def CASE7( self, main ):
         """
         Check state after ONOS failure
         """
-        import json
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
         try:
             main.kill
         except AttributeError:
             main.kill = []
 
-        main.case( "Running ONOS Constant State Tests" )
 
-        main.step( "Check that each switch has a master" )
-        # Assert that each device has a master
-        rolesNotNull = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].rolesNotNull,
-                             name="rolesNotNull-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
+        main.HA.checkStateAfterONOS( main, afterWhich=0 )
 
-        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( "Read device roles from ONOS" )
-        ONOSMastership = []
-        mastershipCheck = main.FALSE
-        consistentMastership = True
-        rolesResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSMastership ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSMastership[ i ] or "Error" in ONOSMastership[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " roles" )
-                main.log.warn( "ONOS" + node + " 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.info(
-                "Switch roles are consistent across all ONOS nodes" )
-        else:
-            consistentMastership = False
-        utilities.assert_equals(
-            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( len( ONOSMastership ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                main.log.warn( "ONOS" + node + " roles: ",
-                               json.dumps( json.loads( ONOSMastership[ i ] ),
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-
-        # NOTE: we expect mastership to change on controller failure
-
-        main.step( "Get the intents and compare across all nodes" )
-        ONOSIntents = []
-        intentCheck = main.FALSE
-        consistentIntents = True
-        intentsResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSIntents ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " intents" )
-                main.log.warn( "ONOS" + node + " 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.info( "Intents are consistent across all ONOS " +
-                             "nodes" )
-        else:
-            consistentIntents = False
-
-        # Try to make it easy to figure out what is happening
-        #
-        # Intent      ONOS1      ONOS2    ...
-        #  0x01     INSTALLED  INSTALLING
-        #  ...        ...         ...
-        #  ...        ...         ...
-        title = "   ID"
-        for n in main.activeNodes:
-            title += " " * 10 + "ONOS" + str( n + 1 )
-        main.log.warn( title )
-        # get all intent keys in the cluster
-        keys = []
-        for nodeStr in ONOSIntents:
-            node = json.loads( nodeStr )
-            for intent in node:
-                keys.append( intent.get( 'id' ) )
-        keys = set( keys )
-        for key in keys:
-            row = "%-13s" % key
-            for nodeStr in ONOSIntents:
-                node = json.loads( nodeStr )
-                for intent in node:
-                    if intent.get( 'id' ) == key:
-                        row += "%-15s" % intent.get( 'state' )
-            main.log.warn( row )
-        # End table view
-
-        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' ] )
-            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( len( main.activeNodes ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                main.log.warn( "ONOS" + node + " 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?
-        sameIntents = main.FALSE
-        try:
-            intentState
-        except NameError:
-            main.log.warn( "No previous intent state was saved" )
-        else:
-            if intentState and intentState == ONOSIntents[ 0 ]:
-                sameIntents = main.TRUE
-                main.log.info( "Intents are consistent with before failure" )
-            # TODO: possibly the states have changed? we may need to figure out
-            #       what the acceptable states are
-            elif len( intentState ) == len( ONOSIntents[ 0 ] ):
-                sameIntents = main.TRUE
-                try:
-                    before = json.loads( intentState )
-                    after = json.loads( ONOSIntents[ 0 ] )
-                    for intent in before:
-                        if intent not in after:
-                            sameIntents = main.FALSE
-                            main.log.debug( "Intent is not currently in ONOS " +
-                                            "(at least in the same form):" )
-                            main.log.debug( json.dumps( intent ) )
-                except ( ValueError, TypeError ):
-                    main.log.exception( "Exception printing intents" )
-                    main.log.debug( repr( ONOSIntents[ 0 ] ) )
-                    main.log.debug( repr( intentState ) )
-            if sameIntents == main.FALSE:
-                try:
-                    main.log.debug( "ONOS intents before: " )
-                    main.log.debug( json.dumps( json.loads( intentState ),
-                                                sort_keys=True, indent=4,
-                                                separators=( ',', ': ' ) ) )
-                    main.log.debug( "Current ONOS intents: " )
-                    main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
-                                                sort_keys=True, indent=4,
-                                                separators=( ',', ': ' ) ) )
-                except ( ValueError, TypeError ):
-                    main.log.exception( "Exception printing intents" )
-                    main.log.debug( repr( ONOSIntents[ 0 ] ) )
-                    main.log.debug( repr( intentState ) )
-            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
-        for i in range( 28 ):
-            main.log.info( "Checking flow table on s" + str( i + 1 ) )
-            tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
-            curSwitch = main.Mininet1.flowTableComp( flows[ i ], tmpFlows )
-            FlowTables = FlowTables and curSwitch
-            if curSwitch == main.FALSE:
-                main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
-        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.Mininet2.pingLongKill()
-        """
-        main.step( "Check the continuous pings to ensure that no packets " +
-                   "were dropped during component failure" )
-        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.info( "No loss of dataplane connectivity" )
-        utilities.assert_equals(
-            expect=main.FALSE,
-            actual=LossInPings,
-            onpass="No Loss of connectivity",
-            onfail="Loss of dataplane connectivity detected" )
-        """
         main.step( "Leadership Election is still functional" )
         # Test of LeadershipElection
         leaderList = []
@@ -2242,680 +235,47 @@
         """
         Compare topo
         """
-        import json
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        main.case( "Compare ONOS Topology view to Mininet topology" )
-        main.caseExplanation = "Compare topology objects between Mininet" +\
-                                " and ONOS"
-        topoResult = main.FALSE
-        topoFailMsg = "ONOS topology don't match Mininet"
-        elapsed = 0
-        count = 0
-        main.step( "Comparing ONOS topology to MN topology" )
-        startTime = time.time()
-        # Give time for Gossip to work
-        while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
-            devicesResults = main.TRUE
-            linksResults = main.TRUE
-            hostsResults = main.TRUE
-            hostAttachmentResults = True
-            count += 1
-            cliStart = time.time()
-            devices = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="devices-" + str( i ),
-                                 args=[ main.CLIs[ i ].devices, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                devices.append( t.result )
-            hosts = []
-            ipResult = main.TRUE
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="hosts-" + str( i ),
-                                 args=[ main.CLIs[ i ].hosts, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                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 ) )
-                    hosts.append( None )
-            for controller in range( 0, len( hosts ) ):
-                controllerStr = str( main.activeNodes[ controller ] + 1 )
-                if hosts[ controller ]:
-                    for host in hosts[ controller ]:
-                        if host is None or host.get( 'ipAddresses', [] ) == []:
-                            main.log.error(
-                                "Error with host ipAddresses on controller" +
-                                controllerStr + ": " + str( host ) )
-                            ipResult = main.FALSE
-            ports = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="ports-" + str( i ),
-                                 args=[ main.CLIs[ i ].ports, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                ports.append( t.result )
-            links = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="links-" + str( i ),
-                                 args=[ main.CLIs[ i ].links, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                links.append( t.result )
-            clusters = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="clusters-" + str( i ),
-                                 args=[ main.CLIs[ i ].clusters, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                clusters.append( t.result )
-
-            elapsed = time.time() - startTime
-            cliTime = time.time() - cliStart
-            print "Elapsed time: " + str( elapsed )
-            print "CLI time: " + str( cliTime )
-
-            if all( e is None for e in devices ) and\
-               all( e is None for e in hosts ) and\
-               all( e is None for e in ports ) and\
-               all( e is None for e in links ) and\
-               all( e is None for e in clusters ):
-                topoFailMsg = "Could not get topology from ONOS"
-                main.log.error( topoFailMsg )
-                continue  # Try again, No use trying to compare
-
-            mnSwitches = main.Mininet1.getSwitches()
-            mnLinks = main.Mininet1.getLinks()
-            mnHosts = main.Mininet1.getHosts()
-            for controller in range( len( main.activeNodes ) ):
-                controllerStr = str( main.activeNodes[ controller ] + 1 )
-                if devices[ controller ] and ports[ controller ] and\
-                        "Error" not in devices[ controller ] and\
-                        "Error" not in ports[ controller ]:
-
-                    try:
-                        currentDevicesResult = main.Mininet1.compareSwitches(
-                                mnSwitches,
-                                json.loads( devices[ controller ] ),
-                                json.loads( ports[ controller ] ) )
-                    except ( TypeError, ValueError ) as e:
-                        main.log.exception( "Object not as expected; devices={!r}\nports={!r}".format(
-                            devices[ controller ], ports[ controller ] ) )
-                else:
-                    currentDevicesResult = main.FALSE
-                utilities.assert_equals( expect=main.TRUE,
-                                         actual=currentDevicesResult,
-                                         onpass="ONOS" + controllerStr +
-                                         " Switches view is correct",
-                                         onfail="ONOS" + controllerStr +
-                                         " Switches view is incorrect" )
-
-                if links[ controller ] and "Error" not in links[ controller ]:
-                    currentLinksResult = main.Mininet1.compareLinks(
-                            mnSwitches, mnLinks,
-                            json.loads( links[ controller ] ) )
-                else:
-                    currentLinksResult = main.FALSE
-                utilities.assert_equals( expect=main.TRUE,
-                                         actual=currentLinksResult,
-                                         onpass="ONOS" + controllerStr +
-                                         " links view is correct",
-                                         onfail="ONOS" + controllerStr +
-                                         " links view is incorrect" )
-                if hosts[ controller ] and "Error" not in hosts[ controller ]:
-                    currentHostsResult = main.Mininet1.compareHosts(
-                            mnHosts,
-                            hosts[ controller ] )
-                elif hosts[ controller ] == []:
-                    currentHostsResult = main.TRUE
-                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" )
-                # CHECKING HOST ATTACHMENT POINTS
-                hostAttachment = True
-                zeroHosts = False
-                # FIXME: topo-HA/obelisk specific mappings:
-                # key is mac and value is dpid
-                mappings = {}
-                for i in range( 1, 29 ):  # hosts 1 through 28
-                    # set up correct variables:
-                    macId = "00:" * 5 + hex( i ).split( "0x" )[ 1 ].upper().zfill( 2 )
-                    if i == 1:
-                        deviceId = "1000".zfill( 16 )
-                    elif i == 2:
-                        deviceId = "2000".zfill( 16 )
-                    elif i == 3:
-                        deviceId = "3000".zfill( 16 )
-                    elif i == 4:
-                        deviceId = "3004".zfill( 16 )
-                    elif i == 5:
-                        deviceId = "5000".zfill( 16 )
-                    elif i == 6:
-                        deviceId = "6000".zfill( 16 )
-                    elif i == 7:
-                        deviceId = "6007".zfill( 16 )
-                    elif i >= 8 and i <= 17:
-                        dpid = '3' + str( i ).zfill( 3 )
-                        deviceId = dpid.zfill( 16 )
-                    elif i >= 18 and i <= 27:
-                        dpid = '6' + str( i ).zfill( 3 )
-                        deviceId = dpid.zfill( 16 )
-                    elif i == 28:
-                        deviceId = "2800".zfill( 16 )
-                    mappings[ macId ] = deviceId
-                if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
-                    if hosts[ controller ] == []:
-                        main.log.warn( "There are no hosts discovered" )
-                        zeroHosts = True
-                    else:
-                        for host in hosts[ controller ]:
-                            mac = None
-                            location = None
-                            device = None
-                            port = None
-                            try:
-                                mac = host.get( 'mac' )
-                                assert mac, "mac field could not be found for this host object"
-
-                                location = host.get( 'locations' )[ 0 ]
-                                assert location, "location field could not be found for this host object"
-
-                                # Trim the protocol identifier off deviceId
-                                device = str( location.get( 'elementId' ) ).split( ':' )[ 1 ]
-                                assert device, "elementId field could not be found for this host location object"
-
-                                port = location.get( 'port' )
-                                assert port, "port field could not be found for this host location object"
-
-                                # Now check if this matches where they should be
-                                if mac and device and port:
-                                    if str( port ) != "1":
-                                        main.log.error( "The attachment port is incorrect for " +
-                                                        "host " + str( mac ) +
-                                                        ". Expected: 1 Actual: " + str( port ) )
-                                        hostAttachment = False
-                                    if device != mappings[ str( mac ) ]:
-                                        main.log.error( "The attachment device is incorrect for " +
-                                                        "host " + str( mac ) +
-                                                        ". Expected: " + mappings[ str( mac ) ] +
-                                                        " Actual: " + device )
-                                        hostAttachment = False
-                                else:
-                                    hostAttachment = False
-                            except AssertionError:
-                                main.log.exception( "Json object not as expected" )
-                                main.log.error( repr( host ) )
-                                hostAttachment = False
-                else:
-                    main.log.error( "No hosts json output or \"Error\"" +
-                                    " in output. hosts = " +
-                                    repr( hosts[ controller ] ) )
-                if zeroHosts is False:
-                    hostAttachment = True
-
-                # END CHECKING HOST ATTACHMENT POINTS
-                devicesResults = devicesResults and currentDevicesResult
-                linksResults = linksResults and currentLinksResult
-                hostsResults = hostsResults and currentHostsResult
-                hostAttachmentResults = hostAttachmentResults and\
-                                        hostAttachment
-                topoResult = ( devicesResults and linksResults
-                               and hostsResults and ipResult and
-                               hostAttachmentResults )
-        utilities.assert_equals( expect=True,
-                                 actual=topoResult,
-                                 onpass="ONOS topology matches Mininet",
-                                 onfail=topoFailMsg )
-        # End of While loop to pull ONOS state
-
-        # Compare json objects for hosts and dataplane clusters
-
-        # hosts
-        main.step( "Hosts view is consistent across all ONOS nodes" )
-        consistentHostsResult = main.TRUE
-        for controller in range( len( hosts ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
-                if hosts[ controller ] == hosts[ 0 ]:
-                    continue
-                else:  # hosts not consistent
-                    main.log.error( "hosts from ONOS" + controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    main.log.warn( repr( hosts[ controller ] ) )
-                    consistentHostsResult = main.FALSE
-
-            else:
-                main.log.error( "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" )
-
-        main.step( "Hosts information is correct" )
-        hostsResults = hostsResults and ipResult
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=hostsResults,
-            onpass="Host information is correct",
-            onfail="Host information is incorrect" )
-
-        main.step( "Host attachment points to the network" )
-        utilities.assert_equals(
-            expect=True,
-            actual=hostAttachmentResults,
-            onpass="Hosts are correctly attached to the network",
-            onfail="ONOS did not correctly attach hosts to the network" )
-
-        # Strongly connected clusters of devices
-        main.step( "Clusters view is consistent across all ONOS nodes" )
-        consistentClustersResult = main.TRUE
-        for controller in range( len( clusters ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if "Error" not in clusters[ controller ]:
-                if clusters[ controller ] == clusters[ 0 ]:
-                    continue
-                else:  # clusters not consistent
-                    main.log.error( "clusters from ONOS" +
-                                     controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    consistentClustersResult = main.FALSE
-            else:
-                main.log.error( "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" )
-        if not consistentClustersResult:
-            main.log.debug( clusters )
-
-        main.step( "There is only one SCC" )
-        # there should always only be one cluster
-        try:
-            numClusters = len( json.loads( clusters[ 0 ] ) )
-        except ( ValueError, TypeError ):
-            main.log.exception( "Error parsing clusters[0]: " +
-                                repr( clusters[ 0 ] ) )
-            numClusters = "ERROR"
-        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 linksResults
-                       and hostsResults and consistentHostsResult
-                       and consistentClustersResult and clusterResults
-                       and ipResult and hostAttachmentResults )
-
-        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" )
-
-        main.step( "Device information is correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=devicesResults,
-            onpass="Device information is correct",
-            onfail="Device information is incorrect" )
-
-        main.step( "Links are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=linksResults,
-            onpass="Link are correct",
-            onfail="Links are incorrect" )
-
-        main.step( "Hosts are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=hostsResults,
-            onpass="Hosts are correct",
-            onfail="Hosts are incorrect" )
-
-        # FIXME: move this to an ONOS state case
-        main.step( "Checking ONOS nodes" )
-        nodeResults = utilities.retry( main.HA.nodesCheck,
-                                       False,
-                                       args=[ main.activeNodes ],
-                                       attempts=5 )
-
-        utilities.assert_equals( expect=True, actual=nodeResults,
-                                 onpass="Nodes check successful",
-                                 onfail="Nodes check NOT successful" )
-        if not nodeResults:
-            for i in main.activeNodes:
-                main.log.debug( "{} components not ACTIVE: \n{}".format(
-                    main.CLIs[ i ].name,
-                    main.CLIs[ i ].sendline( "scr:list | grep -v ACTIVE" ) ) )
-
-        if not topoResult:
-            main.cleanup()
-            main.exit()
+        main.HA.compareTopo( main )
 
     def CASE9( self, main ):
         """
         Link s3-s28 down
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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"
-        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 successful",
-                                 onfail="Failed to bring link down" )
-        # TODO do some sort of check here
+        main.HA.linkDown( main )
 
     def CASE10( self, main ):
         """
         Link s3-s28 up
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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"
-        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 successful",
-                                 onfail="Failed to bring link up" )
-        # TODO do some sort of check here
+        main.HA.linkUp( main )
 
     def CASE11( self, main ):
         """
         Switch Down
         """
         # NOTE: You should probably run a topology check after this
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
-
-        description = "Killing a switch to ensure it is discovered correctly"
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        main.case( description )
-        switch = main.params[ 'kill' ][ 'switch' ]
-        switchDPID = main.params[ 'kill' ][ 'dpid' ]
-
-        # TODO: Make this switch parameterizable
-        main.step( "Kill " + switch )
-        main.log.info( "Deleting " + switch )
-        main.Mininet1.delSwitch( switch )
-        main.log.info( "Waiting " + str( switchSleep ) +
-                       " seconds for switch down to be discovered" )
-        time.sleep( switchSleep )
-        device = onosCli.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 successful",
-                                 onfail="Failed to kill switch?" )
+        main.HA.switchDown( main )
 
     def CASE12( self, main ):
         """
         Switch Up
         """
         # NOTE: You should probably run a topology check after this
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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' ]
-        switchDPID = main.params[ 'kill' ][ 'dpid' ]
-        links = main.params[ 'kill' ][ 'links' ].split()
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        description = "Adding a switch to ensure it is discovered correctly"
-        main.case( description )
-
-        main.step( "Add back " + switch )
-        main.Mininet1.addSwitch( switch, dpid=switchDPID )
-        for peer in links:
-            main.Mininet1.addLink( switch, peer )
-        ipList = [ node.ip_address for node in main.nodes ]
-        main.Mininet1.assignSwController( sw=switch, ip=ipList )
-        main.log.info( "Waiting " + str( switchSleep ) +
-                       " seconds for switch up to be discovered" )
-        time.sleep( switchSleep )
-        device = onosCli.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 successful",
-                                 onfail="Failed to add switch?" )
+        main.HA.switchUp( main )
 
     def CASE13( self, main ):
         """
         Clean up
         """
-        import os
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        # printing colors to terminal
-        colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
-                   'blue': '\033[94m', 'green': '\033[92m',
-                   'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
-        main.case( "Test Cleanup" )
-        main.step( "Killing tcpdumps" )
-        main.Mininet2.stopTcpdump()
-
-        testname = main.TEST
-        if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
-            main.step( "Copying MN pcap and ONOS log files to test station" )
-            teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
-            teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
-            # NOTE: MN Pcap file is being saved to logdir.
-            #       We scp this file as MN and TestON aren't necessarily the same vm
-
-            # FIXME: To be replaced with a Jenkin's post script
-            # TODO: Load these from params
-            # NOTE: must end in /
-            logFolder = "/opt/onos/log/"
-            logFiles = [ "karaf.log", "karaf.log.1" ]
-            # NOTE: must end in /
-            for f in logFiles:
-                for node in main.nodes:
-                    dstName = main.logdir + "/" + node.name + "-" + f
-                    main.ONOSbench.secureCopy( node.user_name, node.ip_address,
-                                               logFolder + f, dstName )
-            # std*.log's
-            # NOTE: must end in /
-            logFolder = "/opt/onos/var/"
-            logFiles = [ "stderr.log", "stdout.log" ]
-            # NOTE: must end in /
-            for f in logFiles:
-                for node in main.nodes:
-                    dstName = main.logdir + "/" + node.name + "-" + f
-                    main.ONOSbench.secureCopy( node.user_name, node.ip_address,
-                                               logFolder + f, dstName )
-        else:
-            main.log.debug( "skipping saving log files" )
-
-        main.step( "Stopping Mininet" )
-        mnResult = main.Mininet1.stopNet()
-        utilities.assert_equals( expect=main.TRUE, actual=mnResult,
-                                 onpass="Mininet stopped",
-                                 onfail="MN cleanup NOT successful" )
-
-        main.step( "Checking ONOS Logs for errors" )
-        for node in main.nodes:
-            main.log.debug( "Checking logs for errors on " + node.name + ":" )
-            main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
-
-        try:
-            timerLog = open( main.logdir + "/Timers.csv", 'w' )
-            # Overwrite with empty line and close
-            labels = "Gossip Intents, Restart"
-            data = str( gossipTime ) + ", " + str( main.restartTime )
-            timerLog.write( labels + "\n" + data )
-            timerLog.close()
-        except NameError as e:
-            main.log.exception( e )
+        main.HAlabels.append( "Restart" )
+        main.HAdata.append( str( main.restartTime ) )
+        main.HA.cleanUp( main )
 
     def CASE14( self, main ):
         """
         start election app on all onos nodes
         """
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        main.case( "Start Leadership Election app" )
-        main.step( "Install leadership election app" )
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        appResult = onosCli.activateApp( "org.onosproject.election" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=appResult,
-            onpass="Election app installed",
-            onfail="Something went wrong with installing Leadership election" )
-
-        main.step( "Run for election on each node" )
-        for i in main.activeNodes:
-            main.CLIs[ i ].electionTestRun()
-        time.sleep( 5 )
-        activeCLIs = [ main.CLIs[ i ] for i in main.activeNodes ]
-        sameResult, leaders = main.HA.consistentLeaderboards( activeCLIs )
-        utilities.assert_equals(
-            expect=True,
-            actual=sameResult,
-            onpass="All nodes see the same leaderboards",
-            onfail="Inconsistent leaderboards" )
-
-        if sameResult:
-            leader = leaders[ 0 ][ 0 ]
-            if main.nodes[ main.activeNodes[ 0 ] ].ip_address in leader:
-                correctLeader = True
-            else:
-                correctLeader = False
-            main.step( "First node was elected leader" )
-            utilities.assert_equals(
-                expect=True,
-                actual=correctLeader,
-                onpass="Correct leader was elected",
-                onfail="Incorrect leader" )
+        main.HA.startElectionApp( main )
 
     def CASE15( self, main ):
         """
@@ -2932,196 +292,16 @@
             old and new variable prefixes refer to data from before vs after
                 withdrawl and later before withdrawl vs after re-election
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        description = "Check that Leadership Election is still functional"
-        main.case( description )
-        # NOTE: Need to re-run after restarts since being a canidate is not persistant
-
-        oldLeaders = []  # list of lists of each nodes' candidates before
-        newLeaders = []  # list of lists of each nodes' candidates after
-        oldLeader = ''  # the old leader from oldLeaders, None if not same
-        newLeader = ''  # the new leaders fron newLoeaders, None if not same
-        oldLeaderCLI = None  # the CLI of the old leader used for re-electing
-        expectNoLeader = False  # True when there is only one leader
-        if main.numCtrls == 1:
-            expectNoLeader = True
-
-        main.step( "Run for election on each node" )
-        electionResult = main.TRUE
-
-        for i in main.activeNodes:  # run test election on each node
-            if main.CLIs[ i ].electionTestRun() == main.FALSE:
-                electionResult = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=electionResult,
-            onpass="All nodes successfully ran for leadership",
-            onfail="At least one node failed to run for leadership" )
-
-        if electionResult == main.FALSE:
-            main.log.error(
-                "Skipping Test Case because Election Test App isn't loaded" )
-            main.skipCase()
-
-        main.step( "Check that each node shows the same leader and candidates" )
-        failMessage = "Nodes have different leaderboards"
-        activeCLIs = [ main.CLIs[ i ] for i in main.activeNodes ]
-        sameResult, oldLeaders = main.HA.consistentLeaderboards( activeCLIs )
-        if sameResult:
-            oldLeader = oldLeaders[ 0 ][ 0 ]
-            main.log.warn( oldLeader )
-        else:
-            oldLeader = None
-        utilities.assert_equals(
-            expect=True,
-            actual=sameResult,
-            onpass="Leaderboards are consistent for the election topic",
-            onfail=failMessage )
-
-        main.step( "Find current leader and withdraw" )
-        withdrawResult = main.TRUE
-        # do some sanity checking on leader before using it
-        if oldLeader is None:
-            main.log.error( "Leadership isn't consistent." )
-            withdrawResult = main.FALSE
-        # Get the CLI of the oldLeader
-        for i in main.activeNodes:
-            if oldLeader == main.nodes[ i ].ip_address:
-                oldLeaderCLI = main.CLIs[ i ]
-                break
-        else:  # FOR/ELSE statement
-            main.log.error( "Leader election, could not find current leader" )
-        if oldLeader:
-            withdrawResult = oldLeaderCLI.electionTestWithdraw()
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=withdrawResult,
-            onpass="Node was withdrawn from election",
-            onfail="Node was not withdrawn from election" )
-
-        main.step( "Check that a new node was elected leader" )
-        failMessage = "Nodes have different leaders"
-        # Get new leaders and candidates
-        newLeaderResult, newLeaders = main.HA.consistentLeaderboards( activeCLIs )
-        newLeader = None
-        if newLeaderResult:
-            if newLeaders[ 0 ][ 0 ] == 'none':
-                main.log.error( "No leader was elected on at least 1 node" )
-                if not expectNoLeader:
-                    newLeaderResult = False
-            newLeader = newLeaders[ 0 ][ 0 ]
-
-        # Check that the new leader is not the older leader, which was withdrawn
-        if newLeader == oldLeader:
-            newLeaderResult = False
-            main.log.error( "All nodes still see old leader: " + str( oldLeader ) +
-                            " as the current leader" )
-        utilities.assert_equals(
-            expect=True,
-            actual=newLeaderResult,
-            onpass="Leadership election passed",
-            onfail="Something went wrong with Leadership election" )
-
-        main.step( "Check that that new leader was the candidate of old leader" )
-        # candidates[ 2 ] should become the top candidate after withdrawl
-        correctCandidateResult = main.TRUE
-        if expectNoLeader:
-            if newLeader == 'none':
-                main.log.info( "No leader expected. None found. Pass" )
-                correctCandidateResult = main.TRUE
-            else:
-                main.log.info( "Expected no leader, got: " + str( newLeader ) )
-                correctCandidateResult = main.FALSE
-        elif len( oldLeaders[ 0 ] ) >= 3:
-            if newLeader == oldLeaders[ 0 ][ 2 ]:
-                # correct leader was elected
-                correctCandidateResult = main.TRUE
-            else:
-                correctCandidateResult = main.FALSE
-                main.log.error( "Candidate {} was elected. {} should have had priority.".format(
-                                    newLeader, oldLeaders[ 0 ][ 2 ] ) )
-        else:
-            main.log.warn( "Could not determine who should be the correct leader" )
-            main.log.debug( oldLeaders[ 0 ] )
-            correctCandidateResult = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=correctCandidateResult,
-            onpass="Correct Candidate Elected",
-            onfail="Incorrect Candidate Elected" )
-
-        main.step( "Run for election on old leader( just so everyone " +
-                   "is in the hat )" )
-        if oldLeaderCLI is not None:
-            runResult = oldLeaderCLI.electionTestRun()
-        else:
-            main.log.error( "No old leader to re-elect" )
-            runResult = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=runResult,
-            onpass="App re-ran for election",
-            onfail="App failed to run for election" )
-
-        main.step(
-            "Check that oldLeader is a candidate, and leader if only 1 node" )
-        # verify leader didn't just change
-        # Get new leaders and candidates
-        reRunLeaders = []
-        time.sleep( 5 )  # Paremterize
-        positionResult, reRunLeaders = main.HA.consistentLeaderboards( activeCLIs )
-
-        # Check that the re-elected node is last on the candidate List
-        if not reRunLeaders[ 0 ]:
-            positionResult = main.FALSE
-        elif oldLeader != reRunLeaders[ 0 ][ -1 ]:
-            main.log.error( "Old Leader ({}) not in the proper position: {} ".format( str( oldLeader ),
-                                                                                      str( reRunLeaders[ 0 ] ) ) )
-            positionResult = main.FALSE
-        utilities.assert_equals(
-            expect=True,
-            actual=positionResult,
-            onpass="Old leader successfully re-ran for election",
-            onfail="Something went wrong with Leadership election after " +
-                   "the old leader re-ran for election" )
+        main.HA.isElectionFunctional( main )
 
     def CASE16( self, main ):
         """
         Install Distributed Primitives app
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        # Variables for the distributed primitives tests
-        main.pCounterName = "TestON-Partitions"
-        main.pCounterValue = 0
-        main.onosSet = set( [] )
-        main.onosSetName = "TestON-set"
-
-        description = "Install Primitives app"
-        main.case( description )
-        main.step( "Install Primitives app" )
-        appName = "org.onosproject.distributedprimitives"
-        node = main.activeNodes[ 0 ]
-        appResults = main.CLIs[ node ].activateApp( appName )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=appResults,
-                                 onpass="Primitives app activated",
-                                 onfail="Primitives app not activated" )
-        time.sleep( 5 )  # To allow all nodes to activate
+        main.HA.installDistributedPrimitiveApp( main )
 
     def CASE17( self, main ):
         """
         Check for basic functionality with distributed primitives
         """
-        main.HA.CASE17( main )
+        main.HA.checkDistPrimitivesFunc( main )
diff --git a/TestON/tests/HA/HAswapNodes/HAswapNodes.params b/TestON/tests/HA/HAswapNodes/HAswapNodes.params
index 0da560a..d557c1e 100644
--- a/TestON/tests/HA/HAswapNodes/HAswapNodes.params
+++ b/TestON/tests/HA/HAswapNodes/HAswapNodes.params
@@ -37,8 +37,10 @@
         <cellName>HA</cellName>
         <appString>drivers,openflow,proxyarp,mobility</appString>
     </ENV>
-    <Git> False </Git>
-    <branch> master </branch>
+    <GIT>
+        <pull>False</pull>
+        <branch>master</branch>
+    </GIT>
     <num_controllers> 7 </num_controllers>
     <tcpdump> False </tcpdump>
 
diff --git a/TestON/tests/HA/HAswapNodes/HAswapNodes.py b/TestON/tests/HA/HAswapNodes/HAswapNodes.py
index fe0399d..81c39dd 100644
--- a/TestON/tests/HA/HAswapNodes/HAswapNodes.py
+++ b/TestON/tests/HA/HAswapNodes/HAswapNodes.py
@@ -50,1762 +50,73 @@
         import re
         main.log.info( "ONOS HA test: Restart all ONOS nodes - " +
                          "initialization" )
-        main.case( "Setting up test environment" )
-        main.caseExplanation = "Setup the test environment including " +\
-                                "installing ONOS, starting Mininet and ONOS" +\
-                                "cli sessions."
-
-        # load some variables from the params file
-        PULLCODE = False
-        if main.params[ 'Git' ] == 'True':
-            PULLCODE = True
-        gitBranch = main.params[ 'branch' ]
-        cellName = main.params[ 'ENV' ][ 'cellName' ]
-
-        main.numCtrls = int( main.params[ 'num_controllers' ] )
-        if main.ONOSbench.maxNodes:
-            if main.ONOSbench.maxNodes < main.numCtrls:
-                main.numCtrls = int( main.ONOSbench.maxNodes )
         # set global variables
         # These are for csv plotting in jenkins
-        global labels
-        global data
-        labels = []
-        data = []
-
+        main.HAlabels = []
+        main.HAdata = []
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        main.testSetUp.envSetupDescription()
         try:
             from tests.HA.dependencies.HA import HA
             main.HA = HA()
             from tests.HA.HAswapNodes.dependencies.Server import Server
             main.Server = Server()
+            # load some variables from the params file
+            cellName = main.params[ 'ENV' ][ 'cellName' ]
+            main.apps = main.params[ 'ENV' ][ 'appString' ]
+            main.numCtrls = int( main.params[ 'num_controllers' ] )
+            if main.ONOSbench.maxNodes and\
+                        main.ONOSbench.maxNodes < main.numCtrls:
+                main.numCtrls = int( main.ONOSbench.maxNodes )
+            main.maxNodes = main.numCtrls
+            stepResult = main.testSetUp.envSetup( hasNode=True )
         except Exception as e:
-            main.log.exception( e )
-            main.cleanup()
-            main.exit()
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
+        main.HA.generateGraph( "HAswapNodes" )
 
-        main.CLIs = []
-        main.nodes = []
-        ipList = []
-        for i in range( 1, main.numCtrls + 1 ):
-            try:
-                main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
-                main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
-                ipList.append( main.nodes[ -1 ].ip_address )
-            except AttributeError:
-                break
 
-        main.step( "Create cell file" )
-        cellAppString = main.params[ 'ENV' ][ 'appString' ]
-        main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
-                                       main.Mininet1.ip_address,
-                                       cellAppString, ipList, main.ONOScli1.karafUser )
-
-        main.step( "Applying cell variable to environment" )
-        cellResult = main.ONOSbench.setCell( cellName )
-        utilities.assert_equals( expect=main.TRUE, actual=cellResult,
-                                 onpass="Set cell successfull",
-                                 onfail="Failled to set cell" )
-
-        main.step( "Verify connectivity to cell" )
-        verifyResult = main.ONOSbench.verifyCell()
-        utilities.assert_equals( expect=main.TRUE, actual=verifyResult,
-                                 onpass="Verify cell passed",
-                                 onfail="Failled to verify cell" )
-
-        # FIXME:this is short term fix
-        main.log.info( "Removing raft logs" )
-        main.ONOSbench.onosRemoveRaftLogs()
-
-        main.log.info( "Uninstalling ONOS" )
-        for node in main.nodes:
-            main.ONOSbench.onosUninstall( node.ip_address )
-
-        # Make sure ONOS is DEAD
-        main.log.info( "Killing any ONOS processes" )
-        killResults = main.TRUE
-        for node in main.nodes:
-            killed = main.ONOSbench.onosKill( node.ip_address )
-            killResults = killResults and killed
-
-        main.step( "Setup server for cluster metadata file" )
-        port = main.params[ 'server' ][ 'port' ]
-        rootDir = os.path.dirname( main.testFile ) + "/dependencies"
-        main.log.debug( "Root dir: {}".format( rootDir ) )
-        status = main.Server.start( main.ONOSbench,
-                                    rootDir,
-                                    port=port,
-                                    logDir=main.logdir + "/server.log" )
-        utilities.assert_equals( expect=main.TRUE, actual=status,
-                                 onpass="Server started",
-                                 onfail="Failled to start SimpleHTTPServer" )
-
-        main.step( "Generate initial metadata file" )
-        if main.numCtrls >= 5:
-            main.numCtrls -= 2
-        else:
-            main.log.error( "Not enough ONOS nodes to run this test. Requires 5 or more" )
-        genResult = main.Server.generateFile( main.numCtrls )
-        utilities.assert_equals( expect=main.TRUE, actual=genResult,
-                                 onpass="New cluster metadata file generated",
-                                 onfail="Failled to generate new metadata file" )
-
-        gitPullResult = main.TRUE
-
-        main.step( "Starting Mininet" )
-        # scp topo file to mininet
-        # TODO: move to params?
-        topoName = "obelisk.py"
-        filePath = main.ONOSbench.home + "/tools/test/topos/"
-        main.ONOSbench.scp( main.Mininet1,
-                            filePath + topoName,
-                            main.Mininet1.home,
-                            direction="to" )
-        mnResult = main.Mininet1.startNet()
-        utilities.assert_equals( expect=main.TRUE, actual=mnResult,
-                                 onpass="Mininet Started",
-                                 onfail="Error starting Mininet" )
-
-        main.step( "Git checkout and pull " + gitBranch )
-        if PULLCODE:
-            main.ONOSbench.gitCheckout( gitBranch )
-            gitPullResult = main.ONOSbench.gitPull()
-            # values of 1 or 3 are good
-            utilities.assert_lesser( expect=0, actual=gitPullResult,
-                                      onpass="Git pull successful",
-                                      onfail="Git pull failed" )
-        main.ONOSbench.getVersion( report=True )
-
-        # GRAPHS
-        # NOTE: important params here:
-        #       job = name of Jenkins job
-        #       Plot Name = Plot-HA, only can be used if multiple plots
-        #       index = The number of the graph under plot name
-        job = "HAswapNodes"
-        plotName = "Plot-HA"
-        index = "2"
-        graphs = '<ac:structured-macro ac:name="html">\n'
-        graphs += '<ac:plain-text-body><![CDATA[\n'
-        graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
-                  '/plot/' + plotName + '/getPlot?index=' + index +\
-                  '&width=500&height=300"' +\
-                  'noborder="0" width="500" height="300" scrolling="yes" ' +\
-                  'seamless="seamless"></iframe>\n'
-        graphs += ']]></ac:plain-text-body>\n'
-        graphs += '</ac:structured-macro>\n'
-        main.log.wiki( graphs )
-
-        main.step( "Copying backup config files" )
-        path = "~/onos/tools/package/bin/onos-service"
-        cp = main.ONOSbench.scp( main.ONOSbench,
-                                     path,
-                                     path + ".backup",
-                                     direction="to" )
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=cp,
-                                 onpass="Copy backup config file succeeded",
-                                 onfail="Copy backup config file failed" )
-        # we need to modify the onos-service file to use remote metadata file
-        # url for cluster metadata file
-        iface = main.params[ 'server' ].get( 'interface' )
-        ip = main.ONOSbench.getIpAddr( iface=iface )
-        metaFile = "cluster.json"
-        javaArgs = r"-Donos.cluster.metadata.uri=http:\/\/{}:{}\/{}".format( ip, port, metaFile )
-        main.log.warn( javaArgs )
-        main.log.warn( repr( javaArgs ) )
-        handle = main.ONOSbench.handle
-        sed = r"sed -i 's/bash/bash\nexport JAVA_OPTS=${{JAVA_OPTS:-{}}}\n/' {}".format( javaArgs, path )
-        main.log.warn( sed )
-        main.log.warn( repr( sed ) )
-        handle.sendline( sed )
-        handle.expect( metaFile )
-        output = handle.before
-        handle.expect( "\$" )
-        output += handle.before
-        main.log.debug( repr( output ) )
-
-        main.step( "Creating ONOS package" )
-        packageResult = main.ONOSbench.buckBuild()
-        utilities.assert_equals( expect=main.TRUE, actual=packageResult,
-                                 onpass="ONOS package successful",
-                                 onfail="ONOS package failed" )
-        if not packageResult:
-            main.cleanup()
-            main.exit()
-
-        main.step( "Installing ONOS package" )
-        onosInstallResult = main.TRUE
-        for i in range( main.ONOSbench.maxNodes ):
-            node = main.nodes[ i ]
-            options = "-f"
-            if i >= main.numCtrls:
-                options = "-nf"  # Don't start more than the current scale
-            tmpResult = main.ONOSbench.onosInstall( options=options,
-                                                    node=node.ip_address )
-            onosInstallResult = onosInstallResult and tmpResult
-        utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
-                                 onpass="ONOS install successful",
-                                 onfail="ONOS install failed" )
-
-        # Cleanup custom onos-service file
-        main.ONOSbench.scp( main.ONOSbench,
-                            path + ".backup",
-                            path,
-                            direction="to" )
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.TRUE
-        for i in range( main.numCtrls ):
-            node = main.nodes[ i ]
-            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=node.ip_address )
-        utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        main.step( "Checking if ONOS is up yet" )
-        for i in range( 2 ):
-            onosIsupResult = main.TRUE
-            for i in range( main.numCtrls ):
-                node = main.nodes[ i ]
-                started = main.ONOSbench.isup( node.ip_address )
-                if not started:
-                    main.log.error( node.name + " hasn't started" )
-                onosIsupResult = onosIsupResult and started
-            if onosIsupResult == main.TRUE:
-                break
-        utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
-                                 onpass="ONOS startup successful",
-                                 onfail="ONOS startup failed" )
-
-        main.step( "Starting ONOS CLI sessions" )
-        cliResults = main.TRUE
-        threads = []
-        for i in range( main.numCtrls ):
-            t = main.Thread( target=main.CLIs[ i ].startOnosCli,
-                             name="startOnosCli-" + str( i ),
-                             args=[ main.nodes[ i ].ip_address ] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            cliResults = cliResults and t.result
-        utilities.assert_equals( expect=main.TRUE, actual=cliResults,
-                                 onpass="ONOS cli startup successful",
-                                 onfail="ONOS cli startup failed" )
-
-        # Create a list of active nodes for use when some nodes are stopped
-        main.activeNodes = [ i for i in range( 0, main.numCtrls ) ]
-
-        if main.params[ 'tcpdump' ].lower() == "true":
-            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' ] )
-
-        main.step( "Checking ONOS nodes" )
-        nodeResults = utilities.retry( main.HA.nodesCheck,
-                                       False,
-                                       args=[ main.activeNodes ],
-                                       attempts=5 )
-        utilities.assert_equals( expect=True, actual=nodeResults,
-                                 onpass="Nodes check successful",
-                                 onfail="Nodes check NOT successful" )
-
-        if not nodeResults:
-            for i in main.activeNodes:
-                cli = main.CLIs[ i ]
-                main.log.debug( "{} components not ACTIVE: \n{}".format(
-                    cli.name,
-                    cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
-            main.log.error( "Failed to start ONOS, stopping test" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Activate apps defined in the params file" )
-        # get data from the params
-        apps = main.params.get( 'apps' )
-        if apps:
-            apps = apps.split( ',' )
-            main.log.warn( apps )
-            activateResult = True
-            for app in apps:
-                main.CLIs[ 0 ].app( app, "Activate" )
-            # TODO: check this worked
-            time.sleep( 10 )  # wait for apps to activate
-            for app in apps:
-                state = main.CLIs[ 0 ].appStatus( app )
-                if state == "ACTIVE":
-                    activateResult = activateResult and True
-                else:
-                    main.log.error( "{} is in {} state".format( app, state ) )
-                    activateResult = False
-            utilities.assert_equals( expect=True,
-                                     actual=activateResult,
-                                     onpass="Successfully activated apps",
-                                     onfail="Failed to activate apps" )
-        else:
-            main.log.warn( "No apps were specified to be loaded after startup" )
-
-        main.step( "Set ONOS configurations" )
-        config = main.params.get( 'ONOS_Configuration' )
-        if config:
-            main.log.debug( config )
-            checkResult = main.TRUE
-            for component in config:
-                for setting in config[ component ]:
-                    value = config[ component ][ setting ]
-                    check = main.CLIs[ 0 ].setCfg( component, setting, value )
-                    main.log.info( "Value was changed? {}".format( main.TRUE == check ) )
-                    checkResult = check and checkResult
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=checkResult,
-                                     onpass="Successfully set config",
-                                     onfail="Failed to set config" )
-        else:
-            main.log.warn( "No configurations were specified to be changed after startup" )
-
-        main.step( "App Ids check" )
-        appCheck = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
-                             name="appToIDCheck-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            appCheck = appCheck and t.result
-        if appCheck != main.TRUE:
-            node = main.activeNodes[ 0 ]
-            main.log.warn( main.CLIs[ node ].apps() )
-            main.log.warn( main.CLIs[ node ].appIDs() )
-        utilities.assert_equals( expect=main.TRUE, actual=appCheck,
-                                 onpass="App Ids seem to be correct",
-                                 onfail="Something is wrong with app Ids" )
+        main.testSetUp.ONOSSetUp( main.Mininet1, cellName=cellName, removeLog=True,
+                                 extraApply=main.HA.customizeOnosService,
+                                 arg=main.HA.swapNodeMetadata,
+                                 extraClean=main.HA.cleanUpOnosService,
+                                 installMax=True )
+        main.HA.initialSetUp()
 
     def CASE2( self, main ):
         """
         Assign devices to controllers
         """
-        import re
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        main.case( "Assigning devices to controllers" )
-        main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
-                                "and check that an ONOS node becomes the " +\
-                                "master of the device."
-        main.step( "Assign switches to controllers" )
-
-        ipList = []
-        for i in range( main.ONOSbench.maxNodes ):
-            ipList.append( main.nodes[ i ].ip_address )
-        swList = []
-        for i in range( 1, 29 ):
-            swList.append( "s" + str( i ) )
-        main.Mininet1.assignSwController( sw=swList, ip=ipList )
-
-        mastershipCheck = main.TRUE
-        for i in range( 1, 29 ):
-            response = main.Mininet1.getSwController( "s" + str( i ) )
-            try:
-                main.log.info( str( response ) )
-            except Exception:
-                main.log.info( repr( response ) )
-            for node in main.nodes:
-                if re.search( "tcp:" + node.ip_address, response ):
-                    mastershipCheck = mastershipCheck and main.TRUE
-                else:
-                    main.log.error( "Error, node " + node.ip_address + " is " +
-                                    "not in the list of controllers s" +
-                                    str( i ) + " is connecting to." )
-                    mastershipCheck = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=mastershipCheck,
-            onpass="Switch mastership assigned correctly",
-            onfail="Switches not assigned correctly to controllers" )
+        main.HA.assignDevices( main )
 
     def CASE21( self, main ):
         """
         Assign mastership to controllers
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        main.case( "Assigning Controller roles for switches" )
-        main.caseExplanation = "Check that ONOS is connected to each " +\
-                                "device. Then manually assign" +\
-                                " mastership to specific ONOS nodes using" +\
-                                " 'device-role'"
-        main.step( "Assign mastership of switches to specific controllers" )
-        # Manually assign mastership to the controller we want
-        roleCall = main.TRUE
-
-        ipList = []
-        deviceList = []
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        try:
-            # Assign mastership to specific controllers. This assignment was
-            # determined for a 7 node cluser, but will work with any sized
-            # cluster
-            for i in range( 1, 29 ):  # switches 1 through 28
-                # set up correct variables:
-                if i == 1:
-                    c = 0
-                    ip = main.nodes[ c ].ip_address  # ONOS1
-                    deviceId = onosCli.getDevice( "1000" ).get( 'id' )
-                elif i == 2:
-                    c = 1 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS2
-                    deviceId = onosCli.getDevice( "2000" ).get( 'id' )
-                elif i == 3:
-                    c = 1 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS2
-                    deviceId = onosCli.getDevice( "3000" ).get( 'id' )
-                elif i == 4:
-                    c = 3 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS4
-                    deviceId = onosCli.getDevice( "3004" ).get( 'id' )
-                elif i == 5:
-                    c = 2 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS3
-                    deviceId = onosCli.getDevice( "5000" ).get( 'id' )
-                elif i == 6:
-                    c = 2 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS3
-                    deviceId = onosCli.getDevice( "6000" ).get( 'id' )
-                elif i == 7:
-                    c = 5 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS6
-                    deviceId = onosCli.getDevice( "6007" ).get( 'id' )
-                elif i >= 8 and i <= 17:
-                    c = 4 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS5
-                    dpid = '3' + str( i ).zfill( 3 )
-                    deviceId = onosCli.getDevice( dpid ).get( 'id' )
-                elif i >= 18 and i <= 27:
-                    c = 6 % main.numCtrls
-                    ip = main.nodes[ c ].ip_address  # ONOS7
-                    dpid = '6' + str( i ).zfill( 3 )
-                    deviceId = onosCli.getDevice( dpid ).get( 'id' )
-                elif i == 28:
-                    c = 0
-                    ip = main.nodes[ c ].ip_address  # ONOS1
-                    deviceId = onosCli.getDevice( "2800" ).get( 'id' )
-                else:
-                    main.log.error( "You didn't write an else statement for " +
-                                    "switch s" + str( i ) )
-                    roleCall = main.FALSE
-                # Assign switch
-                assert deviceId, "No device id for s" + str( i ) + " in ONOS"
-                # TODO: make this controller dynamic
-                roleCall = roleCall and onosCli.deviceRole( deviceId, ip )
-                ipList.append( ip )
-                deviceList.append( deviceId )
-        except ( AttributeError, AssertionError ):
-            main.log.exception( "Something is wrong with ONOS device view" )
-            main.log.info( onosCli.devices() )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=roleCall,
-            onpass="Re-assigned switch mastership to designated controller",
-            onfail="Something wrong with deviceRole calls" )
-
-        main.step( "Check mastership was correctly assigned" )
-        roleCheck = main.TRUE
-        # NOTE: This is due to the fact that device mastership change is not
-        #       atomic and is actually a multi step process
-        time.sleep( 5 )
-        for i in range( len( ipList ) ):
-            ip = ipList[ i ]
-            deviceId = deviceList[ i ]
-            # Check assignment
-            master = onosCli.getRole( deviceId ).get( 'master' )
-            if ip in master:
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-                main.log.error( "Error, controller " + ip + " is not" +
-                                " master " + "of device " +
-                                str( deviceId ) + ". Master is " +
-                                repr( master ) + "." )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=roleCheck,
-            onpass="Switches were successfully reassigned to designated " +
-                   "controller",
-            onfail="Switches were not successfully reassigned" )
+        main.HA.assignMastership( main )
 
     def CASE3( self, main ):
         """
         Assign intents
         """
-        import time
-        import json
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-        try:
-            labels
-        except NameError:
-            main.log.error( "labels not defined, setting to []" )
-            labels = []
-        try:
-            data
-        except NameError:
-            main.log.error( "data not defined, setting to []" )
-            data = []
-        # NOTE: we must reinstall intents until we have a persistant intent
-        #        datastore!
-        main.case( "Adding host Intents" )
-        main.caseExplanation = "Discover hosts by using pingall then " +\
-                                "assign predetermined host-to-host intents." +\
-                                " After installation, check that the intent" +\
-                                " is distributed to all nodes and the state" +\
-                                " is INSTALLED"
-
-        # install onos-app-fwd
-        main.step( "Install reactive forwarding app" )
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        installResults = onosCli.activateApp( "org.onosproject.fwd" )
-        utilities.assert_equals( expect=main.TRUE, actual=installResults,
-                                 onpass="Install fwd successful",
-                                 onfail="Install fwd failed" )
-
-        main.step( "Check app ids" )
-        appCheck = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
-                             name="appToIDCheck-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            appCheck = appCheck and t.result
-        if appCheck != main.TRUE:
-            main.log.warn( onosCli.apps() )
-            main.log.warn( onosCli.appIDs() )
-        utilities.assert_equals( expect=main.TRUE, actual=appCheck,
-                                 onpass="App Ids seem to be correct",
-                                 onfail="Something is wrong with app Ids" )
-
-        main.step( "Discovering Hosts( Via pingall for now )" )
-        # FIXME: Once we have a host discovery mechanism, use that instead
-        # REACTIVE FWD test
-        pingResult = main.FALSE
-        passMsg = "Reactive Pingall test passed"
-        time1 = time.time()
-        pingResult = main.Mininet1.pingall()
-        time2 = time.time()
-        if not pingResult:
-            main.log.warn( "First pingall failed. Trying again..." )
-            pingResult = main.Mininet1.pingall()
-            passMsg += " on the second try"
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=pingResult,
-            onpass=passMsg,
-            onfail="Reactive Pingall failed, " +
-                   "one or more ping pairs failed" )
-        main.log.info( "Time for pingall: %2f seconds" %
-                       ( time2 - time1 ) )
-        # timeout for fwd flows
-        time.sleep( 11 )
-        # uninstall onos-app-fwd
-        main.step( "Uninstall reactive forwarding app" )
-        node = main.activeNodes[ 0 ]
-        uninstallResult = main.CLIs[ node ].deactivateApp( "org.onosproject.fwd" )
-        utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
-                                 onpass="Uninstall fwd successful",
-                                 onfail="Uninstall fwd failed" )
-
-        main.step( "Check app ids" )
-        threads = []
-        appCheck2 = main.TRUE
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
-                             name="appToIDCheck-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            appCheck2 = appCheck2 and t.result
-        if appCheck2 != main.TRUE:
-            node = main.activeNodes[ 0 ]
-            main.log.warn( main.CLIs[ node ].apps() )
-            main.log.warn( main.CLIs[ node ].appIDs() )
-        utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
-                                 onpass="App Ids seem to be correct",
-                                 onfail="Something is wrong with app Ids" )
-
-        main.step( "Add host intents via cli" )
-        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 ) )
-            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 = onosCli.getHost( host1 )
-            host2Dict = onosCli.getHost( host2 )
-            host1Id = None
-            host2Id = None
-            if host1Dict and host2Dict:
-                host1Id = host1Dict.get( 'id', None )
-                host2Id = host2Dict.get( 'id', None )
-            if host1Id and host2Id:
-                nodeNum = ( i % len( main.activeNodes ) )
-                node = main.activeNodes[ nodeNum ]
-                tmpId = main.CLIs[ node ].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 for h" + str( i ) +
-                                " and/or h" + str( i + 10 ) )
-                node = main.activeNodes[ 0 ]
-                hosts = main.CLIs[ node ].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
-        utilities.assert_equals( expect=main.TRUE, actual=hostResult,
-                                 onpass="Found a host id for each host",
-                                 onfail="Error looking up host ids" )
-
-        intentStart = time.time()
-        onosIds = onosCli.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
-        if intentAddResult:
-            intentStop = time.time()
-        else:
-            intentStop = None
-        # Print the intent states
-        intents = onosCli.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 = onosCli.leaders()
-        try:
-            missing = False
-            if leaders:
-                parsedLeaders = json.loads( leaders )
-                main.log.warn( json.dumps( parsedLeaders,
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-                # check for all intent partitions
-                topics = []
-                for i in range( 14 ):
-                    topics.append( "work-partition-" + str( i ) )
-                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" )
-                        missing = True
-            else:
-                main.log.error( "leaders() returned None" )
-        except ( ValueError, TypeError ):
-            main.log.exception( "Error parsing leaders" )
-            main.log.error( repr( leaders ) )
-        # Check all nodes
-        if missing:
-            for i in main.activeNodes:
-                response = main.CLIs[ i ].leaders( jsonFormat=False )
-                main.log.warn( str( main.CLIs[ i ].name ) + " leaders output: \n" +
-                               str( response ) )
-
-        partitions = onosCli.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 = onosCli.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( intentAddResult and not missingIntents and
-                                installedCheck )
-        if not intentAddResult:
-            main.log.error( "Error in pushing host intents to ONOS" )
-
-        main.step( "Intent Anti-Entropy dispersion" )
-        for j in range( 100 ):
-            correct = True
-            main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
-            for i in main.activeNodes:
-                onosIds = []
-                ids = main.CLIs[ i ].getAllIntentsId()
-                onosIds.append( ids )
-                main.log.debug( "Intents in " + main.CLIs[ i ].name + ": " +
-                                str( sorted( onosIds ) ) )
-                if sorted( ids ) != sorted( intentIds ):
-                    main.log.warn( "Set of intent IDs doesn't match" )
-                    correct = False
-                    break
-                else:
-                    intents = json.loads( main.CLIs[ i ].intents() )
-                    for intent in intents:
-                        if intent[ 'state' ] != "INSTALLED":
-                            main.log.warn( "Intent " + intent[ 'id' ] +
-                                           " is " + intent[ 'state' ] )
-                            correct = False
-                            break
-            if correct:
-                break
-            else:
-                time.sleep( 1 )
-        if not intentStop:
-            intentStop = time.time()
-        global gossipTime
-        gossipTime = intentStop - intentStart
-        main.log.info( "It took about " + str( gossipTime ) +
-                        " seconds for all intents to appear in each node" )
-        append = False
-        title = "Gossip Intents"
-        count = 1
-        while append is False:
-            curTitle = title + str( count )
-            if curTitle not in labels:
-                labels.append( curTitle )
-                data.append( str( gossipTime ) )
-                append = True
-            else:
-                count += 1
-        gossipPeriod = int( main.params[ 'timers' ][ 'gossip' ] )
-        maxGossipTime = gossipPeriod * len( main.activeNodes )
-        utilities.assert_greater_equals(
-                expect=maxGossipTime, actual=gossipTime,
-                onpass="ECM anti-entropy for intents worked within " +
-                       "expected time",
-                onfail="Intent ECM anti-entropy took too long. " +
-                       "Expected time:{}, Actual time:{}".format( maxGossipTime,
-                                                                  gossipTime ) )
-        if gossipTime <= maxGossipTime:
-            intentAddResult = True
-
-        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 = onosCli.getAllIntentsId()
-            main.log.info( "Submitted intents: " + str( intentIds ) )
-            main.log.info( "Intents in ONOS: " + str( onosIds ) )
-            # Print the intent states
-            intents = onosCli.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 = onosCli.leaders()
-            try:
-                missing = False
-                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( "work-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" )
-                            missing = True
-                else:
-                    main.log.error( "leaders() returned None" )
-            except ( ValueError, TypeError ):
-                main.log.exception( "Error parsing leaders" )
-                main.log.error( repr( leaders ) )
-            # Check all nodes
-            if missing:
-                for i in main.activeNodes:
-                    node = main.CLIs[ i ]
-                    response = node.leaders( jsonFormat=False )
-                    main.log.warn( str( node.name ) + " leaders output: \n" +
-                                   str( response ) )
-
-            partitions = onosCli.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 = onosCli.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 ) )
+        main.HA.assignIntents( main )
 
     def CASE4( self, main ):
         """
         Ping across added host intents
         """
-        import json
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-        main.case( "Verify connectivity by sending traffic across Intents" )
-        main.caseExplanation = "Ping across added host intents to check " +\
-                                "functionality and check the state of " +\
-                                "the intent"
-
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        main.step( "Check Intent state" )
-        installedCheck = False
-        loopCount = 0
-        while not installedCheck and loopCount < 40:
-            installedCheck = True
-            # Print the intent states
-            intents = onosCli.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." )
-            # Print states
-            intentStates.sort()
-            for i, s in intentStates:
-                count += 1
-                main.log.info( "%-6s%-15s%-15s" %
-                               ( str( count ), str( i ), str( s ) ) )
-            if not installedCheck:
-                time.sleep( 1 )
-                loopCount += 1
-        utilities.assert_equals( expect=True, actual=installedCheck,
-                                 onpass="Intents are all INSTALLED",
-                                 onfail="Intents are not all in " +
-                                        "INSTALLED state" )
-
-        main.step( "Ping across added host intents" )
-        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.error(
-                "Intents have not been installed correctly, pings failed." )
-            # TODO: pretty print
-            main.log.warn( "ONOS1 intents: " )
-            try:
-                tmpIntents = onosCli.intents()
-                main.log.warn( json.dumps( json.loads( tmpIntents ),
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-            except ( ValueError, TypeError ):
-                main.log.warn( repr( tmpIntents ) )
-        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." )
-
-        main.step( "Check leadership of topics" )
-        leaders = onosCli.leaders()
-        topicCheck = main.TRUE
-        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
-                # TODO: Look at Devices as topics now that it uses this system
-                topics = []
-                for i in range( 14 ):
-                    topics.append( "work-partition-" + str( i ) )
-                # FIXME: this should only be after we start the app
-                # FIXME: topics.append( "org.onosproject.election" )
-                # Print leaders output
-                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" )
-                        topicCheck = main.FALSE
-            else:
-                main.log.error( "leaders() returned None" )
-                topicCheck = main.FALSE
-        except ( ValueError, TypeError ):
-            topicCheck = main.FALSE
-            main.log.exception( "Error parsing leaders" )
-            main.log.error( repr( leaders ) )
-            # TODO: Check for a leader of these topics
-        # Check all nodes
-        if topicCheck:
-            for i in main.activeNodes:
-                node = main.CLIs[ i ]
-                response = node.leaders( jsonFormat=False )
-                main.log.warn( str( node.name ) + " leaders output: \n" +
-                               str( response ) )
-
-        utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
-                                 onpass="intent Partitions is in leaders",
-                                 onfail="Some topics were lost " )
-        # Print partitions
-        partitions = onosCli.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 ) )
-        # Print Pending Map
-        pendingMap = onosCli.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 = onosCli.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 = onosCli.leaders()
-            try:
-                missing = False
-                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( "work-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" )
-                            missing = True
-                else:
-                    main.log.error( "leaders() returned None" )
-            except ( ValueError, TypeError ):
-                main.log.exception( "Error parsing leaders" )
-                main.log.error( repr( leaders ) )
-            if missing:
-                for i in main.activeNodes:
-                    node = main.CLIs[ i ]
-                    response = node.leaders( jsonFormat=False )
-                    main.log.warn( str( node.name ) + " leaders output: \n" +
-                                   str( response ) )
-
-            partitions = onosCli.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 = onosCli.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 ) )
-        # Print flowrules
-        node = main.activeNodes[ 0 ]
-        main.log.debug( main.CLIs[ node ].flows( jsonFormat=False ) )
-        main.step( "Wait a minute then ping again" )
-        # the wait is above
-        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.error(
-                "Intents have not been installed correctly, pings failed." )
-            # TODO: pretty print
-            main.log.warn( "ONOS1 intents: " )
-            try:
-                tmpIntents = onosCli.intents()
-                main.log.warn( json.dumps( json.loads( tmpIntents ),
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-            except ( ValueError, TypeError ):
-                main.log.warn( repr( tmpIntents ) )
-        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." )
+        main.HA.pingAcrossHostIntent( main, True, True )
 
     def CASE5( self, main ):
         """
         Reading state of ONOS
         """
-        import json
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        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 each other and also with past states
-
-        main.step( "Check that each switch has a master" )
-        global mastershipState
-        mastershipState = '[]'
-
-        # Assert that each device has a master
-        rolesNotNull = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( "Get the Mastership of each switch from each controller" )
-        ONOSMastership = []
-        consistentMastership = True
-        rolesResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSMastership ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSMastership[ i ] or "Error" in ONOSMastership[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " roles" )
-                main.log.warn( "ONOS" + node + " 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.info(
-                "Switch roles are consistent across all ONOS nodes" )
-        else:
-            consistentMastership = False
-        utilities.assert_equals(
-            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( len( main.activeNodes ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                try:
-                    main.log.warn(
-                        "ONOS" + node + " 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:
-            mastershipState = ONOSMastership[ 0 ]
-
-        main.step( "Get the intents from each controller" )
-        global intentState
-        intentState = []
-        ONOSIntents = []
-        consistentIntents = True  # Are Intents consistent across nodes?
-        intentsResults = True  # Could we read Intents from ONOS?
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSIntents ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " intents" )
-                main.log.warn( "ONOS" + node + " 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.info( "Intents are consistent across all ONOS " +
-                             "nodes" )
-        else:
-            consistentIntents = False
-            main.log.error( "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:
-            # Try to make it easy to figure out what is happening
-            #
-            # Intent      ONOS1      ONOS2    ...
-            #  0x01     INSTALLED  INSTALLING
-            #  ...        ...         ...
-            #  ...        ...         ...
-            title = "   Id"
-            for n in main.activeNodes:
-                title += " " * 10 + "ONOS" + str( n + 1 )
-            main.log.warn( title )
-            # get all intent keys in the cluster
-            keys = []
-            try:
-                # Get the set of all intent keys
-                for nodeStr in ONOSIntents:
-                    node = json.loads( nodeStr )
-                    for intent in node:
-                        keys.append( intent.get( 'id' ) )
-                keys = set( keys )
-                # For each intent key, print the state on each node
-                for key in keys:
-                    row = "%-13s" % key
-                    for nodeStr in ONOSIntents:
-                        node = json.loads( nodeStr )
-                        for intent in node:
-                            if intent.get( 'id', "Error" ) == key:
-                                row += "%-15s" % intent.get( 'state' )
-                    main.log.warn( row )
-                # End of intent state table
-            except ValueError as e:
-                main.log.exception( e )
-                main.log.debug( "nodeStr was: " + repr( nodeStr ) )
-
-        if intentsResults and not consistentIntents:
-            # print the json objects
-            n = str( main.activeNodes[ -1 ] + 1 )
-            main.log.debug( "ONOS" + n + " intents: " )
-            main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
-                                        sort_keys=True,
-                                        indent=4,
-                                        separators=( ',', ': ' ) ) )
-            for i in range( len( ONOSIntents ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
-                    main.log.debug( "ONOS" + node + " intents: " )
-                    main.log.debug( json.dumps( json.loads( ONOSIntents[ i ] ),
-                                                sort_keys=True,
-                                                indent=4,
-                                                separators=( ',', ': ' ) ) )
-                else:
-                    main.log.debug( "ONOS" + node + " intents match ONOS" +
-                                    n + " intents" )
-        elif intentsResults and consistentIntents:
-            intentState = ONOSIntents[ 0 ]
-
-        main.step( "Get the flows from each controller" )
-        global flowState
-        flowState = []
-        ONOSFlows = []
-        ONOSFlowsJson = []
-        flowCheck = main.FALSE
-        consistentFlows = True
-        flowsResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].flows,
-                             name="flows-" + str( i ),
-                             args=[],
-                             kwargs={ 'jsonFormat': True } )
-            threads.append( t )
-            t.start()
-
-        # NOTE: Flows command can take some time to run
-        time.sleep( 30 )
-        for t in threads:
-            t.join()
-            result = t.result
-            ONOSFlows.append( result )
-
-        for i in range( len( ONOSFlows ) ):
-            num = str( main.activeNodes[ i ] + 1 )
-            if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
-                main.log.error( "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.info( "Flow count is consistent across all ONOS nodes" )
-        else:
-            consistentFlows = False
-        utilities.assert_equals(
-            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( len( ONOSFlows ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                try:
-                    main.log.warn(
-                        "ONOS" + node + " flows: " +
-                        json.dumps( json.loads( ONOSFlows[ i ] ), sort_keys=True,
-                                    indent=4, separators=( ',', ': ' ) ) )
-                except ( ValueError, TypeError ):
-                    main.log.warn( "ONOS" + node + " 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.Mininet1.getFlowTable( "s" + str( i ), version="1.3", debug=False ) )
-        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" )
-        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( "Collecting topology information from ONOS" )
-        devices = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].devices,
-                             name="devices-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            devices.append( t.result )
-        hosts = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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" )
-                main.log.warn( repr( t.result ) )
-                hosts.append( None )
-
-        ports = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].ports,
-                             name="ports-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            ports.append( t.result )
-        links = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].links,
-                             name="links-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            links.append( t.result )
-        clusters = []
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].clusters,
-                             name="clusters-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            clusters.append( t.result )
-        # Compare json objects for hosts and dataplane clusters
-
-        # hosts
-        main.step( "Host view is consistent across ONOS nodes" )
-        consistentHostsResult = main.TRUE
-        for controller in range( len( hosts ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if hosts[ controller ] and "Error" not in hosts[ controller ]:
-                if hosts[ controller ] == hosts[ 0 ]:
-                    continue
-                else:  # hosts not consistent
-                    main.log.error( "hosts from ONOS" +
-                                     controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    main.log.warn( repr( hosts[ controller ] ) )
-                    consistentHostsResult = main.FALSE
-
-            else:
-                main.log.error( "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" )
-
-        main.step( "Each host has an IP address" )
-        ipResult = main.TRUE
-        for controller in range( 0, len( hosts ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if hosts[ controller ]:
-                for host in hosts[ controller ]:
-                    if not host.get( 'ipAddresses', [] ):
-                        main.log.error( "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
-        main.step( "Cluster view is consistent across ONOS nodes" )
-        consistentClustersResult = main.TRUE
-        for controller in range( len( clusters ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if "Error" not in clusters[ controller ]:
-                if clusters[ controller ] == clusters[ 0 ]:
-                    continue
-                else:  # clusters not consistent
-                    main.log.error( "clusters from ONOS" + controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    consistentClustersResult = main.FALSE
-
-            else:
-                main.log.error( "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" )
-        if not consistentClustersResult:
-            main.log.debug( clusters )
-
-        # there should always only be one cluster
-        main.step( "Cluster view correct across ONOS nodes" )
-        try:
-            numClusters = len( json.loads( clusters[ 0 ] ) )
-        except ( ValueError, TypeError ):
-            main.log.exception( "Error parsing clusters[0]: " +
-                                repr( clusters[ 0 ] ) )
-            numClusters = "ERROR"
-        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
-        linksResults = main.TRUE
-        hostsResults = main.TRUE
-        mnSwitches = main.Mininet1.getSwitches()
-        mnLinks = main.Mininet1.getLinks()
-        mnHosts = main.Mininet1.getHosts()
-        for controller in main.activeNodes:
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if devices[ controller ] and ports[ controller ] and\
-                    "Error" not in devices[ controller ] and\
-                    "Error" not in ports[ controller ]:
-                currentDevicesResult = main.Mininet1.compareSwitches(
-                        mnSwitches,
-                        json.loads( devices[ controller ] ),
-                        json.loads( ports[ controller ] ) )
-            else:
-                currentDevicesResult = main.FALSE
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=currentDevicesResult,
-                                     onpass="ONOS" + controllerStr +
-                                     " Switches view is correct",
-                                     onfail="ONOS" + controllerStr +
-                                     " Switches view is incorrect" )
-            if links[ controller ] and "Error" not in links[ controller ]:
-                currentLinksResult = main.Mininet1.compareLinks(
-                        mnSwitches, mnLinks,
-                        json.loads( links[ controller ] ) )
-            else:
-                currentLinksResult = main.FALSE
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=currentLinksResult,
-                                     onpass="ONOS" + controllerStr +
-                                     " links view is correct",
-                                     onfail="ONOS" + controllerStr +
-                                     " links view is incorrect" )
-
-            if hosts[ controller ] and "Error" not in hosts[ controller ]:
-                currentHostsResult = main.Mininet1.compareHosts(
-                        mnHosts,
-                        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
-            linksResults = linksResults and currentLinksResult
-            hostsResults = hostsResults and currentHostsResult
-
-        main.step( "Device information is correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=devicesResults,
-            onpass="Device information is correct",
-            onfail="Device information is incorrect" )
-
-        main.step( "Links are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=linksResults,
-            onpass="Link are correct",
-            onfail="Links are incorrect" )
-
-        main.step( "Hosts are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=hostsResults,
-            onpass="Hosts are correct",
-            onfail="Hosts are incorrect" )
+        main.HA.readingState( main )
 
     def CASE6( self, main ):
         """
@@ -1819,17 +130,15 @@
         assert main.CLIs, "main.CLIs not defined"
         assert main.nodes, "main.nodes not defined"
         try:
-            labels
-        except NameError:
-            main.log.error( "labels not defined, setting to []" )
-            global labels
-            labels = []
+            main.HAlabels
+        except ( NameError, AttributeError ):
+            main.log.error( "main.HAlabels not defined, setting to []" )
+            main.HAlabels = []
         try:
-            data
-        except NameError:
-            main.log.error( "data not defined, setting to []" )
-            global data
-            data = []
+            main.HAdata
+        except ( NameError, AttributeError ):
+            main.log.error( "main.HAdata not defined, setting to []" )
+            main.HAdata = []
 
         main.case( "Swap some of the ONOS nodes" )
 
@@ -1957,280 +266,9 @@
         """
         Check state after ONOS scaling
         """
-        import json
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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
-        rolesNotNull = main.TRUE
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.CLIs[ i ].rolesNotNull,
-                             name="rolesNotNull-" + str( i ),
-                             args=[] )
-            threads.append( t )
-            t.start()
+        main.HA.checkStateAfterONOS( main, afterWhich=1 )
 
-        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( "Read device roles from ONOS" )
-        ONOSMastership = []
-        consistentMastership = True
-        rolesResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSMastership ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSMastership[ i ] or "Error" in ONOSMastership[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " roles" )
-                main.log.warn( "ONOS" + node + " 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.info(
-                "Switch roles are consistent across all ONOS nodes" )
-        else:
-            consistentMastership = False
-        utilities.assert_equals(
-            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( len( ONOSMastership ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                main.log.warn( "ONOS" + node + " roles: ",
-                               json.dumps( json.loads( ONOSMastership[ i ] ),
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
-
-        # NOTE: we expect mastership to change on controller scaling down
-
-        main.step( "Get the intents and compare across all nodes" )
-        ONOSIntents = []
-        intentCheck = main.FALSE
-        consistentIntents = True
-        intentsResults = True
-        threads = []
-        for i in main.activeNodes:
-            t = main.Thread( target=main.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( len( ONOSIntents ) ):
-            node = str( main.activeNodes[ i ] + 1 )
-            if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
-                main.log.error( "Error in getting ONOS" + node + " intents" )
-                main.log.warn( "ONOS" + node + " 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.info( "Intents are consistent across all ONOS " +
-                             "nodes" )
-        else:
-            consistentIntents = False
-
-        # Try to make it easy to figure out what is happening
-        #
-        # Intent      ONOS1      ONOS2    ...
-        #  0x01     INSTALLED  INSTALLING
-        #  ...        ...         ...
-        #  ...        ...         ...
-        title = "   ID"
-        for n in main.activeNodes:
-            title += " " * 10 + "ONOS" + str( n + 1 )
-        main.log.warn( title )
-        # get all intent keys in the cluster
-        keys = []
-        for nodeStr in ONOSIntents:
-            node = json.loads( nodeStr )
-            for intent in node:
-                keys.append( intent.get( 'id' ) )
-        keys = set( keys )
-        for key in keys:
-            row = "%-13s" % key
-            for nodeStr in ONOSIntents:
-                node = json.loads( nodeStr )
-                for intent in node:
-                    if intent.get( 'id' ) == key:
-                        row += "%-15s" % intent.get( 'state' )
-            main.log.warn( row )
-        # End table view
-
-        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' ] )
-            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( len( main.activeNodes ) ):
-                node = str( main.activeNodes[ i ] + 1 )
-                main.log.warn( "ONOS" + node + " intents: " )
-                main.log.warn( json.dumps(
-                    json.loads( ONOSIntents[ i ] ),
-                    sort_keys=True,
-                    indent=4,
-                    separators=( ',', ': ' ) ) )
-        elif intentsResults and consistentIntents:
-            intentCheck = main.TRUE
-
-        main.step( "Compare current intents with intents before the scaling" )
-        # NOTE: this requires case 5 to pass for intentState to be set.
-        #      maybe we should stop the test if that fails?
-        sameIntents = main.FALSE
-        try:
-            intentState
-        except NameError:
-            main.log.warn( "No previous intent state was saved" )
-        else:
-            if intentState and intentState == ONOSIntents[ 0 ]:
-                sameIntents = main.TRUE
-                main.log.info( "Intents are consistent with before scaling" )
-            # TODO: possibly the states have changed? we may need to figure out
-            #       what the acceptable states are
-            elif len( intentState ) == len( ONOSIntents[ 0 ] ):
-                sameIntents = main.TRUE
-                try:
-                    before = json.loads( intentState )
-                    after = json.loads( ONOSIntents[ 0 ] )
-                    for intent in before:
-                        if intent not in after:
-                            sameIntents = main.FALSE
-                            main.log.debug( "Intent is not currently in ONOS " +
-                                            "(at least in the same form):" )
-                            main.log.debug( json.dumps( intent ) )
-                except ( ValueError, TypeError ):
-                    main.log.exception( "Exception printing intents" )
-                    main.log.debug( repr( ONOSIntents[ 0 ] ) )
-                    main.log.debug( repr( intentState ) )
-            if sameIntents == main.FALSE:
-                try:
-                    main.log.debug( "ONOS intents before: " )
-                    main.log.debug( json.dumps( json.loads( intentState ),
-                                                sort_keys=True, indent=4,
-                                                separators=( ',', ': ' ) ) )
-                    main.log.debug( "Current ONOS intents: " )
-                    main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
-                                                sort_keys=True, indent=4,
-                                                separators=( ',', ': ' ) ) )
-                except ( ValueError, TypeError ):
-                    main.log.exception( "Exception printing intents" )
-                    main.log.debug( repr( ONOSIntents[ 0 ] ) )
-                    main.log.debug( repr( intentState ) )
-            utilities.assert_equals(
-                expect=main.TRUE,
-                actual=sameIntents,
-                onpass="Intents are consistent with before scaling",
-                onfail="The Intents changed during scaling" )
-        intentCheck = intentCheck and sameIntents
-
-        main.step( "Get the OF Table entries and compare to before " +
-                   "component scaling" )
-        FlowTables = main.TRUE
-        for i in range( 28 ):
-            main.log.info( "Checking flow table on s" + str( i + 1 ) )
-            tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
-            curSwitch = main.Mininet1.flowTableComp( flows[ i ], tmpFlows )
-            FlowTables = FlowTables and curSwitch
-            if curSwitch == main.FALSE:
-                main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
-        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.Mininet2.pingLongKill()
-        """
-        # main.step( "Check the continuous pings to ensure that no packets " +
-        #            "were dropped during component failure" )
-        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.info( "No loss of dataplane connectivity" )
-        # utilities.assert_equals(
-        #     expect=main.FALSE,
-        #     actual=LossInPings,
-        #     onpass="No Loss of connectivity",
-        #     onfail="Loss of dataplane connectivity detected" )
-
-        # NOTE: Since intents are not persisted with IntnentStore,
-        #       we expect loss in dataplane connectivity
-        LossInPings = main.FALSE
-        """
         main.step( "Leadership Election is still functional" )
         # Test of LeadershipElection
         leaderList = []
@@ -2265,620 +303,39 @@
         """
         Compare topo
         """
-        import json
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        main.case( "Compare ONOS Topology view to Mininet topology" )
-        main.caseExplanation = "Compare topology objects between Mininet" +\
-                                " and ONOS"
-        topoResult = main.FALSE
-        topoFailMsg = "ONOS topology don't match Mininet"
-        elapsed = 0
-        count = 0
-        main.step( "Comparing ONOS topology to MN topology" )
-        startTime = time.time()
-        # Give time for Gossip to work
-        while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
-            devicesResults = main.TRUE
-            linksResults = main.TRUE
-            hostsResults = main.TRUE
-            hostAttachmentResults = True
-            count += 1
-            cliStart = time.time()
-            devices = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="devices-" + str( i ),
-                                 args=[ main.CLIs[ i ].devices, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                devices.append( t.result )
-            hosts = []
-            ipResult = main.TRUE
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="hosts-" + str( i ),
-                                 args=[ main.CLIs[ i ].hosts, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                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 ) )
-                    hosts.append( None )
-            for controller in range( 0, len( hosts ) ):
-                controllerStr = str( main.activeNodes[ controller ] + 1 )
-                if hosts[ controller ]:
-                    for host in hosts[ controller ]:
-                        if host is None or host.get( 'ipAddresses', [] ) == []:
-                            main.log.error(
-                                "Error with host ipAddresses on controller" +
-                                controllerStr + ": " + str( host ) )
-                            ipResult = main.FALSE
-            ports = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="ports-" + str( i ),
-                                 args=[ main.CLIs[ i ].ports, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                ports.append( t.result )
-            links = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="links-" + str( i ),
-                                 args=[ main.CLIs[ i ].links, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                links.append( t.result )
-            clusters = []
-            threads = []
-            for i in main.activeNodes:
-                t = main.Thread( target=utilities.retry,
-                                 name="clusters-" + str( i ),
-                                 args=[ main.CLIs[ i ].clusters, [ None ] ],
-                                 kwargs={ 'sleep': 5, 'attempts': 5,
-                                           'randomTime': True } )
-                threads.append( t )
-                t.start()
-
-            for t in threads:
-                t.join()
-                clusters.append( t.result )
-
-            elapsed = time.time() - startTime
-            cliTime = time.time() - cliStart
-            print "Elapsed time: " + str( elapsed )
-            print "CLI time: " + str( cliTime )
-
-            if all( e is None for e in devices ) and\
-               all( e is None for e in hosts ) and\
-               all( e is None for e in ports ) and\
-               all( e is None for e in links ) and\
-               all( e is None for e in clusters ):
-                topoFailMsg = "Could not get topology from ONOS"
-                main.log.error( topoFailMsg )
-                continue  # Try again, No use trying to compare
-
-            mnSwitches = main.Mininet1.getSwitches()
-            mnLinks = main.Mininet1.getLinks()
-            mnHosts = main.Mininet1.getHosts()
-            for controller in range( len( main.activeNodes ) ):
-                controllerStr = str( main.activeNodes[ controller ] + 1 )
-                if devices[ controller ] and ports[ controller ] and\
-                        "Error" not in devices[ controller ] and\
-                        "Error" not in ports[ controller ]:
-
-                    try:
-                        currentDevicesResult = main.Mininet1.compareSwitches(
-                                mnSwitches,
-                                json.loads( devices[ controller ] ),
-                                json.loads( ports[ controller ] ) )
-                    except ( TypeError, ValueError ):
-                        main.log.exception( "Object not as expected; devices={!r}\nports={!r}".format(
-                            devices[ controller ], ports[ controller ] ) )
-                else:
-                    currentDevicesResult = main.FALSE
-                utilities.assert_equals( expect=main.TRUE,
-                                         actual=currentDevicesResult,
-                                         onpass="ONOS" + controllerStr +
-                                         " Switches view is correct",
-                                         onfail="ONOS" + controllerStr +
-                                         " Switches view is incorrect" )
-
-                if links[ controller ] and "Error" not in links[ controller ]:
-                    currentLinksResult = main.Mininet1.compareLinks(
-                            mnSwitches, mnLinks,
-                            json.loads( links[ controller ] ) )
-                else:
-                    currentLinksResult = main.FALSE
-                utilities.assert_equals( expect=main.TRUE,
-                                         actual=currentLinksResult,
-                                         onpass="ONOS" + controllerStr +
-                                         " links view is correct",
-                                         onfail="ONOS" + controllerStr +
-                                         " links view is incorrect" )
-                if hosts[ controller ] and "Error" not in hosts[ controller ]:
-                    currentHostsResult = main.Mininet1.compareHosts(
-                            mnHosts,
-                            hosts[ controller ] )
-                elif hosts[ controller ] == []:
-                    currentHostsResult = main.TRUE
-                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" )
-                # CHECKING HOST ATTACHMENT POINTS
-                hostAttachment = True
-                zeroHosts = False
-                # FIXME: topo-HA/obelisk specific mappings:
-                # key is mac and value is dpid
-                mappings = {}
-                for i in range( 1, 29 ):  # hosts 1 through 28
-                    # set up correct variables:
-                    macId = "00:" * 5 + hex( i ).split( "0x" )[ 1 ].upper().zfill( 2 )
-                    if i == 1:
-                        deviceId = "1000".zfill( 16 )
-                    elif i == 2:
-                        deviceId = "2000".zfill( 16 )
-                    elif i == 3:
-                        deviceId = "3000".zfill( 16 )
-                    elif i == 4:
-                        deviceId = "3004".zfill( 16 )
-                    elif i == 5:
-                        deviceId = "5000".zfill( 16 )
-                    elif i == 6:
-                        deviceId = "6000".zfill( 16 )
-                    elif i == 7:
-                        deviceId = "6007".zfill( 16 )
-                    elif i >= 8 and i <= 17:
-                        dpid = '3' + str( i ).zfill( 3 )
-                        deviceId = dpid.zfill( 16 )
-                    elif i >= 18 and i <= 27:
-                        dpid = '6' + str( i ).zfill( 3 )
-                        deviceId = dpid.zfill( 16 )
-                    elif i == 28:
-                        deviceId = "2800".zfill( 16 )
-                    mappings[ macId ] = deviceId
-                if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
-                    if hosts[ controller ] == []:
-                        main.log.warn( "There are no hosts discovered" )
-                        zeroHosts = True
-                    else:
-                        for host in hosts[ controller ]:
-                            mac = None
-                            location = None
-                            device = None
-                            port = None
-                            try:
-                                mac = host.get( 'mac' )
-                                assert mac, "mac field could not be found for this host object"
-
-                                location = host.get( 'locations' )[ 0 ]
-                                assert location, "location field could not be found for this host object"
-
-                                # Trim the protocol identifier off deviceId
-                                device = str( location.get( 'elementId' ) ).split( ':' )[ 1 ]
-                                assert device, "elementId field could not be found for this host location object"
-
-                                port = location.get( 'port' )
-                                assert port, "port field could not be found for this host location object"
-
-                                # Now check if this matches where they should be
-                                if mac and device and port:
-                                    if str( port ) != "1":
-                                        main.log.error( "The attachment port is incorrect for " +
-                                                        "host " + str( mac ) +
-                                                        ". Expected: 1 Actual: " + str( port ) )
-                                        hostAttachment = False
-                                    if device != mappings[ str( mac ) ]:
-                                        main.log.error( "The attachment device is incorrect for " +
-                                                        "host " + str( mac ) +
-                                                        ". Expected: " + mappings[ str( mac ) ] +
-                                                        " Actual: " + device )
-                                        hostAttachment = False
-                                else:
-                                    hostAttachment = False
-                            except AssertionError:
-                                main.log.exception( "Json object not as expected" )
-                                main.log.error( repr( host ) )
-                                hostAttachment = False
-                else:
-                    main.log.error( "No hosts json output or \"Error\"" +
-                                    " in output. hosts = " +
-                                    repr( hosts[ controller ] ) )
-                if zeroHosts is False:
-                    # TODO: Find a way to know if there should be hosts in a
-                    #       given point of the test
-                    hostAttachment = True
-
-                # END CHECKING HOST ATTACHMENT POINTS
-                devicesResults = devicesResults and currentDevicesResult
-                linksResults = linksResults and currentLinksResult
-                hostsResults = hostsResults and currentHostsResult
-                hostAttachmentResults = hostAttachmentResults and\
-                                        hostAttachment
-                topoResult = ( devicesResults and linksResults
-                               and hostsResults and ipResult and
-                               hostAttachmentResults )
-        utilities.assert_equals( expect=True,
-                                 actual=topoResult,
-                                 onpass="ONOS topology matches Mininet",
-                                 onfail=topoFailMsg )
-        # End of While loop to pull ONOS state
-
-        # Compare json objects for hosts and dataplane clusters
-
-        # hosts
-        main.step( "Hosts view is consistent across all ONOS nodes" )
-        consistentHostsResult = main.TRUE
-        for controller in range( len( hosts ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
-                if hosts[ controller ] == hosts[ 0 ]:
-                    continue
-                else:  # hosts not consistent
-                    main.log.error( "hosts from ONOS" + controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    main.log.warn( repr( hosts[ controller ] ) )
-                    consistentHostsResult = main.FALSE
-
-            else:
-                main.log.error( "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" )
-
-        main.step( "Hosts information is correct" )
-        hostsResults = hostsResults and ipResult
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=hostsResults,
-            onpass="Host information is correct",
-            onfail="Host information is incorrect" )
-
-        main.step( "Host attachment points to the network" )
-        utilities.assert_equals(
-            expect=True,
-            actual=hostAttachmentResults,
-            onpass="Hosts are correctly attached to the network",
-            onfail="ONOS did not correctly attach hosts to the network" )
-
-        # Strongly connected clusters of devices
-        main.step( "Clusters view is consistent across all ONOS nodes" )
-        consistentClustersResult = main.TRUE
-        for controller in range( len( clusters ) ):
-            controllerStr = str( main.activeNodes[ controller ] + 1 )
-            if "Error" not in clusters[ controller ]:
-                if clusters[ controller ] == clusters[ 0 ]:
-                    continue
-                else:  # clusters not consistent
-                    main.log.error( "clusters from ONOS" +
-                                     controllerStr +
-                                     " is inconsistent with ONOS1" )
-                    consistentClustersResult = main.FALSE
-            else:
-                main.log.error( "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" )
-        if not consistentClustersResult:
-            main.log.debug( clusters )
-            for x in links:
-                main.log.warn( "{}: {}".format( len( x ), x ) )
-
-        main.step( "There is only one SCC" )
-        # there should always only be one cluster
-        try:
-            numClusters = len( json.loads( clusters[ 0 ] ) )
-        except ( ValueError, TypeError ):
-            main.log.exception( "Error parsing clusters[0]: " +
-                                repr( clusters[ 0 ] ) )
-            numClusters = "ERROR"
-        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 linksResults
-                       and hostsResults and consistentHostsResult
-                       and consistentClustersResult and clusterResults
-                       and ipResult and hostAttachmentResults )
-
-        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" )
-
-        main.step( "Device information is correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=devicesResults,
-            onpass="Device information is correct",
-            onfail="Device information is incorrect" )
-
-        main.step( "Links are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=linksResults,
-            onpass="Link are correct",
-            onfail="Links are incorrect" )
-
-        main.step( "Hosts are correct" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=hostsResults,
-            onpass="Hosts are correct",
-            onfail="Hosts are incorrect" )
-
-        # FIXME: move this to an ONOS state case
-        main.step( "Checking ONOS nodes" )
-        nodeResults = utilities.retry( main.HA.nodesCheck,
-                                       False,
-                                       args=[ main.activeNodes ],
-                                       attempts=5 )
-        utilities.assert_equals( expect=True, actual=nodeResults,
-                                 onpass="Nodes check successful",
-                                 onfail="Nodes check NOT successful" )
-        if not nodeResults:
-            for i in main.activeNodes:
-                main.log.debug( "{} components not ACTIVE: \n{}".format(
-                    main.CLIs[ i ].name,
-                    main.CLIs[ i ].sendline( "scr:list | grep -v ACTIVE" ) ) )
-
-        if not topoResult:
-            main.cleanup()
-            main.exit()
+        main.HA.compareTopo( main )
 
     def CASE9( self, main ):
         """
         Link s3-s28 down
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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"
-        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 successful",
-                                 onfail="Failed to bring link down" )
-        # TODO do some sort of check here
+        main.HA.linkDown( main )
 
     def CASE10( self, main ):
         """
         Link s3-s28 up
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.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"
-        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 successful",
-                                 onfail="Failed to bring link up" )
-        # TODO do some sort of check here
+        main.HA.linkUp( main )
 
     def CASE11( self, main ):
         """
         Switch Down
         """
         # NOTE: You should probably run a topology check after this
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
-
-        description = "Killing a switch to ensure it is discovered correctly"
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        main.case( description )
-        switch = main.params[ 'kill' ][ 'switch' ]
-        switchDPID = main.params[ 'kill' ][ 'dpid' ]
-
-        # TODO: Make this switch parameterizable
-        main.step( "Kill " + switch )
-        main.log.info( "Deleting " + switch )
-        main.Mininet1.delSwitch( switch )
-        main.log.info( "Waiting " + str( switchSleep ) +
-                       " seconds for switch down to be discovered" )
-        time.sleep( switchSleep )
-        device = onosCli.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 successful",
-                                 onfail="Failed to kill switch?" )
+        main.HA.switchDown( main )
 
     def CASE12( self, main ):
         """
         Switch Up
         """
         # NOTE: You should probably run a topology check after this
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
-        switch = main.params[ 'kill' ][ 'switch' ]
-        switchDPID = main.params[ 'kill' ][ 'dpid' ]
-        links = main.params[ 'kill' ][ 'links' ].split()
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        description = "Adding a switch to ensure it is discovered correctly"
-        main.case( description )
-
-        main.step( "Add back " + switch )
-        main.Mininet1.addSwitch( switch, dpid=switchDPID )
-        for peer in links:
-            main.Mininet1.addLink( switch, peer )
-        ipList = [ node.ip_address for node in main.nodes ]
-        main.Mininet1.assignSwController( sw=switch, ip=ipList )
-        main.log.info( "Waiting " + str( switchSleep ) +
-                       " seconds for switch up to be discovered" )
-        time.sleep( switchSleep )
-        device = onosCli.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 successful",
-                                 onfail="Failed to add switch?" )
+        main.HA.switchUp( main )
 
     def CASE13( self, main ):
         """
         Clean up
         """
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        main.case( "Test Cleanup" )
-        main.step( "Killing tcpdumps" )
-        main.Mininet2.stopTcpdump()
-
-        if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
-            main.step( "Copying MN pcap and ONOS log files to test station" )
-            # NOTE: MN Pcap file is being saved to logdir.
-            #       We scp this file as MN and TestON aren't necessarily the same vm
-
-            # FIXME: To be replaced with a Jenkin's post script
-            # TODO: Load these from params
-            # NOTE: must end in /
-            logFolder = "/opt/onos/log/"
-            logFiles = [ "karaf.log", "karaf.log.1" ]
-            # NOTE: must end in /
-            for f in logFiles:
-                for node in main.nodes:
-                    dstName = main.logdir + "/" + node.name + "-" + f
-                    main.ONOSbench.secureCopy( node.user_name, node.ip_address,
-                                               logFolder + f, dstName )
-            # std*.log's
-            # NOTE: must end in /
-            logFolder = "/opt/onos/var/"
-            logFiles = [ "stderr.log", "stdout.log" ]
-            # NOTE: must end in /
-            for f in logFiles:
-                for node in main.nodes:
-                    dstName = main.logdir + "/" + node.name + "-" + f
-                    main.ONOSbench.secureCopy( node.user_name, node.ip_address,
-                                               logFolder + f, dstName )
-        else:
-            main.log.debug( "skipping saving log files" )
-
-        main.step( "Stopping Mininet" )
-        mnResult = main.Mininet1.stopNet()
-        utilities.assert_equals( expect=main.TRUE, actual=mnResult,
-                                 onpass="Mininet stopped",
-                                 onfail="MN cleanup NOT successful" )
-
-        main.step( "Checking ONOS Logs for errors" )
-        for node in main.nodes:
-            main.log.debug( "Checking logs for errors on " + node.name + ":" )
-            main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
-
-        try:
-            timerLog = open( main.logdir + "/Timers.csv", 'w' )
-            main.log.error( ", ".join( labels ) + "\n" + ", ".join( data ) )
-            timerLog.write( ", ".join( labels ) + "\n" + ", ".join( data ) )
-            timerLog.close()
-        except NameError as e:
-            main.log.exception( e )
+        main.HA.cleanUp( main )
 
         main.step( "Stopping webserver" )
         status = main.Server.stop()
@@ -2891,47 +348,7 @@
         """
         start election app on all onos nodes
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        main.case( "Start Leadership Election app" )
-        main.step( "Install leadership election app" )
-        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
-        appResult = onosCli.activateApp( "org.onosproject.election" )
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=appResult,
-            onpass="Election app installed",
-            onfail="Something went wrong with installing Leadership election" )
-
-        main.step( "Run for election on each node" )
-        for i in main.activeNodes:
-            main.CLIs[ i ].electionTestRun()
-        time.sleep( 5 )
-        activeCLIs = [ main.CLIs[ i ] for i in main.activeNodes ]
-        sameResult, leaders = main.HA.consistentLeaderboards( activeCLIs )
-        utilities.assert_equals(
-            expect=True,
-            actual=sameResult,
-            onpass="All nodes see the same leaderboards",
-            onfail="Inconsistent leaderboards" )
-
-        if sameResult:
-            leader = leaders[ 0 ][ 0 ]
-            if main.nodes[ main.activeNodes[ 0 ] ].ip_address in leader:
-                correctLeader = True
-            else:
-                correctLeader = False
-            main.step( "First node was elected leader" )
-            utilities.assert_equals(
-                expect=True,
-                actual=correctLeader,
-                onpass="Correct leader was elected",
-                onfail="Incorrect leader" )
+        main.HA.startElectionApp( main )
 
     def CASE15( self, main ):
         """
@@ -2948,196 +365,16 @@
             old and new variable prefixes refer to data from before vs after
                 withdrawl and later before withdrawl vs after re-election
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        description = "Check that Leadership Election is still functional"
-        main.case( description )
-        # NOTE: Need to re-run after restarts since being a canidate is not persistant
-
-        oldLeaders = []  # list of lists of each nodes' candidates before
-        newLeaders = []  # list of lists of each nodes' candidates after
-        oldLeader = ''  # the old leader from oldLeaders, None if not same
-        newLeader = ''  # the new leaders fron newLoeaders, None if not same
-        oldLeaderCLI = None  # the CLI of the old leader used for re-electing
-        expectNoLeader = False  # True when there is only one leader
-        if main.numCtrls == 1:
-            expectNoLeader = True
-
-        main.step( "Run for election on each node" )
-        electionResult = main.TRUE
-
-        for i in main.activeNodes:  # run test election on each node
-            if main.CLIs[ i ].electionTestRun() == main.FALSE:
-                electionResult = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=electionResult,
-            onpass="All nodes successfully ran for leadership",
-            onfail="At least one node failed to run for leadership" )
-
-        if electionResult == main.FALSE:
-            main.log.error(
-                "Skipping Test Case because Election Test App isn't loaded" )
-            main.skipCase()
-
-        main.step( "Check that each node shows the same leader and candidates" )
-        failMessage = "Nodes have different leaderboards"
-        activeCLIs = [ main.CLIs[ i ] for i in main.activeNodes ]
-        sameResult, oldLeaders = main.HA.consistentLeaderboards( activeCLIs )
-        if sameResult:
-            oldLeader = oldLeaders[ 0 ][ 0 ]
-            main.log.warn( oldLeader )
-        else:
-            oldLeader = None
-        utilities.assert_equals(
-            expect=True,
-            actual=sameResult,
-            onpass="Leaderboards are consistent for the election topic",
-            onfail=failMessage )
-
-        main.step( "Find current leader and withdraw" )
-        withdrawResult = main.TRUE
-        # do some sanity checking on leader before using it
-        if oldLeader is None:
-            main.log.error( "Leadership isn't consistent." )
-            withdrawResult = main.FALSE
-        # Get the CLI of the oldLeader
-        for i in main.activeNodes:
-            if oldLeader == main.nodes[ i ].ip_address:
-                oldLeaderCLI = main.CLIs[ i ]
-                break
-        else:  # FOR/ELSE statement
-            main.log.error( "Leader election, could not find current leader" )
-        if oldLeader:
-            withdrawResult = oldLeaderCLI.electionTestWithdraw()
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=withdrawResult,
-            onpass="Node was withdrawn from election",
-            onfail="Node was not withdrawn from election" )
-
-        main.step( "Check that a new node was elected leader" )
-        failMessage = "Nodes have different leaders"
-        # Get new leaders and candidates
-        newLeaderResult, newLeaders = main.HA.consistentLeaderboards( activeCLIs )
-        newLeader = None
-        if newLeaderResult:
-            if newLeaders[ 0 ][ 0 ] == 'none':
-                main.log.error( "No leader was elected on at least 1 node" )
-                if not expectNoLeader:
-                    newLeaderResult = False
-            newLeader = newLeaders[ 0 ][ 0 ]
-
-        # Check that the new leader is not the older leader, which was withdrawn
-        if newLeader == oldLeader:
-            newLeaderResult = False
-            main.log.error( "All nodes still see old leader: " + str( oldLeader ) +
-                            " as the current leader" )
-        utilities.assert_equals(
-            expect=True,
-            actual=newLeaderResult,
-            onpass="Leadership election passed",
-            onfail="Something went wrong with Leadership election" )
-
-        main.step( "Check that that new leader was the candidate of old leader" )
-        # candidates[ 2 ] should become the top candidate after withdrawl
-        correctCandidateResult = main.TRUE
-        if expectNoLeader:
-            if newLeader == 'none':
-                main.log.info( "No leader expected. None found. Pass" )
-                correctCandidateResult = main.TRUE
-            else:
-                main.log.info( "Expected no leader, got: " + str( newLeader ) )
-                correctCandidateResult = main.FALSE
-        elif len( oldLeaders[ 0 ] ) >= 3:
-            if newLeader == oldLeaders[ 0 ][ 2 ]:
-                # correct leader was elected
-                correctCandidateResult = main.TRUE
-            else:
-                correctCandidateResult = main.FALSE
-                main.log.error( "Candidate {} was elected. {} should have had priority.".format(
-                                    newLeader, oldLeaders[ 0 ][ 2 ] ) )
-        else:
-            main.log.warn( "Could not determine who should be the correct leader" )
-            main.log.debug( oldLeaders[ 0 ] )
-            correctCandidateResult = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=correctCandidateResult,
-            onpass="Correct Candidate Elected",
-            onfail="Incorrect Candidate Elected" )
-
-        main.step( "Run for election on old leader( just so everyone " +
-                   "is in the hat )" )
-        if oldLeaderCLI is not None:
-            runResult = oldLeaderCLI.electionTestRun()
-        else:
-            main.log.error( "No old leader to re-elect" )
-            runResult = main.FALSE
-        utilities.assert_equals(
-            expect=main.TRUE,
-            actual=runResult,
-            onpass="App re-ran for election",
-            onfail="App failed to run for election" )
-
-        main.step(
-            "Check that oldLeader is a candidate, and leader if only 1 node" )
-        # verify leader didn't just change
-        # Get new leaders and candidates
-        reRunLeaders = []
-        time.sleep( 5 )  # Paremterize
-        positionResult, reRunLeaders = main.HA.consistentLeaderboards( activeCLIs )
-
-        # Check that the re-elected node is last on the candidate List
-        if not reRunLeaders[ 0 ]:
-            positionResult = main.FALSE
-        elif oldLeader != reRunLeaders[ 0 ][ -1 ]:
-            main.log.error( "Old Leader ({}) not in the proper position: {} ".format( str( oldLeader ),
-                                                                                      str( reRunLeaders[ 0 ] ) ) )
-            positionResult = main.FALSE
-        utilities.assert_equals(
-            expect=True,
-            actual=positionResult,
-            onpass="Old leader successfully re-ran for election",
-            onfail="Something went wrong with Leadership election after " +
-                   "the old leader re-ran for election" )
+        main.HA.isElectionFunctional( main )
 
     def CASE16( self, main ):
         """
         Install Distributed Primitives app
         """
-        import time
-        assert main.numCtrls, "main.numCtrls not defined"
-        assert main, "main not defined"
-        assert utilities.assert_equals, "utilities.assert_equals not defined"
-        assert main.CLIs, "main.CLIs not defined"
-        assert main.nodes, "main.nodes not defined"
-
-        # Variables for the distributed primitives tests
-        main.pCounterName = "TestON-Partitions"
-        main.pCounterValue = 0
-        main.onosSet = set( [] )
-        main.onosSetName = "TestON-set"
-
-        description = "Install Primitives app"
-        main.case( description )
-        main.step( "Install Primitives app" )
-        appName = "org.onosproject.distributedprimitives"
-        node = main.activeNodes[ 0 ]
-        appResults = main.CLIs[ node ].activateApp( appName )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=appResults,
-                                 onpass="Primitives app activated",
-                                 onfail="Primitives app not activated" )
-        time.sleep( 5 )  # To allow all nodes to activate
+        main.HA.installDistributedPrimitiveApp( main )
 
     def CASE17( self, main ):
         """
         Check for basic functionality with distributed primitives
         """
-        main.HA.CASE17( main )
+        main.HA.checkDistPrimitivesFunc( main )
diff --git a/TestON/tests/HA/dependencies/HA.py b/TestON/tests/HA/dependencies/HA.py
index ac0e891..b974972 100644
--- a/TestON/tests/HA/dependencies/HA.py
+++ b/TestON/tests/HA/dependencies/HA.py
@@ -7,6 +7,126 @@
     def __init__( self ):
         self.default = ''
 
+    def customizeOnosGenPartitions( self ):
+        self.startingMininet()
+        # copy gen-partions file to ONOS
+        # NOTE: this assumes TestON and ONOS are on the same machine
+        srcFile = main.testDir + "/HA/dependencies/onos-gen-partitions"
+        dstDir = main.ONOSbench.home + "/tools/test/bin/onos-gen-partitions"
+        cpResult = main.ONOSbench.secureCopy( main.ONOSbench.user_name,
+                                              main.ONOSbench.ip_address,
+                                              srcFile,
+                                              dstDir,
+                                              pwd=main.ONOSbench.pwd,
+                                              direction="from" )
+    def cleanUpGenPartition( self ):
+        # clean up gen-partitions file
+        try:
+            main.ONOSbench.handle.sendline( "cd " + main.ONOSbench.home )
+            main.ONOSbench.handle.expect( main.ONOSbench.home + "\$" )
+            main.ONOSbench.handle.sendline( "git checkout -- tools/test/bin/onos-gen-partitions" )
+            main.ONOSbench.handle.expect( main.ONOSbench.home + "\$" )
+            main.log.info( " Cleaning custom gen partitions file, response was: \n" +
+                           str( main.ONOSbench.handle.before ) )
+        except ( pexpect.TIMEOUT, pexpect.EOF ):
+            main.log.exception( "ONOSbench: pexpect exception found:" +
+                                main.ONOSbench.handle.before )
+            main.cleanup()
+            main.exit()
+    def startingMininet( self ):
+        main.step( "Starting Mininet" )
+        # scp topo file to mininet
+        # TODO: move to params?
+        topoName = "obelisk.py"
+        filePath = main.ONOSbench.home + "/tools/test/topos/"
+        main.ONOSbench.scp( main.Mininet1,
+                            filePath + topoName,
+                            main.Mininet1.home,
+                            direction="to" )
+        mnResult = main.Mininet1.startNet()
+        utilities.assert_equals( expect=main.TRUE, actual=mnResult,
+                                 onpass="Mininet Started",
+                                 onfail="Error starting Mininet" )
+    def scalingMetadata( self ):
+        import re
+        main.scaling = main.params[ 'scaling' ].split( "," )
+        main.log.debug( main.scaling )
+        scale = main.scaling.pop( 0 )
+        main.log.debug( scale )
+        if "e" in scale:
+            equal = True
+        else:
+            equal = False
+        main.log.debug( equal )
+        main.numCtrls = int( re.search( "\d+", scale ).group( 0 ) )
+        genResult = main.Server.generateFile( main.numCtrls, equal=equal )
+        utilities.assert_equals( expect=main.TRUE, actual=genResult,
+                                 onpass="New cluster metadata file generated",
+                                 onfail="Failled to generate new metadata file" )
+    def swapNodeMetadata( self ):
+        if main.numCtrls >= 5:
+            main.numCtrls -= 2
+        else:
+            main.log.error( "Not enough ONOS nodes to run this test. Requires 5 or more" )
+        genResult = main.Server.generateFile( main.numCtrls )
+        utilities.assert_equals( expect=main.TRUE, actual=genResult,
+                                 onpass="New cluster metadata file generated",
+                                 onfail="Failled to generate new metadata file" )
+    def customizeOnosService( self, metadataMethod ):
+        import os
+        main.step( "Setup server for cluster metadata file" )
+        main.serverPort = main.params[ 'server' ][ 'port' ]
+        rootDir = os.path.dirname( main.testFile ) + "/dependencies"
+        main.log.debug( "Root dir: {}".format( rootDir ) )
+        status = main.Server.start( main.ONOSbench,
+                                    rootDir,
+                                    port=main.serverPort,
+                                    logDir=main.logdir + "/server.log" )
+        utilities.assert_equals( expect=main.TRUE, actual=status,
+                                 onpass="Server started",
+                                 onfail="Failled to start SimpleHTTPServer" )
+
+        main.step( "Generate initial metadata file" )
+        metadataMethod()
+
+        self.startingMininet()
+
+        main.step( "Copying backup config files" )
+        main.onosServicepath = main.ONOSbench.home + "/tools/package/bin/onos-service"
+        cp = main.ONOSbench.scp( main.ONOSbench,
+                                 main.onosServicepath,
+                                 main.onosServicepath + ".backup",
+                                 direction="to" )
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=cp,
+                                 onpass="Copy backup config file succeeded",
+                                 onfail="Copy backup config file failed" )
+        # we need to modify the onos-service file to use remote metadata file
+        # url for cluster metadata file
+        iface = main.params[ 'server' ].get( 'interface' )
+        ip = main.ONOSbench.getIpAddr( iface=iface )
+        metaFile = "cluster.json"
+        javaArgs = r"-Donos.cluster.metadata.uri=http:\/\/{}:{}\/{}".format( ip, main.serverPort, metaFile )
+        main.log.warn( javaArgs )
+        main.log.warn( repr( javaArgs ) )
+        handle = main.ONOSbench.handle
+        sed = r"sed -i 's/bash/bash\nexport JAVA_OPTS=${{JAVA_OPTS:-{}}}\n/' {}".format( javaArgs, main.onosServicepath )
+        main.log.warn( sed )
+        main.log.warn( repr( sed ) )
+        handle.sendline( sed )
+        handle.expect( metaFile )
+        output = handle.before
+        handle.expect( "\$" )
+        output += handle.before
+        main.log.debug( repr( output ) )
+
+    def cleanUpOnosService( self ):
+        # Cleanup custom onos-service file
+        main.ONOSbench.scp( main.ONOSbench,
+                            main.onosServicepath + ".backup",
+                            main.onosServicepath,
+                            direction="to" )
     def consistentCheck( self ):
         """
         Checks that TestON counters are consistent across all nodes.
@@ -159,6 +279,128 @@
                 currentResult = False
             results = results and currentResult
         return results
+    def generateGraph( self, testName, plotName="Plot-HA", index=2 ):
+        # GRAPHS
+        # NOTE: important params here:
+        #       job = name of Jenkins job
+        #       Plot Name = Plot-HA, only can be used if multiple plots
+        #       index = The number of the graph under plot name
+        job = testName
+        graphs = '<ac:structured-macro ac:name="html">\n'
+        graphs += '<ac:plain-text-body><![CDATA[\n'
+        graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
+                  '/plot/' + plotName + '/getPlot?index=' + str( index ) +\
+                  '&width=500&height=300"' +\
+                  'noborder="0" width="500" height="300" scrolling="yes" ' +\
+                  'seamless="seamless"></iframe>\n'
+        graphs += ']]></ac:plain-text-body>\n'
+        graphs += '</ac:structured-macro>\n'
+        main.log.wiki( graphs )
+    def initialSetUp( self, serviceClean=False ):
+        """
+        rest of initialSetup
+        """
+
+        # Create a list of active nodes for use when some nodes are stopped
+        main.activeNodes = [ i for i in range( 0, main.numCtrls ) ]
+
+        if main.params[ 'tcpdump' ].lower() == "true":
+            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' ] )
+
+        if serviceClean:
+            main.step( "Clean up ONOS service changes" )
+            main.ONOSbench.handle.sendline( "git checkout -- tools/package/init/onos.conf" )
+            main.ONOSbench.handle.sendline( "git checkout -- tools/package/init/onos.service" )
+            main.ONOSbench.handle.expect( "\$" )
+
+        main.step( "Checking ONOS nodes" )
+        nodeResults = utilities.retry( self.nodesCheck,
+                                       False,
+                                       args=[ main.activeNodes ],
+                                       attempts=5 )
+
+        utilities.assert_equals( expect=True, actual=nodeResults,
+                                 onpass="Nodes check successful",
+                                 onfail="Nodes check NOT successful" )
+
+        if not nodeResults:
+            for i in main.activeNodes:
+                cli = main.CLIs[ i ]
+                main.log.debug( "{} components not ACTIVE: \n{}".format(
+                    cli.name,
+                    cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
+            main.log.error( "Failed to start ONOS, stopping test" )
+            main.cleanup()
+            main.exit()
+
+        main.step( "Activate apps defined in the params file" )
+        # get data from the params
+        apps = main.params.get( 'apps' )
+        if apps:
+            apps = apps.split( ',' )
+            main.log.warn( apps )
+            activateResult = True
+            for app in apps:
+                main.CLIs[ 0 ].app( app, "Activate" )
+            # TODO: check this worked
+            time.sleep( 10 )  # wait for apps to activate
+            for app in apps:
+                state = main.CLIs[ 0 ].appStatus( app )
+                if state == "ACTIVE":
+                    activateResult = activateResult and True
+                else:
+                    main.log.error( "{} is in {} state".format( app, state ) )
+                    activateResult = False
+            utilities.assert_equals( expect=True,
+                                     actual=activateResult,
+                                     onpass="Successfully activated apps",
+                                     onfail="Failed to activate apps" )
+        else:
+            main.log.warn( "No apps were specified to be loaded after startup" )
+
+        main.step( "Set ONOS configurations" )
+        config = main.params.get( 'ONOS_Configuration' )
+        if config:
+            main.log.debug( config )
+            checkResult = main.TRUE
+            for component in config:
+                for setting in config[ component ]:
+                    value = config[ component ][ setting ]
+                    check = main.CLIs[ 0 ].setCfg( component, setting, value )
+                    main.log.info( "Value was changed? {}".format( main.TRUE == check ) )
+                    checkResult = check and checkResult
+            utilities.assert_equals( expect=main.TRUE,
+                                     actual=checkResult,
+                                     onpass="Successfully set config",
+                                     onfail="Failed to set config" )
+        else:
+            main.log.warn( "No configurations were specified to be changed after startup" )
+
+        main.step( "App Ids check" )
+        appCheck = main.TRUE
+        threads = []
+        for i in main.activeNodes:
+            t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
+                             name="appToIDCheck-" + str( i ),
+                             args=[] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            appCheck = appCheck and t.result
+        if appCheck != main.TRUE:
+            node = main.activeNodes[ 0 ]
+            main.log.warn( main.CLIs[ node ].apps() )
+            main.log.warn( main.CLIs[ node ].appIDs() )
+        utilities.assert_equals( expect=main.TRUE, actual=appCheck,
+                                 onpass="App Ids seem to be correct",
+                                 onfail="Something is wrong with app Ids" )
 
     def workQueueStatsCheck( self, workQueueName, completed, inProgress, pending ):
         # Completed
@@ -222,7 +464,1245 @@
                 workQueueName, pending, pendingValues ) )
         return completedResult and inProgressResult and pendingResult
 
-    def CASE17( self, main ):
+    def assignDevices( self, main ):
+        """
+        Assign devices to controllers
+        """
+        import re
+        assert main.numCtrls, "main.numCtrls not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert main.CLIs, "main.CLIs not defined"
+        assert main.nodes, "main.nodes not defined"
+
+        main.case( "Assigning devices to controllers" )
+        main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " + \
+                               "and check that an ONOS node becomes the " + \
+                               "master of the device."
+        main.step( "Assign switches to controllers" )
+
+        ipList = []
+        for i in range( main.ONOSbench.maxNodes ):
+            ipList.append( main.nodes[ i ].ip_address )
+        swList = []
+        for i in range( 1, 29 ):
+            swList.append( "s" + str( i ) )
+        main.Mininet1.assignSwController( sw=swList, ip=ipList )
+
+        mastershipCheck = main.TRUE
+        for i in range( 1, 29 ):
+            response = main.Mininet1.getSwController( "s" + str( i ) )
+            try:
+                main.log.info( str( response ) )
+            except Exception:
+                main.log.info( repr( response ) )
+            for node in main.nodes:
+                if re.search( "tcp:" + node.ip_address, response ):
+                    mastershipCheck = mastershipCheck and main.TRUE
+                else:
+                    main.log.error( "Error, node " + node.ip_address + " is " +
+                                    "not in the list of controllers s" +
+                                    str( i ) + " is connecting to." )
+                    mastershipCheck = main.FALSE
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=mastershipCheck,
+            onpass="Switch mastership assigned correctly",
+            onfail="Switches not assigned correctly to controllers" )
+    def assignIntents( self, main ):
+        """
+        Assign intents
+        """
+        import time
+        import json
+        assert main.numCtrls, "main.numCtrls not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert main.CLIs, "main.CLIs not defined"
+        assert main.nodes, "main.nodes not defined"
+        try:
+            main.HAlabels
+        except ( NameError, AttributeError ):
+            main.log.error( "main.HAlabels not defined, setting to []" )
+            main.HAlabels = []
+        try:
+            main.HAdata
+        except ( NameError, AttributeError ):
+            main.log.error( "data not defined, setting to []" )
+            main.HAdata = []
+        main.case( "Adding host Intents" )
+        main.caseExplanation = "Discover hosts by using pingall then " +\
+                                "assign predetermined host-to-host intents." +\
+                                " After installation, check that the intent" +\
+                                " is distributed to all nodes and the state" +\
+                                " is INSTALLED"
+
+        # install onos-app-fwd
+        main.step( "Install reactive forwarding app" )
+        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
+        installResults = onosCli.activateApp( "org.onosproject.fwd" )
+        utilities.assert_equals( expect=main.TRUE, actual=installResults,
+                                 onpass="Install fwd successful",
+                                 onfail="Install fwd failed" )
+
+        main.step( "Check app ids" )
+        appCheck = main.TRUE
+        threads = []
+        for i in main.activeNodes:
+            t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
+                             name="appToIDCheck-" + str( i ),
+                             args=[] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            appCheck = appCheck and t.result
+        if appCheck != main.TRUE:
+            main.log.warn( onosCli.apps() )
+            main.log.warn( onosCli.appIDs() )
+        utilities.assert_equals( expect=main.TRUE, actual=appCheck,
+                                 onpass="App Ids seem to be correct",
+                                 onfail="Something is wrong with app Ids" )
+
+        main.step( "Discovering Hosts( Via pingall for now )" )
+        # FIXME: Once we have a host discovery mechanism, use that instead
+        # REACTIVE FWD test
+        pingResult = main.FALSE
+        passMsg = "Reactive Pingall test passed"
+        time1 = time.time()
+        pingResult = main.Mininet1.pingall()
+        time2 = time.time()
+        if not pingResult:
+            main.log.warn( "First pingall failed. Trying again..." )
+            pingResult = main.Mininet1.pingall()
+            passMsg += " on the second try"
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=pingResult,
+            onpass=passMsg,
+            onfail="Reactive Pingall failed, " +
+                   "one or more ping pairs failed" )
+        main.log.info( "Time for pingall: %2f seconds" %
+                       ( time2 - time1 ) )
+        # timeout for fwd flows
+        time.sleep( 11 )
+        # uninstall onos-app-fwd
+        main.step( "Uninstall reactive forwarding app" )
+        node = main.activeNodes[ 0 ]
+        uninstallResult = main.CLIs[ node ].deactivateApp( "org.onosproject.fwd" )
+        utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
+                                 onpass="Uninstall fwd successful",
+                                 onfail="Uninstall fwd failed" )
+
+        main.step( "Check app ids" )
+        threads = []
+        appCheck2 = main.TRUE
+        for i in main.activeNodes:
+            t = main.Thread( target=main.CLIs[ i ].appToIDCheck,
+                             name="appToIDCheck-" + str( i ),
+                             args=[] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            appCheck2 = appCheck2 and t.result
+        if appCheck2 != main.TRUE:
+            node = main.activeNodes[ 0 ]
+            main.log.warn( main.CLIs[ node ].apps() )
+            main.log.warn( main.CLIs[ node ].appIDs() )
+        utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
+                                 onpass="App Ids seem to be correct",
+                                 onfail="Something is wrong with app Ids" )
+
+        main.step( "Add host intents via cli" )
+        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 ) )
+            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 = onosCli.getHost( host1 )
+            host2Dict = onosCli.getHost( host2 )
+            host1Id = None
+            host2Id = None
+            if host1Dict and host2Dict:
+                host1Id = host1Dict.get( 'id', None )
+                host2Id = host2Dict.get( 'id', None )
+            if host1Id and host2Id:
+                nodeNum = ( i % len( main.activeNodes ) )
+                node = main.activeNodes[ nodeNum ]
+                tmpId = main.CLIs[ node ].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 for h" + str( i ) +
+                                " and/or h" + str( i + 10 ) )
+                node = main.activeNodes[ 0 ]
+                hosts = main.CLIs[ node ].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
+        utilities.assert_equals( expect=main.TRUE, actual=hostResult,
+                                 onpass="Found a host id for each host",
+                                 onfail="Error looking up host ids" )
+
+        intentStart = time.time()
+        onosIds = onosCli.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
+        if intentAddResult:
+            intentStop = time.time()
+        else:
+            intentStop = None
+        # Print the intent states
+        intents = onosCli.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 = onosCli.leaders()
+        try:
+            missing = False
+            if leaders:
+                parsedLeaders = json.loads( leaders )
+                main.log.warn( json.dumps( parsedLeaders,
+                                           sort_keys=True,
+                                           indent=4,
+                                           separators=( ',', ': ' ) ) )
+                # check for all intent partitions
+                topics = []
+                for i in range( 14 ):
+                    topics.append( "work-partition-" + str( i ) )
+                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" )
+                        missing = True
+            else:
+                main.log.error( "leaders() returned None" )
+        except ( ValueError, TypeError ):
+            main.log.exception( "Error parsing leaders" )
+            main.log.error( repr( leaders ) )
+        # Check all nodes
+        if missing:
+            for i in main.activeNodes:
+                response = main.CLIs[ i ].leaders( jsonFormat=False )
+                main.log.warn( str( main.CLIs[ i ].name ) + " leaders output: \n" +
+                               str( response ) )
+
+        partitions = onosCli.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 = onosCli.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( intentAddResult and not missingIntents and
+                                installedCheck )
+        if not intentAddResult:
+            main.log.error( "Error in pushing host intents to ONOS" )
+
+        main.step( "Intent Anti-Entropy dispersion" )
+        for j in range( 100 ):
+            correct = True
+            main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
+            for i in main.activeNodes:
+                onosIds = []
+                ids = main.CLIs[ i ].getAllIntentsId()
+                onosIds.append( ids )
+                main.log.debug( "Intents in " + main.CLIs[ i ].name + ": " +
+                                str( sorted( onosIds ) ) )
+                if sorted( ids ) != sorted( intentIds ):
+                    main.log.warn( "Set of intent IDs doesn't match" )
+                    correct = False
+                    break
+                else:
+                    intents = json.loads( main.CLIs[ i ].intents() )
+                    for intent in intents:
+                        if intent[ 'state' ] != "INSTALLED":
+                            main.log.warn( "Intent " + intent[ 'id' ] +
+                                           " is " + intent[ 'state' ] )
+                            correct = False
+                            break
+            if correct:
+                break
+            else:
+                time.sleep( 1 )
+        if not intentStop:
+            intentStop = time.time()
+        global gossipTime
+        gossipTime = intentStop - intentStart
+        main.log.info( "It took about " + str( gossipTime ) +
+                        " seconds for all intents to appear in each node" )
+        append = False
+        title = "Gossip Intents"
+        count = 1
+        while append is False:
+            curTitle = title + str( count )
+            if curTitle not in main.HAlabels:
+                main.HAlabels.append( curTitle )
+                main.HAdata.append( str( gossipTime ) )
+                append = True
+            else:
+                count += 1
+        gossipPeriod = int( main.params[ 'timers' ][ 'gossip' ] )
+        maxGossipTime = gossipPeriod * len( main.activeNodes )
+        utilities.assert_greater_equals(
+                expect=maxGossipTime, actual=gossipTime,
+                onpass="ECM anti-entropy for intents worked within " +
+                       "expected time",
+                onfail="Intent ECM anti-entropy took too long. " +
+                       "Expected time:{}, Actual time:{}".format( maxGossipTime,
+                                                                  gossipTime ) )
+        if gossipTime <= maxGossipTime:
+            intentAddResult = True
+
+        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 = onosCli.getAllIntentsId()
+            main.log.info( "Submitted intents: " + str( intentIds ) )
+            main.log.info( "Intents in ONOS: " + str( onosIds ) )
+            # Print the intent states
+            intents = onosCli.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 = onosCli.leaders()
+            try:
+                missing = False
+                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( "work-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" )
+                            missing = True
+                else:
+                    main.log.error( "leaders() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing leaders" )
+                main.log.error( repr( leaders ) )
+            # Check all nodes
+            if missing:
+                for i in main.activeNodes:
+                    node = main.CLIs[ i ]
+                    response = node.leaders( jsonFormat=False )
+                    main.log.warn( str( node.name ) + " leaders output: \n" +
+                                   str( response ) )
+
+            partitions = onosCli.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 = onosCli.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 pingAcrossHostIntent( self, main, multiIntentCheck, activateNode ):
+        """
+        Ping across added host intents
+        """
+        import json
+        import time
+        assert main.numCtrls, "main.numCtrls not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert main.CLIs, "main.CLIs not defined"
+        assert main.nodes, "main.nodes not defined"
+        main.case( "Verify connectivity by sending traffic across Intents" )
+        main.caseExplanation = "Ping across added host intents to check " +\
+                                "functionality and check the state of " +\
+                                "the intent"
+
+        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
+        main.step( "Check Intent state" )
+        installedCheck = False
+        loopCount = 0
+        while not installedCheck and loopCount < 40:
+            installedCheck = True
+            # Print the intent states
+            intents = onosCli.intents() if multiIntentCheck else 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." )
+            # Print states
+            intentStates.sort()
+            for i, s in intentStates:
+                count += 1
+                main.log.info( "%-6s%-15s%-15s" %
+                               ( str( count ), str( i ), str( s ) ) )
+            if not multiIntentCheck:
+                break
+            if not installedCheck:
+                time.sleep( 1 )
+                loopCount += 1
+        utilities.assert_equals( expect=True, actual=installedCheck,
+                                 onpass="Intents are all INSTALLED",
+                                 onfail="Intents are not all in " +
+                                        "INSTALLED state" )
+
+        main.step( "Ping across added host intents" )
+        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.error(
+                "Intents have not been installed correctly, pings failed." )
+            # TODO: pretty print
+            main.log.warn( "ONOS1 intents: " )
+            try:
+                tmpIntents = onosCli.intents()
+                main.log.warn( json.dumps( json.loads( tmpIntents ),
+                                           sort_keys=True,
+                                           indent=4,
+                                           separators=( ',', ': ' ) ) )
+            except ( ValueError, TypeError ):
+                main.log.warn( repr( tmpIntents ) )
+        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." )
+
+        main.step( "Check leadership of topics" )
+        leaders = onosCli.leaders()
+        topicCheck = main.TRUE
+        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
+                # TODO: Look at Devices as topics now that it uses this system
+                topics = []
+                for i in range( 14 ):
+                    topics.append( "work-partition-" + str( i ) )
+                # FIXME: this should only be after we start the app
+                # FIXME: topics.append( "org.onosproject.election" )
+                # Print leaders output
+                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" )
+                        topicCheck = main.FALSE
+            else:
+                main.log.error( "leaders() returned None" )
+                topicCheck = main.FALSE
+        except ( ValueError, TypeError ):
+            topicCheck = main.FALSE
+            main.log.exception( "Error parsing leaders" )
+            main.log.error( repr( leaders ) )
+            # TODO: Check for a leader of these topics
+        # Check all nodes
+        if topicCheck:
+            for i in main.activeNodes:
+                node = main.CLIs[ i ]
+                response = node.leaders( jsonFormat=False )
+                main.log.warn( str( node.name ) + " leaders output: \n" +
+                               str( response ) )
+
+        utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
+                                 onpass="intent Partitions is in leaders",
+                                 onfail="Some topics were lost " )
+        # Print partitions
+        partitions = onosCli.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 ) )
+        # Print Pending Map
+        pendingMap = onosCli.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 = onosCli.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 = onosCli.leaders()
+            try:
+                missing = False
+                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( "work-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" )
+                            missing = True
+                else:
+                    main.log.error( "leaders() returned None" )
+            except ( ValueError, TypeError ):
+                main.log.exception( "Error parsing leaders" )
+                main.log.error( repr( leaders ) )
+            if missing:
+                for i in main.activeNodes:
+                    node = main.CLIs[ i ]
+                    response = node.leaders( jsonFormat=False )
+                    main.log.warn( str( node.name ) + " leaders output: \n" +
+                                   str( response ) )
+
+            partitions = onosCli.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 = onosCli.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 ) )
+        # Print flowrules
+        main.log.debug( main.CLIs[ main.activeNodes[0] ].flows( jsonFormat=False ) if activateNode else onosCli.flows( jsonFormat=False ) )
+        main.step( "Wait a minute then ping again" )
+        # the wait is above
+        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.error(
+                "Intents have not been installed correctly, pings failed." )
+            # TODO: pretty print
+            main.log.warn( "ONOS1 intents: " )
+            try:
+                tmpIntents = onosCli.intents()
+                main.log.warn( json.dumps( json.loads( tmpIntents ),
+                                           sort_keys=True,
+                                           indent=4,
+                                           separators=( ',', ': ' ) ) )
+            except ( ValueError, TypeError ):
+                main.log.warn( repr( tmpIntents ) )
+        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 readingState( self, main ):
+        """
+        Reading state of ONOS
+        """
+        import json
+        import time
+        assert main.numCtrls, "main.numCtrls not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert main.CLIs, "main.CLIs not defined"
+        assert main.nodes, "main.nodes not defined"
+        try:
+            from tests.dependencies.topology import Topology
+        except ImportError:
+            main.log.error( "Topology not found exiting the test" )
+            main.exit()
+        try:
+            main.topoRelated
+        except ( NameError, AttributeError ):
+            main.topoRelated = Topology()
+        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 each other and also with past states
+
+        main.step( "Check that each switch has a master" )
+        global mastershipState
+        mastershipState = '[]'
+
+        # Assert that each device has a master
+        rolesNotNull = main.TRUE
+        threads = []
+        for i in main.activeNodes:
+            t = main.Thread( target=main.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( "Get the Mastership of each switch from each controller" )
+        ONOSMastership = []
+        consistentMastership = True
+        rolesResults = True
+        threads = []
+        for i in main.activeNodes:
+            t = main.Thread( target=main.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( len( ONOSMastership ) ):
+            node = str( main.activeNodes[ i ] + 1 )
+            if not ONOSMastership[ i ] or "Error" in ONOSMastership[ i ]:
+                main.log.error( "Error in getting ONOS" + node + " roles" )
+                main.log.warn( "ONOS" + node + " 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.info(
+                "Switch roles are consistent across all ONOS nodes" )
+        else:
+            consistentMastership = False
+        utilities.assert_equals(
+            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( len( main.activeNodes ) ):
+                node = str( main.activeNodes[ i ] + 1 )
+                try:
+                    main.log.warn(
+                        "ONOS" + node + " 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:
+            mastershipState = ONOSMastership[ 0 ]
+
+        main.step( "Get the intents from each controller" )
+        global intentState
+        intentState = []
+        ONOSIntents = []
+        consistentIntents = True  # Are Intents consistent across nodes?
+        intentsResults = True  # Could we read Intents from ONOS?
+        threads = []
+        for i in main.activeNodes:
+            t = main.Thread( target=main.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( len( ONOSIntents ) ):
+            node = str( main.activeNodes[ i ] + 1 )
+            if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
+                main.log.error( "Error in getting ONOS" + node + " intents" )
+                main.log.warn( "ONOS" + node + " 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.info( "Intents are consistent across all ONOS " +
+                             "nodes" )
+        else:
+            consistentIntents = False
+            main.log.error( "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:
+            # Try to make it easy to figure out what is happening
+            #
+            # Intent      ONOS1      ONOS2    ...
+            #  0x01     INSTALLED  INSTALLING
+            #  ...        ...         ...
+            #  ...        ...         ...
+            title = "   Id"
+            for n in main.activeNodes:
+                title += " " * 10 + "ONOS" + str( n + 1 )
+            main.log.warn( title )
+            # get all intent keys in the cluster
+            keys = []
+            try:
+                # Get the set of all intent keys
+                for nodeStr in ONOSIntents:
+                    node = json.loads( nodeStr )
+                    for intent in node:
+                        keys.append( intent.get( 'id' ) )
+                keys = set( keys )
+                # For each intent key, print the state on each node
+                for key in keys:
+                    row = "%-13s" % key
+                    for nodeStr in ONOSIntents:
+                        node = json.loads( nodeStr )
+                        for intent in node:
+                            if intent.get( 'id', "Error" ) == key:
+                                row += "%-15s" % intent.get( 'state' )
+                    main.log.warn( row )
+                # End of intent state table
+            except ValueError as e:
+                main.log.exception( e )
+                main.log.debug( "nodeStr was: " + repr( nodeStr ) )
+
+        if intentsResults and not consistentIntents:
+            # print the json objects
+            n = str( main.activeNodes[ -1 ] + 1 )
+            main.log.debug( "ONOS" + n + " intents: " )
+            main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
+                                        sort_keys=True,
+                                        indent=4,
+                                        separators=( ',', ': ' ) ) )
+            for i in range( len( ONOSIntents ) ):
+                node = str( main.activeNodes[ i ] + 1 )
+                if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
+                    main.log.debug( "ONOS" + node + " intents: " )
+                    main.log.debug( json.dumps( json.loads( ONOSIntents[ i ] ),
+                                                sort_keys=True,
+                                                indent=4,
+                                                separators=( ',', ': ' ) ) )
+                else:
+                    main.log.debug( "ONOS" + node + " intents match ONOS" +
+                                    n + " intents" )
+        elif intentsResults and consistentIntents:
+            intentState = ONOSIntents[ 0 ]
+
+        main.step( "Get the flows from each controller" )
+        global flowState
+        flowState = []
+        ONOSFlows = []
+        ONOSFlowsJson = []
+        flowCheck = main.FALSE
+        consistentFlows = True
+        flowsResults = True
+        threads = []
+        for i in main.activeNodes:
+            t = main.Thread( target=main.CLIs[ i ].flows,
+                             name="flows-" + str( i ),
+                             args=[],
+                             kwargs={ 'jsonFormat': True } )
+            threads.append( t )
+            t.start()
+
+        # NOTE: Flows command can take some time to run
+        time.sleep( 30 )
+        for t in threads:
+            t.join()
+            result = t.result
+            ONOSFlows.append( result )
+
+        for i in range( len( ONOSFlows ) ):
+            num = str( main.activeNodes[ i ] + 1 )
+            if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
+                main.log.error( "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.info( "Flow count is consistent across all ONOS nodes" )
+        else:
+            consistentFlows = False
+        utilities.assert_equals(
+            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( len( ONOSFlows ) ):
+                node = str( main.activeNodes[ i ] + 1 )
+                try:
+                    main.log.warn(
+                        "ONOS" + node + " flows: " +
+                        json.dumps( json.loads( ONOSFlows[ i ] ), sort_keys=True,
+                                    indent=4, separators=( ',', ': ' ) ) )
+                except ( ValueError, TypeError ):
+                    main.log.warn( "ONOS" + node + " 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.Mininet1.getFlowTable( "s" + str( i ), version="1.3", debug=False ) )
+        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" )
+        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( "Collecting topology information from ONOS" )
+        devices = main.topoRelated.getAllDevices( main.activeNodes, False )
+        hosts = main.topoRelated.getAllHosts( main.activeNodes, False, inJson=True )
+        ports = main.topoRelated.getAllPorts( main.activeNodes, False )
+        links = main.topoRelated.getAllLinks( main.activeNodes, False )
+        clusters = main.topoRelated.getAllClusters( main.activeNodes, False )
+        # Compare json objects for hosts and dataplane clusters
+
+        # hosts
+        main.step( "Host view is consistent across ONOS nodes" )
+        consistentHostsResult = main.TRUE
+        for controller in range( len( hosts ) ):
+            controllerStr = str( main.activeNodes[ controller ] + 1 )
+            if hosts[ controller ] and "Error" not in hosts[ controller ]:
+                if hosts[ controller ] == hosts[ 0 ]:
+                    continue
+                else:  # hosts not consistent
+                    main.log.error( "hosts from ONOS" +
+                                     controllerStr +
+                                     " is inconsistent with ONOS1" )
+                    main.log.warn( repr( hosts[ controller ] ) )
+                    consistentHostsResult = main.FALSE
+
+            else:
+                main.log.error( "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" )
+
+        main.step( "Each host has an IP address" )
+        ipResult = main.TRUE
+        for controller in range( 0, len( hosts ) ):
+            controllerStr = str( main.activeNodes[ controller ] + 1 )
+            if hosts[ controller ]:
+                for host in hosts[ controller ]:
+                    if not host.get( 'ipAddresses', [] ):
+                        main.log.error( "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
+        main.step( "Cluster view is consistent across ONOS nodes" )
+        consistentClustersResult = main.TRUE
+        for controller in range( len( clusters ) ):
+            controllerStr = str( main.activeNodes[ controller ] + 1 )
+            if "Error" not in clusters[ controller ]:
+                if clusters[ controller ] == clusters[ 0 ]:
+                    continue
+                else:  # clusters not consistent
+                    main.log.error( "clusters from ONOS" + controllerStr +
+                                     " is inconsistent with ONOS1" )
+                    consistentClustersResult = main.FALSE
+
+            else:
+                main.log.error( "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" )
+        if not consistentClustersResult:
+            main.log.debug( clusters )
+
+        # there should always only be one cluster
+        main.step( "Cluster view correct across ONOS nodes" )
+        try:
+            numClusters = len( json.loads( clusters[ 0 ] ) )
+        except ( ValueError, TypeError ):
+            main.log.exception( "Error parsing clusters[0]: " +
+                                repr( clusters[ 0 ] ) )
+            numClusters = "ERROR"
+        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
+        linksResults = main.TRUE
+        hostsResults = main.TRUE
+        mnSwitches = main.Mininet1.getSwitches()
+        mnLinks = main.Mininet1.getLinks()
+        mnHosts = main.Mininet1.getHosts()
+        for controller in main.activeNodes:
+            controllerStr = str( main.activeNodes[ controller ] + 1 )
+            currentDevicesResult = main.topoRelated.compareDevicePort(
+                                                main.Mininet1, controller,
+                                                mnSwitches, devices, ports )
+            utilities.assert_equals( expect=main.TRUE,
+                                     actual=currentDevicesResult,
+                                     onpass="ONOS" + controllerStr +
+                                     " Switches view is correct",
+                                     onfail="ONOS" + controllerStr +
+                                     " Switches view is incorrect" )
+
+            currentLinksResult = main.topoRelated.compareBase( links, controller,
+                                                                   main.Mininet1.compareLinks,
+                                                                   [ mnSwitches, mnLinks ] )
+            utilities.assert_equals( expect=main.TRUE,
+                                     actual=currentLinksResult,
+                                     onpass="ONOS" + controllerStr +
+                                     " links view is correct",
+                                     onfail="ONOS" + controllerStr +
+                                     " links view is incorrect" )
+
+            if hosts[ controller ] and "Error" not in hosts[ controller ]:
+                currentHostsResult = main.Mininet1.compareHosts(
+                        mnHosts,
+                        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
+            linksResults = linksResults and currentLinksResult
+            hostsResults = hostsResults and currentHostsResult
+
+        main.step( "Device information is correct" )
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=devicesResults,
+            onpass="Device information is correct",
+            onfail="Device information is incorrect" )
+
+        main.step( "Links are correct" )
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=linksResults,
+            onpass="Link are correct",
+            onfail="Links are incorrect" )
+
+        main.step( "Hosts are correct" )
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=hostsResults,
+            onpass="Hosts are correct",
+            onfail="Hosts are incorrect" )
+
+    def checkDistPrimitivesFunc( self, main ):
         """
         Check for basic functionality with distributed primitives
         """
@@ -238,12 +1718,12 @@
             # NOTE: assert fails if value is 0/None/Empty/False
             try:
                 main.pCounterValue
-            except NameError:
+            except ( NameError, AttributeError ):
                 main.log.error( "main.pCounterValue not defined, setting to 0" )
                 main.pCounterValue = 0
             try:
                 main.onosSet
-            except NameError:
+            except ( NameError, AttributeError ):
                 main.log.error( "main.onosSet not defined, setting to empty Set" )
                 main.onosSet = set( [] )
             # Variables for the distributed primitives tests. These are local only
@@ -325,7 +1805,7 @@
                                             " counter" )
 
             main.step( "Counters we added have the correct values" )
-            incrementCheck = main.HA.counterCheck( main.pCounterName, main.pCounterValue )
+            incrementCheck = self.counterCheck( main.pCounterName, main.pCounterValue )
             utilities.assert_equals( expect=main.TRUE,
                                      actual=incrementCheck,
                                      onpass="Added counters are correct",
@@ -425,7 +1905,7 @@
                                             " counter" )
 
             main.step( "Counters we added have the correct values" )
-            incrementCheck = main.HA.counterCheck( main.pCounterName, main.pCounterValue )
+            incrementCheck = self.counterCheck( main.pCounterName, main.pCounterValue )
             utilities.assert_equals( expect=main.TRUE,
                                      actual=incrementCheck,
                                      onpass="Added counters are correct",
@@ -1708,3 +3188,1342 @@
                                      onfail="Work Queue stats incorrect " )
         except Exception as e:
             main.log.error( "Exception: " + str( e ) )
+
+    def cleanUp( self, main ):
+        """
+        Clean up
+        """
+        import os
+        import time
+        assert main.numCtrls, "main.numCtrls not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert main.CLIs, "main.CLIs not defined"
+        assert main.nodes, "main.nodes not defined"
+
+        # printing colors to terminal
+        colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
+                   'blue': '\033[94m', 'green': '\033[92m',
+                   'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
+        main.case( "Test Cleanup" )
+        main.step( "Killing tcpdumps" )
+        main.Mininet2.stopTcpdump()
+
+        testname = main.TEST
+        if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
+            main.step( "Copying MN pcap and ONOS log files to test station" )
+            teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
+            teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
+            # NOTE: MN Pcap file is being saved to logdir.
+            #       We scp this file as MN and TestON aren't necessarily the same vm
+
+            # FIXME: To be replaced with a Jenkin's post script
+            # TODO: Load these from params
+            # NOTE: must end in /
+            logFolder = "/opt/onos/log/"
+            logFiles = [ "karaf.log", "karaf.log.1" ]
+            # NOTE: must end in /
+            for f in logFiles:
+                for node in main.nodes:
+                    dstName = main.logdir + "/" + node.name + "-" + f
+                    main.ONOSbench.secureCopy( node.user_name, node.ip_address,
+                                               logFolder + f, dstName )
+            # std*.log's
+            # NOTE: must end in /
+            logFolder = "/opt/onos/var/"
+            logFiles = [ "stderr.log", "stdout.log" ]
+            # NOTE: must end in /
+            for f in logFiles:
+                for node in main.nodes:
+                    dstName = main.logdir + "/" + node.name + "-" + f
+                    main.ONOSbench.secureCopy( node.user_name, node.ip_address,
+                                               logFolder + f, dstName )
+        else:
+            main.log.debug( "skipping saving log files" )
+
+        main.step( "Stopping Mininet" )
+        mnResult = main.Mininet1.stopNet()
+        utilities.assert_equals( expect=main.TRUE, actual=mnResult,
+                                 onpass="Mininet stopped",
+                                 onfail="MN cleanup NOT successful" )
+
+        main.step( "Checking ONOS Logs for errors" )
+        for node in main.nodes:
+            main.log.debug( "Checking logs for errors on " + node.name + ":" )
+            main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
+
+        try:
+            timerLog = open( main.logdir + "/Timers.csv", 'w' )
+            main.log.debug( ", ".join( main.HAlabels ) + "\n" + ", ".join( main.HAdata ) )
+            timerLog.write( ", ".join( main.HAlabels ) + "\n" + ", ".join( main.HAdata ) )
+            timerLog.close()
+        except NameError as e:
+            main.log.exception( e )
+    def assignMastership( self, main ):
+        """
+        Assign mastership to controllers
+        """
+        import time
+        assert main.numCtrls, "main.numCtrls not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert main.CLIs, "main.CLIs not defined"
+        assert main.nodes, "main.nodes not defined"
+
+        main.case( "Assigning Controller roles for switches" )
+        main.caseExplanation = "Check that ONOS is connected to each " +\
+                                "device. Then manually assign" +\
+                                " mastership to specific ONOS nodes using" +\
+                                " 'device-role'"
+        main.step( "Assign mastership of switches to specific controllers" )
+        # Manually assign mastership to the controller we want
+        roleCall = main.TRUE
+
+        ipList = []
+        deviceList = []
+        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
+        try:
+            # Assign mastership to specific controllers. This assignment was
+            # determined for a 7 node cluser, but will work with any sized
+            # cluster
+            for i in range( 1, 29 ):  # switches 1 through 28
+                # set up correct variables:
+                if i == 1:
+                    c = 0
+                    ip = main.nodes[ c ].ip_address  # ONOS1
+                    deviceId = onosCli.getDevice( "1000" ).get( 'id' )
+                elif i == 2:
+                    c = 1 % main.numCtrls
+                    ip = main.nodes[ c ].ip_address  # ONOS2
+                    deviceId = onosCli.getDevice( "2000" ).get( 'id' )
+                elif i == 3:
+                    c = 1 % main.numCtrls
+                    ip = main.nodes[ c ].ip_address  # ONOS2
+                    deviceId = onosCli.getDevice( "3000" ).get( 'id' )
+                elif i == 4:
+                    c = 3 % main.numCtrls
+                    ip = main.nodes[ c ].ip_address  # ONOS4
+                    deviceId = onosCli.getDevice( "3004" ).get( 'id' )
+                elif i == 5:
+                    c = 2 % main.numCtrls
+                    ip = main.nodes[ c ].ip_address  # ONOS3
+                    deviceId = onosCli.getDevice( "5000" ).get( 'id' )
+                elif i == 6:
+                    c = 2 % main.numCtrls
+                    ip = main.nodes[ c ].ip_address  # ONOS3
+                    deviceId = onosCli.getDevice( "6000" ).get( 'id' )
+                elif i == 7:
+                    c = 5 % main.numCtrls
+                    ip = main.nodes[ c ].ip_address  # ONOS6
+                    deviceId = onosCli.getDevice( "6007" ).get( 'id' )
+                elif i >= 8 and i <= 17:
+                    c = 4 % main.numCtrls
+                    ip = main.nodes[ c ].ip_address  # ONOS5
+                    dpid = '3' + str( i ).zfill( 3 )
+                    deviceId = onosCli.getDevice( dpid ).get( 'id' )
+                elif i >= 18 and i <= 27:
+                    c = 6 % main.numCtrls
+                    ip = main.nodes[ c ].ip_address  # ONOS7
+                    dpid = '6' + str( i ).zfill( 3 )
+                    deviceId = onosCli.getDevice( dpid ).get( 'id' )
+                elif i == 28:
+                    c = 0
+                    ip = main.nodes[ c ].ip_address  # ONOS1
+                    deviceId = onosCli.getDevice( "2800" ).get( 'id' )
+                else:
+                    main.log.error( "You didn't write an else statement for " +
+                                    "switch s" + str( i ) )
+                    roleCall = main.FALSE
+                # Assign switch
+                assert deviceId, "No device id for s" + str( i ) + " in ONOS"
+                # TODO: make this controller dynamic
+                roleCall = roleCall and onosCli.deviceRole( deviceId, ip )
+                ipList.append( ip )
+                deviceList.append( deviceId )
+        except ( AttributeError, AssertionError ):
+            main.log.exception( "Something is wrong with ONOS device view" )
+            main.log.info( onosCli.devices() )
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=roleCall,
+            onpass="Re-assigned switch mastership to designated controller",
+            onfail="Something wrong with deviceRole calls" )
+
+        main.step( "Check mastership was correctly assigned" )
+        roleCheck = main.TRUE
+        # NOTE: This is due to the fact that device mastership change is not
+        #       atomic and is actually a multi step process
+        time.sleep( 5 )
+        for i in range( len( ipList ) ):
+            ip = ipList[ i ]
+            deviceId = deviceList[ i ]
+            # Check assignment
+            master = onosCli.getRole( deviceId ).get( 'master' )
+            if ip in master:
+                roleCheck = roleCheck and main.TRUE
+            else:
+                roleCheck = roleCheck and main.FALSE
+                main.log.error( "Error, controller " + ip + " is not" +
+                                " master " + "of device " +
+                                str( deviceId ) + ". Master is " +
+                                repr( master ) + "." )
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=roleCheck,
+            onpass="Switches were successfully reassigned to designated " +
+                   "controller",
+            onfail="Switches were not successfully reassigned" )
+    def bringUpStoppedNode( self, main ):
+        """
+        The bring up stopped nodes
+        """
+        import time
+        assert main.numCtrls, "main.numCtrls not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert main.CLIs, "main.CLIs not defined"
+        assert main.nodes, "main.nodes not defined"
+        assert main.kill, "main.kill not defined"
+        main.case( "Restart minority of ONOS nodes" )
+
+        main.step( "Restarting " + str( len( main.kill ) ) + " ONOS nodes" )
+        startResults = main.TRUE
+        restartTime = time.time()
+        for i in main.kill:
+            startResults = startResults and\
+                           main.ONOSbench.onosStart( main.nodes[ i ].ip_address )
+        utilities.assert_equals( expect=main.TRUE, actual=startResults,
+                                 onpass="ONOS nodes started successfully",
+                                 onfail="ONOS nodes NOT successfully started" )
+
+        main.step( "Checking if ONOS is up yet" )
+        count = 0
+        onosIsupResult = main.FALSE
+        while onosIsupResult == main.FALSE and count < 10:
+            onosIsupResult = main.TRUE
+            for i in main.kill:
+                onosIsupResult = onosIsupResult and\
+                                 main.ONOSbench.isup( main.nodes[ i ].ip_address )
+            count = count + 1
+        utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
+                                 onpass="ONOS restarted successfully",
+                                 onfail="ONOS restart NOT successful" )
+
+        main.step( "Restarting ONOS main.CLIs" )
+        cliResults = main.TRUE
+        for i in main.kill:
+            cliResults = cliResults and\
+                         main.CLIs[ i ].startOnosCli( main.nodes[ i ].ip_address )
+            main.activeNodes.append( i )
+        utilities.assert_equals( expect=main.TRUE, actual=cliResults,
+                                 onpass="ONOS cli restarted",
+                                 onfail="ONOS cli did not restart" )
+        main.activeNodes.sort()
+        try:
+            assert list( set( main.activeNodes ) ) == main.activeNodes,\
+                   "List of active nodes has duplicates, this likely indicates something was run out of order"
+        except AssertionError:
+            main.log.exception( "" )
+            main.cleanup()
+            main.exit()
+
+        # Grab the time of restart so we chan check how long the gossip
+        # protocol has had time to work
+        main.restartTime = time.time() - restartTime
+        main.log.debug( "Restart time: " + str( main.restartTime ) )
+        # TODO: MAke this configurable. Also, we are breaking the above timer
+        main.step( "Checking ONOS nodes" )
+        nodeResults = utilities.retry( self.nodesCheck,
+                                       False,
+                                       args=[ main.activeNodes ],
+                                       sleep=15,
+                                       attempts=5 )
+
+        utilities.assert_equals( expect=True, actual=nodeResults,
+                                 onpass="Nodes check successful",
+                                 onfail="Nodes check NOT successful" )
+
+        if not nodeResults:
+            for i in main.activeNodes:
+                cli = main.CLIs[ i ]
+                main.log.debug( "{} components not ACTIVE: \n{}".format(
+                    cli.name,
+                    cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
+            main.log.error( "Failed to start ONOS, stopping test" )
+            main.cleanup()
+            main.exit()
+
+        node = main.activeNodes[ 0 ]
+        main.log.debug( main.CLIs[ node ].nodes( jsonFormat=False ) )
+        main.log.debug( main.CLIs[ node ].leaders( jsonFormat=False ) )
+        main.log.debug( main.CLIs[ node ].partitions( jsonFormat=False ) )
+        main.log.debug(main.CLIs[node].apps(jsonFormat=False))
+
+        main.step( "Rerun for election on the node(s) that were killed" )
+        runResults = main.TRUE
+        for i in main.kill:
+            runResults = runResults and\
+                         main.CLIs[ i ].electionTestRun()
+        utilities.assert_equals( expect=main.TRUE, actual=runResults,
+                                 onpass="ONOS nodes reran for election topic",
+                                 onfail="Errror rerunning for election" )
+
+
+    def checkStateAfterONOS( self, main, afterWhich, compareSwitch=False, isRestart=False ):
+        """
+        afterWhich :
+            0: failture
+            1: scaling
+        """
+        """
+        Check state after ONOS failure/scaling
+        """
+        import json
+        assert main.numCtrls, "main.numCtrls not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert main.CLIs, "main.CLIs not defined"
+        assert main.nodes, "main.nodes not defined"
+        main.case( "Running ONOS Constant State Tests" )
+
+        OnosAfterWhich = [ "failure" , "scaliing" ]
+
+        main.step( "Check that each switch has a master" )
+        # Assert that each device has a master
+        rolesNotNull = main.TRUE
+        threads = []
+        for i in main.activeNodes:
+            t = main.Thread( target=main.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( "Read device roles from ONOS" )
+        ONOSMastership = []
+        consistentMastership = True
+        rolesResults = True
+        threads = []
+        for i in main.activeNodes:
+            t = main.Thread( target=main.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( len( ONOSMastership ) ):
+            node = str( main.activeNodes[ i ] + 1 )
+            if not ONOSMastership[ i ] or "Error" in ONOSMastership[ i ]:
+                main.log.error( "Error in getting ONOS" + node + " roles" )
+                main.log.warn( "ONOS" + node + " 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.info(
+                "Switch roles are consistent across all ONOS nodes" )
+        else:
+            consistentMastership = False
+        utilities.assert_equals(
+            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( len( ONOSMastership ) ):
+                node = str( main.activeNodes[ i ] + 1 )
+                main.log.warn( "ONOS" + node + " roles: ",
+                               json.dumps( json.loads( ONOSMastership[ i ] ),
+                                           sort_keys=True,
+                                           indent=4,
+                                           separators=( ',', ': ' ) ) )
+
+        if compareSwitch:
+            description2 = "Compare switch roles from before failure"
+            main.step( description2 )
+            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 ) ) )
+                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
+            utilities.assert_equals(
+                expect=main.TRUE,
+                actual=mastershipCheck,
+                onpass="Mastership of Switches was not changed",
+                onfail="Mastership of some switches changed" )
+
+        # NOTE: we expect mastership to change on controller failure/scaling down
+        main.step( "Get the intents and compare across all nodes" )
+        ONOSIntents = []
+        intentCheck = main.FALSE
+        consistentIntents = True
+        intentsResults = True
+        threads = []
+        for i in main.activeNodes:
+            t = main.Thread( target=main.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( len( ONOSIntents ) ):
+            node = str( main.activeNodes[ i ] + 1 )
+            if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
+                main.log.error( "Error in getting ONOS" + node + " intents" )
+                main.log.warn( "ONOS" + node + " 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.info( "Intents are consistent across all ONOS " +
+                             "nodes" )
+        else:
+            consistentIntents = False
+
+        # Try to make it easy to figure out what is happening
+        #
+        # Intent      ONOS1      ONOS2    ...
+        #  0x01     INSTALLED  INSTALLING
+        #  ...        ...         ...
+        #  ...        ...         ...
+        title = "   ID"
+        for n in main.activeNodes:
+            title += " " * 10 + "ONOS" + str( n + 1 )
+        main.log.warn( title )
+        # get all intent keys in the cluster
+        keys = []
+        for nodeStr in ONOSIntents:
+            node = json.loads( nodeStr )
+            for intent in node:
+                keys.append( intent.get( 'id' ) )
+        keys = set( keys )
+        for key in keys:
+            row = "%-13s" % key
+            for nodeStr in ONOSIntents:
+                node = json.loads( nodeStr )
+                for intent in node:
+                    if intent.get( 'id' ) == key:
+                        row += "%-15s" % intent.get( 'state' )
+            main.log.warn( row )
+        # End table view
+
+        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' ] )
+            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( len( main.activeNodes ) ):
+                node = str( main.activeNodes[ i ] + 1 )
+                main.log.warn( "ONOS" + node + " 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
+        if not isRestart:
+            main.step( "Compare current intents with intents before the " + OnosAfterWhich[ afterWhich ] )
+            # NOTE: this requires case 5 to pass for intentState to be set.
+            #      maybe we should stop the test if that fails?
+            sameIntents = main.FALSE
+            try:
+                intentState
+            except NameError:
+                main.log.warn( "No previous intent state was saved" )
+            else:
+                if intentState and intentState == ONOSIntents[ 0 ]:
+                    sameIntents = main.TRUE
+                    main.log.info( "Intents are consistent with before " + OnosAfterWhich[ afterWhich ] )
+                # TODO: possibly the states have changed? we may need to figure out
+                #       what the acceptable states are
+                elif len( intentState ) == len( ONOSIntents[ 0 ] ):
+                    sameIntents = main.TRUE
+                    try:
+                        before = json.loads( intentState )
+                        after = json.loads( ONOSIntents[ 0 ] )
+                        for intent in before:
+                            if intent not in after:
+                                sameIntents = main.FALSE
+                                main.log.debug( "Intent is not currently in ONOS " +
+                                                "(at least in the same form):" )
+                                main.log.debug( json.dumps( intent ) )
+                    except ( ValueError, TypeError ):
+                        main.log.exception( "Exception printing intents" )
+                        main.log.debug( repr( ONOSIntents[ 0 ] ) )
+                        main.log.debug( repr( intentState ) )
+                if sameIntents == main.FALSE:
+                    try:
+                        main.log.debug( "ONOS intents before: " )
+                        main.log.debug( json.dumps( json.loads( intentState ),
+                                                    sort_keys=True, indent=4,
+                                                    separators=( ',', ': ' ) ) )
+                        main.log.debug( "Current ONOS intents: " )
+                        main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
+                                                    sort_keys=True, indent=4,
+                                                    separators=( ',', ': ' ) ) )
+                    except ( ValueError, TypeError ):
+                        main.log.exception( "Exception printing intents" )
+                        main.log.debug( repr( ONOSIntents[ 0 ] ) )
+                        main.log.debug( repr( intentState ) )
+                utilities.assert_equals(
+                    expect=main.TRUE,
+                    actual=sameIntents,
+                    onpass="Intents are consistent with before " + OnosAfterWhich[ afterWhich ] ,
+                    onfail="The Intents changed during " + OnosAfterWhich[ afterWhich ] )
+            intentCheck = intentCheck and sameIntents
+
+            main.step( "Get the OF Table entries and compare to before " +
+                       "component " + OnosAfterWhich[ afterWhich ] )
+            FlowTables = main.TRUE
+            for i in range( 28 ):
+                main.log.info( "Checking flow table on s" + str( i + 1 ) )
+                tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
+                curSwitch = main.Mininet1.flowTableComp( flows[ i ], tmpFlows )
+                FlowTables = FlowTables and curSwitch
+                if curSwitch == main.FALSE:
+                    main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
+            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.Mininet2.pingLongKill()
+
+        """
+        main.step( "Check the continuous pings to ensure that no packets " +
+                   "were dropped during component failure" )
+        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.info( "No loss of dataplane connectivity" )
+        utilities.assert_equals(
+            expect=main.FALSE,
+            actual=LossInPings,
+            onpass="No Loss of connectivity",
+            onfail="Loss of dataplane connectivity detected" )
+        # NOTE: Since intents are not persisted with IntnentStore,
+        #       we expect loss in dataplane connectivity
+        LossInPings = main.FALSE
+        """
+
+    def compareTopo( self, main ):
+        """
+        Compare topo
+        """
+        import json
+        import time
+        assert main.numCtrls, "main.numCtrls not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert main.CLIs, "main.CLIs not defined"
+        assert main.nodes, "main.nodes not defined"
+        try:
+            from tests.dependencies.topology import Topology
+        except ImportError:
+            main.log.error( "Topology not found exiting the test" )
+            main.exit()
+        try:
+            main.topoRelated
+        except ( NameError, AttributeError ):
+            main.topoRelated = Topology()
+        main.case( "Compare ONOS Topology view to Mininet topology" )
+        main.caseExplanation = "Compare topology objects between Mininet" +\
+                                " and ONOS"
+        topoResult = main.FALSE
+        topoFailMsg = "ONOS topology don't match Mininet"
+        elapsed = 0
+        count = 0
+        main.step( "Comparing ONOS topology to MN topology" )
+        startTime = time.time()
+        # Give time for Gossip to work
+        while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
+            devicesResults = main.TRUE
+            linksResults = main.TRUE
+            hostsResults = main.TRUE
+            hostAttachmentResults = True
+            count += 1
+            cliStart = time.time()
+            devices = main.topoRelated.getAllDevices( main.activeNodes, True,
+                                                       kwargs={ 'sleep': 5, 'attempts': 5,
+                                                                'randomTime': True } )
+            ipResult = main.TRUE
+
+            hosts = main.topoRelated.getAllHosts( main.activeNodes, True,
+                                                    kwargs={ 'sleep': 5, 'attempts': 5,
+                                                                'randomTime': True },
+                                                    inJson=True )
+
+            for controller in range( 0, len( hosts ) ):
+                controllerStr = str( main.activeNodes[ controller ] + 1 )
+                if hosts[ controller ]:
+                    for host in hosts[ controller ]:
+                        if host is None or host.get( 'ipAddresses', [] ) == []:
+                            main.log.error(
+                                "Error with host ipAddresses on controller" +
+                                controllerStr + ": " + str( host ) )
+                            ipResult = main.FALSE
+            ports = main.topoRelated.getAllPorts( main.activeNodes , True,
+                                        kwargs={ 'sleep': 5, 'attempts': 5,
+                                                    'randomTime': True } )
+            links = main.topoRelated.getAllLinks( main.activeNodes, True,
+                                        kwargs={ 'sleep': 5, 'attempts': 5,
+                                                    'randomTime': True } )
+            clusters = main.topoRelated.getAllClusters( main.activeNodes , True,
+                                        kwargs={ 'sleep': 5, 'attempts': 5,
+                                                    'randomTime': True } )
+
+            elapsed = time.time() - startTime
+            cliTime = time.time() - cliStart
+            print "Elapsed time: " + str( elapsed )
+            print "CLI time: " + str( cliTime )
+
+            if all( e is None for e in devices ) and\
+               all( e is None for e in hosts ) and\
+               all( e is None for e in ports ) and\
+               all( e is None for e in links ) and\
+               all( e is None for e in clusters ):
+                topoFailMsg = "Could not get topology from ONOS"
+                main.log.error( topoFailMsg )
+                continue  # Try again, No use trying to compare
+
+            mnSwitches = main.Mininet1.getSwitches()
+            mnLinks = main.Mininet1.getLinks()
+            mnHosts = main.Mininet1.getHosts()
+            for controller in range( len( main.activeNodes ) ):
+                controllerStr = str( main.activeNodes[ controller ] + 1 )
+                currentDevicesResult = main.topoRelated.compareDevicePort( main.Mininet1, controller,
+                                                          mnSwitches,
+                                                          devices, ports )
+                utilities.assert_equals( expect=main.TRUE,
+                                         actual=currentDevicesResult,
+                                         onpass="ONOS" + controllerStr +
+                                         " Switches view is correct",
+                                         onfail="ONOS" + controllerStr +
+                                         " Switches view is incorrect" )
+
+
+                currentLinksResult = main.topoRelated.compareBase( links, controller,
+                                                        main.Mininet1.compareLinks,
+                                                        [mnSwitches, mnLinks] )
+                utilities.assert_equals( expect=main.TRUE,
+                                         actual=currentLinksResult,
+                                         onpass="ONOS" + controllerStr +
+                                         " links view is correct",
+                                         onfail="ONOS" + controllerStr +
+                                         " links view is incorrect" )
+                if hosts[ controller ] and "Error" not in hosts[ controller ]:
+                    currentHostsResult = main.Mininet1.compareHosts(
+                            mnHosts,
+                            hosts[ controller ] )
+                elif hosts[ controller ] == []:
+                    currentHostsResult = main.TRUE
+                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" )
+                # CHECKING HOST ATTACHMENT POINTS
+                hostAttachment = True
+                zeroHosts = False
+                # FIXME: topo-HA/obelisk specific mappings:
+                # key is mac and value is dpid
+                mappings = {}
+                for i in range( 1, 29 ):  # hosts 1 through 28
+                    # set up correct variables:
+                    macId = "00:" * 5 + hex( i ).split( "0x" )[ 1 ].upper().zfill( 2 )
+                    if i == 1:
+                        deviceId = "1000".zfill( 16 )
+                    elif i == 2:
+                        deviceId = "2000".zfill( 16 )
+                    elif i == 3:
+                        deviceId = "3000".zfill( 16 )
+                    elif i == 4:
+                        deviceId = "3004".zfill( 16 )
+                    elif i == 5:
+                        deviceId = "5000".zfill( 16 )
+                    elif i == 6:
+                        deviceId = "6000".zfill( 16 )
+                    elif i == 7:
+                        deviceId = "6007".zfill( 16 )
+                    elif i >= 8 and i <= 17:
+                        dpid = '3' + str( i ).zfill( 3 )
+                        deviceId = dpid.zfill( 16 )
+                    elif i >= 18 and i <= 27:
+                        dpid = '6' + str( i ).zfill( 3 )
+                        deviceId = dpid.zfill( 16 )
+                    elif i == 28:
+                        deviceId = "2800".zfill( 16 )
+                    mappings[ macId ] = deviceId
+                if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
+                    if hosts[ controller ] == []:
+                        main.log.warn( "There are no hosts discovered" )
+                        zeroHosts = True
+                    else:
+                        for host in hosts[ controller ]:
+                            mac = None
+                            location = None
+                            device = None
+                            port = None
+                            try:
+                                mac = host.get( 'mac' )
+                                assert mac, "mac field could not be found for this host object"
+
+                                location = host.get( 'locations' )[ 0 ]
+                                assert location, "location field could not be found for this host object"
+
+                                # Trim the protocol identifier off deviceId
+                                device = str( location.get( 'elementId' ) ).split( ':' )[ 1 ]
+                                assert device, "elementId field could not be found for this host location object"
+
+                                port = location.get( 'port' )
+                                assert port, "port field could not be found for this host location object"
+
+                                # Now check if this matches where they should be
+                                if mac and device and port:
+                                    if str( port ) != "1":
+                                        main.log.error( "The attachment port is incorrect for " +
+                                                        "host " + str( mac ) +
+                                                        ". Expected: 1 Actual: " + str( port ) )
+                                        hostAttachment = False
+                                    if device != mappings[ str( mac ) ]:
+                                        main.log.error( "The attachment device is incorrect for " +
+                                                        "host " + str( mac ) +
+                                                        ". Expected: " + mappings[ str( mac ) ] +
+                                                        " Actual: " + device )
+                                        hostAttachment = False
+                                else:
+                                    hostAttachment = False
+                            except AssertionError:
+                                main.log.exception( "Json object not as expected" )
+                                main.log.error( repr( host ) )
+                                hostAttachment = False
+                else:
+                    main.log.error( "No hosts json output or \"Error\"" +
+                                    " in output. hosts = " +
+                                    repr( hosts[ controller ] ) )
+                if zeroHosts is False:
+                    # TODO: Find a way to know if there should be hosts in a
+                    #       given point of the test
+                    hostAttachment = True
+
+                # END CHECKING HOST ATTACHMENT POINTS
+                devicesResults = devicesResults and currentDevicesResult
+                linksResults = linksResults and currentLinksResult
+                hostsResults = hostsResults and currentHostsResult
+                hostAttachmentResults = hostAttachmentResults and\
+                                        hostAttachment
+                topoResult = ( devicesResults and linksResults
+                               and hostsResults and ipResult and
+                               hostAttachmentResults )
+        utilities.assert_equals( expect=True,
+                                 actual=topoResult,
+                                 onpass="ONOS topology matches Mininet",
+                                 onfail=topoFailMsg )
+        # End of While loop to pull ONOS state
+
+        # Compare json objects for hosts and dataplane clusters
+
+        # hosts
+        main.step( "Hosts view is consistent across all ONOS nodes" )
+        consistentHostsResult = main.TRUE
+        for controller in range( len( hosts ) ):
+            controllerStr = str( main.activeNodes[ controller ] + 1 )
+            if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
+                if hosts[ controller ] == hosts[ 0 ]:
+                    continue
+                else:  # hosts not consistent
+                    main.log.error( "hosts from ONOS" + controllerStr +
+                                     " is inconsistent with ONOS1" )
+                    main.log.warn( repr( hosts[ controller ] ) )
+                    consistentHostsResult = main.FALSE
+
+            else:
+                main.log.error( "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" )
+
+        main.step( "Hosts information is correct" )
+        hostsResults = hostsResults and ipResult
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=hostsResults,
+            onpass="Host information is correct",
+            onfail="Host information is incorrect" )
+
+        main.step( "Host attachment points to the network" )
+        utilities.assert_equals(
+            expect=True,
+            actual=hostAttachmentResults,
+            onpass="Hosts are correctly attached to the network",
+            onfail="ONOS did not correctly attach hosts to the network" )
+
+        # Strongly connected clusters of devices
+        main.step( "Clusters view is consistent across all ONOS nodes" )
+        consistentClustersResult = main.TRUE
+        for controller in range( len( clusters ) ):
+            controllerStr = str( main.activeNodes[ controller ] + 1 )
+            if "Error" not in clusters[ controller ]:
+                if clusters[ controller ] == clusters[ 0 ]:
+                    continue
+                else:  # clusters not consistent
+                    main.log.error( "clusters from ONOS" +
+                                     controllerStr +
+                                     " is inconsistent with ONOS1" )
+                    consistentClustersResult = main.FALSE
+            else:
+                main.log.error( "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" )
+        if not consistentClustersResult:
+            main.log.debug( clusters )
+            for x in links:
+                main.log.warn( "{}: {}".format( len( x ), x ) )
+
+        main.step( "There is only one SCC" )
+        # there should always only be one cluster
+        try:
+            numClusters = len( json.loads( clusters[ 0 ] ) )
+        except ( ValueError, TypeError ):
+            main.log.exception( "Error parsing clusters[0]: " +
+                                repr( clusters[ 0 ] ) )
+            numClusters = "ERROR"
+        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 linksResults
+                       and hostsResults and consistentHostsResult
+                       and consistentClustersResult and clusterResults
+                       and ipResult and hostAttachmentResults )
+
+        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" )
+
+        main.step( "Device information is correct" )
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=devicesResults,
+            onpass="Device information is correct",
+            onfail="Device information is incorrect" )
+
+        main.step( "Links are correct" )
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=linksResults,
+            onpass="Link are correct",
+            onfail="Links are incorrect" )
+
+        main.step( "Hosts are correct" )
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=hostsResults,
+            onpass="Hosts are correct",
+            onfail="Hosts are incorrect" )
+
+        # FIXME: move this to an ONOS state case
+        main.step( "Checking ONOS nodes" )
+        nodeResults = utilities.retry( self.nodesCheck,
+                                       False,
+                                       args=[ main.activeNodes ],
+                                       attempts=5 )
+        utilities.assert_equals( expect=True, actual=nodeResults,
+                                 onpass="Nodes check successful",
+                                 onfail="Nodes check NOT successful" )
+        if not nodeResults:
+            for i in main.activeNodes:
+                main.log.debug( "{} components not ACTIVE: \n{}".format(
+                    main.CLIs[ i ].name,
+                    main.CLIs[ i ].sendline( "scr:list | grep -v ACTIVE" ) ) )
+
+        if not topoResult:
+            main.cleanup()
+            main.exit()
+    def linkDown( self, main, fromS="s3", toS="s28" ):
+        """
+        Link fromS-toS down
+        """
+        import time
+        assert main.numCtrls, "main.numCtrls not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert main.CLIs, "main.CLIs not defined"
+        assert main.nodes, "main.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"
+        main.case( description )
+
+        main.step( "Kill Link between " + fromS + " and " + toS )
+        LinkDown = main.Mininet1.link( END1=fromS, END2=toS, 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 successful",
+                                 onfail="Failed to bring link down" )
+        # TODO do some sort of check here
+
+    def linkUp( self, main, fromS="s3", toS="s28" ):
+        """
+        Link fromS-toS up
+        """
+        import time
+        assert main.numCtrls, "main.numCtrls not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert main.CLIs, "main.CLIs not defined"
+        assert main.nodes, "main.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"
+        main.case( description )
+
+        main.step( "Bring link between " + fromS + " and " + toS +" back up" )
+        LinkUp = main.Mininet1.link( END1=fromS, END2=toS, 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 successful",
+                                 onfail="Failed to bring link up" )
+
+    def switchDown( self, main ):
+        """
+        Switch Down
+        """
+        # NOTE: You should probably run a topology check after this
+        import time
+        assert main.numCtrls, "main.numCtrls not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert main.CLIs, "main.CLIs not defined"
+        assert main.nodes, "main.nodes not defined"
+
+        switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
+
+        description = "Killing a switch to ensure it is discovered correctly"
+        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
+        main.case( description )
+        switch = main.params[ 'kill' ][ 'switch' ]
+        switchDPID = main.params[ 'kill' ][ 'dpid' ]
+
+        # TODO: Make this switch parameterizable
+        main.step( "Kill " + switch )
+        main.log.info( "Deleting " + switch )
+        main.Mininet1.delSwitch( switch )
+        main.log.info( "Waiting " + str( switchSleep ) +
+                       " seconds for switch down to be discovered" )
+        time.sleep( switchSleep )
+        device = onosCli.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 successful",
+                                 onfail="Failed to kill switch?" )
+    def switchUp( self, main ):
+        """
+        Switch Up
+        """
+        # NOTE: You should probably run a topology check after this
+        import time
+        assert main.numCtrls, "main.numCtrls not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert main.CLIs, "main.CLIs not defined"
+        assert main.nodes, "main.nodes not defined"
+
+        switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
+        switch = main.params[ 'kill' ][ 'switch' ]
+        switchDPID = main.params[ 'kill' ][ 'dpid' ]
+        links = main.params[ 'kill' ][ 'links' ].split()
+        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
+        description = "Adding a switch to ensure it is discovered correctly"
+        main.case( description )
+
+        main.step( "Add back " + switch )
+        main.Mininet1.addSwitch( switch, dpid=switchDPID )
+        for peer in links:
+            main.Mininet1.addLink( switch, peer )
+        ipList = [ node.ip_address for node in main.nodes ]
+        main.Mininet1.assignSwController( sw=switch, ip=ipList )
+        main.log.info( "Waiting " + str( switchSleep ) +
+                       " seconds for switch up to be discovered" )
+        time.sleep( switchSleep )
+        device = onosCli.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 successful",
+                                 onfail="Failed to add switch?" )
+
+    def startElectionApp( self, main ):
+        """
+        start election app on all onos nodes
+        """
+        assert main.numCtrls, "main.numCtrls not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert main.CLIs, "main.CLIs not defined"
+        assert main.nodes, "main.nodes not defined"
+
+        main.case( "Start Leadership Election app" )
+        main.step( "Install leadership election app" )
+        onosCli = main.CLIs[ main.activeNodes[ 0 ] ]
+        appResult = onosCli.activateApp( "org.onosproject.election" )
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=appResult,
+            onpass="Election app installed",
+            onfail="Something went wrong with installing Leadership election" )
+
+        main.step( "Run for election on each node" )
+        for i in main.activeNodes:
+            main.CLIs[ i ].electionTestRun()
+        time.sleep( 5 )
+        activeCLIs = [ main.CLIs[ i ] for i in main.activeNodes ]
+        sameResult, leaders = self.consistentLeaderboards( activeCLIs )
+        utilities.assert_equals(
+            expect=True,
+            actual=sameResult,
+            onpass="All nodes see the same leaderboards",
+            onfail="Inconsistent leaderboards" )
+
+        if sameResult:
+            leader = leaders[ 0 ][ 0 ]
+            if main.nodes[ main.activeNodes[ 0 ] ].ip_address in leader:
+                correctLeader = True
+            else:
+                correctLeader = False
+            main.step( "First node was elected leader" )
+            utilities.assert_equals(
+                expect=True,
+                actual=correctLeader,
+                onpass="Correct leader was elected",
+                onfail="Incorrect leader" )
+    def isElectionFunctional( self, main ):
+        """
+        Check that Leadership Election is still functional
+            15.1 Run election on each node
+            15.2 Check that each node has the same leaders and candidates
+            15.3 Find current leader and withdraw
+            15.4 Check that a new node was elected leader
+            15.5 Check that that new leader was the candidate of old leader
+            15.6 Run for election on old leader
+            15.7 Check that oldLeader is a candidate, and leader if only 1 node
+            15.8 Make sure that the old leader was added to the candidate list
+
+            old and new variable prefixes refer to data from before vs after
+                withdrawl and later before withdrawl vs after re-election
+        """
+        import time
+        assert main.numCtrls, "main.numCtrls not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert main.CLIs, "main.CLIs not defined"
+        assert main.nodes, "main.nodes not defined"
+
+        description = "Check that Leadership Election is still functional"
+        main.case( description )
+        # NOTE: Need to re-run after restarts since being a canidate is not persistant
+
+        oldLeaders = []  # list of lists of each nodes' candidates before
+        newLeaders = []  # list of lists of each nodes' candidates after
+        oldLeader = ''  # the old leader from oldLeaders, None if not same
+        newLeader = ''  # the new leaders fron newLoeaders, None if not same
+        oldLeaderCLI = None  # the CLI of the old leader used for re-electing
+        expectNoLeader = False  # True when there is only one leader
+        if main.numCtrls == 1:
+            expectNoLeader = True
+
+        main.step( "Run for election on each node" )
+        electionResult = main.TRUE
+
+        for i in main.activeNodes:  # run test election on each node
+            if main.CLIs[ i ].electionTestRun() == main.FALSE:
+                electionResult = main.FALSE
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=electionResult,
+            onpass="All nodes successfully ran for leadership",
+            onfail="At least one node failed to run for leadership" )
+
+        if electionResult == main.FALSE:
+            main.log.error(
+                "Skipping Test Case because Election Test App isn't loaded" )
+            main.skipCase()
+
+        main.step( "Check that each node shows the same leader and candidates" )
+        failMessage = "Nodes have different leaderboards"
+        activeCLIs = [ main.CLIs[ i ] for i in main.activeNodes ]
+        sameResult, oldLeaders = self.consistentLeaderboards( activeCLIs )
+        if sameResult:
+            oldLeader = oldLeaders[ 0 ][ 0 ]
+            main.log.warn( oldLeader )
+        else:
+            oldLeader = None
+        utilities.assert_equals(
+            expect=True,
+            actual=sameResult,
+            onpass="Leaderboards are consistent for the election topic",
+            onfail=failMessage )
+
+        main.step( "Find current leader and withdraw" )
+        withdrawResult = main.TRUE
+        # do some sanity checking on leader before using it
+        if oldLeader is None:
+            main.log.error( "Leadership isn't consistent." )
+            withdrawResult = main.FALSE
+        # Get the CLI of the oldLeader
+        for i in main.activeNodes:
+            if oldLeader == main.nodes[ i ].ip_address:
+                oldLeaderCLI = main.CLIs[ i ]
+                break
+        else:  # FOR/ELSE statement
+            main.log.error( "Leader election, could not find current leader" )
+        if oldLeader:
+            withdrawResult = oldLeaderCLI.electionTestWithdraw()
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=withdrawResult,
+            onpass="Node was withdrawn from election",
+            onfail="Node was not withdrawn from election" )
+
+        main.step( "Check that a new node was elected leader" )
+        failMessage = "Nodes have different leaders"
+        # Get new leaders and candidates
+        newLeaderResult, newLeaders = self.consistentLeaderboards( activeCLIs )
+        newLeader = None
+        if newLeaderResult:
+            if newLeaders[ 0 ][ 0 ] == 'none':
+                main.log.error( "No leader was elected on at least 1 node" )
+                if not expectNoLeader:
+                    newLeaderResult = False
+            newLeader = newLeaders[ 0 ][ 0 ]
+
+        # Check that the new leader is not the older leader, which was withdrawn
+        if newLeader == oldLeader:
+            newLeaderResult = False
+            main.log.error( "All nodes still see old leader: " + str( oldLeader ) +
+                            " as the current leader" )
+        utilities.assert_equals(
+            expect=True,
+            actual=newLeaderResult,
+            onpass="Leadership election passed",
+            onfail="Something went wrong with Leadership election" )
+
+        main.step( "Check that that new leader was the candidate of old leader" )
+        # candidates[ 2 ] should become the top candidate after withdrawl
+        correctCandidateResult = main.TRUE
+        if expectNoLeader:
+            if newLeader == 'none':
+                main.log.info( "No leader expected. None found. Pass" )
+                correctCandidateResult = main.TRUE
+            else:
+                main.log.info( "Expected no leader, got: " + str( newLeader ) )
+                correctCandidateResult = main.FALSE
+        elif len( oldLeaders[ 0 ] ) >= 3:
+            if newLeader == oldLeaders[ 0 ][ 2 ]:
+                # correct leader was elected
+                correctCandidateResult = main.TRUE
+            else:
+                correctCandidateResult = main.FALSE
+                main.log.error( "Candidate {} was elected. {} should have had priority.".format(
+                                    newLeader, oldLeaders[ 0 ][ 2 ] ) )
+        else:
+            main.log.warn( "Could not determine who should be the correct leader" )
+            main.log.debug( oldLeaders[ 0 ] )
+            correctCandidateResult = main.FALSE
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=correctCandidateResult,
+            onpass="Correct Candidate Elected",
+            onfail="Incorrect Candidate Elected" )
+
+        main.step( "Run for election on old leader( just so everyone " +
+                   "is in the hat )" )
+        if oldLeaderCLI is not None:
+            runResult = oldLeaderCLI.electionTestRun()
+        else:
+            main.log.error( "No old leader to re-elect" )
+            runResult = main.FALSE
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=runResult,
+            onpass="App re-ran for election",
+            onfail="App failed to run for election" )
+
+        main.step(
+            "Check that oldLeader is a candidate, and leader if only 1 node" )
+        # verify leader didn't just change
+        # Get new leaders and candidates
+        reRunLeaders = []
+        time.sleep( 5 )  # Paremterize
+        positionResult, reRunLeaders = self.consistentLeaderboards( activeCLIs )
+
+        # Check that the re-elected node is last on the candidate List
+        if not reRunLeaders[ 0 ]:
+            positionResult = main.FALSE
+        elif oldLeader != reRunLeaders[ 0 ][ -1 ]:
+            main.log.error( "Old Leader ({}) not in the proper position: {} ".format( str( oldLeader ),
+                                                                                      str( reRunLeaders[ 0 ] ) ) )
+            positionResult = main.FALSE
+        utilities.assert_equals(
+            expect=True,
+            actual=positionResult,
+            onpass="Old leader successfully re-ran for election",
+            onfail="Something went wrong with Leadership election after " +
+                   "the old leader re-ran for election" )
+    def installDistributedPrimitiveApp( self, main ):
+        """
+        Install Distributed Primitives app
+        """
+        import time
+        assert main.numCtrls, "main.numCtrls not defined"
+        assert main, "main not defined"
+        assert utilities.assert_equals, "utilities.assert_equals not defined"
+        assert main.CLIs, "main.CLIs not defined"
+        assert main.nodes, "main.nodes not defined"
+
+        # Variables for the distributed primitives tests
+        main.pCounterName = "TestON-Partitions"
+        main.pCounterValue = 0
+        main.onosSet = set( [] )
+        main.onosSetName = "TestON-set"
+
+        description = "Install Primitives app"
+        main.case( description )
+        main.step( "Install Primitives app" )
+        appName = "org.onosproject.distributedprimitives"
+        node = main.activeNodes[ 0 ]
+        appResults = main.CLIs[ node ].activateApp( appName )
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=appResults,
+                                 onpass="Primitives app activated",
+                                 onfail="Primitives app not activated" )
+        # TODO check on all nodes instead of sleeping
+        time.sleep( 5 )  # To allow all nodes to activate
\ No newline at end of file
diff --git a/TestON/tests/MISC/SCPFbatchFlowResp/SCPFbatchFlowResp.params b/TestON/tests/MISC/SCPFbatchFlowResp/SCPFbatchFlowResp.params
index 146faf4..bfeeec3 100755
--- a/TestON/tests/MISC/SCPFbatchFlowResp/SCPFbatchFlowResp.params
+++ b/TestON/tests/MISC/SCPFbatchFlowResp/SCPFbatchFlowResp.params
@@ -15,7 +15,10 @@
 
     <!-- <testcases>1,10,100,1000,100,2000,100,110</testcases> -->
     <testcases>1,2,10,100,1000,2100,100,3100,100,110,210</testcases>
-
+    <GIT>
+        <pull>False</pull>
+        <branch>master</branch>
+    </GIT>
     <GLOBAL>
         <maxNodes>1</maxNodes> # currently only runs in single node onos
         <numSw>63</numSw> # Number of devices used in topology
@@ -34,8 +37,6 @@
     <CASE1>
         <cellName>temp</cellName>
         <cellApps>drivers</cellApps>
-        <gitPull>False</gitPull>
-        <gitBranch>master</gitBranch>
     </CASE1>
 
     <CASE2>
diff --git a/TestON/tests/MISC/SCPFbatchFlowResp/SCPFbatchFlowResp.py b/TestON/tests/MISC/SCPFbatchFlowResp/SCPFbatchFlowResp.py
index d2a55bb..e6f7d76 100644
--- a/TestON/tests/MISC/SCPFbatchFlowResp/SCPFbatchFlowResp.py
+++ b/TestON/tests/MISC/SCPFbatchFlowResp/SCPFbatchFlowResp.py
@@ -18,54 +18,38 @@
         - GIT ( optional )
             - Checkout ONOS master branch
             - Pull latest ONOS code
-        - Building ONOS ( optional )
-            - Install ONOS package
-            - Build ONOS package
         """
-        main.case( "Constructing test variables and building ONOS package" )
-        main.step( "Constructing test variables" )
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        main.testSetUp.envSetupDescription()
+        stepResult = main.FALSE
+        try:
+            # Test variables
+            main.testOnDirectory = os.path.dirname( os.getcwd() )
+            main.cellName = main.params[ 'CASE1' ][ 'cellName' ]
+            main.apps = main.params[ 'CASE1' ][ 'cellApps' ]
+            main.maxNodes = int( main.params[ 'GLOBAL' ][ 'maxNodes' ] )
+            main.startUpSleep = float( main.params[ 'GLOBAL' ][ 'SLEEP' ][ 'startup' ] )
+            main.startMNSleep = float( main.params[ 'GLOBAL' ][ 'SLEEP' ][ 'startMN' ] )
+            main.addFlowSleep = float( main.params[ 'GLOBAL' ][ 'SLEEP' ][ 'addFlow' ] )
+            main.delFlowSleep = float( main.params[ 'GLOBAL' ][ 'SLEEP' ][ 'delFlow' ] )
+            main.chkFlowSleep = float( main.params[ 'GLOBAL' ][ 'SLEEP' ][ 'chkFlow' ] )
+            main.onosPackaging = main.params[ 'CASE2' ][ 'incPackaging' ] == "true"
+            main.cfgSleep = float( main.params[ 'GLOBAL' ][ 'SLEEP' ][ 'cfg' ] )
+            main.numSw = int( main.params[ 'GLOBAL' ][ 'numSw' ] )
+            main.numThreads = int( main.params[ 'GLOBAL' ][ 'numThreads' ] )
+            main.cluster = main.params[ 'GLOBAL' ][ 'cluster' ]
 
-        # Test variables
-        main.testOnDirectory = os.path.dirname( os.getcwd() )
-        main.cellName = main.params[ 'CASE1' ][ 'cellName' ]
-        main.apps = main.params[ 'CASE1' ][ 'cellApps' ]
-        gitBranch = main.params[ 'CASE1' ][ 'gitBranch' ]
-        gitPull = main.params[ 'CASE1' ][ 'gitPull' ]
-        main.maxNodes = int( main.params[ 'GLOBAL' ][ 'maxNodes' ] )
-        main.startUpSleep = float( main.params[ 'GLOBAL' ][ 'SLEEP' ][ 'startup' ] )
-        main.startMNSleep = float( main.params[ 'GLOBAL' ][ 'SLEEP' ][ 'startMN' ] )
-        main.addFlowSleep = float( main.params[ 'GLOBAL' ][ 'SLEEP' ][ 'addFlow' ] )
-        main.delFlowSleep = float( main.params[ 'GLOBAL' ][ 'SLEEP' ][ 'delFlow' ] )
-        main.chkFlowSleep = float( main.params[ 'GLOBAL' ][ 'SLEEP' ][ 'chkFlow' ] )
-        main.cfgSleep = float( main.params[ 'GLOBAL' ][ 'SLEEP' ][ 'cfg' ] )
-        main.numSw = int( main.params[ 'GLOBAL' ][ 'numSw' ] )
-        main.numThreads = int( main.params[ 'GLOBAL' ][ 'numThreads' ] )
-        main.cellData = {}  # for creating cell file
-        main.CLIs = []
-        main.ONOSip = []
-
-        main.ONOSip = main.ONOSbench.getOnosIps()
-        main.commit = main.ONOSbench.getVersion()
+            stepResult = main.testSetUp.envSetup()
+        except Exception as e:
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
         main.commit = main.commit.split( " " )[ 1 ]
 
-        main.cluster = main.params[ 'GLOBAL' ][ 'cluster' ]
-
-        # Assigning ONOS cli handles to a list
-        for i in range( 1, main.maxNodes + 1 ):
-            main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
-
-        if main.CLIs:
-            stepResult = main.TRUE
-        else:
-            main.log.error( "Did not properly created list of ONOS CLI handle" )
-            stepResult = main.FALSE
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully construct " +
-                                        "test variables ",
-                                 onfail="Failed to construct test variables" )
-
 
     def CASE2( self, main ):
         """
@@ -79,113 +63,7 @@
         - Install ONOS cluster
         - Connect to cli
         """
-        main.numCtrls = int( main.maxNodes )
-
-        main.case( "Starting up " + str( main.numCtrls ) +
-                   " node( s ) ONOS cluster" )
-
-        main.log.info( "Safety check, killing all ONOS processes" +
-                       " before initiating environment setup" )
-
-        tempOnosIp = []
-        for i in range( main.numCtrls ):
-            tempOnosIp.append( main.ONOSip[ i ] )
-
-        if main.params[ 'CASE2' ][ 'incPackaging' ] == "true":
-            main.step( "Create onos cell file with: " + main.apps )
-            main.ONOSbench.createCellFile( main.ONOSbench.ip_address, "temp",
-                                           main.Mininet1.ip_address, main.apps,
-                                           tempOnosIp, main.ONOScli1.karafUser )
-
-            main.step( "Apply cell to environment" )
-            cellResult = main.ONOSbench.setCell( "temp" )
-            verifyResult = main.ONOSbench.verifyCell()
-            stepResult = cellResult and verifyResult
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=stepResult,
-                                     onpass="Successfully applied cell to " +
-                                        "environment",
-                                     onfail="Failed to apply cell to environment " )
-
-            main.step( "Creating ONOS package" )
-            packageResult = main.ONOSbench.buckBuild()
-            stepResult = packageResult
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=stepResult,
-                                     onpass="Successfully created ONOS package",
-                                     onfail="Failed to create ONOS package" )
-            time.sleep( main.startUpSleep )
-
-            main.step( "Uninstalling ONOS package" )
-            onosUninstallResult = main.TRUE
-            for i in range( main.numCtrls ):
-                onosUninstallResult = onosUninstallResult and \
-                    main.ONOSbench.onosUninstall( nodeIp=main.ONOSip[ i ] )
-            stepResult = onosUninstallResult
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=stepResult,
-                                     onpass="Successfully uninstalled ONOS package",
-                                     onfail="Failed to uninstall ONOS package" )
-            time.sleep( main.startUpSleep )
-
-        else:
-            main.log.info( "onos Packaging Skipped!" )
-
-        main.step( "Installing ONOS package" )
-        onosInstallResult = main.TRUE
-        for i in range( main.numCtrls ):
-            onosInstallResult = onosInstallResult and \
-                    main.ONOSbench.onosInstall( node=main.ONOSip[ i ] )
-        stepResult = onosInstallResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully installed ONOS package",
-                                 onfail="Failed to install ONOS package" )
-        time.sleep( main.startUpSleep )
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.TRUE
-        for i in range( main.numCtrls ):
-            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=main.ONOSip[ i ] )
-        utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        time.sleep( main.startUpSleep )
-        main.step( "Starting ONOS service" )
-        stopResult = main.TRUE
-        startResult = main.TRUE
-        onosIsUp = main.TRUE
-
-        for i in range( main.numCtrls ):
-            onosIsUp = onosIsUp and main.ONOSbench.isup( main.ONOSip[ i ] )
-        if onosIsUp == main.TRUE:
-            main.log.report( "ONOS instance is up and ready" )
-        else:
-            main.log.report( "ONOS instance may not be up, stop and " +
-                             "start ONOS again " )
-            for i in range( main.numCtrls ):
-                stopResult = stopResult and \
-                        main.ONOSbench.onosStop( main.ONOSip[ i ] )
-            for i in range( main.numCtrls ):
-                startResult = startResult and \
-                        main.ONOSbench.onosStart( main.ONOSip[ i ] )
-        stepResult = onosIsUp and stopResult and startResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="ONOS service is ready",
-                                 onfail="ONOS service did not start properly" )
-
-        main.step( "Start ONOS cli" )
-        cliResult = main.TRUE
-        for i in range( i, main.numCtrls ):
-            cliResult = cliResult and \
-                        main.ONOScli1.startOnosCli( main.ONOSip[ i ] )
-        stepResult = cliResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully start ONOS cli",
-                                 onfail="Failed to start ONOS cli" )
+        main.testSetUp.ONOSSetUp( main.Mininet1, skipPack=main.onosPackaging )
 
     def CASE10( self, main ):
         """
diff --git a/TestON/tests/SAMP/SAMPstartTemplate_1node/SAMPstartTemplate_1node.params b/TestON/tests/SAMP/SAMPstartTemplate_1node/SAMPstartTemplate_1node.params
index d753377..3a17969 100755
--- a/TestON/tests/SAMP/SAMPstartTemplate_1node/SAMPstartTemplate_1node.params
+++ b/TestON/tests/SAMP/SAMPstartTemplate_1node/SAMPstartTemplate_1node.params
@@ -25,10 +25,12 @@
     -->
 
     <testcases>0,1,10,11,12,22,2,32</testcases>
+    <GIT>
+        <pull>False</pull>
+        <branch>master</branch>
+    </GIT>
 
     <CASE0>
-        <gitPull>False</gitPull> # False or True
-        <gitBranch>master</gitBranch>
     </CASE0>
 
     <CASE1>
diff --git a/TestON/tests/SAMP/SAMPstartTemplate_1node/SAMPstartTemplate_1node.py b/TestON/tests/SAMP/SAMPstartTemplate_1node/SAMPstartTemplate_1node.py
index 96ac3d8..300cc1d 100644
--- a/TestON/tests/SAMP/SAMPstartTemplate_1node/SAMPstartTemplate_1node.py
+++ b/TestON/tests/SAMP/SAMPstartTemplate_1node/SAMPstartTemplate_1node.py
@@ -15,31 +15,16 @@
             test env. We want Jenkins jobs to pull&build for flexibility to handle
             different versions of ONOS.
         '''
-        gitPull = main.params['CASE0']['gitPull']
-        gitBranch = main.params['CASE0']['gitBranch']
-
-        main.case("Pull onos branch and build onos on Teststation.")
-
-        if gitPull == 'True':
-            main.step( "Git Checkout ONOS branch: " + gitBranch)
-            stepResult = main.ONOSbench.gitCheckout( branch = gitBranch )
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=stepResult,
-                                     onpass="Successfully checkout onos branch.",
-                                     onfail="Failed to checkout onos branch. Exiting test..." )
-            if not stepResult: main.exit()
-
-            main.step( "Git Pull on ONOS branch:" + gitBranch)
-            stepResult = main.ONOSbench.gitPull( )
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=stepResult,
-                                     onpass="Successfully pull onos. ",
-                                     onfail="Failed to pull onos. Exiting test ..." )
-            if not stepResult: main.exit()
-
-        else:
-            main.log.warn( "Skipped pulling onos" )
-
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        try:
+            main.testSetUp
+        except ( NameError, AttributeError ):
+            main.testSetUp = ONOSSetup()
+        main.testSetUp.gitPulling()
 
     def CASE1( self, main ):
         '''
@@ -47,29 +32,31 @@
             Uninstall all running cells in test env defined in .topo file
 
         '''
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        try:
+            main.testSetUp
+        except ( NameError, AttributeError ):
+            main.testSetUp = ONOSSetup()
 
-        main.case( "Constructing global test variables and clean cluster env." )
+        main.testSetUp.envSetupDescription()
+        stepResult = main.FALSE
+        try:
+            main.nodeList = main.params['CASE1']['NodeList'].split(",")
+            main.onosStartupSleep = float( main.params['CASE1']['SleepTimers']['onosStartup'] )
+            main.onosCfgSleep = float( main.params['CASE1']['SleepTimers']['onosCfg'] )
+            main.mnStartupSleep = float( main.params['CASE1']['SleepTimers']['mnStartup'] )
+            main.mnCfgSleep = float( main.params['CASE1']['SleepTimers']['mnCfg'] )
+            main.numCtrls = int( main.params['CASE10']['numNodes'] )
+            stepResult = main.testSetUp.envSetup( includeGitPull=False )
+        except Exception as e:
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
 
-        main.step( "Constructing test variables" )
-        main.branch = main.ONOSbench.getBranchName()
-        main.log.info( "Running onos branch: " + main.branch )
-        main.commitNum = main.ONOSbench.getVersion().split(' ')[1]
-        main.log.info( "Running onos commit Number: " + main.commitNum)
-        main.nodeList = main.params['CASE1']['NodeList'].split(",")
-        main.onosStartupSleep = float( main.params['CASE1']['SleepTimers']['onosStartup'] )
-        main.onosCfgSleep = float( main.params['CASE1']['SleepTimers']['onosCfg'] )
-        main.mnStartupSleep = float( main.params['CASE1']['SleepTimers']['mnStartup'] )
-        main.mnCfgSleep = float( main.params['CASE1']['SleepTimers']['mnCfg'] )
-        main.numCtrls = int( main.params['CASE10']['numNodes'] )
-        main.AllONOSip = main.ONOSbench.getOnosIps()
-        main.ONOSip = []
-        for i in range( main.numCtrls ):
-            main.ONOSip.append( main.AllONOSip[i] )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=main.TRUE,
-                                 onpass="Successfully construct " +
-                                        "test variables ",
-                                 onfail="Failed to construct test variables" )
+
 
     def CASE2( self, main ):
         '''
@@ -94,7 +81,15 @@
         """
 
         import time
-
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        try:
+            main.testSetUp
+        except ( NameError, AttributeError ):
+            main.testSetUp = ONOSSetup()
         main.case( "Start up " + str( main.numCtrls ) + "-node onos cluster.")
         main.step( "Start ONOS cluster with basic (drivers) app.")
         stepResult = main.ONOSbench.startBasicONOS( nodeList=main.ONOSip, opSleep=200,
@@ -104,22 +99,14 @@
                                  onpass="Successfully started basic ONOS cluster ",
                                  onfail="Failed to start basic ONOS Cluster " )
 
-        main.step( "Establishing Handles on ONOS CLIs.")
-        cliResult = main.TRUE
-        for n in range( 1, main.numCtrls + 1 ):
-            handle = "main.ONOScli" + str( n )
-            cliResult = cliResult & ( eval( handle ).startOnosCli( main.ONOSip[ n-1 ] ) )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=cliResult,
-                                 onpass="Successfully started onos cli's ",
-                                 onfail="Failed to start onos cli's " )
+        main.testSetUp.startOnosClis()
 
         main.step( "Activate onos apps.")
-        apps = main.params['CASE10'].get( 'Apps' )
-        if apps:
-            main.log.info( "Apps to activate: " + apps )
+        main.apps = main.params['CASE10'].get( 'Apps' )
+        if main.apps:
+            main.log.info( "Apps to activate: " + main.apps )
             activateResult = main.TRUE
-            for a in apps.split(","):
+            for a in main.apps.split(","):
                 activateResult = activateResult & main.ONOScli1.activateApp(a)
             # TODO: check this worked
             time.sleep( main.onosCfgSleep )  # wait for apps to activate
diff --git a/TestON/tests/SAMP/SAMPstartTemplate_3node/SAMPstartTemplate_3node.params b/TestON/tests/SAMP/SAMPstartTemplate_3node/SAMPstartTemplate_3node.params
index 645174e..99996dd 100755
--- a/TestON/tests/SAMP/SAMPstartTemplate_3node/SAMPstartTemplate_3node.params
+++ b/TestON/tests/SAMP/SAMPstartTemplate_3node/SAMPstartTemplate_3node.params
@@ -25,6 +25,10 @@
    -->
 
     <testcases>0,1,10,11,12,22,2,32</testcases>
+    <GIT>
+        <pull>False</pull>
+        <branch>master</branch>
+    </GIT>
 
     <CASE0>
         <gitPull>False</gitPull> # False or True
diff --git a/TestON/tests/SAMP/SAMPstartTemplate_3node/SAMPstartTemplate_3node.py b/TestON/tests/SAMP/SAMPstartTemplate_3node/SAMPstartTemplate_3node.py
index 8d8faed..6ac9280 100644
--- a/TestON/tests/SAMP/SAMPstartTemplate_3node/SAMPstartTemplate_3node.py
+++ b/TestON/tests/SAMP/SAMPstartTemplate_3node/SAMPstartTemplate_3node.py
@@ -15,30 +15,17 @@
             test env. We want Jenkins jobs to pull&build for flexibility to handle
             different versions of ONOS.
         '''
-        gitPull = main.params['CASE0']['gitPull']
-        gitBranch = main.params['CASE0']['gitBranch']
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        try:
+            main.testSetUp
+        except ( NameError, AttributeError ):
+            main.testSetUp = ONOSSetup()
 
-        main.case("Pull onos branch and build onos on Teststation.")
-
-        if gitPull == 'True':
-            main.step( "Git Checkout ONOS branch: " + gitBranch)
-            stepResult = main.ONOSbench.gitCheckout( branch = gitBranch )
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=stepResult,
-                                     onpass="Successfully checkout onos branch.",
-                                     onfail="Failed to checkout onos branch. Exiting test..." )
-            if not stepResult: main.exit()
-
-            main.step( "Git Pull on ONOS branch:" + gitBranch)
-            stepResult = main.ONOSbench.gitPull( )
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=stepResult,
-                                     onpass="Successfully pull onos. ",
-                                     onfail="Failed to pull onos. Exiting test ..." )
-            if not stepResult: main.exit()
-
-        else:
-            main.log.warn( "Skipped pulling onos and Skipped building ONOS" )
+        main.testSetUp.gitPulling()
 
 
     def CASE1( self, main ):
@@ -47,29 +34,30 @@
             Uninstall all running cells in test env defined in .topo file
 
         '''
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        try:
+            main.testSetUp
+        except ( NameError, AttributeError ):
+            main.testSetUp = ONOSSetup()
 
-        main.case( "Constructing global test variables and clean cluster env." )
+        main.testSetUp.envSetupDescription()
+        stepResult = main.FALSE
+        try:
+            main.nodeList = main.params['CASE1']['NodeList'].split(",")
+            main.onosStartupSleep = float(main.params['CASE1']['SleepTimers']['onosStartup'])
+            main.onosCfgSleep = float(main.params['CASE1']['SleepTimers']['onosCfg'])
+            main.mnStartupSleep = float(main.params['CASE1']['SleepTimers']['mnStartup'])
+            main.mnCfgSleep = float(main.params['CASE1']['SleepTimers']['mnCfg'])
+            main.numCtrls = int( main.params['CASE10']['numNodes'] )
+            stepResult = main.testSetUp.envSetup( includeGitPull=False )
+        except Exception as e:
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
 
-        main.step( "Constructing test variables" )
-        main.branch = main.ONOSbench.getBranchName()
-        main.log.info( "Running onos branch: " + main.branch )
-        main.commitNum = main.ONOSbench.getVersion().split(' ')[1]
-        main.log.info( "Running onos commit Number: " + main.commitNum)
-        main.nodeList = main.params['CASE1']['NodeList'].split(",")
-        main.onosStartupSleep = float( main.params['CASE1']['SleepTimers']['onosStartup'] )
-        main.onosCfgSleep = float( main.params['CASE1']['SleepTimers']['onosCfg'] )
-        main.mnStartupSleep = float( main.params['CASE1']['SleepTimers']['mnStartup'] )
-        main.mnCfgSleep = float( main.params['CASE1']['SleepTimers']['mnCfg'] )
-        main.numCtrls = int( main.params['CASE10']['numNodes'] )
-        main.AllONOSip = main.ONOSbench.getOnosIps()
-        main.ONOSip = []
-        for i in range( main.numCtrls ):
-            main.ONOSip.append( main.AllONOSip[i] )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=main.TRUE,
-                                 onpass="Successfully construct " +
-                                        "test variables ",
-                                 onfail="Failed to construct test variables" )
 
     def CASE2( self, main ):
         '''
@@ -92,6 +80,15 @@
         2) activate apps via ONOSCliDriver;
         3) configure onos via ONOSCliDriver;
         """
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        try:
+            main.testSetUp
+        except ( NameError, AttributeError ):
+            main.testSetUp = ONOSSetup()
 
         import time
 
@@ -104,22 +101,14 @@
                                  onpass="Successfully started basic ONOS cluster ",
                                  onfail="Failed to start basic ONOS Cluster " )
 
-        main.step( "Establishing Handles on ONOS CLIs.")
-        cliResult = main.TRUE
-        for n in range( 1, main.numCtrls + 1 ):
-            handle = "main.ONOScli" + str( n )
-            cliResult = cliResult & ( eval( handle ).startOnosCli( main.ONOSip[ n-1 ] ) )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=cliResult,
-                                 onpass="Successfully started onos cli's ",
-                                 onfail="Failed to start onos cli's " )
+        main.testSetUp.startOnosClis()
 
         main.step( "Activate onos apps.")
-        apps = main.params['CASE10'].get( 'Apps' )
-        if apps:
-            main.log.info( "Apps to activate: " + apps )
+        main.apps = main.params['CASE10'].get( 'Apps' )
+        if main.apps:
+            main.log.info( "Apps to activate: " + main.apps )
             activateResult = main.TRUE
-            for a in apps.split(","):
+            for a in main.apps.split(","):
                 activateResult = activateResult & main.ONOScli1.activateApp(a)
             # TODO: check this worked
             time.sleep( main.onosCfgSleep )  # wait for apps to activate
diff --git a/TestON/tests/SCPF/SCPFcbench/SCPFcbench.params b/TestON/tests/SCPF/SCPFcbench/SCPFcbench.params
index 0b51d1a..633955f 100644
--- a/TestON/tests/SCPF/SCPFcbench/SCPFcbench.params
+++ b/TestON/tests/SCPF/SCPFcbench/SCPFcbench.params
@@ -16,8 +16,8 @@
     </TEST>
 
     <GIT>
-        <autopull>off</autopull>
-        <checkout>master</checkout>
+        <pull>False</pull>
+        <branch>master</branch>
     </GIT>
 
     <CTRL>
diff --git a/TestON/tests/SCPF/SCPFcbench/SCPFcbench.py b/TestON/tests/SCPF/SCPFcbench/SCPFcbench.py
index 9de1993..2547317 100644
--- a/TestON/tests/SCPF/SCPFcbench/SCPFcbench.py
+++ b/TestON/tests/SCPF/SCPFcbench/SCPFcbench.py
@@ -27,96 +27,41 @@
         except NameError:
             init = False
 
-        #Load values from params file
-        checkoutBranch = main.params[ 'GIT' ][ 'checkout' ]
-        gitPull = main.params[ 'GIT' ][ 'autopull' ]
-        BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
-        BENCHUser = main.params[ 'BENCH' ][ 'user' ]
-        CBENCHuser = main.params[ 'CBENCH'][ 'user' ]
-        MN1Ip = os.environ[ main.params[ 'MN' ][ 'ip1' ] ]
-        maxNodes = int(main.params[ 'availableNodes' ])
-        cellName = main.params[ 'ENV' ][ 'cellName' ]
-        cellApps = main.params[ 'ENV' ][ 'cellApps' ]
-
         # -- INIT SECTION, ONLY RUNS ONCE -- #
         if init == False:
             init = True
-            global clusterCount             #number of nodes running
-            global ONOSIp                   #list of ONOS IP addresses
-            global scale
+            try:
+                from tests.dependencies.ONOSSetup import ONOSSetup
+                main.testSetUp = ONOSSetup()
+            except ImportError:
+                main.log.error( "ONOSSetup not found. exiting the test" )
+                main.exit()
+            main.testSetUp.envSetupDescription()
+            stepResult = main.FALSE
+            try:
+                # Load values from params file
+                BENCHIp = main.params['BENCH']['ip1']
+                BENCHUser = main.params['BENCH']['user']
+                CBENCHuser = main.params['CBENCH']['user']
+                MN1Ip = os.environ[main.params['MN']['ip1']]
+                main.maxNodes = int(main.params['availableNodes'])
+                main.cellName = main.params['ENV']['cellName']
+                main.apps = main.params['ENV']['cellApps']
+                main.scale = (main.params['SCALE']).split(",")
 
-            clusterCount = 0
-            ONOSIp = [ 0 ]
-            scale = (main.params[ 'SCALE' ]).split(",")
-            clusterCount = int(scale[0])
+                stepResult = main.testSetUp.envSetup( hasCli=False )
+            except Exception as e:
+                main.testSetUp.envSetupException( e )
+            main.testSetUp.evnSetupConclusion( stepResult )
 
-            #Populate ONOSIp with ips from params
-            for i in range(1, maxNodes + 1):
-                ipString = os.environ[main.params['CTRL']['ip1']]
-                ONOSIp.append(ipString)
-
-            #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.commit = ( main.commit.split( " " ) )[ 1 ]
         # -- END OF INIT SECTION --#
 
-        clusterCount = int(scale[0])
-        scale.remove(scale[0])
-
-        #kill off all onos processes
-        main.step("Safety check, killing all ONOS processes")
-        main.step("before initiating environment setup")
-        for node in range(1, maxNodes + 1):
-            main.ONOSbench.onosStop(ONOSIp[node])
-            main.ONOSbench.onosKill(ONOSIp[node])
-
-        #Uninstall everywhere
-        main.step( "Cleaning Enviornment..." )
-        for i in range(1, maxNodes + 1):
-            main.log.info(" Uninstalling ONOS " + str(i) )
-            main.ONOSbench.onosUninstall( ONOSIp[i] )
-
-        time.sleep(10)
-
-        print "Cellname is: "+ cellName + "ONOS IP is: " + str(ONOSIp)
-        main.ONOSbench.createCellFile(BENCHIp, cellName, MN1Ip,
-                                      cellApps, [ONOSIp[1]], main.ONOScli1.karafUser)
-
-        main.step( "Set Cell" )
-        main.ONOSbench.setCell(cellName)
-
-        main.step( "Creating ONOS package" )
-        packageResult = main.ONOSbench.buckBuild()
-
-        main.step( "verify cells" )
-        verifyCellResult = main.ONOSbench.verifyCell()
-
-        main.log.report( "Initializing " + str( clusterCount ) + " node cluster." )
-        for node in range(1, clusterCount + 1):
-            main.log.info("Starting ONOS " + str(node) + " at IP: " + ONOSIp[node])
-            main.ONOSbench.onosInstall( ONOSIp[node])
-            main.ONOSbench.onosSecureSSH( node=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!" )
-        main.log.info("Startup sequence complete")
+        main.testSetUp.ONOSSetUp( MN1Ip, True, hasCli=False,
+                                  cellName=main.cellName )
 
         for i in range(5):
-            main.ONOSbench.onosCfgSet(ONOSIp[1], "org.onosproject.fwd.ReactiveForwarding","packetOutOnly true")
+            main.ONOSbench.onosCfgSet(main.ONOSip[0], "org.onosproject.fwd.ReactiveForwarding","packetOutOnly true")
             time.sleep(5)
             main.ONOSbench.handle.sendline("onos $OC1 cfg get|grep packetOutOnly")
             main.ONOSbench.handle.expect(":~")
@@ -146,7 +91,7 @@
         if mode != "t":
             mode = " "
 
-        runCbench = ( "ssh " + CBENCHuser + "@" + ONOSIp[1] + " " + cbenchCMD + mode )
+        runCbench = ( "ssh " + CBENCHuser + "@" + main.ONOSip[0] + " " + cbenchCMD + mode )
         main.ONOSbench.handle.sendline(runCbench)
         time.sleep(30)
         main.ONOSbench.handle.expect(":~")
@@ -174,20 +119,16 @@
                 main.log.info("Average: \t\t\t" + avg)
                 main.log.info("Standard Deviation: \t" + stdev)
 
-
-                commit = main.ONOSbench.getVersion()
-                commit = (commit.split(" "))[1]
-
                 try:
                     dbFileName="/tmp/CbenchDB"
                     dbfile = open(dbFileName, "w+")
-                    temp = "'" + commit + "',"
+                    temp = "'" + main.commit + "',"
                     temp += "'" + mode + "',"
                     temp += "'" + avg + "',"
                     temp += "'" + stdev + "'\n"
                     dbfile.write(temp)
                     dbfile.close()
-                    main.ONOSbench.logReport(ONOSIp[1], ["ERROR", "WARNING", "EXCEPT"], outputMode="d")
+                    main.ONOSbench.logReport(main.ONOSip[0], ["ERROR", "WARNING", "EXCEPT"], outputMode="d")
                 except IOError:
                     main.log.warn("Error opening " + dbFileName + " to write results.")
 
diff --git a/TestON/tests/SCPF/SCPFflowTp1g/SCPFflowTp1g.params b/TestON/tests/SCPF/SCPFflowTp1g/SCPFflowTp1g.params
index 3ce83c0..a263ca6 100644
--- a/TestON/tests/SCPF/SCPFflowTp1g/SCPFflowTp1g.params
+++ b/TestON/tests/SCPF/SCPFflowTp1g/SCPFflowTp1g.params
@@ -26,8 +26,8 @@
     </TEST>
 
     <GIT>
-        <autopull>off</autopull>
-        <checkout>master</checkout>
+        <pull>False</pull>
+        <branch>master</branch>
     </GIT>
 
     <CTRL>
diff --git a/TestON/tests/SCPF/SCPFflowTp1g/SCPFflowTp1g.py b/TestON/tests/SCPF/SCPFflowTp1g/SCPFflowTp1g.py
index af88ab5..7dd924d 100644
--- a/TestON/tests/SCPF/SCPFflowTp1g/SCPFflowTp1g.py
+++ b/TestON/tests/SCPF/SCPFflowTp1g/SCPFflowTp1g.py
@@ -18,122 +18,43 @@
         import time
         global init
         try:
-            if type(init) is not bool:
+            if type( init ) is not bool:
                 init = False
         except NameError:
             init = False
 
-        #Load values from params file
-        checkoutBranch = main.params[ 'GIT' ][ 'checkout' ]
-        gitPull = main.params[ 'GIT' ][ 'autopull' ]
-        cellName = main.params[ 'ENV' ][ 'cellName' ]
-        Apps = main.params[ 'ENV' ][ 'cellApps' ]
-        BENCHUser = main.params[ 'BENCH' ][ 'user' ]
-        BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
-        main.maxNodes = int(main.params[ 'max' ])
-        cellName = main.params[ 'ENV' ][ 'cellName' ]
-
-        main.log.info("==========DEBUG VERSION 3===========")
+        main.log.info( "==========DEBUG VERSION 3===========" )
 
         # -- INIT SECTION, ONLY RUNS ONCE -- #
         if init == False:
-            init = True
-            global clusterCount             #number of nodes running
-            global ONOSIp                   #list of ONOS IP addresses
-            global scale
-            global commit
-
-            clusterCount = 0
-            ONOSIp = [ 0 ]
-            scale = (main.params[ 'SCALE' ]).split(",")
-            clusterCount = int(scale[0])
-
-            #Populate ONOSIp with ips from params
-            for i in range(1, main.maxNodes + 1):
-                ipString = 'ip' + str(i)
-                ONOSIp.append(main.params[ 'CTRL' ][ ipString ])
-
-            ONOSIp = [0]
-            ONOSIp.extend(main.ONOSbench.getOnosIps())
-
-            #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" )
-
-            commit = main.ONOSbench.getVersion()
-            commit = (commit.split(" "))[1]
-
-            resultsDB = open("/tmp/flowTP1gDB", "w+")
-            resultsDB.close()
-
+            try:
+                init = True
+                try:
+                    from tests.dependencies.ONOSSetup import ONOSSetup
+                    main.testSetUp = ONOSSetup()
+                except ImportError:
+                    main.log.error( "ONOSSetup not found. exiting the test" )
+                    main.exit()
+                main.testSetUp.envSetupDescription()
+                #Load values from params file
+                cellName = main.params[ 'ENV' ][ 'cellName' ]
+                main.apps = main.params[ 'ENV' ][ 'cellApps' ]
+                BENCHUser = main.params[ 'BENCH' ][ 'user' ]
+                BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
+                main.scale = ( main.params[ 'SCALE' ]  ).split( "," )
+                stepResult = main.testSetUp.envSetup()
+                resultsDB = open( "/tmp/flowTP1gDB", "w+" )
+                resultsDB.close()
+            except Exception as e:
+                main.testSetUp.envSetupException( e )
+            main.testSetUp.evnSetupConclusion( stepResult )
+            main.commit = (main.commit.split(" "))[1]
         # -- END OF INIT SECTION --#
 
-        clusterCount = int(scale[0])
-        scale.remove(scale[0])
-        main.log.info("CLUSTER COUNT: " + str(clusterCount))
-
-        #kill off all onos processes
-        main.step("Safety check, killing all ONOS processes")
-        main.step("before initiating environment setup")
-        for node in range(1, main.maxNodes + 1):
-            main.ONOSbench.onosStop(ONOSIp[node])
-            main.ONOSbench.onosKill(ONOSIp[node])
-
-        #Uninstall everywhere
-        main.step( "Cleaning Enviornment..." )
-        for i in range(1, main.maxNodes + 1):
-            main.log.info(" Uninstalling ONOS " + str(i) )
-            main.ONOSbench.onosUninstall( ONOSIp[i] )
-
-        #construct the cell file
-        main.log.info("Creating cell file")
-        cellIp = []
-        for node in range (1, clusterCount + 1):
-            cellIp.append(ONOSIp[node])
-
-        main.ONOSbench.createCellFile(BENCHIp, cellName, "localhost",
-                                      str(Apps), cellIp, main.ONOScli1.karafUser)
-        main.log.info("Cell Ip list: " + str(cellIp))
-
-        main.step( "Set Cell" )
-        main.ONOSbench.setCell(cellName)
-
-        main.step( "Creating ONOS package" )
-        packageResult = main.ONOSbench.buckBuild()
-
-        main.step( "verify cells" )
-        verifyCellResult = main.ONOSbench.verifyCell()
-
-        main.log.report( "Initializeing " + str( clusterCount ) + " node cluster." )
-        for node in range(1, clusterCount + 1):
-            main.log.info("Starting ONOS " + str(node) + " at IP: " + ONOSIp[node])
-            main.ONOSbench.onosInstall( ONOSIp[node])
-
-        for node in range(1, clusterCount + 1):
-            secureSshResult = main.ONOSbench.onosSecureSSH( 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!" )
-
-        for node in range(1, clusterCount + 1):
-            exec "a = main.ONOScli%s.startOnosCli" %str(node)
-            a(ONOSIp[node])
+        main.testSetUp.ONOSSetUp( "localhost", True, cellName=cellName )
 
         main.log.info("Startup sequence complete")
-        main.ONOSbench.logReport(ONOSIp[1], ["ERROR", "WARNING", "EXCEPT"], outputMode="d")
+        main.ONOSbench.logReport(main.ONOSip[0], ["ERROR", "WARNING", "EXCEPT"], outputMode="d")
 
     def CASE2( self, main ):
         #
@@ -164,7 +85,6 @@
         neighborList = (main.params[ 'TEST' ][ 'neighbors' ]).split(",")
         testCMD[0] = main.params[ 'TEST' ][ 'testCMD0' ]
         testCMD[1] = main.params[ 'TEST' ][ 'testCMD1' ]
-        main.maxNodes = main.params[ 'max' ]
         cooldown = main.params[ 'TEST' ][ 'cooldown' ]
         cellName = main.params[ 'ENV' ][ 'cellName' ]
         BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
@@ -174,14 +94,14 @@
         flowRuleBackup = str(main.params[ 'TEST' ][ 'enableFlowRuleStoreBackup' ])
         main.log.info("Flow Rule Backup is set to:" + flowRuleBackup)
 
-        servers = str(clusterCount)
+        servers = str( main.numCtrls )
 
-        if clusterCount == 1:
+        if main.numCtrls == 1:
             neighborList = ['0']
             currentNeighbors = "r"
         else:
             if currentNeighbors == "a":
-                neighborList = [str(clusterCount-1)]
+                neighborList = [ str( main.numCtrls - 1 ) ]
                 currentNeighbors = "r"
             else:
                 neighborList = ['0']
@@ -193,23 +113,23 @@
 
         for n in neighborList:
             main.step("\tSTARTING TEST")
-            main.step("\tLOADING FROM SERVERS:  \t" + str(clusterCount) )
+            main.step("\tLOADING FROM SERVERS:  \t" + str( main.numCtrls ) )
             main.step("\tNEIGHBORS:\t" + n )
             main.log.info("=============================================================")
             main.log.info("=============================================================")
             #write file to configure nil link
             ipCSV = ""
-            for i in range (1, int(main.maxNodes) + 1):
-                tempstr = "ip" + str(i)
+            for i in range ( main.maxNodes ):
+                tempstr = "ip" + str( i + 1 )
                 ipCSV += main.params[ 'CTRL' ][ tempstr ]
-                if i < int(main.maxNodes):
+                if i + 1 < main.maxNodes:
                     ipCSV +=","
 
-            main.ONOSbench.onosCfgSet(ONOSIp[1], "org.onosproject.store.flow.impl.DistributedFlowRuleStore", "backupCount 1")
+            main.ONOSbench.onosCfgSet(main.ONOSip[0], "org.onosproject.store.flow.impl.DistributedFlowRuleStore", "backupCount 1")
             for i in range(3):
-                main.ONOSbench.onosCfgSet(ONOSIp[1], "org.onosproject.provider.nil.NullProviders", "deviceCount 35")
-                main.ONOSbench.onosCfgSet(ONOSIp[1], "org.onosproject.provider.nil.NullProviders", "topoShape linear")
-                main.ONOSbench.onosCfgSet(ONOSIp[1], "org.onosproject.provider.nil.NullProviders", "enabled true")
+                main.ONOSbench.onosCfgSet(main.ONOSip[0], "org.onosproject.provider.nil.NullProviders", "deviceCount 35")
+                main.ONOSbench.onosCfgSet(main.ONOSip[0], "org.onosproject.provider.nil.NullProviders", "topoShape linear")
+                main.ONOSbench.onosCfgSet(main.ONOSip[0], "org.onosproject.provider.nil.NullProviders", "enabled true")
 
                 time.sleep(5)
                 main.ONOSbench.handle.sendline("onos $OC1 summary")
@@ -236,8 +156,8 @@
 
             #build list of servers in "$OC1, $OC2...." format
             serverEnvVars = ""
-            for i in range (1,int(servers)+1):
-                serverEnvVars += ("-s " + ONOSIp[i] + " ")
+            for i in range( int( servers ) ):
+                serverEnvVars += ( "-s " + main.ONOSip[ i ] + " " )
 
             data = [[""]*int(servers)]*int(sampleSize)
             maxes = [""]*int(sampleSize)
@@ -263,10 +183,10 @@
                 if "failed" in rawResult:
                     main.log.report("FLOW_TESTER.PY FAILURE")
                     main.log.report( " \n" + rawResult + " \n")
-                    for i in range(1, clusterCount+1):
+                    for i in range( main.numCtrls ):
                         main.log.report("=======================================================")
-                        main.log.report(" ONOS " + str(i) + "LOG REPORT")
-                        main.ONOSbench.logReport(ONOSIp[i], ["ERROR", "WARNING", "EXCEPT"], outputMode="d")
+                        main.log.report(" ONOS " + str( i + 1 ) + "LOG REPORT")
+                        main.ONOSbench.logReport( main.ONOSip[ i ], ["ERROR", "WARNING", "EXCEPT"], outputMode="d" )
                     main.ONOSbench.handle.sendline("onos $OC1 flows")
                     main.ONOSbench.handle.expect(":~")
                     main.log.info(main.ONOSbench.handle.before)
@@ -274,17 +194,17 @@
                     break
 
             ########################################################################################
-                result = [""]*(clusterCount)
+                result = [""]*( main.numCtrls )
 
                 #print("rawResult: " + rawResult)
 
                 rawResult = rawResult.splitlines()
 
-                for node in range(1, clusterCount + 1):
+                for node in range( main.numCtrls ):
                     for line in rawResult:
                         #print("line: " + line)
-                        if ONOSIp[node] in line and "server" in line:
-                            temp = line.split(" ")
+                        if main.ONOSip[ node ] in line and "server" in line:
+                            temp = line.split( " " )
                             for word in temp:
                                 #print ("word: " + word)
                                 if "elapsed" in repr(word):
@@ -292,8 +212,8 @@
                                     myParsed = (temp[index]).replace(",","")
                                     myParsed = myParsed.replace("}","")
                                     myParsed = int(myParsed)
-                                    result[node-1] = myParsed
-                                    main.log.info( ONOSIp[node] + " : " + str(myParsed))
+                                    result[ node ] = myParsed
+                                    main.log.info( main.ONOSip[ node ] + " : " + str( myParsed ) )
                                     break
 
                 if test >= warmUp:
@@ -370,16 +290,16 @@
             main.log.info("Average thoughput:  " + str(avgTP) + " Kflows/second" )
             main.log.info("Standard deviation of throughput: " + str(stdTP) + " Kflows/second")
 
-            resultsLog = open("/tmp/flowTP1gDB","a")
-            resultString = ("'" + commit + "',")
-            resultString += ("'1gig',")
-            resultString += ((main.params[ 'TEST' ][ 'flows' ]) + ",")
-            resultString += (str(clusterCount) + ",")
-            resultString += (str(n) + ",")
-            resultString += (str(avgTP) + "," + str(stdTP) + "\n")
-            resultsLog.write(resultString)
+            resultsLog = open( "/tmp/flowTP1gDB", "a" )
+            resultString = ( "'" + main.commit + "'," )
+            resultString += ( "'1gig'," )
+            resultString += ( (main.params[ 'TEST' ][ 'flows' ] ) + "," )
+            resultString += ( str( main.numCtrls ) + "," )
+            resultString += ( str( n ) + "," )
+            resultString += ( str( avgTP ) + "," + str( stdTP ) + "\n" )
+            resultsLog.write( resultString )
             resultsLog.close()
 
-            main.log.report("Result line to file: " + resultString)
+            main.log.report( "Result line to file: " + resultString )
 
-        main.ONOSbench.logReport(ONOSIp[1], ["ERROR", "WARNING", "EXCEPT"], outputMode="d")
+        main.ONOSbench.logReport( main.ONOSip[ 0 ], [ "ERROR", "WARNING", "EXCEPT" ], outputMode="d" )
diff --git a/TestON/tests/SCPF/SCPFhostLat/SCPFhostLat.py b/TestON/tests/SCPF/SCPFhostLat/SCPFhostLat.py
index e3af24a..8ab7a44 100644
--- a/TestON/tests/SCPF/SCPFhostLat/SCPFhostLat.py
+++ b/TestON/tests/SCPF/SCPFhostLat/SCPFhostLat.py
@@ -18,83 +18,69 @@
         import time
         import os
         import imp
-
-        main.case( "Constructing test variables and building ONOS package" )
-        main.step( "Constructing test variables" )
-        stepResult = main.FALSE
-
-        # Test variables
-        main.testOnDirectory = os.path.dirname( os.getcwd ( ) )
-        main.cellName = main.params[ 'ENV' ][ 'cellName' ]
-        main.apps = main.params[ 'ENV' ][ 'cellApps' ]
-        main.scale = ( main.params[ 'SCALE' ] ).split( "," )
-        main.ONOSport = main.params[ 'CTRL' ][ 'port' ]
-        main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
-        main.installSleep = int( main.params[ 'SLEEP' ][ 'install' ] )
-        main.measurementSleep = int( main.params['SLEEP']['measurement'])
-        main.timeout = int( main.params['SLEEP']['timeout'] )
-        main.dbFileName = main.params['DATABASE']['file']
-        main.cellData = {} # for creating cell file
-
-        # Tshark params
-        main.tsharkResultPath = main.params['TSHARK']['tsharkPath']
-        main.tsharkPacketIn = main.params['TSHARK']['tsharkPacketIn']
-
-        main.numlter = main.params['TEST']['numIter']
-        main.iterIgnore = int(main.params['TEST']['iterIgnore'])
-        main.hostTimestampKey = main.params['TEST']['hostTimestamp']
-        main.thresholdStr = main.params['TEST']['singleSwThreshold']
-        main.thresholdObj = main.thresholdStr.split(',')
-        main.thresholdMin = int(main.thresholdObj[0])
-        main.thresholdMax = int(main.thresholdObj[1])
-        main.threadID = 0
-
-        main.CLIs = []
-        main.ONOSip = []
-        main.maxNumBatch = 0
-        main.ONOSip = main.ONOSbench.getOnosIps()
-        main.log.info(main.ONOSip)
-        main.setupSkipped = False
-
-        gitBranch = main.params[ 'GIT' ][ 'branch' ]
-        gitPull = main.params[ 'GIT' ][ 'pull' ]
-        nic = main.params['DATABASE']['nic']
-        node = main.params['DATABASE']['node']
-        nic = main.params['DATABASE']['nic']
-        node = main.params['DATABASE']['node']
-        stepResult = main.TRUE
-
-        main.log.info("Cresting DB file")
-        with open(main.dbFileName, "w+") as dbFile:
-            dbFile.write("")
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="environment set up successfull",
-                                 onfail="environment set up Failed" )
-
-    def CASE1( self ):
-        # main.scale[ 0 ] determines the current number of ONOS controller
-        main.CLIs = []
-        main.numCtrls = int( main.scale[ 0 ] )
-        main.log.info( "Creating list of ONOS cli handles" )
-        for i in range(main.numCtrls):
-            main.CLIs.append( getattr( main, 'ONOScli%s' % (i+1) ) )
-
-        main.log.info(main.CLIs)
-        if not main.CLIs:
-            main.log.error( "Failed to create the list of ONOS cli handles" )
-            main.cleanup()
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
             main.exit()
+        main.testSetUp.envSetupDescription()
+        stepResult = main.FALSE
+        try:
 
-        main.commit = main.ONOSbench.getVersion(report=True)
-        main.commit = main.commit.split(" ")[1]
+            # Test variables
+            main.cellName = main.params[ 'ENV' ][ 'cellName' ]
+            main.apps = main.params[ 'ENV' ][ 'cellApps' ]
+            main.scale = ( main.params[ 'SCALE' ] ).split( "," )
+            main.ONOSport = main.params[ 'CTRL' ][ 'port' ]
+            main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
+            main.installSleep = int( main.params[ 'SLEEP' ][ 'install' ] )
+            main.measurementSleep = int( main.params[ 'SLEEP' ][ 'measurement' ] )
+            main.timeout = int( main.params[ 'SLEEP' ][ 'timeout' ] )
+            main.dbFileName = main.params[ 'DATABASE' ][ 'file' ]
 
-        with open(main.dbFileName, "a") as dbFile:
+            # Tshark params
+            main.tsharkResultPath = main.params[ 'TSHARK' ][ 'tsharkPath' ]
+            main.tsharkPacketIn = main.params[ 'TSHARK' ][ 'tsharkPacketIn' ]
+
+            main.numlter = main.params[ 'TEST' ][ 'numIter' ]
+            main.iterIgnore = int( main.params[ 'TEST' ][ 'iterIgnore' ] )
+            main.hostTimestampKey = main.params[ 'TEST' ][ 'hostTimestamp' ]
+            main.thresholdStr = main.params[ 'TEST' ][ 'singleSwThreshold' ]
+            main.thresholdObj = main.thresholdStr.split( ',' )
+            main.thresholdMin = int( main.thresholdObj[ 0 ] )
+            main.thresholdMax = int( main.thresholdObj[ 1 ] )
+            main.threadID = 0
+
+            main.maxNumBatch = 0
+            main.setupSkipped = False
+
+            nic = main.params[ 'DATABASE' ][ 'nic' ]
+            node = main.params[ 'DATABASE' ][ 'node' ]
+            nic = main.params[ 'DATABASE' ][ 'nic' ]
+            node = main.params[ 'DATABASE' ][ 'node' ]
+            stepResult = main.TRUE
+
+            main.log.info( "Cresting DB file" )
+            with open( main.dbFileName, "w+" ) as dbFile:
+                dbFile.write( "" )
+
+            stepResult = main.testSetUp.gitPulling()
+        except Exception as e:
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
+
+        main.commit = main.commit.split( " " )[ 1 ]
+
+        with open( main.dbFileName, "a" ) as dbFile:
             temp = "'" + main.commit + "',"
             temp += "'" + nic + "',"
-            dbFile.write(temp)
+            dbFile.write( temp )
             dbFile.close()
+    def CASE1( self ):
+        # main.scale[ 0 ] determines the current number of ONOS controller
+        main.testSetUp.getNumCtrls( True )
+        main.testSetUp.envSetup( includeGitPull=False, makeMaxNodes=False )
 
     def CASE2( self, main ):
         """
@@ -103,118 +89,9 @@
         - Install ONOS cluster
         - Connect to cli
         """
-        main.log.info( "Starting up %s node(s) ONOS cluster" % main.numCtrls)
-        main.log.info( "Safety check, killing all ONOS processes" +
-                       " before initiating environment setup" )
-
-        for i in range( main.numCtrls ):
-            main.ONOSbench.onosStop( main.ONOSip[ i ] )
-            main.ONOSbench.onosKill( main.ONOSip[ i ] )
-
-        main.log.info( "NODE COUNT = %s" % main.numCtrls)
-
-        tempOnosIp = []
-        for i in range( main.numCtrls ):
-            tempOnosIp.append( main.ONOSip[i] )
-
-        main.ONOSbench.createCellFile( main.ONOSbench.ip_address,
-                                       "temp",
-                                       main.Mininet1.ip_address,
-                                       main.apps,
-                                       tempOnosIp,
-                                       main.ONOScli1.karafUser )
-
-        main.step( "Apply cell to environment" )
-        cellResult = main.ONOSbench.setCell( "temp" )
-        verifyResult = main.ONOSbench.verifyCell()
-        stepResult = cellResult and verifyResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully applied cell to " + \
-                                        "environment",
-                                 onfail="Failed to apply cell to environment " )
-
-        main.step( "Creating ONOS package" )
-        packageResult = main.ONOSbench.buckBuild()
-        stepResult = packageResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully created ONOS package",
-                                 onfail="Failed to create ONOS package" )
-
-        main.step( "Uninstall ONOS package on all Nodes" )
-        uninstallResult = main.TRUE
-        for i in range( int( main.numCtrls ) ):
-            main.log.info( "Uninstalling package on ONOS Node IP: " + main.ONOSip[i] )
-            u_result = main.ONOSbench.onosUninstall( main.ONOSip[i] )
-            utilities.assert_equals( expect=main.TRUE, actual=u_result,
-                                     onpass="Test step PASS",
-                                     onfail="Test step FAIL" )
-            uninstallResult = ( uninstallResult and u_result )
-
-        main.step( "Install ONOS package on all Nodes" )
-        installResult = main.TRUE
-        for i in range( int( main.numCtrls ) ):
-            main.log.info( "Installing package on ONOS Node IP: " + main.ONOSip[i] )
-            i_result = main.ONOSbench.onosInstall( node=main.ONOSip[i] )
-            utilities.assert_equals( expect=main.TRUE, actual=i_result,
-                                     onpass="Test step PASS",
-                                     onfail="Test step FAIL" )
-            installResult = installResult and i_result
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.TRUE
-        for i in range( int( main.numCtrls ) ):
-            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=main.ONOSip[i] )
-        utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        time.sleep( main.startUpSleep )
-        main.step( "Starting ONOS service" )
-        stopResult = main.TRUE
-        startResult = main.TRUE
-        onosIsUp = main.TRUE
-
-        for i in range( main.numCtrls ):
-            onosIsUp = onosIsUp and main.ONOSbench.isup( main.ONOSip[ i ] )
-        if onosIsUp == main.TRUE:
-            main.log.report( "ONOS instance is up and ready" )
-        else:
-            main.log.report( "ONOS instance may not be up, stop and " +
-                             "start ONOS again " )
-            for i in range( main.numCtrls ):
-                stopResult = stopResult and \
-                        main.ONOSbench.onosStop( main.ONOSip[ i ] )
-            for i in range( main.numCtrls ):
-                startResult = startResult and \
-                        main.ONOSbench.onosStart( main.ONOSip[ i ] )
-        stepResult = onosIsUp and stopResult and startResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="ONOS service is ready",
-                                 onfail="ONOS service did not start properly" )
-
-        main.step( "Start ONOS CLI on all nodes" )
-        cliResult = main.TRUE
-        main.step(" Start ONOS cli using thread ")
-        time.sleep( main.startUpSleep )
-        startCliResult  = main.TRUE
-        pool = []
-
-        for i in range( int( main.numCtrls) ):
-            t = main.Thread( target=main.CLIs[i].startOnosCli,
-                             threadID=main.threadID,
-                             name="startOnosCli",
-                             args=[ main.ONOSip[i] ],
-                             kwargs = {"onosStartTimeout":main.timeout} )
-            pool.append(t)
-            t.start()
-            main.threadID = main.threadID + 1
-        for t in pool:
-            t.join()
-            startCliResult = startCliResult and t.result
-        time.sleep( main.startUpSleep )
+        main.testSetUp.ONOSSetUp( main.Mininet1, True,
+                                  cellName=main.cellName, killRemoveMax=False,
+                                  CtrlsSet=False )
 
     def CASE11( self, main ):
         main.log.info( "set and configure Application" )
@@ -224,7 +101,7 @@
         main.step( "Activating org.onosproject.proxyarp" )
         appStatus = utilities.retry( main.ONOSrest1.activateApp,
                                      main.FALSE,
-                                     ['org.onosproject.proxyarp'],
+                                     [ 'org.onosproject.proxyarp' ],
                                      sleep=3,
                                      attempts=3 )
         utilities.assert_equals( expect=main.TRUE,
@@ -246,7 +123,7 @@
                                  onpass="Successfully set DefaultTopologyProvider",
                                  onfail="Failed to set DefaultTopologyProvider" )
 
-        time.sleep(main.startUpSleep)
+        time.sleep( main.startUpSleep)
         main.step('Starting mininet topology')
         mnStatus = main.Mininet1.startNet(args='--topo=linear,1')
         utilities.assert_equals( expect=main.TRUE,
@@ -261,7 +138,7 @@
                                  onpass="Successfully assigned switches to masters",
                                  onfail="Failed assign switches to masters" )
 
-        time.sleep(main.startUpSleep)
+        time.sleep( main.startUpSleep)
 
     def CASE20(self, main):
         """
@@ -278,72 +155,80 @@
         import requests
         import os
         import numpy
-
+        try:
+            from tests.dependencies.utils import Utils
+        except ImportError:
+            main.log.error( "Utils not found exiting the test" )
+            main.exit()
+        try:
+            main.Utils
+        except ( NameError, AttributeError ):
+            main.Utils = Utils()
         # Host adding measurement
         assertion = main.TRUE
 
         main.log.report('Latency of adding one host to ONOS')
-        main.log.report('First ' + str(main.iterIgnore) + ' iterations ignored' + ' for jvm warmup time')
-        main.log.report('Total iterations of test: ' + str(main.numlter))
+        main.log.report('First ' + str( main.iterIgnore ) + ' iterations ignored' + ' for jvm warmup time')
+        main.log.report('Total iterations of test: ' + str( main.numlter ) )
 
         addingHostTime = []
         metricsResultList = []
-        for i in range(0, int(main.numlter)):
-            main.log.info('Clean up data file')
-            with open(main.tsharkResultPath, "w") as dbFile:
-                dbFile.write("")
+        for i in range( 0, int( main.numlter ) ):
+            main.log.info( 'Clean up data file' )
+            with open( main.tsharkResultPath, "w" ) as dbFile:
+                dbFile.write( "" )
 
             main.log.info('Starting tshark capture')
-            main.ONOSbench.tsharkGrep(main.tsharkPacketIn, main.tsharkResultPath)
-            time.sleep(main.measurementSleep)
+            main.ONOSbench.tsharkGrep( main.tsharkPacketIn, main.tsharkResultPath )
+            time.sleep( main.measurementSleep )
 
             main.log.info('host 1 arping...')
             main.Mininet1.arping(srcHost='h1', dstHost='10.0.0.2')
 
-            time.sleep(main.measurementSleep)
+            time.sleep( main.measurementSleep )
 
             main.log.info('Stopping all Tshark processes')
             main.ONOSbench.tsharkStop()
 
-            time.sleep(main.measurementSleep)
+            time.sleep( main.measurementSleep )
 
             # Get tshark output
-            with open(main.tsharkResultPath, "r") as resultFile:
+            with open( main.tsharkResultPath, "r" ) as resultFile:
                 resultText = resultFile.readline()
-                main.log.info('Capture result:' + resultText)
+                main.log.info( 'Capture result:' + resultText )
                 resultText = resultText.split(' ')
-                if len(resultText) > 1:
-                    tsharkResultTime = float(resultText[1]) * 1000.0
+                if len( resultText ) > 1:
+                    tsharkResultTime = float( resultText[ 1 ] ) * 1000.0
                 else:
-                    main.log.error('Tshark output file for packet_in' + ' returned unexpected results')
+                    main.log.error( 'Tshark output file for packet_in' + ' returned unexpected results' )
                     hostTime = 0
                     caseResult = main.FALSE
                 resultFile.close()
             # Compare the timestemps, and get the lowest one.
             temp = 0;
             # Get host event timestamps from each nodes
-            for node in range (0, main.numCtrls):
-                metricsResult = json.loads(main.CLIs[node].topologyEventsMetrics())
-                metricsResult = metricsResult.get(main.hostTimestampKey).get("value")
-                main.log.info("ONOS topology event matrics timestemp: {}".format(str(metricsResult)) )
+            for node in range ( 0, main.numCtrls ):
+                metricsResult = json.loads( main.CLIs[ node ].topologyEventsMetrics() )
+                metricsResult = metricsResult.get( main.hostTimestampKey ).get( "value" )
+                main.log.info( "ONOS topology event matrics timestemp: {}".format( str( metricsResult ) ) )
 
                 if temp < metricsResult:
                     temp = metricsResult
                 metricsResult = temp
 
-            addingHostTime.append(float(metricsResult) - tsharkResultTime)
-            main.log.info("Result of this iteration: {}".format( str( float(metricsResult) - tsharkResultTime) ))
+            addingHostTime.append( float( metricsResult ) - tsharkResultTime )
+            main.log.info( "Result of this iteration: {}".format( str( float( metricsResult ) - tsharkResultTime) ) )
             # gethost to remove
             gethost = main.ONOSrest1.hosts()
             HosttoRemove = []
-            HosttoRemove.append( json.loads( gethost[1:len(gethost)-1] ).get('id') )
-            main.CLIs[0].removeHost(HosttoRemove)
+            HosttoRemove.append( json.loads( gethost[ 1:len( gethost )-1 ] ).get( 'id' ) )
+            main.CLIs[0].removeHost( HosttoRemove )
 
-        main.log.info("Result List: {}".format(addingHostTime))
+        main.log.info( "Result List: {}".format( addingHostTime ) )
 
         # calculate average latency from each nodes
-        averageResult = numpy.average(addingHostTime)
-        main.log.info("Average Latency: {}".format(averageResult))
+        averageResult = numpy.average( addingHostTime )
+        main.log.info( "Average Latency: {}".format( averageResult ) )
 
         # calculate std
         stdResult = numpy.std(addingHostTime)
@@ -368,5 +253,4 @@
                 onpass='Host latency test successful',
                 onfail='Host latency test failed')
 
-        main.Mininet1.stopNet()
-        del main.scale[0]
+        main.Utils.mininetCleanup( main.Mininet1 )
diff --git a/TestON/tests/SCPF/SCPFintentEventTp/SCPFintentEventTp.params b/TestON/tests/SCPF/SCPFintentEventTp/SCPFintentEventTp.params
index 7952499..30e6e02 100644
--- a/TestON/tests/SCPF/SCPFintentEventTp/SCPFintentEventTp.params
+++ b/TestON/tests/SCPF/SCPFintentEventTp/SCPFintentEventTp.params
@@ -13,8 +13,8 @@
     <max>7</max>
 
     <GIT>
-        <gitPull>off</gitPull>
-        <gitBranch>master</gitBranch>
+        <pull>False</pull>
+        <branch>master</branch>
     </GIT>
 
     <CTRL>
diff --git a/TestON/tests/SCPF/SCPFintentEventTp/SCPFintentEventTp.py b/TestON/tests/SCPF/SCPFintentEventTp/SCPFintentEventTp.py
index f71d2e5..adc6ac2 100644
--- a/TestON/tests/SCPF/SCPFintentEventTp/SCPFintentEventTp.py
+++ b/TestON/tests/SCPF/SCPFintentEventTp/SCPFintentEventTp.py
@@ -24,196 +24,69 @@
             different versions of ONOS.
         - Construct tests variables
         '''
-        gitPull = main.params['GIT']['gitPull']
-        gitBranch = main.params['GIT']['gitBranch']
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        main.testSetUp.envSetupDescription()
+        stepResult = main.FALSE
+        try:
+            main.cellName = main.params[ 'ENV'][ 'cellName']
+            main.apps = main.params[ 'ENV' ][ 'cellApps' ]
+            main.BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
+            main.BENCHUser = main.params[ 'BENCH' ][ 'user' ]
+            main.MN1Ip = main.params[ 'MN' ][ 'ip1' ]
+            main.maxNodes = int( main.params[ 'max' ] )
+            main.numSwitches = ( main.params[ 'TEST' ][ 'numSwitches' ] ).split(",")
+            main.skipRelRsrc = main.params[ 'TEST' ][ 'skipReleaseResourcesOnWithdrawal' ]
+            main.flowObj = main.params[ 'TEST' ][ 'flowObj' ]
+            main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
+            main.installSleep = int( main.params[ 'SLEEP' ][ 'install' ] )
+            main.verifySleep = int( main.params[ 'SLEEP' ][ 'verify' ] )
+            main.scale = ( main.params[ 'SCALE' ] ).split(",")
+            main.testDuration = main.params[ 'TEST' ][ 'duration' ]
+            main.logInterval = main.params[ 'TEST' ][ 'log_interval' ]
+            main.debug = main.params[ 'debugMode' ]
+            main.timeout = int( main.params[ 'SLEEP' ][ 'timeout' ] )
+            main.cyclePeriod = main.params[ 'TEST' ][ 'cyclePeriod' ]
+            if main.flowObj == "True":
+                main.flowObj = True
+                main.dbFileName = main.params[ 'DATABASE' ][ 'dbFlowObj' ]
+                main.numKeys = main.params[ 'TEST' ][ 'numKeysFlowObj' ]
+            else:
+                main.flowObj = False
+                main.dbFileName = main.params[ 'DATABASE' ][ 'dbName' ]
+                main.numKeys = main.params[ 'TEST' ][ 'numKeys' ]
 
-        main.case( "Pull onos branch and build onos on Teststation." )
+            stepResult = main.testSetUp.gitPulling()
+            # Create DataBase file
+            main.log.info( "Create Database file " + main.dbFileName )
+            resultsDB = open( main.dbFileName, "w+" )
+            resultsDB.close()
 
-        if gitPull == 'True':
-            main.step( "Git Checkout ONOS branch: " + gitBranch )
-            stepResult = main.ONOSbench.gitCheckout( branch=gitBranch )
-            utilities.assert_equals(expect=main.TRUE,
-                                    actual=stepResult,
-                                    onpass="Successfully checkout onos branch.",
-                                    onfail="Failed to checkout onos branch. Exiting test...")
-            if not stepResult: main.exit()
-
-            main.step( "Git Pull on ONOS branch:" + gitBranch )
-            stepResult = main.ONOSbench.gitPull()
-            utilities.assert_equals(expect=main.TRUE,
-                                    actual=stepResult,
-                                    onpass="Successfully pull onos. ",
-                                    onfail="Failed to pull onos. Exiting test ...")
-            if not stepResult: main.exit()
-
-        else:
-            main.log.warn( "Skipped pulling onos" )
-
-        main.cellName = main.params['ENV']['cellName']
-        main.Apps = main.params['ENV']['cellApps']
-        main.BENCHIp = main.params['BENCH']['ip1']
-        main.BENCHUser = main.params['BENCH']['user']
-        main.MN1Ip = main.params['MN']['ip1']
-        main.maxNodes = int(main.params['max'])
-        main.numSwitches = (main.params['TEST']['numSwitches']).split(",")
-        main.skipRelRsrc = main.params['TEST']['skipReleaseResourcesOnWithdrawal']
-        main.flowObj = main.params['TEST']['flowObj']
-        main.startUpSleep = int(main.params['SLEEP']['startup'])
-        main.installSleep = int(main.params['SLEEP']['install'])
-        main.verifySleep = int(main.params['SLEEP']['verify'])
-        main.scale = (main.params['SCALE']).split(",")
-        main.testDuration = main.params[ 'TEST' ][ 'duration' ]
-        main.logInterval = main.params[ 'TEST' ][ 'log_interval' ]
-        main.debug = main.params[ 'debugMode' ]
-        main.timeout = int(main.params['SLEEP']['timeout'])
-        main.cyclePeriod = main.params[ 'TEST' ][ 'cyclePeriod' ]
-        if main.flowObj == "True":
-            main.flowObj = True
-            main.dbFileName = main.params['DATABASE']['dbFlowObj']
-            main.numKeys = main.params[ 'TEST' ][ 'numKeysFlowObj' ]
-        else:
-            main.flowObj = False
-            main.dbFileName = main.params['DATABASE']['dbName']
-            main.numKeys = main.params[ 'TEST' ][ 'numKeys' ]
-        # Create DataBase file
-        main.log.info( "Create Database file " + main.dbFileName )
-        resultsDB = open( main.dbFileName, "w+" )
-        resultsDB.close()
-
-        # set neighbors
-        main.neighbors = "1"
+            # set neighbors
+            main.neighbors = "1"
+        except Exception as e:
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
+        main.commit = main.commit.split( " " )[ 1 ]
 
     def CASE1( self, main ):
         # Clean up test environment and set up
         import time
-        main.log.info( "Get ONOS cluster IP" )
-        print( main.scale )
-        main.numCtrls = int( main.scale.pop(0) )
-        main.ONOSip = []
         main.maxNumBatch = 0
-        main.AllONOSip = main.ONOSbench.getOnosIps()
-        for i in range( main.numCtrls ):
-            main.ONOSip.append( main.AllONOSip[i] )
-        main.log.info( main.ONOSip )
-        main.CLIs = []
-        main.log.info( "Creating list of ONOS cli handles" )
-        for i in range( main.numCtrls ):
-            main.CLIs.append( getattr( main, 'ONOScli%s' % (i + 1) ) )
-
-        if not main.CLIs:
-            main.log.error( "Failed to create the list of ONOS cli handles" )
-            main.cleanup()
-            main.exit()
-
-        main.commit = main.ONOSbench.getVersion( report=True )
-        main.commit = main.commit.split(" ")[1]
-        main.log.info( "Starting up %s node(s) ONOS cluster" % main.numCtrls )
-        main.log.info("Safety check, killing all ONOS processes" +
-                      " before initiating environment setup")
-
-        for i in range( main.numCtrls ):
-            main.ONOSbench.onosStop( main.ONOSip[i] )
-            main.ONOSbench.onosKill( main.ONOSip[i] )
-
-        main.log.info( "NODE COUNT = %s" % main.numCtrls )
-        main.ONOSbench.createCellFile(main.ONOSbench.ip_address,
-                                      main.cellName,
-                                      main.MN1Ip,
-                                      main.Apps,
-                                      main.ONOSip,
-                                      main.ONOScli1.karafUser )
-        main.step( "Apply cell to environment" )
-        cellResult = main.ONOSbench.setCell( main.cellName )
-        verifyResult = main.ONOSbench.verifyCell()
-        stepResult = cellResult and verifyResult
-        utilities.assert_equals(expect=main.TRUE,
-                                actual=stepResult,
-                                onpass="Successfully applied cell to " + \
-                                       "environment",
-                                onfail="Failed to apply cell to environment ")
-
-        main.step( "Creating ONOS package" )
-        packageResult = main.ONOSbench.buckBuild()
-        stepResult = packageResult
-        utilities.assert_equals(expect=main.TRUE,
-                                actual=stepResult,
-                                onpass="Successfully created ONOS package",
-                                onfail="Failed to create ONOS package")
-
-        main.step( "Uninstall ONOS package on all Nodes" )
-        uninstallResult = main.TRUE
-        for i in range( int( main.numCtrls ) ):
-            main.log.info( "Uninstalling package on ONOS Node IP: " + main.ONOSip[i] )
-            u_result = main.ONOSbench.onosUninstall( main.ONOSip[i] )
-            utilities.assert_equals(expect=main.TRUE, actual=u_result,
-                                    onpass="Test step PASS",
-                                    onfail="Test step FAIL")
-            uninstallResult = ( uninstallResult and u_result )
-
-        main.step( "Install ONOS package on all Nodes" )
-        installResult = main.TRUE
-        for i in range( int( main.numCtrls ) ):
-            main.log.info( "Installing package on ONOS Node IP: " + main.ONOSip[i] )
-            i_result = main.ONOSbench.onosInstall(node=main.ONOSip[i])
-            utilities.assert_equals(expect=main.TRUE, actual=i_result,
-                                    onpass="Test step PASS",
-                                    onfail="Test step FAIL")
-            installResult = installResult and i_result
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.TRUE
-        for i in range( int( main.numCtrls ) ):
-            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=main.ONOSip[i] )
-        utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        time.sleep( main.startUpSleep )
-        main.step( "Starting ONOS service" )
-        stopResult = main.TRUE
-        startResult = main.TRUE
-        onosIsUp = main.TRUE
-        for i in range( main.numCtrls ):
-            onosIsUp = onosIsUp and main.ONOSbench.isup( main.ONOSip[ i ] )
-        if onosIsUp == main.TRUE:
-            main.log.report( "ONOS instance is up and ready" )
-        else:
-            main.log.report( "ONOS instance may not be up, stop and " +
-                             "start ONOS again " )
-            for i in range( main.numCtrls ):
-                stopResult = stopResult and \
-                        main.ONOSbench.onosStop( main.ONOSip[ i ] )
-            for i in range( main.numCtrls ):
-                startResult = startResult and \
-                        main.ONOSbench.onosStart( main.ONOSip[ i ] )
-        stepResult = onosIsUp and stopResult and startResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="ONOS service is ready",
-                                 onfail="ONOS service did not start properly" )
-
-        main.step( "Start ONOS cli using thread" )
-        startCliResult = main.TRUE
-        pool = []
-        main.threadID = 0
-        for i in range(int(main.numCtrls)):
-            t = main.Thread(target=main.CLIs[i].startOnosCli,
-                            threadID=main.threadID,
-                            name="startOnosCli",
-                            args=[main.ONOSip[i]],
-                            kwargs={"onosStartTimeout": main.timeout})
-            pool.append(t)
-            t.start()
-            main.threadID = main.threadID + 1
-        for t in pool:
-            t.join()
-            startCliResult = startCliResult and t.result
-        time.sleep( main.startUpSleep )
+        main.testSetUp.getNumCtrls( True )
+        main.testSetUp.envSetup( includeGitPull=False, makeMaxNodes=False )
+        main.testSetUp.ONOSSetUp( main.MN1Ip, True,
+                                  cellName=main.cellName, killRemoveMax=False,
+                                  CtrlsSet=False )
 
         # config apps
         main.CLIs[0].setCfg( "org.onosproject.net.intent.impl.IntentManager",
                                   "skipReleaseResourcesOnWithdrawal " + main.skipRelRsrc )
-        main.CLIs[0].setCfg( "org.onosproject.provider.nil.NullProviders", "deviceCount " + str(int(main.numCtrls*10)) )
+        main.CLIs[0].setCfg( "org.onosproject.provider.nil.NullProviders", "deviceCount " + str(int( main.numCtrls*10)) )
         main.CLIs[0].setCfg( "org.onosproject.provider.nil.NullProviders", "topoShape linear" )
         main.CLIs[0].setCfg( "org.onosproject.provider.nil.NullProviders", "enabled true" )
         if main.flowObj:
@@ -248,7 +121,7 @@
         main.CLIs[0].setCfg( "org.onosproject.intentperf.IntentPerfInstaller", "numNeighbors " + str( main.neighbors ) )
         main.CLIs[0].setCfg( "org.onosproject.intentperf.IntentPerfInstaller", "cyclePeriod " + main.cyclePeriod )
 
-        main.log.info( "Starting intent-perf test for " + str(main.testDuration) + " seconds..." )
+        main.log.info( "Starting intent-perf test for " + str( main.testDuration) + " seconds..." )
         main.CLIs[0].sendline( "intent-perf-start" )
         stop = time.time() + float( main.testDuration )
 
@@ -256,20 +129,20 @@
             time.sleep(15)
             result = main.CLIs[0].getIntentPerfSummary()
             if result:
-                for ip in main.ONOSip:
-                    main.log.info( "Node {} Overall Rate: {}".format( ip, result[ip] ) )
+                for i in range( main.numCtrls ):
+                    main.log.info( "Node {} Overall Rate: {}".format( main.ONOSip[ i ], result[ main.ONOSip[ i ] ] ) )
         main.log.info( "Stop intent-perf" )
-        for node in main.CLIs:
-            node.sendline( "intent-perf-stop" )
+        for i in range( main.numCtrls ):
+            main.CLIs[i].sendline( "intent-perf-stop" )
         if result:
-            for ip in main.ONOSip:
-                main.log.info( "Node {} final Overall Rate: {}".format( ip, result[ip] ) )
+            for i in range( main.numCtrls ):
+                main.log.info( "Node {} final Overall Rate: {}".format( main.ONOSip[ i ], result[ main.ONOSip[ i ] ] ) )
 
         with open( main.dbFileName, "a" ) as resultDB:
-            for nodes in range( 0, len( main.ONOSip ) ):
+            for nodes in range( main.numCtrls ):
                 resultString = "'" + main.commit + "',"
                 resultString += "'1gig',"
-                resultString += str(main.numCtrls) + ","
+                resultString += str( main.numCtrls) + ","
                 resultString += "'baremetal" + str( nodes+1 ) + "',"
                 resultString += main.neighbors + ","
                 resultString += result[ main.ONOSip[ nodes ] ]+","
diff --git a/TestON/tests/SCPF/SCPFintentInstallWithdrawLat/SCPFintentInstallWithdrawLat.params b/TestON/tests/SCPF/SCPFintentInstallWithdrawLat/SCPFintentInstallWithdrawLat.params
index 308e0d0..033c05f 100644
--- a/TestON/tests/SCPF/SCPFintentInstallWithdrawLat/SCPFintentInstallWithdrawLat.params
+++ b/TestON/tests/SCPF/SCPFintentInstallWithdrawLat/SCPFintentInstallWithdrawLat.params
@@ -21,8 +21,8 @@
      </TEST>
 
     <GIT>
-        <gitPull>off</gitPull>
-        <gitBranch>master</gitBranch>
+        <pull>False</pull>
+        <branch>master</branch>
     </GIT>
 
     <DATABASE>
diff --git a/TestON/tests/SCPF/SCPFintentInstallWithdrawLat/SCPFintentInstallWithdrawLat.py b/TestON/tests/SCPF/SCPFintentInstallWithdrawLat/SCPFintentInstallWithdrawLat.py
index 345bd44..093b5ca 100644
--- a/TestON/tests/SCPF/SCPFintentInstallWithdrawLat/SCPFintentInstallWithdrawLat.py
+++ b/TestON/tests/SCPF/SCPFintentInstallWithdrawLat/SCPFintentInstallWithdrawLat.py
@@ -4,7 +4,7 @@
     - Use Push-test-intents command to push intents
     - Use Null provider with 7 devices and linear topology
     - Always push intents between 1/6 and 7/5
-    - The batch size is defined in parm file. (default 1,100,1000)
+    - The batch size is defined in parm file. ( default 1,100,1000)
 
     yunpeng@onlab.us
 """
@@ -22,220 +22,91 @@
             different versions of ONOS.
         - Construct tests variables
         '''
-        gitPull = main.params['GIT']['gitPull']
-        gitBranch = main.params['GIT']['gitBranch']
 
-        main.case("Pull onos branch and build onos on Teststation.")
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        main.testSetUp.envSetupDescription()
+        stepResult = main.FALSE
+        try:
 
-        if gitPull == 'True':
-            main.step("Git Checkout ONOS branch: " + gitBranch)
-            stepResult = main.ONOSbench.gitCheckout(branch=gitBranch)
-            utilities.assert_equals(expect=main.TRUE,
-                                    actual=stepResult,
-                                    onpass="Successfully checkout onos branch.",
-                                    onfail="Failed to checkout onos branch. Exiting test...")
-            if not stepResult: main.exit()
+            main.apps = main.params[ 'ENV' ][ 'cellApps' ]
+            main.BENCHUser = main.params[ 'BENCH' ][ 'user' ]
+            main.BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
+            main.MN1Ip = main.params[ 'MN' ][ 'ip1' ]
+            main.maxNodes = int( main.params[ 'max' ] )
+            main.cellName = main.params[ 'ENV' ][ 'cellName' ]
+            main.scale = ( main.params[ 'SCALE' ] ).split( "," )
+            main.timeout = int( main.params[ 'SLEEP' ][ 'timeout' ] )
+            main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
+            main.installSleep = int( main.params[ 'SLEEP' ][ 'install' ] )
+            main.verifySleep = int( main.params[ 'SLEEP' ][ 'verify' ] )
+            main.verifyAttempts = int( main.params[ 'ATTEMPTS' ][ 'verify' ] )
+            main.sampleSize = int( main.params[ 'TEST' ][ 'sampleSize' ] )
+            main.warmUp = int( main.params[ 'TEST' ][ 'warmUp' ] )
+            main.intentsList = ( main.params[ 'TEST' ][ 'intents' ] ).split( "," )
+            main.ingress = main.params[ 'TEST' ][ 'ingress' ]
+            main.egress = main.params[ 'TEST' ][ 'egress' ]
+            main.debug = main.params[ 'TEST' ][ 'debug' ]
+            main.flowObj = main.params[ 'TEST' ][ 'flowObj' ]
 
-            main.step("Git Pull on ONOS branch:" + gitBranch)
-            stepResult = main.ONOSbench.gitPull()
-            utilities.assert_equals(expect=main.TRUE,
-                                    actual=stepResult,
-                                    onpass="Successfully pull onos. ",
-                                    onfail="Failed to pull onos. Exiting test ...")
-            if not stepResult: main.exit()
+            if main.flowObj == "True":
+                main.flowObj = True
+                main.dbFileName = main.params[ 'DATABASE' ][ 'dbFlowObj' ]
+            else:
+                main.flowObj = False
+                main.dbFileName = main.params[ 'DATABASE' ][ 'dbName' ]
 
+            for i in range( 0, len( main.intentsList ) ):
+                main.intentsList[ i ] = int( main.intentsList[ i ] )
 
-        else:
-            main.log.warn("Skipped pulling onos and Skipped building ONOS")
-
-        main.apps = main.params['ENV']['cellApps']
-        main.BENCHUser = main.params['BENCH']['user']
-        main.BENCHIp = main.params['BENCH']['ip1']
-        main.MN1Ip = main.params['MN']['ip1']
-        main.maxNodes = int(main.params['max'])
-        main.cellName = main.params['ENV']['cellName']
-        main.scale = (main.params['SCALE']).split(",")
-        main.timeout = int(main.params['SLEEP']['timeout'])
-        main.startUpSleep = int(main.params['SLEEP']['startup'])
-        main.installSleep = int(main.params['SLEEP']['install'])
-        main.verifySleep = int(main.params['SLEEP']['verify'])
-        main.verifyAttempts = int(main.params['ATTEMPTS']['verify'])
-        main.sampleSize = int(main.params['TEST']['sampleSize'])
-        main.warmUp = int(main.params['TEST']['warmUp'])
-        main.intentsList = (main.params['TEST']['intents']).split(",")
-        main.ingress = main.params['TEST']['ingress']
-        main.egress = main.params['TEST']['egress']
-        main.debug = main.params['TEST']['debug']
-        main.flowObj = main.params['TEST']['flowObj']
-
-        if main.flowObj == "True":
-            main.flowObj = True
-            main.dbFileName = main.params['DATABASE']['dbFlowObj']
-        else:
-            main.flowObj = False
-            main.dbFileName = main.params['DATABASE']['dbName']
-
-        for i in range(0, len(main.intentsList)):
-            main.intentsList[i] = int(main.intentsList[i])
-        # Create DataBase file
-        main.log.info("Create Database file " + main.dbFileName)
-        resultsDB = open(main.dbFileName, "w+")
-        resultsDB.close()
-
+            stepResult = main.testSetUp.gitPulling()
+            # Create DataBase file
+            main.log.info( "Create Database file " + main.dbFileName )
+            resultsDB = open( main.dbFileName, "w+" )
+            resultsDB.close()
+        except Exception as e:
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
+        main.commit = main.commit.split( " " )[ 1 ]
     def CASE1( self, main ):
         # Clean up test environment and set up
         import time
-        main.log.info("Get ONOS cluster IP")
-        print(main.scale)
-        main.numCtrls = int(main.scale[0])
-        main.ONOSip = []
+
         main.maxNumBatch = 0
-        main.AllONOSip = main.ONOSbench.getOnosIps()
-        for i in range(main.numCtrls):
-            main.ONOSip.append(main.AllONOSip[i])
-        main.log.info(main.ONOSip)
-        main.CLIs = []
-        main.log.info("Creating list of ONOS cli handles")
-        for i in range(main.numCtrls):
-            main.CLIs.append(getattr(main, 'ONOScli%s' %(i + 1)))
-
-        if not main.CLIs:
-            main.log.error("Failed to create the list of ONOS cli handles")
-            main.cleanup()
-            main.exit()
-
-        main.commit = main.ONOSbench.getVersion(report=True)
-        main.commit = main.commit.split(" ")[1]
-        main.log.info("Starting up %s node(s) ONOS cluster" % main.numCtrls)
-        main.log.info("Safety check, killing all ONOS processes" +
-                      " before initiating environment setup")
-
-        for i in range(main.numCtrls):
-            main.ONOSbench.onosStop(main.ONOSip[i])
-            main.ONOSbench.onosKill(main.ONOSip[i])
-
-        main.log.info("NODE COUNT = %s" % main.numCtrls)
-        main.ONOSbench.createCellFile(main.ONOSbench.ip_address,
-                                      main.cellName,
-                                      main.MN1Ip,
-                                      main.apps,
-                                      main.ONOSip,
-                                      main.ONOScli1.karafUser )
-        main.step("Apply cell to environment")
-        cellResult = main.ONOSbench.setCell(main.cellName)
-        verifyResult = main.ONOSbench.verifyCell()
-        stepResult = cellResult and verifyResult
-        utilities.assert_equals(expect=main.TRUE,
-                                actual=stepResult,
-                                onpass="Successfully applied cell to " + \
-                                       "environment",
-                                onfail="Failed to apply cell to environment ")
-
-        main.step("Creating ONOS package")
-        packageResult = main.ONOSbench.buckBuild()
-        stepResult = packageResult
-        utilities.assert_equals(expect=main.TRUE,
-                                actual=stepResult,
-                                onpass="Successfully created ONOS package",
-                                onfail="Failed to create ONOS package")
-
-        main.step("Uninstall ONOS package on all Nodes")
-        uninstallResult = main.TRUE
-        for i in range(int(main.numCtrls)):
-            main.log.info("Uninstalling package on ONOS Node IP: " + main.ONOSip[i])
-            u_result = main.ONOSbench.onosUninstall(main.ONOSip[i])
-            utilities.assert_equals(expect=main.TRUE, actual=u_result,
-                                    onpass="Test step PASS",
-                                    onfail="Test step FAIL")
-            uninstallResult = (uninstallResult and u_result)
-
-        main.step("Install ONOS package on all Nodes")
-        installResult = main.TRUE
-        for i in range(int(main.numCtrls)):
-            main.log.info("Installing package on ONOS Node IP: " + main.ONOSip[i])
-            i_result = main.ONOSbench.onosInstall(node=main.ONOSip[i])
-            utilities.assert_equals(expect=main.TRUE, actual=i_result,
-                                    onpass="Test step PASS",
-                                    onfail="Test step FAIL")
-            installResult = installResult and i_result
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.TRUE
-        for i in range( int( main.numCtrls ) ):
-            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=main.ONOSip[i] )
-        utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        time.sleep( main.startUpSleep )
-        main.step( "Starting ONOS service" )
-        stopResult = main.TRUE
-        startResult = main.TRUE
-        onosIsUp = main.TRUE
-        for i in range( main.numCtrls ):
-            onosIsUp = onosIsUp and main.ONOSbench.isup( main.ONOSip[ i ] )
-        if onosIsUp == main.TRUE:
-            main.log.report( "ONOS instance is up and ready" )
-        else:
-            main.log.report( "ONOS instance may not be up, stop and " +
-                             "start ONOS again " )
-            for i in range( main.numCtrls ):
-                stopResult = stopResult and \
-                        main.ONOSbench.onosStop( main.ONOSip[ i ] )
-            for i in range( main.numCtrls ):
-                startResult = startResult and \
-                        main.ONOSbench.onosStart( main.ONOSip[ i ] )
-        stepResult = onosIsUp and stopResult and startResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="ONOS service is ready",
-                                 onfail="ONOS service did not start properly" )
-
-        time.sleep(2)
-        main.step("Start ONOS CLI on all nodes")
-        cliResult = main.TRUE
-        main.step(" Start ONOS cli using thread ")
-        startCliResult = main.TRUE
-        pool = []
-        main.threadID = 0
-        for i in range(int(main.numCtrls)):
-            t = main.Thread(target=main.CLIs[i].startOnosCli,
-                            threadID=main.threadID,
-                            name="startOnosCli",
-                            args=[main.ONOSip[i]],
-                            kwargs={"onosStartTimeout": main.timeout})
-            pool.append(t)
-            t.start()
-            main.threadID = main.threadID + 1
-        for t in pool:
-            t.join()
-            startCliResult = startCliResult and t.result
-        time.sleep(main.startUpSleep)
+        main.testSetUp.getNumCtrls( True )
+        main.testSetUp.envSetup( includeGitPull=False, makeMaxNodes=False )
+        main.testSetUp.ONOSSetUp( main.MN1Ip, True,
+                                  cellName=main.cellName, killRemoveMax=False,
+                                  CtrlsSet=False )
 
         # configure apps
-        main.CLIs[0].setCfg("org.onosproject.provider.nil.NullProviders", "deviceCount", value=7)
-        main.CLIs[0].setCfg("org.onosproject.provider.nil.NullProviders", "topoShape", value="linear")
-        main.CLIs[0].setCfg("org.onosproject.provider.nil.NullProviders", "enabled", value="true")
-        main.CLIs[0].setCfg("org.onosproject.net.intent.impl.IntentManager", "skipReleaseResourcesOnWithdrawal", value="true")
+        main.CLIs[ 0 ].setCfg( "org.onosproject.provider.nil.NullProviders", "deviceCount", value=7 )
+        main.CLIs[ 0 ].setCfg( "org.onosproject.provider.nil.NullProviders", "topoShape", value="linear" )
+        main.CLIs[ 0 ].setCfg( "org.onosproject.provider.nil.NullProviders", "enabled", value="true" )
+        main.CLIs[ 0 ].setCfg( "org.onosproject.net.intent.impl.IntentManager", "skipReleaseResourcesOnWithdrawal", value="true" )
         if main.flowObj:
-            main.CLIs[0].setCfg("org.onosproject.net.intent.impl.compiler.IntentConfigurableRegistrator",
-                                "useFlowObjectives", value="true")
-            main.CLIs[0].setCfg("org.onosproject.net.intent.impl.compiler.IntentConfigurableRegistrator",
+            main.CLIs[ 0 ].setCfg( "org.onosproject.net.intent.impl.compiler.IntentConfigurableRegistrator",
+                                "useFlowObjectives", value="true" )
+            main.CLIs[ 0 ].setCfg( "org.onosproject.net.intent.impl.compiler.IntentConfigurableRegistrator",
                                 "defaultFlowObjectiveCompiler",
-                                value='org.onosproject.net.intent.impl.compiler.LinkCollectionIntentObjectiveCompiler')
-        time.sleep(main.startUpSleep)
+                                value='org.onosproject.net.intent.impl.compiler.LinkCollectionIntentObjectiveCompiler' )
+        time.sleep( main.startUpSleep )
 
         # balanceMasters
-        main.CLIs[0].balanceMasters()
-        time.sleep(main.startUpSleep)
+        main.CLIs[ 0 ].balanceMasters()
+        time.sleep( main.startUpSleep )
 
     def CASE2( self, main ):
         import time
         import numpy
         import json
-        print(main.intentsList)
+        print( main.intentsList )
         for batchSize in main.intentsList:
-            main.log.report("Intent Batch size: {}".format(batchSize))
+            main.log.report( "Intent Batch size: {}".format( batchSize ) )
             main.installLatList = []
             main.withdrawLatList = []
             validrun = 0
@@ -243,20 +114,20 @@
             # we use two variables to control the iteration
             while validrun <= main.warmUp + main.sampleSize and invalidrun < 20:
                 if validrun >= main.warmUp:
-                    main.log.info("================================================")
-                    main.log.info("Starting test iteration " + str(validrun - main.warmUp))
-                    main.log.info("Total test iteration: " + str(invalidrun + validrun))
-                    main.log.info("================================================")
+                    main.log.info( "================================================" )
+                    main.log.info( "Starting test iteration " + str( validrun - main.warmUp ) )
+                    main.log.info( "Total test iteration: " + str( invalidrun + validrun ) )
+                    main.log.info( "================================================" )
                 else:
-                    main.log.info("====================Warm Up=====================")
+                    main.log.info( "====================Warm Up=====================" )
 
                 # push intents
-                installResult = main.CLIs[0].pushTestIntents(main.ingress, main.egress, batchSize,
+                installResult = main.CLIs[ 0 ].pushTestIntents( main.ingress, main.egress, batchSize,
                                                              offset=1, options="-i", timeout=main.timeout,
-                                                             getResponse=True)
-                if type(installResult) is str:
+                                                             getResponse=True )
+                if type( installResult ) is str:
                     if "Failure" in installResult:
-                        main.log.error("Install Intents failure, ignore this iteration.")
+                        main.log.error( "Install Intents failure, ignore this iteration." )
                         if validrun < main.warmUp:
                             validrun += 1
                             continue
@@ -265,12 +136,12 @@
                             continue
 
                     try:
-                        latency = int(installResult.split()[5])
-                        main.log.info(installResult)
+                        latency = int( installResult.split()[ 5 ] )
+                        main.log.info( installResult )
                     except:
-                        main.log.error("Failed to get latency, ignore this iteration.")
-                        main.log.error("Response from ONOS:")
-                        print(installResult)
+                        main.log.error( "Failed to get latency, ignore this iteration." )
+                        main.log.error( "Response from ONOS:" )
+                        print( installResult )
                         if validrun < main.warmUp:
                             validrun += 1
                             continue
@@ -279,19 +150,19 @@
                             continue
 
                     if validrun >= main.warmUp:
-                        main.installLatList.append(latency)
+                        main.installLatList.append( latency )
                 else:
                     invalidrun += 1
                     continue
-                time.sleep(2)
+                time.sleep( 2 )
                 # Withdraw Intents
-                withdrawResult = main.CLIs[0].pushTestIntents(main.ingress, main.egress, batchSize,
+                withdrawResult = main.CLIs[ 0 ].pushTestIntents( main.ingress, main.egress, batchSize,
                                                               offset=1, options="-w", timeout=main.timeout,
-                                                              getResponse=True)
+                                                              getResponse=True )
 
-                if type(withdrawResult) is str:
+                if type( withdrawResult ) is str:
                     if "Failure" in withdrawResult:
-                        main.log.error("withdraw Intents failure, ignore this iteration.")
+                        main.log.error( "withdraw Intents failure, ignore this iteration." )
                         if validrun < main.warmUp:
                             validrun += 1
                             continue
@@ -300,12 +171,12 @@
                             continue
 
                     try:
-                        latency = int(withdrawResult.split()[5])
-                        main.log.info(withdrawResult)
+                        latency = int( withdrawResult.split()[ 5 ] )
+                        main.log.info( withdrawResult )
                     except:
-                        main.log.error("Failed to get latency, ignore this iteration.")
-                        main.log.error("Response from ONOS:")
-                        print(withdrawResult)
+                        main.log.error( "Failed to get latency, ignore this iteration." )
+                        main.log.error( "Response from ONOS:" )
+                        print( withdrawResult )
                         if validrun < main.warmUp:
                             validrun += 1
                             continue
@@ -314,34 +185,33 @@
                             continue
 
                     if validrun >= main.warmUp:
-                        main.withdrawLatList.append(latency)
+                        main.withdrawLatList.append( latency )
                 else:
                     invalidrun += 1
                     continue
-                time.sleep(2)
-                main.CLIs[0].purgeWithdrawnIntents()
+                time.sleep( 2 )
+                main.CLIs[ 0 ].purgeWithdrawnIntents()
                 validrun += 1
-            installave = numpy.average(main.installLatList)
-            installstd = numpy.std(main.installLatList)
-            withdrawave = numpy.average(main.withdrawLatList)
-            withdrawstd = numpy.std(main.withdrawLatList)
+            installave = numpy.average( main.installLatList )
+            installstd = numpy.std( main.installLatList )
+            withdrawave = numpy.average( main.withdrawLatList )
+            withdrawstd = numpy.std( main.withdrawLatList )
             # log report
-            main.log.report("----------------------------------------------------")
-            main.log.report("Scale: " + str(main.numCtrls))
-            main.log.report("Intent batch: " + str(batchSize))
-            main.log.report("Install average: {}    std: {}".format(installave, installstd))
-            main.log.report("Withdraw average: {}   std: {}".format(withdrawave, withdrawstd))
+            main.log.report( "----------------------------------------------------" )
+            main.log.report( "Scale: " + str( main.numCtrls ) )
+            main.log.report( "Intent batch: " + str( batchSize ) )
+            main.log.report( "Install average: {}    std: {}".format( installave, installstd ) )
+            main.log.report( "Withdraw average: {}   std: {}".format( withdrawave, withdrawstd ) )
             # write result to database file
-            if not (numpy.isnan(installave) or numpy.isnan(installstd) or\
-                    numpy.isnan(withdrawstd) or numpy.isnan(withdrawave)):
+            if not ( numpy.isnan( installave ) or numpy.isnan( installstd ) or\
+                    numpy.isnan( withdrawstd ) or numpy.isnan( withdrawave ) ):
                 databaseString = "'" + main.commit + "',"
-                databaseString += str(main.numCtrls) + ","
-                databaseString += str(batchSize) + ","
-                databaseString += str(installave) + ","
-                databaseString += str(installstd) + ","
-                databaseString += str(withdrawave) + ","
-                databaseString += str(withdrawstd) + "\n"
-                resultsDB = open(main.dbFileName, "a")
-                resultsDB.write(databaseString)
+                databaseString += str( main.numCtrls ) + ","
+                databaseString += str( batchSize ) + ","
+                databaseString += str( installave ) + ","
+                databaseString += str( installstd ) + ","
+                databaseString += str( withdrawave ) + ","
+                databaseString += str( withdrawstd ) + "\n"
+                resultsDB = open( main.dbFileName, "a" )
+                resultsDB.write( databaseString )
                 resultsDB.close()
-        del main.scale[0]
diff --git a/TestON/tests/SCPF/SCPFintentRerouteLat/SCPFintentRerouteLat.params b/TestON/tests/SCPF/SCPFintentRerouteLat/SCPFintentRerouteLat.params
index fd3553c..87e3888 100644
--- a/TestON/tests/SCPF/SCPFintentRerouteLat/SCPFintentRerouteLat.params
+++ b/TestON/tests/SCPF/SCPFintentRerouteLat/SCPFintentRerouteLat.params
@@ -46,8 +46,8 @@
     </DATABASE>
 
     <GIT>
-        <gitPull>False</gitPull>
-        <gitBranch>master</gitBranch>
+        <pull>False</pull>
+        <branch>master</branch>
     </GIT>
 
     <ATTEMPTS>
diff --git a/TestON/tests/SCPF/SCPFintentRerouteLat/SCPFintentRerouteLat.py b/TestON/tests/SCPF/SCPFintentRerouteLat/SCPFintentRerouteLat.py
index 3ef9be8..baff10b 100644
--- a/TestON/tests/SCPF/SCPFintentRerouteLat/SCPFintentRerouteLat.py
+++ b/TestON/tests/SCPF/SCPFintentRerouteLat/SCPFintentRerouteLat.py
@@ -31,76 +31,65 @@
             different versions of ONOS.
         - Construct tests variables
         '''
-        gitPull = main.params['GIT']['gitPull']
-        gitBranch = main.params['GIT']['gitBranch']
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        main.testSetUp.envSetupDescription()
+        stepResult = main.FALSE
+        try:
+            main.onosIp = main.ONOSbench.getOnosIps()
+            main.apps = main.params[ 'ENV' ][ 'cellApps' ]
+            main.BENCHUser = main.params[ 'BENCH' ][ 'user' ]
+            main.BENCHIp = main.params[ 'BENCH' ][ 'ip1' ]
+            main.MN1Ip = main.params[ 'MN' ][ 'ip1' ]
+            main.maxNodes = int( main.params[ 'max' ] )
+            main.cellName = main.params[ 'ENV' ][ 'cellName' ]
+            main.scale = ( main.params[ 'SCALE' ] ).split(",")
+            main.timeout = int( main.params[ 'SLEEP' ][ 'timeout' ] )
+            main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
+            main.installSleep = int( main.params[ 'SLEEP' ][ 'install' ] )
+            main.verifySleep = int( main.params[ 'SLEEP' ][ 'verify' ] )
+            main.setMasterSleep = int( main.params[ 'SLEEP' ][ 'setmaster' ] )
+            main.verifyAttempts = int( main.params[ 'ATTEMPTS' ][ 'verify' ] )
+            main.maxInvalidRun = int( main.params[ 'ATTEMPTS' ][ 'maxInvalidRun' ] )
+            main.sampleSize = int( main.params[ 'TEST' ][ 'sampleSize' ] )
+            main.warmUp = int( main.params[ 'TEST' ][ 'warmUp' ] )
+            main.ingress = main.params[ 'TEST' ][ 'ingress' ]
+            main.egress = main.params[ 'TEST' ][ 'egress' ]
+            main.debug = main.params[ 'TEST' ][ 'debug' ]
+            main.flowObj = main.params[ 'TEST' ][ 'flowObj' ]
+            main.deviceCount = int( main.params[ 'TEST' ][ 'deviceCount' ] )
+            main.end1 = main.params[ 'TEST' ][ 'end1' ]
+            main.end2 = main.params[ 'TEST' ][ 'end2' ]
+            main.searchTerm = main.params[ 'SEARCHTERM' ]
+            if main.flowObj == "True":
+                main.flowObj = True
+                main.dbFileName = main.params[ 'DATABASE' ][ 'dbFlowObj' ]
+                main.intentsList = ( main.params[ 'TEST' ][ 'FObjintents' ] ).split( "," )
+            else:
+                main.flowObj = False
+                main.dbFileName = main.params[ 'DATABASE' ][ 'dbName' ]
+                main.intentsList = ( main.params[ 'TEST' ][ 'intents' ] ).split( "," )
 
-        main.case("Pull onos branch and build onos on Teststation.")
+            stepResult = main.testSetUp.gitPulling()
 
-        if gitPull == 'True':
-            main.step("Git Checkout ONOS branch: " + gitBranch)
-            stepResult = main.ONOSbench.gitCheckout(branch=gitBranch)
-            utilities.assert_equals(expect=main.TRUE,
-                                    actual=stepResult,
-                                    onpass="Successfully checkout onos branch.",
-                                    onfail="Failed to checkout onos branch. Exiting test...")
-            if not stepResult:
-                main.exit()
+            for i in range( 0, len( main.intentsList) ):
+                main.intentsList[ i ] = int( main.intentsList[ i ] )
+                # Create DataBase file
+            main.log.info( "Create Database file " + main.dbFileName )
+            resultsDB = open( main.dbFileName, "w+" )
+            resultsDB.close()
+            file1 = main.params[ "DEPENDENCY" ][ "FILE1" ]
+            main.dependencyPath = os.path.dirname( os.getcwd() ) + main.params[ "DEPENDENCY" ][ "PATH" ]
+            main.intentRerouteLatFuncs = imp.load_source( file1, main.dependencyPath + file1 + ".py" )
 
-            main.step("Git Pull on ONOS branch:" + gitBranch)
-            stepResult = main.ONOSbench.gitPull()
-            utilities.assert_equals(expect=main.TRUE,
-                                    actual=stepResult,
-                                    onpass="Successfully pull onos. ",
-                                    onfail="Failed to pull onos. Exiting test ...")
-            if not stepResult: main.exit()
-
-        else:
-            main.log.warn("Skipped pulling onos and Skipped building ONOS")
-        main.onosIp = main.ONOSbench.getOnosIps()
-        main.apps = main.params['ENV']['cellApps']
-        main.BENCHUser = main.params['BENCH']['user']
-        main.BENCHIp = main.params['BENCH']['ip1']
-        main.MN1Ip = main.params['MN']['ip1']
-        main.maxNodes = int(main.params['max'])
-        main.cellName = main.params['ENV']['cellName']
-        main.scale = (main.params['SCALE']).split(",")
-        main.timeout = int(main.params['SLEEP']['timeout'])
-        main.startUpSleep = int(main.params['SLEEP']['startup'])
-        main.installSleep = int(main.params['SLEEP']['install'])
-        main.verifySleep = int(main.params['SLEEP']['verify'])
-        main.setMasterSleep = int(main.params['SLEEP']['setmaster'])
-        main.verifyAttempts = int(main.params['ATTEMPTS']['verify'])
-        main.maxInvalidRun = int(main.params['ATTEMPTS']['maxInvalidRun'])
-        main.sampleSize = int(main.params['TEST']['sampleSize'])
-        main.warmUp = int(main.params['TEST']['warmUp'])
-        main.ingress = main.params['TEST']['ingress']
-        main.egress = main.params['TEST']['egress']
-        main.debug = main.params['TEST']['debug']
-        main.flowObj = main.params['TEST']['flowObj']
-        main.deviceCount = int(main.params['TEST']['deviceCount'])
-        main.end1 = main.params['TEST']['end1']
-        main.end2 = main.params['TEST']['end2']
-        main.searchTerm = main.params['SEARCHTERM']
-        if main.flowObj == "True":
-            main.flowObj = True
-            main.dbFileName = main.params['DATABASE']['dbFlowObj']
-            main.intentsList = (main.params['TEST']['FObjintents']).split(",")
-        else:
-            main.flowObj = False
-            main.dbFileName = main.params['DATABASE']['dbName']
-            main.intentsList = (main.params['TEST']['intents']).split(",")
-
-        for i in range(0, len(main.intentsList)):
-            main.intentsList[i] = int(main.intentsList[i])
-            # Create DataBase file
-        main.log.info("Create Database file " + main.dbFileName)
-        resultsDB = open(main.dbFileName, "w+")
-        resultsDB.close()
-        file1 = main.params[ "DEPENDENCY" ][ "FILE1" ]
-        main.dependencyPath = os.path.dirname( os.getcwd() ) + main.params[ "DEPENDENCY" ][ "PATH" ]
-        main.intentRerouteLatFuncs = imp.load_source(file1, main.dependencyPath + file1 + ".py")
-
-        main.record = 0
+            main.record = 0
+        except Exception as e:
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
 
     def CASE1( self, main ):
         '''
@@ -108,133 +97,12 @@
         '''
         import time
 
-        main.log.info("Get ONOS cluster IP")
-        print(main.scale)
-        main.numCtrls = int(main.scale[0])
-        main.ONOSip = []
         main.maxNumBatch = 0
-        main.AllONOSip = main.ONOSbench.getOnosIps()
-        for i in range(main.numCtrls):
-            main.ONOSip.append(main.AllONOSip[i])
-        main.log.info(main.ONOSip)
-        main.CLIs = []
-        main.log.info("Creating list of ONOS cli handles")
-        for i in range(main.numCtrls):
-            main.CLIs.append(getattr(main, 'ONOScli%s' % (i + 1)))
-
-        if not main.CLIs:
-            main.log.error("Failed to create the list of ONOS cli handles")
-            main.cleanup()
-            main.exit()
-
-        main.commit = main.ONOSbench.getVersion(report=True)
-        main.commit = main.commit.split(" ")[1]
-        main.log.info("Starting up %s node(s) ONOS cluster" % main.numCtrls)
-        main.log.info("Safety check, killing all ONOS processes" +
-                      " before initiating environment setup")
-
-        for i in range(main.numCtrls):
-            main.ONOSbench.onosStop(main.ONOSip[i])
-            main.ONOSbench.onosKill(main.ONOSip[i])
-
-        main.log.info("NODE COUNT = %s" % main.numCtrls)
-        main.ONOSbench.createCellFile(main.ONOSbench.ip_address,
-                                      main.cellName,
-                                      main.MN1Ip,
-                                      main.apps,
-                                      main.ONOSip,
-                                      main.ONOScli1.karafUser)
-        main.step("Apply cell to environment")
-        cellResult = main.ONOSbench.setCell(main.cellName)
-        verifyResult = main.ONOSbench.verifyCell()
-        stepResult = cellResult and verifyResult
-        utilities.assert_equals(expect=main.TRUE,
-                                actual=stepResult,
-                                onpass="Successfully applied cell to " + \
-                                       "environment",
-                                onfail="Failed to apply cell to environment ")
-
-        main.step("Creating ONOS package")
-        packageResult = main.ONOSbench.buckBuild()
-        stepResult = packageResult
-        utilities.assert_equals(expect=main.TRUE,
-                                actual=stepResult,
-                                onpass="Successfully created ONOS package",
-                                onfail="Failed to create ONOS package")
-
-        main.step("Uninstall ONOS package on all Nodes")
-        uninstallResult = main.TRUE
-        for i in range(int(main.numCtrls)):
-            main.log.info("Uninstalling package on ONOS Node IP: " + main.ONOSip[i])
-            u_result = main.ONOSbench.onosUninstall(main.ONOSip[i])
-            utilities.assert_equals(expect=main.TRUE, actual=u_result,
-                                    onpass="Test step PASS",
-                                    onfail="Test step FAIL")
-            uninstallResult = (uninstallResult and u_result)
-
-        main.step("Install ONOS package on all Nodes")
-        installResult = main.TRUE
-        for i in range(int(main.numCtrls)):
-            main.log.info("Installing package on ONOS Node IP: " + main.ONOSip[i])
-            i_result = main.ONOSbench.onosInstall(node=main.ONOSip[i])
-            utilities.assert_equals(expect=main.TRUE, actual=i_result,
-                                    onpass="Test step PASS",
-                                    onfail="Test step FAIL")
-            installResult = installResult and i_result
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.TRUE
-        for i in range( int( main.numCtrls ) ):
-            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=main.ONOSip[i] )
-            utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
-                                    onpass="Test step PASS",
-                                    onfail="Test step FAIL" )
-
-        main.step( "Starting ONOS service" )
-        stopResult = main.TRUE
-        startResult = main.TRUE
-        onosIsUp = main.TRUE
-
-        for i in range( main.numCtrls ):
-            onosIsUp = onosIsUp and main.ONOSbench.isup( main.ONOSip[ i ] )
-        if onosIsUp == main.TRUE:
-            main.log.report( "ONOS instance is up and ready" )
-        else:
-            main.log.report( "ONOS instance may not be up, stop and " +
-                             "start ONOS again " )
-
-            for i in range( main.numCtrls ):
-                stopResult = stopResult and \
-                        main.ONOSbench.onosStop( main.ONOSip[ i ] )
-            for i in range( main.numCtrls ):
-                startResult = startResult and \
-                        main.ONOSbench.onosStart( main.ONOSip[ i ] )
-        stepResult = onosIsUp and stopResult and startResult
-        utilities.assert_equals( expect=main.TRUE, actual=stepResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        time.sleep(main.startUpSleep)
-        main.step("Start ONOS CLI on all nodes")
-        cliResult = main.TRUE
-        main.step(" Start ONOS cli using thread ")
-        startCliResult = main.TRUE
-        pool = []
-        main.threadID = 0
-        for i in range(int(main.numCtrls)):
-            t = main.Thread(target=main.CLIs[i].startOnosCli,
-                            threadID=main.threadID,
-                            name="startOnosCli",
-                            args=[main.ONOSip[i]],
-                            kwargs={"onosStartTimeout": main.timeout})
-            pool.append(t)
-            t.start()
-            main.threadID = main.threadID + 1
-        for t in pool:
-            t.join()
-            startCliResult = startCliResult and t.result
-        time.sleep(main.startUpSleep)
-
+        main.testSetUp.getNumCtrls( True )
+        main.testSetUp.envSetup( includeGitPull=False, makeMaxNodes=False )
+        main.testSetUp.ONOSSetUp( main.MN1Ip, True,
+                                  cellName=main.cellName, killRemoveMax=False,
+                                  CtrlsSet=False )
         # configure apps
         main.CLIs[0].setCfg("org.onosproject.provider.nil.NullProviders", "deviceCount", value=main.deviceCount)
         main.CLIs[0].setCfg("org.onosproject.provider.nil.NullProviders", "topoShape", value="reroute")
@@ -252,9 +120,9 @@
         # Balance Master
         main.CLIs[0].balanceMasters()
         time.sleep( main.setMasterSleep )
-        if len(main.ONOSip) > 1:
-            main.CLIs[0].deviceRole(main.end1[ 'name' ], main.ONOSip[0])
-            main.CLIs[0].deviceRole(main.end2[ 'name' ], main.ONOSip[0])
+        if main.numCtrls:
+            main.CLIs[0].deviceRole( main.end1[ 'name' ], main.ONOSip[0] )
+            main.CLIs[0].deviceRole( main.end2[ 'name' ], main.ONOSip[0] )
         time.sleep( main.setMasterSleep )
 
     def CASE2( self, main ):
@@ -264,7 +132,7 @@
         import json
         # from scipy import stats
 
-        print(main.intentsList)
+        print( main.intentsList)
         for batchSize in main.intentsList:
             main.batchSize = batchSize
             main.log.report("Intent Batch size: " + str(batchSize) + "\n      ")
@@ -278,18 +146,18 @@
             while main.validRun <= main.warmUp + main.sampleSize and main.invalidRun <= main.maxInvalidRun:
                 if main.validRun >= main.warmUp:
                     main.log.info("================================================")
-                    main.log.info("Valid iteration: {} ".format( main.validRun - main.warmUp))
-                    main.log.info("Total iteration: {}".format( main.validRun + main.invalidRun))
+                    main.log.info("Valid iteration: {} ".format( main.validRun - main.warmUp) )
+                    main.log.info("Total iteration: {}".format( main.validRun + main.invalidRun) )
                     main.log.info("================================================")
                 else:
                     main.log.info("====================Warm Up=====================")
 
                 # push intents
-                main.CLIs[0].pushTestIntents(main.ingress, main.egress, main.batchSize,
+                main.CLIs[0].pushTestIntents( main.ingress, main.egress, main.batchSize,
                                              offset=1, options="-i", timeout=main.timeout)
 
                 # check links, flows and intents
-                main.intentRerouteLatFuncs.sanityCheck( main, main.deviceCount * 2, batchSize * (main.deviceCount - 1 ), main.batchSize )
+                main.intentRerouteLatFuncs.sanityCheck( main, main.deviceCount * 2, batchSize * ( main.deviceCount - 1 ), main.batchSize )
                 if not main.verify:
                     main.log.warn( "Sanity check failed, skipping this iteration..." )
                     continue
@@ -303,7 +171,7 @@
                                   timeout=main.timeout, showResponse=False)
 
                 # check links, flows and intents
-                main.intentRerouteLatFuncs.sanityCheck( main, (main.deviceCount - 1) * 2, batchSize * main.deviceCount, main.batchSize )
+                main.intentRerouteLatFuncs.sanityCheck( main, ( main.deviceCount - 1) * 2, batchSize * main.deviceCount, main.batchSize )
                 if not main.verify:
                     main.log.warn( "Sanity check failed, skipping this iteration..." )
                     continue
@@ -366,7 +234,7 @@
                 # bring up link and withdraw intents
                 main.CLIs[0].link( main.end1[ 'port' ], main.end2[ 'port' ], "up",
                                   timeout=main.timeout)
-                main.CLIs[0].pushTestIntents(main.ingress, main.egress, batchSize,
+                main.CLIs[0].pushTestIntents( main.ingress, main.egress, batchSize,
                                              offset=1, options="-w", timeout=main.timeout)
                 main.CLIs[0].purgeWithdrawnIntents()
 
@@ -396,4 +264,3 @@
                 resultsDB.write( str( aveLocalLatency ) + "," )
                 resultsDB.write( str( stdLocalLatency ) + "\n" )
                 resultsDB.close()
-        del main.scale[ 0 ]
diff --git a/TestON/tests/SCPF/SCPFportLat/SCPFportLat.params b/TestON/tests/SCPF/SCPFportLat/SCPFportLat.params
index 4fc830f..6dbd03d 100644
--- a/TestON/tests/SCPF/SCPFportLat/SCPFportLat.params
+++ b/TestON/tests/SCPF/SCPFportLat/SCPFportLat.params
@@ -20,8 +20,8 @@
     </DEPENDENCY>
 
     <GIT>
-        <gitPull>off</gitPull>
-        <gitBranch>master</gitBranch>
+        <pull>False</pull>
+        <branch>master</branch>
     </GIT>
 
     <TSHARK>
diff --git a/TestON/tests/SCPF/SCPFportLat/SCPFportLat.py b/TestON/tests/SCPF/SCPFportLat/SCPFportLat.py
index 24e8e60..f00af91 100644
--- a/TestON/tests/SCPF/SCPFportLat/SCPFportLat.py
+++ b/TestON/tests/SCPF/SCPFportLat/SCPFportLat.py
@@ -22,214 +22,89 @@
             different versions of ONOS.
         - Construct tests variables
         '''
-        gitPull = main.params['GIT']['gitPull']
-        gitBranch = main.params['GIT']['gitBranch']
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        main.testSetUp.envSetupDescription()
+        stepResult = main.FALSE
+        try:
+            main.MN1Ip = main.params[ 'MN' ][ 'ip1' ]
+            main.dependencyPath = main.testOnDirectory + \
+                                  main.params[ 'DEPENDENCY' ][ 'path' ]
+            main.dependencyFunc = main.params[ 'DEPENDENCY' ][ 'function' ]
+            main.topoName = main.params[ 'DEPENDENCY' ][ 'topology' ]
+            main.cellName = main.params[ 'ENV' ][ 'cellName' ]
+            main.apps = main.params[ 'ENV' ][ 'cellApps' ]
+            main.scale = ( main.params[ 'SCALE' ] ).split( "," )
+            main.ofportStatus = main.params[ 'TSHARK' ][ 'ofpPortStatus' ]
+            main.tsharkResultPath = main.params[ 'TSHARK' ][ 'tsharkReusltPath' ]
+            main.sampleSize = int( main.params[ 'TEST' ][ 'sampleSize' ] )
+            main.warmUp = int( main.params[ 'TEST' ][ 'warmUp' ] )
+            main.maxProcessTime = int( main.params[ 'TEST' ][ 'maxProcessTime' ] )
+            main.dbFileName = main.params[ 'DATABASE' ][ 'dbName' ]
+            main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
+            main.measurementSleep = int( main.params[ 'SLEEP' ][ 'measure' ] )
+            main.maxScale = int( main.params[ 'max' ] )
+            main.interface = main.params[ 'TEST' ][ 'interface' ]
+            main.timeout = int( main.params[ 'TIMEOUT' ][ 'timeout' ] )
+            main.MNSleep = int( main.params[ 'SLEEP' ][ 'mininet' ] )
+            main.device = main.params[ 'TEST' ][ 'device' ]
+            main.debug = main.params[ 'TEST' ][ 'debug' ]
 
-        main.case( "Pull onos branch and build onos on Teststation." )
+            if main.debug == "True":
+                main.debug = True
+            else:
+                main.debug = False
 
-        if gitPull == 'True':
-            main.step( "Git Checkout ONOS branch: " + gitBranch )
-            stepResult = main.ONOSbench.gitCheckout( branch=gitBranch )
-            utilities.assert_equals(expect=main.TRUE,
-                                    actual=stepResult,
-                                    onpass="Successfully checkout onos branch.",
-                                    onfail="Failed to checkout onos branch. Exiting test...")
-            if not stepResult: main.exit()
+            stepResult = main.testSetUp.gitPulling()
+            main.log.info( "Create Database file " + main.dbFileName )
+            resultsDB = open( main.dbFileName, "w+" )
+            resultsDB.close()
 
-            main.step( "Git Pull on ONOS branch:" + gitBranch )
-            stepResult = main.ONOSbench.gitPull()
-            utilities.assert_equals(expect=main.TRUE,
-                                    actual=stepResult,
-                                    onpass="Successfully pull onos. ",
-                                    onfail="Failed to pull onos. Exiting test ...")
-            if not stepResult: main.exit()
-
-
-        else:
-            main.log.warn( "Skipped pulling onos and Skipped building ONOS" )
-
-        main.testOnDirectory = os.path.dirname( os.getcwd() )
-        main.MN1Ip = main.params['MN']['ip1']
-        main.dependencyPath = main.testOnDirectory + \
-                              main.params['DEPENDENCY']['path']
-        main.dependencyFunc = main.params['DEPENDENCY']['function']
-        main.topoName = main.params['DEPENDENCY']['topology']
-        main.cellName = main.params['ENV']['cellName']
-        main.Apps = main.params['ENV']['cellApps']
-        main.scale = (main.params['SCALE']).split(",")
-        main.ofportStatus = main.params['TSHARK']['ofpPortStatus']
-        main.tsharkResultPath = main.params['TSHARK']['tsharkReusltPath']
-        main.sampleSize = int( main.params['TEST']['sampleSize'] )
-        main.warmUp = int( main.params['TEST']['warmUp'] )
-        main.maxProcessTime = int( main.params['TEST']['maxProcessTime'])
-        main.dbFileName = main.params['DATABASE']['dbName']
-        main.startUpSleep = int( main.params['SLEEP']['startup'] )
-        main.measurementSleep = int( main.params['SLEEP']['measure'] )
-        main.maxScale = int( main.params['max'] )
-        main.interface = main.params['TEST']['interface']
-        main.timeout = int( main.params['TIMEOUT']['timeout'] )
-        main.MNSleep = int( main.params['SLEEP']['mininet'])
-        main.device = main.params['TEST']['device']
-        main.debug = main.params['TEST']['debug']
-
-        if main.debug == "True":
-            main.debug = True
-        else:
-            main.debug = False
-
-        main.log.info( "Create Database file " + main.dbFileName )
-        resultsDB = open( main.dbFileName, "w+" )
-        resultsDB.close()
-
-        main.portFunc = imp.load_source(main.dependencyFunc,
-                                       main.dependencyPath +
-                                       main.dependencyFunc +
-                                       ".py")
+            main.portFunc = imp.load_source( main.dependencyFunc,
+                                           main.dependencyPath +
+                                           main.dependencyFunc +
+                                           ".py" )
+        except Exception as e:
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
+        main.commit = main.commit.split( " " )[ 1 ]
 
     def CASE1( self, main ):
         # Clean up test environment and set up
         import time
-        main.log.info( "Get ONOS cluster IP" )
-        print( main.scale )
-        main.numCtrls = int( main.scale.pop(0) )
-        main.ONOSip = []
-        main.maxNumBatch = 0
-        main.AllONOSip = main.ONOSbench.getOnosIps()
-        for i in range( main.numCtrls ):
-            main.ONOSip.append( main.AllONOSip[i] )
-        main.log.info( main.ONOSip )
-        main.CLIs = []
-        main.log.info( "Creating list of ONOS cli handles" )
-        for i in range( main.numCtrls ):
-            main.CLIs.append( getattr(main, 'ONOScli%s' % (i + 1)) )
-
-        if not main.CLIs:
-            main.log.error( "Failed to create the list of ONOS cli handles" )
-            main.cleanup()
-            main.exit()
-
-        main.commit = main.ONOSbench.getVersion( report=True )
-        main.commit = main.commit.split(" ")[1]
-        main.log.info( "Starting up %s node(s) ONOS cluster" % main.numCtrls )
-        main.log.info("Safety check, killing all ONOS processes" +
-                      " before initiating environment setup")
-
-        for i in range( main.numCtrls ):
-            main.ONOSbench.onosStop( main.ONOSip[i] )
-            main.ONOSbench.onosKill( main.ONOSip[i] )
-
-        main.log.info( "NODE COUNT = %s" % main.numCtrls )
-        main.ONOSbench.createCellFile(main.ONOSbench.ip_address,
-                                      main.cellName,
-                                      main.MN1Ip,
-                                      main.Apps,
-                                      main.ONOSip,
-                                      main.ONOScli1.karafUser)
-        main.step( "Apply cell to environment" )
-        cellResult = main.ONOSbench.setCell( main.cellName )
-        verifyResult = main.ONOSbench.verifyCell()
-        stepResult = cellResult and verifyResult
-        utilities.assert_equals(expect=main.TRUE,
-                                actual=stepResult,
-                                onpass="Successfully applied cell to " + \
-                                       "environment",
-                                onfail="Failed to apply cell to environment ")
-
-        main.step( "Creating ONOS package" )
-        packageResult = main.ONOSbench.buckBuild()
-        stepResult = packageResult
-        utilities.assert_equals(expect=main.TRUE,
-                                actual=stepResult,
-                                onpass="Successfully created ONOS package",
-                                onfail="Failed to create ONOS package")
-
-        main.step( "Uninstall ONOS package on all Nodes" )
-        uninstallResult = main.TRUE
-        for i in range( int( main.numCtrls ) ):
-            main.log.info( "Uninstalling package on ONOS Node IP: " + main.ONOSip[i] )
-            u_result = main.ONOSbench.onosUninstall( main.ONOSip[i] )
-            utilities.assert_equals(expect=main.TRUE, actual=u_result,
-                                    onpass="Test step PASS",
-                                    onfail="Test step FAIL")
-            uninstallResult = uninstallResult and u_result
-
-        main.step( "Install ONOS package on all Nodes" )
-        installResult = main.TRUE
-        for i in range( int( main.numCtrls ) ):
-            main.log.info( "Installing package on ONOS Node IP: " + main.ONOSip[i] )
-            i_result = main.ONOSbench.onosInstall( node=main.ONOSip[i] )
-            utilities.assert_equals(expect=main.TRUE, actual=i_result,
-                                    onpass="Test step PASS",
-                                    onfail="Test step FAIL")
-            installResult = installResult and i_result
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.TRUE
-        for i in range( int( main.numCtrls ) ):
-            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=main.ONOSip[i] )
-        utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        time.sleep( main.startUpSleep )
-        main.step( "Starting ONOS service" )
-        stopResult = main.TRUE
-        startResult = main.TRUE
-        onosIsUp = main.TRUE
-        for i in range( main.numCtrls ):
-            onosIsUp = onosIsUp and main.ONOSbench.isup( main.ONOSip[ i ] )
-        if onosIsUp == main.TRUE:
-            main.log.report( "ONOS instance is up and ready" )
-        else:
-            main.log.report( "ONOS instance may not be up, stop and " +
-                             "start ONOS again " )
-            for i in range( main.numCtrls ):
-                stopResult = stopResult and \
-                        main.ONOSbench.onosStop( main.ONOSip[ i ] )
-            for i in range( main.numCtrls ):
-                startResult = startResult and \
-                        main.ONOSbench.onosStart( main.ONOSip[ i ] )
-        stepResult = onosIsUp and stopResult and startResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="ONOS service is ready",
-                                 onfail="ONOS service did not start properly" )
-
-        main.step( "Start ONOS CLI on all nodes" )
-        cliResult = main.TRUE
-        main.step( " Start ONOS cli using thread " )
-        startCliResult = main.TRUE
-        pool = []
-        main.threadID = 0
-        for i in range( int( main.numCtrls ) ):
-            t = main.Thread(target=main.CLIs[i].startOnosCli,
-                            threadID=main.threadID,
-                            name="startOnosCli",
-                            args=[main.ONOSip[i]],
-                            kwargs={"onosStartTimeout": main.timeout})
-            pool.append(t)
-            t.start()
-            main.threadID = main.threadID + 1
-        for t in pool:
-            t.join()
-            startCliResult = startCliResult and t.result
-        time.sleep( main.startUpSleep )
+        main.testSetUp.getNumCtrls( True )
+        main.testSetUp.envSetup( includeGitPull=False, makeMaxNodes=False )
+        main.testSetUp.ONOSSetUp( main.Mininet1, True,
+                                  cellName=main.cellName, killRemoveMax=False,
+                                  CtrlsSet=False )
 
         main.log.info( "Configure apps" )
-        main.CLIs[0].setCfg("org.onosproject.net.topology.impl.DefaultTopologyProvider",
-                            "maxEvents 1")
-        main.CLIs[0].setCfg("org.onosproject.net.topology.impl.DefaultTopologyProvider",
-                            "maxBatchMs 0")
-        main.CLIs[0].setCfg("org.onosproject.net.topology.impl.DefaultTopologyProvider",
-                            "maxIdleMs 0")
+        main.CLIs[0].setCfg( "org.onosproject.net.topology.impl.DefaultTopologyProvider",
+                            "maxEvents 1" )
+        main.CLIs[0].setCfg( "org.onosproject.net.topology.impl.DefaultTopologyProvider",
+                            "maxBatchMs 0" )
+        main.CLIs[0].setCfg( "org.onosproject.net.topology.impl.DefaultTopologyProvider",
+                            "maxIdleMs 0" )
         time.sleep(1)
         main.log.info( "Copy topology file to Mininet" )
-        main.ONOSbench.copyMininetFile(main.topoName,
+        main.ONOSbench.copyMininetFile( main.topoName,
                                        main.dependencyPath,
                                        main.Mininet1.user_name,
                                        main.Mininet1.ip_address)
-        main.log.info( "Stop Mininet..." )
-        main.Mininet1.stopNet()
+        try:
+            from tests.dependencies.utils import Utils
+        except ImportError:
+            main.log.error( "Utils not found exiting the test" )
+            main.exit()
+        try:
+            main.Utils
+        except ( NameError, AttributeError ):
+            main.Utils = Utils()
+        main.Utils.mininetCleanup( main.Mininet1 )
         time.sleep( main.MNSleep )
         main.log.info( "Start new mininet topology" )
         main.Mininet1.startNet()
@@ -270,66 +145,66 @@
 
         # Dictionary for result
         maxDict  = {}
-        maxDict['down'] = {}
-        maxDict['up'] = {}
-        maxDict['down']['max'] = 0
-        maxDict['up']['max'] = 0
-        maxDict['down']['node'] = 0
-        maxDict['up']['node'] = 0
+        maxDict[ 'down' ] = {}
+        maxDict[ 'up' ] = {}
+        maxDict[ 'down' ][ 'max' ] = 0
+        maxDict[ 'up' ][ 'max' ] = 0
+        maxDict[ 'down' ][ 'node' ] = 0
+        maxDict[ 'up' ][ 'node' ] = 0
         EtoEtemp = 0
         for d in resultDict:
             for i in range( 1, main.numCtrls + 1 ):
                 # calculate average and std for result, and grep the max End to End data
-                EtoEtemp = numpy.average( resultDict[d][ 'node' + str(i) ]['EtoE'] )
+                EtoEtemp = numpy.average( resultDict[d][ 'node' + str(i) ][ 'EtoE' ] )
                 resultDict[d][ 'node' + str(i) ][ 'Ave' ][ 'EtoE' ] = EtoEtemp
-                if maxDict[d]['max'] < EtoEtemp:
+                if maxDict[d][ 'max' ] < EtoEtemp:
                     # get max End to End latency
-                    maxDict[d]['max'] = EtoEtemp
-                    maxDict[d]['node'] = i
-                resultDict[d]['node' + str(i)]['Ave']['PtoD'] = numpy.average(resultDict[d]['node' + str(i)]['PtoD'])
-                resultDict[d]['node' + str(i)]['Ave']['DtoL'] = numpy.average(resultDict[d]['node' + str(i)]['DtoL'])
-                resultDict[d]['node' + str(i)]['Ave']['LtoG'] = numpy.average(resultDict[d]['node' + str(i)]['LtoG'])
+                    maxDict[d][ 'max' ] = EtoEtemp
+                    maxDict[d][ 'node' ] = i
+                resultDict[d][ 'node' + str(i)][ 'Ave' ][ 'PtoD' ] = numpy.average(resultDict[d][ 'node' + str(i)][ 'PtoD' ] )
+                resultDict[d][ 'node' + str(i)][ 'Ave' ][ 'DtoL' ] = numpy.average(resultDict[d][ 'node' + str(i)][ 'DtoL' ] )
+                resultDict[d][ 'node' + str(i)][ 'Ave' ][ 'LtoG' ] = numpy.average(resultDict[d][ 'node' + str(i)][ 'LtoG' ] )
 
-                resultDict[d]['node' + str(i)]['Std']['EtoE'] = numpy.std(resultDict[d]['node' + str(i)]['EtoE'])
-                resultDict[d]['node' + str(i)]['Std']['PtoD'] = numpy.std(resultDict[d]['node' + str(i)]['PtoD'])
-                resultDict[d]['node' + str(i)]['Std']['DtoL'] = numpy.std(resultDict[d]['node' + str(i)]['DtoL'])
-                resultDict[d]['node' + str(i)]['Std']['LtoG'] = numpy.std(resultDict[d]['node' + str(i)]['LtoG'])
+                resultDict[d][ 'node' + str(i)][ 'Std' ][ 'EtoE' ] = numpy.std(resultDict[d][ 'node' + str(i)][ 'EtoE' ] )
+                resultDict[d][ 'node' + str(i)][ 'Std' ][ 'PtoD' ] = numpy.std(resultDict[d][ 'node' + str(i)][ 'PtoD' ] )
+                resultDict[d][ 'node' + str(i)][ 'Std' ][ 'DtoL' ] = numpy.std(resultDict[d][ 'node' + str(i)][ 'DtoL' ] )
+                resultDict[d][ 'node' + str(i)][ 'Std' ][ 'LtoG' ] = numpy.std(resultDict[d][ 'node' + str(i)][ 'LtoG' ] )
 
                 main.log.report( "=====node{} Summary:=====".format( str(i) ) )
                 main.log.report( "=============Port {}=======".format( str(d) ) )
                 main.log.report(
-                    "End to End average: {}".format( str(resultDict[d][ 'node' + str(i) ][ 'Ave' ][ 'EtoE' ]) ) )
+                    "End to End average: {}".format( str(resultDict[d][ 'node' + str(i) ][ 'Ave' ][ 'EtoE' ] ) ) )
                 main.log.report(
-                    "End to End Std: {}".format( str(resultDict[d][ 'node' + str(i) ][ 'Std' ][ 'EtoE' ]) ) )
+                    "End to End Std: {}".format( str(resultDict[d][ 'node' + str(i) ][ 'Std' ][ 'EtoE' ] ) ) )
                 main.log.report(
-                    "Package to Device average: {}".format( str(resultDict[d]['node' + str(i)]['Ave']['PtoD']) ) )
+                    "Package to Device average: {}".format( str(resultDict[d][ 'node' + str(i)][ 'Ave' ][ 'PtoD' ] ) ) )
                 main.log.report(
-                    "Package to Device Std: {}".format( str( resultDict[d]['node' + str(i)]['Std']['PtoD'])))
+                    "Package to Device Std: {}".format( str( resultDict[d][ 'node' + str(i)][ 'Std' ][ 'PtoD' ] ) ))
                 main.log.report(
-                    "Device to Link average: {}".format( str( resultDict[d]['node' + str(i)]['Ave']['DtoL']) ) )
+                    "Device to Link average: {}".format( str( resultDict[d][ 'node' + str(i)][ 'Ave' ][ 'DtoL' ] ) ) )
                 main.log.report(
-                    "Device to Link Std: {}".format( str( resultDict[d]['node' + str(i)]['Std']['DtoL'])))
+                    "Device to Link Std: {}".format( str( resultDict[d][ 'node' + str(i)][ 'Std' ][ 'DtoL' ] ) ))
                 main.log.report(
-                    "Link to Grapg average: {}".format( str( resultDict[d]['node' + str(i)]['Ave']['LtoG']) ) )
+                    "Link to Grapg average: {}".format( str( resultDict[d][ 'node' + str(i)][ 'Ave' ][ 'LtoG' ] ) ) )
                 main.log.report(
-                    "Link to Grapg Std: {}".format( str( resultDict[d]['node' + str(i)]['Std']['LtoG'] ) ) )
+                    "Link to Grapg Std: {}".format( str( resultDict[d][ 'node' + str(i)][ 'Std' ][ 'LtoG' ] ) ) )
 
         with open( main.dbFileName, "a" ) as dbFile:
             # Scale number
             temp = str( main.numCtrls )
             temp += ",'baremetal1'"
             # put result
-            temp += "," + str( resultDict['up'][ 'node' + str(maxDict['up']['node']) ][ 'Ave' ][ 'EtoE' ] )
-            temp += "," + str( resultDict['up'][ 'node' + str(maxDict['up']['node']) ][ 'Ave' ][ 'PtoD' ] )
-            temp += "," + str( resultDict['up'][ 'node' + str(maxDict['up']['node']) ][ 'Ave' ][ 'DtoL' ] )
-            temp += "," + str( resultDict['up'][ 'node' + str(maxDict['up']['node']) ][ 'Ave' ][ 'LtoG' ] )
-            temp += "," + str( resultDict['down'][ 'node' + str(maxDict['down']['node']) ][ 'Ave' ][ 'EtoE' ] )
-            temp += "," + str( resultDict['down'][ 'node' + str(maxDict['down']['node']) ][ 'Ave' ][ 'PtoD' ] )
-            temp += "," + str( resultDict['down'][ 'node' + str(maxDict['down']['node']) ][ 'Ave' ][ 'DtoL' ] )
-            temp += "," + str( resultDict['down'][ 'node' + str(maxDict['down']['node']) ][ 'Ave' ][ 'LtoG' ] )
+            temp += "," + str( resultDict[ 'up' ][ 'node' + str( maxDict[ 'up' ][ 'node' ] ) ][ 'Ave' ][ 'EtoE' ] )
+            temp += "," + str( resultDict[ 'up' ][ 'node' + str( maxDict[ 'up' ][ 'node' ] ) ][ 'Ave' ][ 'PtoD' ] )
+            temp += "," + str( resultDict[ 'up' ][ 'node' + str( maxDict[ 'up' ][ 'node' ] ) ][ 'Ave' ][ 'DtoL' ] )
+            temp += "," + str( resultDict[ 'up' ][ 'node' + str( maxDict[ 'up' ][ 'node' ] ) ][ 'Ave' ][ 'LtoG' ] )
+            temp += "," + str( resultDict[ 'down' ][ 'node' + str( maxDict[ 'down' ][ 'node' ] ) ][ 'Ave' ][ 'EtoE' ] )
+            temp += "," + str( resultDict[ 'down' ][ 'node' + str( maxDict[ 'down' ][ 'node' ] ) ][ 'Ave' ][ 'PtoD' ] )
+            temp += "," + str( resultDict[ 'down' ][ 'node' + str( maxDict[ 'down' ][ 'node' ] ) ][ 'Ave' ][ 'DtoL' ] )
+            temp += "," + str( resultDict[ 'down' ][ 'node' + str( maxDict[ 'down' ][ 'node' ] ) ][ 'Ave' ][ 'LtoG' ] )
 
-            temp += "," + str( resultDict['up'][ 'node' + str(maxDict['up']['node']) ][ 'Std' ][ 'EtoE' ] )
-            temp += "," + str( resultDict['down'][ 'node' + str(maxDict['down']['node']) ][ 'Std' ][ 'EtoE' ] )
+            temp += "," + str( resultDict[ 'up' ][ 'node' + str( maxDict[ 'up' ][ 'node' ] ) ][ 'Std' ][ 'EtoE' ] )
+            temp += "," + str( resultDict[ 'down' ][ 'node' + str( maxDict[ 'down' ][ 'node' ] ) ][ 'Std' ][ 'EtoE' ] )
 
             temp += "\n"
             dbFile.write( temp )
diff --git a/TestON/tests/SCPF/SCPFscaleTopo/SCPFscaleTopo.py b/TestON/tests/SCPF/SCPFscaleTopo/SCPFscaleTopo.py
index 32bd302..58505e9 100644
--- a/TestON/tests/SCPF/SCPFscaleTopo/SCPFscaleTopo.py
+++ b/TestON/tests/SCPF/SCPFscaleTopo/SCPFscaleTopo.py
@@ -19,106 +19,88 @@
             - Install ONOS package
             - Build ONOS package
         """
-        main.case( "Constructing test variables" )
-        main.step( "Constructing test variables" )
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        main.testSetUp.envSetupDescription()
         stepResult = main.FALSE
-        # The variable to decide if the data should be written into data base.
-        # 1 means Yes and -1 means No.
-        main.writeData = 1
-        main.searchTerm = main.params[ 'SearchTerm' ]
-        main.testOnDirectory = os.path.dirname( os.getcwd ( ) )
-        main.apps = main.params[ 'ENV' ][ 'cellApps' ]
-        gitBranch = main.params[ 'GIT' ][ 'branch' ]
-        main.dependencyPath = main.testOnDirectory + \
-                              main.params[ 'DEPENDENCY' ][ 'path' ]
-        main.tsharkResultPath = main.params[ 'TsharkPath' ]
-        main.roleRequest = main.params[ 'SearchTerm' ]['roleRequest']
-        main.multiovs = main.params[ 'DEPENDENCY' ][ 'multiovs' ]
-        main.topoName = main.params[ 'TOPOLOGY' ][ 'topology' ]
-        main.numCtrls = int( main.params[ 'CTRL' ][ 'numCtrls' ] )
-        main.topoScale = ( main.params[ 'TOPOLOGY' ][ 'scale' ] ).split( "," )
-        main.topoScaleSize = len( main.topoScale )
-        wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
-        wrapperFile2 = main.params[ 'DEPENDENCY' ][ 'wrapper2' ]
-        wrapperFile3 = main.params[ 'DEPENDENCY' ][ 'wrapper3' ]
-        main.topoCmpAttempts = int( main.params[ 'ATTEMPTS' ][ 'topoCmp' ] )
-        main.pingallAttempts = int( main.params[ 'ATTEMPTS' ][ 'pingall' ] )
-        main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
-        main.balanceSleep = int( main.params[ 'SLEEP' ][ 'balance' ] )
-        main.nodeSleep = int( main.params[ 'SLEEP' ][ 'nodeSleep' ] )
-        main.pingallSleep = int( main.params[ 'SLEEP' ][ 'pingall' ] )
-        main.MNSleep = int( main.params[ 'SLEEP' ][ 'MNsleep' ] )
-        main.pingTimeout = float( main.params[ 'TIMEOUT' ][ 'pingall' ] )
-        main.hostDiscover = main.params[ 'TOPOLOGY' ][ 'host' ]
-        main.hostDiscoverSleep = float( main.params['SLEEP']['host'] )
-        if main.hostDiscover == 'True':
-            main.hostDiscover = True
-        else:
-            main.hostDiscover = False
-        gitPull = main.params[ 'GIT' ][ 'pull' ]
-        main.homeDir = os.path.expanduser('~')
-        main.cellData = {} # for creating cell file
-        main.hostsData = {}
-        main.CLIs = []
-        main.ONOSip = []
-        main.activeNodes = []
-        main.ONOSip = main.ONOSbench.getOnosIps()
-
-        for i in range(main.numCtrls):
-                main.CLIs.append( getattr( main, 'ONOScli%s' % (i+1) ) )
-
-        main.allinfo = {} # The dictionary to record all the data from karaf.log
-
-        for i in range( 2 ):
-            main.allinfo[ i ]={}
-            for w in range ( 3 ):
-                # Totaltime: the time from the new switchConnection to its end
-                # swConnection: the time from the first new switchConnection to the last new switchConnection
-                # lastSwToLastRr: the time from the last new switchConnection to the last role request
-                # lastRrToLastTopology: the time form the last role request to the last topology
-                # disconnectRate: the rate that shows how many switch disconnect after connection
-                main.allinfo[ i ][ 'info' + str( w ) ]= { 'totalTime': 0, 'swConnection': 0, 'lastSwToLastRr': 0, 'lastRrToLastTopology': 0, 'disconnectRate': 0 }
-
-        main.dbFilePath = main.params[ 'DATABASE' ][ 'dbPath' ]
-        main.log.info( "Create Database file " + main.dbFilePath )
-        resultDB = open(main.dbFilePath, 'w+' )
-        resultDB.close()
+        try:
+            # The variable to decide if the data should be written into data base.
+            # 1 means Yes and -1 means No.
+            main.writeData = 1
+            main.searchTerm = main.params[ 'SearchTerm' ]
+            main.apps = main.params[ 'ENV' ][ 'cellApps' ]
+            main.dependencyPath = main.testOnDirectory + \
+                                  main.params[ 'DEPENDENCY' ][ 'path' ]
+            main.tsharkResultPath = main.params[ 'TsharkPath' ]
+            main.roleRequest = main.params[ 'SearchTerm' ]['roleRequest']
+            main.multiovs = main.params[ 'DEPENDENCY' ][ 'multiovs' ]
+            main.topoName = main.params[ 'TOPOLOGY' ][ 'topology' ]
+            main.numCtrls = int( main.params[ 'CTRL' ][ 'numCtrls' ] )
+            main.topoScale = ( main.params[ 'TOPOLOGY' ][ 'scale' ] ).split( "," )
+            main.topoScaleSize = len( main.topoScale )
+            wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
+            wrapperFile2 = main.params[ 'DEPENDENCY' ][ 'wrapper2' ]
+            wrapperFile3 = main.params[ 'DEPENDENCY' ][ 'wrapper3' ]
+            main.topoCmpAttempts = int( main.params[ 'ATTEMPTS' ][ 'topoCmp' ] )
+            main.pingallAttempts = int( main.params[ 'ATTEMPTS' ][ 'pingall' ] )
+            main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
+            main.balanceSleep = int( main.params[ 'SLEEP' ][ 'balance' ] )
+            main.nodeSleep = int( main.params[ 'SLEEP' ][ 'nodeSleep' ] )
+            main.pingallSleep = int( main.params[ 'SLEEP' ][ 'pingall' ] )
+            main.MNSleep = int( main.params[ 'SLEEP' ][ 'MNsleep' ] )
+            main.pingTimeout = float( main.params[ 'TIMEOUT' ][ 'pingall' ] )
+            main.hostDiscover = main.params[ 'TOPOLOGY' ][ 'host' ]
+            main.hostDiscoverSleep = float( main.params['SLEEP']['host'] )
+            if main.hostDiscover == 'True':
+                main.hostDiscover = True
+            else:
+                main.hostDiscover = False
+            main.homeDir = os.path.expanduser('~')
+            main.hostsData = {}
+            main.activeNodes = []
 
 
-        main.startUp = imp.load_source( wrapperFile1,
-                                        main.dependencyPath +
-                                        wrapperFile1 +
-                                        ".py" )
+            stepResult = main.testSetUp.envSetup()
+            main.allinfo = {} # The dictionary to record all the data from karaf.log
 
-        main.scaleTopoFunction = imp.load_source( wrapperFile2,
-                                                  main.dependencyPath +
-                                                  wrapperFile2 +
-                                                  ".py" )
+            for i in range( 2 ):
+                main.allinfo[ i ]={}
+                for w in range ( 3 ):
+                    # Totaltime: the time from the new switchConnection to its end
+                    # swConnection: the time from the first new switchConnection to the last new switchConnection
+                    # lastSwToLastRr: the time from the last new switchConnection to the last role request
+                    # lastRrToLastTopology: the time form the last role request to the last topology
+                    # disconnectRate: the rate that shows how many switch disconnect after connection
+                    main.allinfo[ i ][ 'info' + str( w ) ]= { 'totalTime': 0, 'swConnection': 0, 'lastSwToLastRr': 0, 'lastRrToLastTopology': 0, 'disconnectRate': 0 }
 
-        main.topo = imp.load_source( wrapperFile3,
-                                     main.dependencyPath +
-                                     wrapperFile3 +
-                                     ".py" )
+            main.dbFilePath = main.params[ 'DATABASE' ][ 'dbPath' ]
+            main.log.info( "Create Database file " + main.dbFilePath )
+            resultDB = open(main.dbFilePath, 'w+' )
+            resultDB.close()
 
-        main.ONOSbench.scp( main.Mininet1,
-                            main.dependencyPath +
-                            main.multiovs,
-                            main.Mininet1.home,
-                            direction="to" )
+            main.scaleTopoFunction = imp.load_source( wrapperFile2,
+                                                      main.dependencyPath +
+                                                      wrapperFile2 +
+                                                      ".py" )
 
-        if main.CLIs:
-                stepResult = main.TRUE
-        else:
-            main.log.error( "Did not properly created list of " +
-                            "ONOS CLI handle" )
-            stepResult = main.FALSE
+            main.topo = imp.load_source( wrapperFile3,
+                                         main.dependencyPath +
+                                         wrapperFile3 +
+                                         ".py" )
 
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully construct " +
-                                        "test variables ",
-                                 onfail="Failed to construct test variables" )
-
+            main.ONOSbench.scp( main.Mininet1,
+                                main.dependencyPath +
+                                main.multiovs,
+                                main.Mininet1.home,
+                                direction="to" )
+        except Exception as e:
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
+        main.commit = main.commit.split( " " )[ 1 ]
 
     def CASE2( self, main):
         """
@@ -133,127 +115,20 @@
         - Connect to cli
         """
         import time
-        main.log.info( "Checking if mininet is already running" )
-        if len( main.topoScale ) < main.topoScaleSize:
-            main.log.info( "Mininet is already running. Stopping mininet." )
-            main.Mininet1.stopNet()
-            time.sleep(main.MNSleep)
-        else:
-            main.log.info( "Mininet was not running" )
-
-        main.commit = main.ONOSbench.getVersion(report=True)
-        main.commit = main.commit.split(" ")[1]
-
-        main.case( "Starting up " + str( main.numCtrls ) +
-                   " node(s) ONOS cluster" )
-        main.caseExplanation = "Set up ONOS with " + str( main.numCtrls ) +\
-                                " node(s) ONOS cluster"
-
-        #kill off all onos processes
-        main.log.info( "Safety check, killing all ONOS processes" +
-                       " before initiating environment setup" )
-
-        for i in range( main.numCtrls ):
-            main.ONOSbench.onosStop( main.ONOSip[ i ] )
-            main.ONOSbench.onosKill( main.ONOSip[ i ] )
-
-        tempOnosIp = []
-        for i in range( main.numCtrls ):
-            tempOnosIp.append( main.ONOSip[i] )
-
-        main.ONOSbench.createCellFile( main.ONOSbench.ip_address,
-                                       "temp", main.Mininet1.ip_address,
-                                       main.apps, tempOnosIp, main.ONOScli1.karafUser )
-
-        main.step( "Apply cell to environment" )
-        cellResult = main.ONOSbench.setCell( "temp" )
-        verifyResult = main.ONOSbench.verifyCell()
-        stepResult = cellResult and verifyResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully applied cell to " + \
-                                        "environment",
-                                 onfail="Failed to apply cell to environment " )
-
-        main.step( "Creating ONOS package" )
-        packageResult = main.ONOSbench.buckBuild()
-        stepResult = packageResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully created ONOS package",
-                                 onfail="Failed to create ONOS package" )
-
-        time.sleep( main.startUpSleep )
-        main.step( "Uninstalling ONOS package" )
-        onosUninstallResult = main.TRUE
-        for ip in main.ONOSip:
-            onosUninstallResult = onosUninstallResult and \
-                    main.ONOSbench.onosUninstall( nodeIp=ip )
-        stepResult = onosUninstallResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully uninstalled ONOS package",
-                                 onfail="Failed to uninstall ONOS package" )
-
-        time.sleep( main.startUpSleep )
-        main.step( "Installing ONOS package" )
-        onosInstallResult = main.TRUE
-        for i in range( main.numCtrls ):
-            onosInstallResult = onosInstallResult and \
-                    main.ONOSbench.onosInstall( node=main.ONOSip[ i ] )
-        stepResult = onosInstallResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully installed ONOS package",
-                                 onfail="Failed to install ONOS package" )
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.TRUE
-        for i in range( int( main.numCtrls ) ):
-            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=main.ONOSip[i] )
-        utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        time.sleep( main.startUpSleep )
-        main.step( "Starting ONOS service" )
-        stopResult = main.TRUE
-        startResult = main.TRUE
-        onosIsUp = main.TRUE
-
-        for i in range( main.numCtrls ):
-            onosIsUp = onosIsUp and main.ONOSbench.isup( main.ONOSip[ i ] )
-        if onosIsUp == main.TRUE:
-            main.log.report( "ONOS instance is up and ready" )
-        else:
-            main.log.report( "ONOS instance may not be up, stop and " +
-                             "start ONOS again " )
-
-            for i in range( main.numCtrls ):
-                stopResult = stopResult and \
-                        main.ONOSbench.onosStop( main.ONOSip[ i ] )
-            for i in range( main.numCtrls ):
-                startResult = startResult and \
-                        main.ONOSbench.onosStart( main.ONOSip[ i ] )
-        stepResult = onosIsUp and stopResult and startResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="ONOS service is ready",
-                                 onfail="ONOS service did not start properly" )
-
-        main.step( "Start ONOS cli" )
-        cliResult = main.TRUE
+        try:
+            from tests.dependencies.utils import Utils
+        except ImportError:
+            main.log.error( "Utils not found exiting the test" )
+            main.exit()
+        try:
+            main.Utils
+        except ( NameError, AttributeError ):
+            main.Utils = Utils()
+        main.Utils.mininetCleanup( main.Mininet1 )
+        main.testSetUp.ONOSSetUp( main.Mininet1 )
         main.activeNodes = []
         for i in range( main.numCtrls ):
-            cliResult = cliResult and \
-                        main.CLIs[ i ].startOnosCli( main.ONOSip[ i ] )
             main.activeNodes.append( i )
-        stepResult = cliResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully start ONOS cli",
-                                 onfail="Failed to start ONOS cli" )
-        time.sleep( main.startUpSleep )
 
     def CASE10( self, main ):
         """
@@ -303,6 +178,15 @@
         """
         import json
         import time
+        try:
+            from tests.dependencies.topology import Topology
+        except ImportError:
+            main.log.error( "Topology not found exiting the test" )
+            main.exit()
+        try:
+            main.topoRelated
+        except ( NameError, AttributeError ):
+            main.topoRelated = Topology()
         # First capture
         for i in range( 3 ):
             # Calculate total time
@@ -328,30 +212,22 @@
         compareRetry = 0
         while compareRetry < 3:
             #While loop for retry
-            devices = main.topo.getAllDevices( main )
-            ports = main.topo.getAllPorts( main )
-            links = main.topo.getAllLinks( main)
+            devices = main.topoRelated.getAllDevices( main.numCtrls, False )
+            ports = main.topoRelated.getAllPorts( main.numCtrls, False )
+            links = main.topoRelated.getAllLinks( main.numCtrls, False)
             mnSwitches = main.Mininet1.getSwitches()
             mnLinks = main.Mininet1.getLinks(timeout=180)
 
             for controller in range(len(main.activeNodes)):
                 # controllerStr = str( main.activeNodes[controller] + 1 )
-                if devices[ controller ] and ports[ controller ] and \
-                                "Error" not in devices[ controller ] and \
-                                "Error" not in ports[ controller ]:
-                    currentDevicesResult = main.Mininet1.compareSwitches(
-                            mnSwitches,
-                            json.loads( devices[ controller ] ),
-                            json.loads( ports[ controller ] ) )
-                else:
-                    currentDevicesResult = main.FALSE
+                currentDevicesResult = main.topoRelated.compareDevicePort(
+                                                            main.Mininet1, controller,
+                                                            mnSwitches,
+                                                            devices, ports )
 
-                if links[ controller ] and "Error" not in links[ controller ]:
-                    currentLinksResult = main.Mininet1.compareLinks(
-                            mnSwitches, mnLinks,
-                            json.loads( links[ controller ] ) )
-                else:
-                    currentLinksResult = main.FALSE
+                currentLinksResult = main.topoRelated.compareBase( links, controller,
+                                                        main.Mininet1.compareLinks,
+                                                        [ mnSwitches, mnLinks ] )
 
                 stepResult = stepResult and currentDevicesResult and currentLinksResult
             if stepResult:
diff --git a/TestON/tests/SCPF/SCPFscaleTopo/dependencies/startUp.py b/TestON/tests/SCPF/SCPFscaleTopo/dependencies/startUp.py
deleted file mode 100644
index 501cbb3..0000000
--- a/TestON/tests/SCPF/SCPFscaleTopo/dependencies/startUp.py
+++ /dev/null
@@ -1,38 +0,0 @@
-"""
-    This wrapper function is use for starting up onos instance
-"""
-
-import time
-import os
-import json
-
-def onosBuild( main, gitBranch ):
-    """
-        This includes pulling ONOS and building it using maven install
-    """
-
-    buildResult = main.FALSE
-
-    # Git checkout a branch of ONOS
-    checkOutResult = main.ONOSbench.gitCheckout( gitBranch )
-    # Does the git pull on the branch that was checked out
-    if not checkOutResult:
-        main.log.warn( "Failed to checked out " + gitBranch +
-                                           " branch")
-    else:
-        main.log.info( "Successfully checked out " + gitBranch +
-                                           " branch")
-    gitPullResult = main.ONOSbench.gitPull()
-    if gitPullResult == main.ERROR:
-        main.log.error( "Error pulling git branch" )
-    else:
-        main.log.info( "Successfully pulled " + gitBranch + " branch" )
-
-    # buck build
-    buildResult = main.ONOSbench.buckBuild()
-
-    return buildResult
-
-
-
-
diff --git a/TestON/tests/SCPF/SCPFscaleTopo/dependencies/topo.py b/TestON/tests/SCPF/SCPFscaleTopo/dependencies/topo.py
index 22505ff..d7a878e 100644
--- a/TestON/tests/SCPF/SCPFscaleTopo/dependencies/topo.py
+++ b/TestON/tests/SCPF/SCPFscaleTopo/dependencies/topo.py
@@ -6,97 +6,6 @@
 import os
 import json
 
-def getAllDevices( main ):
-    """
-        Return a list containing the devices output from each ONOS node
-    """
-    devices = []
-    threads = []
-    for i in main.activeNodes:
-        t = main.Thread( target=main.CLIs[i].devices,
-                         name="devices-" + str( i ),
-                         args=[ ] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        devices.append( t.result )
-    return devices
-
-def getAllHosts( main ):
-    """
-        Return a list containing the hosts output from each ONOS node
-    """
-    hosts = []
-    ipResult = main.TRUE
-    threads = []
-    for i in main.activeNodes:
-        t = main.Thread( target=main.CLIs[i].hosts,
-                         name="hosts-" + str( i ),
-                         args=[ ] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        hosts.append( t.result )
-    return hosts
-
-def getAllPorts( main ):
-    """
-        Return a list containing the ports output from each ONOS node
-    """
-    ports = []
-    threads = []
-    for i in main.activeNodes:
-        t = main.Thread( target=main.CLIs[i].ports,
-                         name="ports-" + str( i ),
-                         args=[ ] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        ports.append( t.result )
-    return ports
-
-def getAllLinks( main ):
-    """
-        Return a list containing the links output from each ONOS node
-    """
-    links = []
-    threads = []
-    for i in main.activeNodes:
-        t = main.Thread( target=main.CLIs[i].links,
-                         name="links-" + str( i ),
-                         args=[ ] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        links.append( t.result )
-    return links
-
-def getAllClusters( main ):
-    """
-        Return a list containing the clusters output from each ONOS node
-    """
-    clusters = []
-    threads = []
-    for i in main.activeNodes:
-        t = main.Thread( target=main.CLIs[i].clusters,
-                         name="clusters-" + str( i ),
-                         args=[ ] )
-        threads.append( t )
-        t.start()
-
-    for t in threads:
-        t.join()
-        clusters.append( t.result )
-    return clusters
-
 def sendArpPackage( main, hostList ):
     import json
     import time
diff --git a/TestON/tests/SCPF/SCPFscalingMaxIntents/SCPFscalingMaxIntents.py b/TestON/tests/SCPF/SCPFscalingMaxIntents/SCPFscalingMaxIntents.py
index 5a81c23..1106f83 100644
--- a/TestON/tests/SCPF/SCPFscalingMaxIntents/SCPFscalingMaxIntents.py
+++ b/TestON/tests/SCPF/SCPFscalingMaxIntents/SCPFscalingMaxIntents.py
@@ -21,105 +21,70 @@
         import time
         import os
         import imp
-
-        main.case( "Constructing test variables and building ONOS package" )
-        main.step( "Constructing test variables" )
-        stepResult = main.FALSE
-
-        # Test variables
-        main.testOnDirectory = os.path.dirname( os.getcwd ( ) )
-        main.dependencyPath = main.testOnDirectory + \
-                main.params['DEPENDENCY']['path']
-        main.cellName = main.params[ 'ENV' ][ 'cellName' ]
-        main.apps = main.params[ 'ENV' ][ 'cellApps' ]
-        main.topology = main.params[ 'DEPENDENCY' ][ 'topology' ]
-        main.scale = ( main.params[ 'SCALE' ] ).split( "," )
-        main.ONOSport = main.params[ 'CTRL' ][ 'port' ]
-        main.timeout = int(main.params['SLEEP']['timeout'])
-        main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
-        main.installSleep = int( main.params[ 'SLEEP' ][ 'install' ] )
-        main.verifySleep = int( main.params[ 'SLEEP' ][ 'verify' ] )
-        main.rerouteSleep = int ( main.params['SLEEP']['reroute'] )
-        main.verifyAttempts = int( main.params['ATTEMPTS']['verify'] )
-        main.ingress = main.params['LINK']['ingress']
-        main.egress = main.params['LINK']['egress']
-        main.cellData = {} # for creating cell file
-        main.reroute = main.params['reroute']
-        main.flowObj = main.params['TEST']['flowObj']
-        if main.flowObj == "True":
-            main.flowObj = True
-            main.dbFileName = main.params['DATABASE']['dbFlowObj']
-        else:
-            main.flowObj = False
-            main.dbFileName = main.params['DATABASE']['dbName']
-        main.threadID = 0
-
-        if main.reroute == "True":
-            main.reroute = True
-        else:
-            main.reroute = False
-
-        main.CLIs = []
-        main.setupSkipped = False
-
-        wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
-        gitBranch = main.params[ 'GIT' ][ 'branch' ]
-        gitPull = main.params[ 'GIT' ][ 'pull' ]
-        nic = main.params['DATABASE']['nic']
-        node = main.params['DATABASE']['node']
-        nic = main.params['DATABASE']['nic']
-        node = main.params['DATABASE']['node']
-        stepResult = main.TRUE
-
-        main.log.info("Cresting DB file")
-        with open(main.dbFileName, "w+") as dbFile:
-            dbFile.write("")
-
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="environment set up successfull",
-                                 onfail="environment set up Failed" )
-
-    def CASE1( self ):
-        # main.scale[ 0 ] determines the current number of ONOS controller
-        main.CLIs = []
-        main.numCtrls = int( main.scale[ 0 ] )
-        main.ONOSip = []
-        main.maxNumBatch = 0
-        main.AllONOSip = main.ONOSbench.getOnosIps()
-        for i in range(main.numCtrls):
-            main.ONOSip.append(main.AllONOSip[i])
-        main.log.info(main.ONOSip)
-
-        main.log.info( "Creating list of ONOS cli handles" )
-        for i in range(main.numCtrls):
-            main.CLIs.append( getattr( main, 'ONOScli%s' % (i+1) ) )
-
-        main.log.info(main.CLIs)
-        if not main.CLIs:
-            main.log.error( "Failed to create the list of ONOS cli handles" )
-            main.cleanup()
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
             main.exit()
+        main.testSetUp.envSetupDescription()
+        stepResult = main.FALSE
+        try:
+            # Test variables
+            main.dependencyPath = main.testOnDirectory + \
+                    main.params[ 'DEPENDENCY' ][ 'path' ]
+            main.cellName = main.params[ 'ENV' ][ 'cellName' ]
+            main.apps = main.params[ 'ENV' ][ 'cellApps' ]
+            main.topology = main.params[ 'DEPENDENCY' ][ 'topology' ]
+            main.scale = ( main.params[ 'SCALE' ] ).split( "," )
+            main.ONOSport = main.params[ 'CTRL' ][ 'port' ]
+            main.timeout = int( main.params[ 'SLEEP' ][ 'timeout' ] )
+            main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
+            main.installSleep = int( main.params[ 'SLEEP' ][ 'install' ] )
+            main.verifySleep = int( main.params[ 'SLEEP' ][ 'verify' ] )
+            main.rerouteSleep = int ( main.params[ 'SLEEP' ][ 'reroute' ] )
+            main.verifyAttempts = int( main.params[ 'ATTEMPTS' ][ 'verify' ] )
+            main.ingress = main.params[ 'LINK' ][ 'ingress' ]
+            main.egress = main.params[ 'LINK' ][ 'egress' ]
+            main.reroute = main.params[ 'reroute' ]
+            main.flowObj = main.params[ 'TEST' ][ 'flowObj' ]
+            if main.flowObj == "True":
+                main.flowObj = True
+                main.dbFileName = main.params[ 'DATABASE' ][ 'dbFlowObj' ]
+            else:
+                main.flowObj = False
+                main.dbFileName = main.params[ 'DATABASE' ][ 'dbName' ]
+            main.threadID = 0
 
-        main.log.info( "Loading wrapper files" )
-        main.startUp = imp.load_source( wrapperFile1,
-                                        main.dependencyPath +
-                                        wrapperFile1 +
-                                        ".py" )
+            if main.reroute == "True":
+                main.reroute = True
+            else:
+                main.reroute = False
+            main.setupSkipped = False
 
+            wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
+            nic = main.params[ 'DATABASE' ][ 'nic' ]
+            node = main.params[ 'DATABASE' ][ 'node' ]
+            stepResult = main.testSetUp.gitPulling()
+            main.log.info( "Cresting DB file" )
+            with open( main.dbFileName, "w+" ) as dbFile:
+                dbFile.write("")
+        except Exception as e:
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
+        main.commit = main.commit.split( " " )[ 1 ]
+        with open( main.dbFileName, "a" ) as dbFile:
+            temp = "'" + main.commit + "',"
+            temp += "'" + nic + "',"
+            dbFile.write( temp )
+    def CASE1( self ):
+        main.testSetUp.getNumCtrls( True )
+        main.testSetUp.envSetup( includeGitPull=False, makeMaxNodes=False )
         copyResult = main.ONOSbench.copyMininetFile( main.topology,
                                                      main.dependencyPath,
                                                      main.Mininet1.user_name,
                                                      main.Mininet1.ip_address )
 
-        commit = main.ONOSbench.getVersion(report=True)
-        commit = commit.split(" ")[1]
-
-        with open(main.dbFileName, "a") as dbFile:
-            temp = "'" + commit + "',"
-            temp += "'" + nic + "',"
-            dbFile.write(temp)
-
     def CASE2( self, main ):
         """
         - Uninstall ONOS cluster
@@ -127,115 +92,8 @@
         - Install ONOS cluster
         - Connect to cli
         """
-        main.log.info( "Starting up %s node(s) ONOS cluster" % main.numCtrls)
-        main.log.info( "Safety check, killing all ONOS processes" +
-                       " before initiating environment setup" )
-
-        for i in range( main.numCtrls ):
-            main.ONOSbench.onosStop( main.ONOSip[ i ] )
-            main.ONOSbench.onosKill( main.ONOSip[ i ] )
-
-        main.log.info( "NODE COUNT = %s" % main.numCtrls)
-
-        tempOnosIp = []
-        for i in range( main.numCtrls ):
-            tempOnosIp.append( main.ONOSip[i] )
-
-        main.ONOSbench.createCellFile( main.ONOSbench.ip_address,
-                                       "temp",
-                                       main.Mininet1.ip_address,
-                                       main.apps,
-                                       tempOnosIp, main.ONOScli1.karafUser )
-
-        main.step( "Apply cell to environment" )
-        cellResult = main.ONOSbench.setCell( "temp" )
-        verifyResult = main.ONOSbench.verifyCell()
-        stepResult = cellResult and verifyResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully applied cell to " + \
-                                        "environment",
-                                 onfail="Failed to apply cell to environment " )
-
-        main.step( "Creating ONOS package" )
-        packageResult = main.ONOSbench.buckBuild()
-        stepResult = packageResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully created ONOS package",
-                                 onfail="Failed to create ONOS package" )
-
-        main.step( "Uninstall ONOS package on all Nodes" )
-        uninstallResult = main.TRUE
-        for i in range( int( main.numCtrls ) ):
-            main.log.info( "Uninstalling package on ONOS Node IP: " + main.ONOSip[i] )
-            u_result = main.ONOSbench.onosUninstall( main.ONOSip[i] )
-            utilities.assert_equals( expect=main.TRUE, actual=u_result,
-                                     onpass="Test step PASS",
-                                     onfail="Test step FAIL" )
-            uninstallResult = ( uninstallResult and u_result )
-
-        main.step( "Install ONOS package on all Nodes" )
-        installResult = main.TRUE
-        for i in range( int( main.numCtrls ) ):
-            main.log.info( "Installing package on ONOS Node IP: " + main.ONOSip[i] )
-            i_result = main.ONOSbench.onosInstall( node=main.ONOSip[i] )
-            utilities.assert_equals( expect=main.TRUE, actual=i_result,
-                                     onpass="Test step PASS",
-                                     onfail="Test step FAIL" )
-            installResult = installResult and i_result
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.TRUE
-        for i in range( int( main.numCtrls ) ):
-            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=main.ONOSip[i] )
-        utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        time.sleep( main.startUpSleep )
-        main.step( "Starting ONOS service" )
-        stopResult = main.TRUE
-        startResult = main.TRUE
-        onosIsUp = main.TRUE
-        for i in range( main.numCtrls ):
-            onosIsUp = onosIsUp and main.ONOSbench.isup( main.ONOSip[ i ] )
-        if onosIsUp == main.TRUE:
-            main.log.report( "ONOS instance is up and ready" )
-        else:
-            main.log.report( "ONOS instance may not be up, stop and " +
-                             "start ONOS again " )
-            for i in range( main.numCtrls ):
-                stopResult = stopResult and \
-                        main.ONOSbench.onosStop( main.ONOSip[ i ] )
-            for i in range( main.numCtrls ):
-                startResult = startResult and \
-                        main.ONOSbench.onosStart( main.ONOSip[ i ] )
-        stepResult = onosIsUp and stopResult and startResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="ONOS service is ready",
-                                 onfail="ONOS service did not start properly" )
-
-        main.step( "Start ONOS CLI on all nodes" )
-        cliResult = main.TRUE
-        main.step(" Start ONOS cli using thread ")
-        startCliResult  = main.TRUE
-        pool = []
-
-        for i in range( int( main.numCtrls) ):
-            t = main.Thread( target=main.CLIs[i].startOnosCli,
-                             threadID=main.threadID,
-                             name="startOnosCli",
-                             args=[ main.ONOSip[i] ],
-                             kwargs = {"onosStartTimeout":main.timeout} )
-            pool.append(t)
-            t.start()
-            main.threadID = main.threadID + 1
-        for t in pool:
-            t.join()
-            startCliResult = startCliResult and t.result
-        time.sleep( main.startUpSleep )
+        main.testSetUp.ONOSSetUp( main.Mininet1, True,
+                                  killRemoveMax=False, CtrlsSet=False )
 
     def CASE10( self, main ):
         """
@@ -246,7 +104,7 @@
         main.step("Activating null-provider")
         appStatus = utilities.retry( main.CLIs[0].activateApp,
                                      main.FALSE,
-                                     ['org.onosproject.null'],
+                                     [ 'org.onosproject.null' ],
                                      sleep=main.verifySleep,
                                      attempts=main.verifyAttempts )
         utilities.assert_equals( expect=main.TRUE,
@@ -259,20 +117,20 @@
         cfgStatus = utilities.retry( main.ONOSbench.onosCfgSet,
                                     main.FALSE,
                                     [ main.ONOSip[0],
-                                      'org.onosproject.provider.nil.NullProviders', 'deviceCount 8'],
+                                      'org.onosproject.provider.nil.NullProviders', 'deviceCount 8' ],
                                     sleep=main.verifySleep,
                                     attempts = main.verifyAttempts )
         cfgStatus = cfgStatus and utilities.retry( main.ONOSbench.onosCfgSet,
                                                    main.FALSE,
                                                    [ main.ONOSip[0],
-                                                     'org.onosproject.provider.nil.NullProviders', 'topoShape reroute'],
+                                                     'org.onosproject.provider.nil.NullProviders', 'topoShape reroute' ],
                                                    sleep=main.verifySleep,
                                                    attempts = main.verifyAttempts )
 
         cfgStatus = cfgStatus and utilities.retry( main.ONOSbench.onosCfgSet,
                                                    main.FALSE,
                                                    [ main.ONOSip[0],
-                                                     'org.onosproject.provider.nil.NullProviders', 'enabled true'],
+                                                     'org.onosproject.provider.nil.NullProviders', 'enabled true' ],
                                                    sleep=main.verifySleep,
                                                    attempts = main.verifyAttempts )
 
@@ -405,16 +263,25 @@
 
 
     def CASE20( self, main ):
+        try:
+            from tests.dependencies.utils import Utils
+        except ImportError:
+            main.log.error( "Utils not found exiting the test" )
+            main.exit()
+        try:
+            main.Utils
+        except ( NameError, AttributeError ):
+            main.Utils = Utils()
         if main.reroute:
-            main.minIntents = int(main.params['NULL']['REROUTE']['min_intents'])
-            main.maxIntents = int(main.params['NULL']['REROUTE']['max_intents'])
-            main.checkInterval = int(main.params['NULL']['REROUTE']['check_interval'])
-            main.batchSize = int(main.params['NULL']['REROUTE']['batch_size'])
+            main.minIntents = int(main.params[ 'NULL' ][ 'REROUTE' ][ 'min_intents' ] )
+            main.maxIntents = int(main.params[ 'NULL' ][ 'REROUTE' ][ 'max_intents' ] )
+            main.checkInterval = int(main.params[ 'NULL' ][ 'REROUTE' ][ 'check_interval' ] )
+            main.batchSize = int(main.params[ 'NULL' ][ 'REROUTE' ][ 'batch_size' ] )
         else:
-            main.minIntents = int(main.params['NULL']['PUSH']['min_intents'])
-            main.maxIntents = int(main.params['NULL']['PUSH']['max_intents'])
-            main.checkInterval = int(main.params['NULL']['PUSH']['check_interval'])
-            main.batchSize = int(main.params['NULL']['PUSH']['batch_size'])
+            main.minIntents = int(main.params[ 'NULL' ][ 'PUSH' ][ 'min_intents' ] )
+            main.maxIntents = int(main.params[ 'NULL' ][ 'PUSH' ][ 'max_intents' ] )
+            main.checkInterval = int(main.params[ 'NULL' ][ 'PUSH' ][ 'check_interval' ] )
+            main.batchSize = int(main.params[ 'NULL' ][ 'PUSH' ][ 'batch_size' ] )
 
         # check if the case needs to be skipped
         if main.setupSkipped:
@@ -536,7 +403,6 @@
                     main.log.info("Total Intents: {}".format( verifyTotalIntents) )
                     break
 
-        del main.scale[0]
         utilities.assert_equals( expect = main.TRUE,
                                  actual = intentsState,
                                  onpass = "Successfully pushed and verified intents",
@@ -545,8 +411,8 @@
         main.log.info( "Total Intents Installed before crash: {}".format( totalIntents ) )
         main.log.info( "Total Flows ADDED before crash: {}".format( totalFlows ) )
 
-        main.step('clean up Mininet')
-        main.Mininet1.stopNet()
+        main.Utils.mininetCleanup( main.Mininet1 )
+
         main.log.info("Writing results to DS file")
         with open(main.dbFileName, "a") as dbFile:
             # Scale number
diff --git a/TestON/tests/SCPF/SCPFscalingMaxIntents/dependencies/startUp.py b/TestON/tests/SCPF/SCPFscalingMaxIntents/dependencies/startUp.py
deleted file mode 100644
index 501cbb3..0000000
--- a/TestON/tests/SCPF/SCPFscalingMaxIntents/dependencies/startUp.py
+++ /dev/null
@@ -1,38 +0,0 @@
-"""
-    This wrapper function is use for starting up onos instance
-"""
-
-import time
-import os
-import json
-
-def onosBuild( main, gitBranch ):
-    """
-        This includes pulling ONOS and building it using maven install
-    """
-
-    buildResult = main.FALSE
-
-    # Git checkout a branch of ONOS
-    checkOutResult = main.ONOSbench.gitCheckout( gitBranch )
-    # Does the git pull on the branch that was checked out
-    if not checkOutResult:
-        main.log.warn( "Failed to checked out " + gitBranch +
-                                           " branch")
-    else:
-        main.log.info( "Successfully checked out " + gitBranch +
-                                           " branch")
-    gitPullResult = main.ONOSbench.gitPull()
-    if gitPullResult == main.ERROR:
-        main.log.error( "Error pulling git branch" )
-    else:
-        main.log.info( "Successfully pulled " + gitBranch + " branch" )
-
-    # buck build
-    buildResult = main.ONOSbench.buckBuild()
-
-    return buildResult
-
-
-
-
diff --git a/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.params b/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.params
index c45fef8..f06a7c8 100644
--- a/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.params
+++ b/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.params
@@ -16,8 +16,8 @@
     </DEPENDENCY>
 
     <GIT>
-        <gitPull>off</gitPull>
-        <gitBranch>master</gitBranch>
+        <pull>False</pull>
+        <branch>master</branch>
     </GIT>
 
     <CTRL>
diff --git a/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.py b/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.py
index 6a5731d..deaaead 100644
--- a/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.py
+++ b/TestON/tests/SCPF/SCPFswitchLat/SCPFswitchLat.py
@@ -25,198 +25,75 @@
             different versions of ONOS.
         - Construct tests variables
         '''
-        gitPull = main.params['GIT']['gitPull']
-        gitBranch = main.params['GIT']['gitBranch']
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        main.testSetUp.envSetupDescription()
+        stepResult = main.FALSE
+        try:
+            # The dictionary to record different type of wrongs
+            main.wrong = { 'totalWrong': 0, 'skipDown' : 0, 'TsharkValueIncorrect': 0,
+                    'TypeError' : 0, 'decodeJasonError': 0,
+                    'checkResultIncorrect': 0}
+            main.maxWrong = int( main.params['TEST'] ['MaxWrong'] )
+            main.resultRange = main.params['TEST']['ResultRange']
+            main.searchTerm = main.params['TEST']['SearchTerm']
+            main.MN1Ip = main.params['MN']['ip1']
+            main.dependencyPath = main.testOnDirectory + \
+                                  main.params['DEPENDENCY']['path']
+            main.topoName = main.params['DEPENDENCY']['topology']
+            main.dependencyFunc = main.params['DEPENDENCY']['function']
+            main.cellName = main.params['ENV']['cellName']
+            main.apps = main.params['ENV']['cellApps']
+            main.scale = (main.params['SCALE']).split(",")
 
-        main.case( "Pull onos branch and build onos on Teststation." )
+            main.ofPackage = main.params['TSHARK']
 
-        if gitPull == 'True':
-            main.step( "Git Checkout ONOS branch: " + gitBranch )
-            stepResult = main.ONOSbench.gitCheckout( branch=gitBranch )
-            utilities.assert_equals(expect=main.TRUE,
-                                    actual=stepResult,
-                                    onpass="Successfully checkout onos branch.",
-                                    onfail="Failed to checkout onos branch. Exiting test...")
-            if not stepResult: main.exit()
+            main.tsharkResultPath = main.params['TEST']['tsharkResultPath']
+            main.sampleSize = int(main.params['TEST']['sampleSize'])
+            main.warmUp = int(main.params['TEST']['warmUp'])
+            main.dbFileName = main.params['DATABASE']['dbName']
+            main.startUpSleep = int(main.params['SLEEP']['startup'])
+            main.measurementSleep = int( main.params['SLEEP']['measure'] )
+            main.deleteSwSleep = int( main.params['SLEEP']['deleteSW'] )
+            main.maxScale = int( main.params['max'] )
+            main.timeout = int( main.params['TIMEOUT']['timeout'] )
+            main.MNSleep = int( main.params['SLEEP']['mininet'])
+            main.device = main.params['TEST']['device']
+            stepResult = main.testSetUp.gitPulling()
+            main.log.info("Create Database file " + main.dbFileName)
+            resultsDB = open(main.dbFileName, "w+")
+            resultsDB.close()
 
-            main.step( "Git Pull on ONOS branch:" + gitBranch )
-            stepResult = main.ONOSbench.gitPull()
-            utilities.assert_equals(expect=main.TRUE,
-                                    actual=stepResult,
-                                    onpass="Successfully pull onos. ",
-                                    onfail="Failed to pull onos. Exiting test ...")
-            if not stepResult: main.exit()
-
-
-        else:
-            main.log.warn( "Skipped pulling onos and Skipped building ONOS" )
-        # The dictionary to record different type of wrongs
-        main.wrong = { 'totalWrong': 0, 'skipDown' : 0, 'TsharkValueIncorrect': 0,
-                'TypeError' : 0, 'decodeJasonError': 0,
-                'checkResultIncorrect': 0}
-        main.maxWrong = int( main.params['TEST'] ['MaxWrong'] )
-        main.resultRange = main.params['TEST']['ResultRange']
-        main.searchTerm = main.params['TEST']['SearchTerm']
-        main.testOnDirectory = os.path.dirname( os.getcwd() )
-        main.MN1Ip = main.params['MN']['ip1']
-        main.dependencyPath = main.testOnDirectory + \
-                              main.params['DEPENDENCY']['path']
-        main.topoName = main.params['DEPENDENCY']['topology']
-        main.dependencyFunc = main.params['DEPENDENCY']['function']
-        main.cellName = main.params['ENV']['cellName']
-        main.Apps = main.params['ENV']['cellApps']
-        main.scale = (main.params['SCALE']).split(",")
-
-        main.ofPackage = main.params['TSHARK']
-
-        main.tsharkResultPath = main.params['TEST']['tsharkResultPath']
-        main.sampleSize = int(main.params['TEST']['sampleSize'])
-        main.warmUp = int(main.params['TEST']['warmUp'])
-        main.dbFileName = main.params['DATABASE']['dbName']
-        main.startUpSleep = int(main.params['SLEEP']['startup'])
-        main.measurementSleep = int( main.params['SLEEP']['measure'] )
-        main.deleteSwSleep = int( main.params['SLEEP']['deleteSW'] )
-        main.maxScale = int( main.params['max'] )
-        main.timeout = int( main.params['TIMEOUT']['timeout'] )
-        main.MNSleep = int( main.params['SLEEP']['mininet'])
-        main.device = main.params['TEST']['device']
-        main.log.info("Create Database file " + main.dbFileName)
-        resultsDB = open(main.dbFileName, "w+")
-        resultsDB.close()
-
-        main.switchFunc = imp.load_source(main.dependencyFunc,
-                                       main.dependencyPath +
-                                       main.dependencyFunc +
-                                       ".py")
-
+            main.switchFunc = imp.load_source(main.dependencyFunc,
+                                           main.dependencyPath +
+                                           main.dependencyFunc +
+                                           ".py")
+        except Exception as e:
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
+        main.commit = main.commit.split( " " )[ 1 ]
     def CASE1(self, main):
         # Clean up test environment and set up
         import time
-        main.log.info("Get ONOS cluster IP")
-        print(main.scale)
-        main.numCtrls = int(main.scale.pop(0))
-        main.ONOSip = []
-        main.maxNumBatch = 0
-        main.AllONOSip = main.ONOSbench.getOnosIps()
-        for i in range(main.numCtrls):
-            main.ONOSip.append(main.AllONOSip[i])
-        main.log.info(main.ONOSip)
-        main.CLIs = []
-        main.log.info("Creating list of ONOS cli handles")
-        for i in range(main.numCtrls):
-            main.CLIs.append(getattr(main, 'ONOScli%s' % (i + 1)))
-
-        if not main.CLIs:
-            main.log.error("Failed to create the list of ONOS cli handles")
-            main.cleanup()
+        try:
+            from tests.dependencies.utils import Utils
+        except ImportError:
+            main.log.error( "Utils not found exiting the test" )
             main.exit()
-
-        main.commit = main.ONOSbench.getVersion(report=True)
-        main.commit = main.commit.split(" ")[1]
-        main.log.info("Starting up %s node(s) ONOS cluster" % main.numCtrls)
-        main.log.info("Safety check, killing all ONOS processes" +
-                      " before initiating environment setup")
-
-        for i in range(main.numCtrls):
-            main.ONOSbench.onosStop(main.ONOSip[i])
-            main.ONOSbench.onosKill(main.ONOSip[i])
-
-        main.log.info("NODE COUNT = %s" % main.numCtrls)
-        main.ONOSbench.createCellFile(main.ONOSbench.ip_address,
-                                      main.cellName,
-                                      main.MN1Ip,
-                                      main.Apps,
-                                      main.ONOSip, main.ONOScli1.karafUser)
-        main.step("Apply cell to environment")
-        cellResult = main.ONOSbench.setCell(main.cellName)
-        verifyResult = main.ONOSbench.verifyCell()
-        stepResult = cellResult and verifyResult
-        utilities.assert_equals(expect=main.TRUE,
-                                actual=stepResult,
-                                onpass="Successfully applied cell to " + \
-                                       "environment",
-                                onfail="Failed to apply cell to environment ")
-
-        main.step("Creating ONOS package")
-        packageResult = main.ONOSbench.buckBuild()
-        stepResult = packageResult
-        utilities.assert_equals(expect=main.TRUE,
-                                actual=stepResult,
-                                onpass="Successfully created ONOS package",
-                                onfail="Failed to create ONOS package")
-
-        main.step("Uninstall ONOS package on all Nodes")
-        uninstallResult = main.TRUE
-        for i in range(int(main.numCtrls)):
-            main.log.info("Uninstalling package on ONOS Node IP: " + main.ONOSip[i])
-            u_result = main.ONOSbench.onosUninstall(main.ONOSip[i])
-            utilities.assert_equals(expect=main.TRUE, actual=u_result,
-                                    onpass="Test step PASS",
-                                    onfail="Test step FAIL")
-            uninstallResult = (uninstallResult and u_result)
-
-        main.step("Install ONOS package on all Nodes")
-        installResult = main.TRUE
-        for i in range(int(main.numCtrls)):
-            main.log.info("Installing package on ONOS Node IP: " + main.ONOSip[i])
-            i_result = main.ONOSbench.onosInstall(node=main.ONOSip[i])
-            utilities.assert_equals(expect=main.TRUE, actual=i_result,
-                                    onpass="Test step PASS",
-                                    onfail="Test step FAIL")
-            installResult = installResult and i_result
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.TRUE
-        for i in range( int( main.numCtrls ) ):
-            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=main.ONOSip[i] )
-        utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        time.sleep( main.startUpSleep )
-        main.step( "Starting ONOS service" )
-        stopResult = main.TRUE
-        startResult = main.TRUE
-        onosIsUp = main.TRUE
-        for i in range( main.numCtrls ):
-            onosIsUp = onosIsUp and main.ONOSbench.isup( main.ONOSip[ i ] )
-        if onosIsUp == main.TRUE:
-            main.log.report( "ONOS instance is up and ready" )
-        else:
-            main.log.report( "ONOS instance may not be up, stop and " +
-                             "start ONOS again " )
-            for i in range( main.numCtrls ):
-                stopResult = stopResult and \
-                        main.ONOSbench.onosStop( main.ONOSip[ i ] )
-            for i in range( main.numCtrls ):
-                startResult = startResult and \
-                        main.ONOSbench.onosStart( main.ONOSip[ i ] )
-        stepResult = onosIsUp and stopResult and startResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="ONOS service is ready",
-                                 onfail="ONOS service did not start properly" )
-
-        time.sleep(2)
-        main.step("Start ONOS CLI on all nodes")
-        cliResult = main.TRUE
-        main.step(" Start ONOS cli using thread ")
-        startCliResult = main.TRUE
-        pool = []
-        main.threadID = 0
-        for i in range(int(main.numCtrls)):
-            t = main.Thread(target=main.CLIs[i].startOnosCli,
-                            threadID=main.threadID,
-                            name="startOnosCli",
-                            args=[main.ONOSip[i]],
-                            kwargs={"onosStartTimeout": main.timeout})
-            pool.append(t)
-            t.start()
-            main.threadID = main.threadID + 1
-        for t in pool:
-            t.join()
-            startCliResult = startCliResult and t.result
-        time.sleep(main.startUpSleep)
+        try:
+            main.Utils
+        except ( NameError, AttributeError ):
+            main.Utils = Utils()
+        main.maxNumBatch = 0
+        main.testSetUp.getNumCtrls( True )
+        main.testSetUp.envSetup( includeGitPull=False, makeMaxNodes=False )
+        main.testSetUp.ONOSSetUp( main.Mininet1, True,
+                                  cellName=main.cellName, killRemoveMax=False,
+                                  CtrlsSet=False )
 
         main.log.info("Configure apps")
         main.CLIs[0].setCfg("org.onosproject.net.topology.impl.DefaultTopologyProvider",
@@ -234,8 +111,7 @@
                                        main.dependencyPath,
                                        main.Mininet1.user_name,
                                        main.Mininet1.ip_address)
-        main.log.info("Stop Mininet...")
-        main.Mininet1.stopNet()
+        main.Utils.mininetCleanup( main.Mininet1 )
         time.sleep(main.MNSleep)
         main.log.info("Start new mininet topology")
         main.Mininet1.startNet()
diff --git a/TestON/tests/USECASE/SDNIPfunction/SDNIPfunction.params b/TestON/tests/USECASE/SDNIPfunction/SDNIPfunction.params
index a50d461..2d46894 100644
--- a/TestON/tests/USECASE/SDNIPfunction/SDNIPfunction.params
+++ b/TestON/tests/USECASE/SDNIPfunction/SDNIPfunction.params
@@ -14,8 +14,8 @@
     </CTRL>
 
     <GIT>
-        <autoPull>on</autoPull>
-        <branch1>master</branch1>
+        <pull>False</pull>
+        <branch>master</branch>
         <branch2>onos-1.2</branch2>
     </GIT>
 
diff --git a/TestON/tests/USECASE/SDNIPfunction/SDNIPfunction.py b/TestON/tests/USECASE/SDNIPfunction/SDNIPfunction.py
index b3d34de..5c1244e 100644
--- a/TestON/tests/USECASE/SDNIPfunction/SDNIPfunction.py
+++ b/TestON/tests/USECASE/SDNIPfunction/SDNIPfunction.py
@@ -19,58 +19,24 @@
            onos-install -f
            onos-wait-for-start
         """
-        main.case( "Setting up test environment" )
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        main.testSetUp.envSetupDescription()
+        stepResult = main.FALSE
 
-        cellName = main.params[ 'ENV' ][ 'cellName' ]
-        ONOS1Ip = main.params[ 'CTRL' ][ 'ip1' ]
+        try:
+            cellName = main.params[ 'ENV' ][ 'cellName' ]
+            ONOS1Ip = main.params['CTRL']['ip1']
+            stepResult = main.testSetUp.envSetup( specificIp=ONOS1Ip )
+        except Exception as e:
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
 
-        main.step( "Applying cell variable to environment" )
-        cellResult = main.ONOSbench.setCell( cellName )
-        verifyResult = main.ONOSbench.verifyCell()
-
-        branchName = main.ONOSbench.getBranchName()
-        main.log.info( "ONOS is on branch: " + branchName )
-
-        main.log.report( "Uninstalling ONOS" )
-        main.ONOSbench.onosUninstall( ONOS1Ip )
-
-        # gitPullResult = main.TRUE
-
-        main.step( "Git pull" )
-        gitPullResult = main.ONOSbench.gitPull()
-
-
-        main.ONOSbench.getVersion( report = True )
-
-        main.step( "Creating ONOS package" )
-        packageResult = main.ONOSbench.buckBuild()
-
-        main.step( "Installing ONOS package" )
-        onos1InstallResult = main.ONOSbench.onosInstall( options = "-f",
-                                                           node = ONOS1Ip )
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.ONOSbench.onosSecureSSH( node=ONOS1Ip )
-
-        main.step( "Checking if ONOS is up yet" )
-        for i in range( 2 ):
-            onos1Isup = main.ONOSbench.isup( ONOS1Ip, timeout = 420 )
-            if onos1Isup:
-                break
-        if not onos1Isup:
-            main.log.report( "ONOS1 didn't start!" )
-
-        cliResult = main.ONOScli.startOnosCli( ONOS1Ip,
-                commandlineTimeout = 100, onosStartTimeout = 600 )
-
-        case1Result = ( packageResult and cellResult and
-                        verifyResult and onos1InstallResult and
-                        onos1Isup and secureSshResult and
-                        cliResult )
-
-        utilities.assert_equals( expect = main.TRUE, actual = case1Result,
-                                 onpass = "ONOS startup successful",
-                                 onfail = "ONOS startup NOT successful" )
+        case1Result = main.testSetUp.ONOSSetUp( "", newCell=False, cellname=cellName )
 
         if case1Result == main.FALSE:
             main.cleanup()
@@ -136,10 +102,10 @@
             routeIntentsExpectedHost4 + routeIntentsExpectedHost5
 
         main.step( "Get links in the network" )
-        listResult = main.ONOScli.links( jsonFormat = False )
+        listResult = main.ONOScli1.links( jsonFormat = False )
         main.log.info( listResult )
         main.log.info( "Activate sdn-ip application" )
-        main.ONOScli.activateApp( "org.onosproject.sdnip" )
+        main.ONOScli1.activateApp( "org.onosproject.sdnip" )
         # wait sdn-ip to finish installing connectivity intents, and the BGP
         # paths in data plane are ready.
         time.sleep( int( main.params[ 'timers' ][ 'SdnIpSetup' ] ) )
@@ -194,7 +160,7 @@
         time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
         time.sleep( int( main.params[ 'timers' ][ 'PathAvailable' ] ) )
         # get routes inside SDN-IP
-        getRoutesResult = main.ONOScli.routes( jsonFormat = True )
+        getRoutesResult = main.ONOScli1.routes( jsonFormat = True )
 
         allRoutesActual = \
             main.QuaggaCliHost3.extractActualRoutesMaster( getRoutesResult )
@@ -211,7 +177,7 @@
             onpass = "***Routes in SDN-IP are correct!***",
             onfail = "***Routes in SDN-IP are wrong!***" )
 
-        getIntentsResult = main.ONOScli.intents( jsonFormat = True )
+        getIntentsResult = main.ONOScli1.intents( jsonFormat = True )
 
         main.step( "Check MultiPointToSinglePointIntent intents installed" )
         # routeIntentsExpected are generated when generating routes
@@ -273,7 +239,7 @@
         time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
         time.sleep( int( main.params[ 'timers' ][ 'PathAvailable' ] ) )
 
-        getRoutesResult = main.ONOScli.routes( jsonFormat = True )
+        getRoutesResult = main.ONOScli1.routes( jsonFormat = True )
         allRoutesActual = \
             main.QuaggaCliHost3.extractActualRoutesMaster( getRoutesResult )
         main.log.info( "allRoutes_actual = " )
@@ -285,7 +251,7 @@
             onfail = "***Routes number in SDN-IP is not 0, wrong!***" )
 
         main.step( "Check intents after deleting routes" )
-        getIntentsResult = main.ONOScli.intents( jsonFormat = True )
+        getIntentsResult = main.ONOScli1.intents( jsonFormat = True )
         routeIntentsActualNum = \
             main.QuaggaCliHost3.extractActualRouteIntentNum( 
                 getIntentsResult )
diff --git a/TestON/tests/USECASE/SDNIPfunction/SDNIPfunction.topo b/TestON/tests/USECASE/SDNIPfunction/SDNIPfunction.topo
index 21cbfb4..226fa9a 100644
--- a/TestON/tests/USECASE/SDNIPfunction/SDNIPfunction.topo
+++ b/TestON/tests/USECASE/SDNIPfunction/SDNIPfunction.topo
@@ -12,7 +12,7 @@
             </COMPONENTS>
         </ONOSbench>
 
-        <ONOScli>
+        <ONOScli1>
             <host>127.0.0.1</host>
             <user>sdn</user>
             <password>rocks</password>
@@ -23,7 +23,7 @@
                 <karaf_password></karaf_password>
                 <prompt></prompt>
             </COMPONENTS>
-        </ONOScli>
+        </ONOScli1>
 
         <ONOS1>
             <host>10.128.4.52</host>
diff --git a/TestON/tests/USECASE/SDNIPperf/SDNIPperf.params b/TestON/tests/USECASE/SDNIPperf/SDNIPperf.params
index a7c774d..5c1ed8f 100644
--- a/TestON/tests/USECASE/SDNIPperf/SDNIPperf.params
+++ b/TestON/tests/USECASE/SDNIPperf/SDNIPperf.params
@@ -13,8 +13,8 @@
     </CTRL>
 
     <GIT>
-        <autoPull>off</autoPull>
-        <branch1>master</branch1>
+        <autoPull>False</autoPull>
+        <branch>master</branch>
         <branch2>onos-1.3</branch2>
     </GIT>
     <timers>
diff --git a/TestON/tests/USECASE/SDNIPperf/SDNIPperf.py b/TestON/tests/USECASE/SDNIPperf/SDNIPperf.py
index 0134e42..772dad8 100644
--- a/TestON/tests/USECASE/SDNIPperf/SDNIPperf.py
+++ b/TestON/tests/USECASE/SDNIPperf/SDNIPperf.py
@@ -17,57 +17,24 @@
            onos-install -f
            onos-wait-for-start
         """
-        main.case( "Setting up test environment" )
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        main.testSetUp.envSetupDescription()
+        stepResult = main.FALSE
 
-        cellName = main.params[ 'ENV' ][ 'cellName' ]
-        ONOS1Ip = main.params[ 'CTRL' ][ 'ip1' ]
+        try:
+            cellName = main.params[ 'ENV' ][ 'cellName' ]
+            ONOS1Ip = main.params['CTRL']['ip1']
+            stepResult = main.testSetUp.envSetup( specificIp=ONOS1Ip )
+        except Exception as e:
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
 
-        main.step( "Applying cell variable to environment" )
-        cellResult = main.ONOSbench.setCell( cellName )
-        verifyResult = main.ONOSbench.verifyCell()
-
-        branchName = main.ONOSbench.getBranchName()
-        main.log.info( "ONOS is on branch: " + branchName )
-
-        main.log.report( "Uninstalling ONOS" )
-        main.ONOSbench.onosUninstall( ONOS1Ip )
-
-        main.step( "Git pull" )
-        gitPullResult = main.FALSE
-        #Need to push some new code to ONOS before using the git pull
-        #gitPullResult = main.ONOSbench.gitPull()
-
-        main.ONOSbench.getVersion( report=True )
-
-        main.step( "Creating ONOS package" )
-        packageResult = main.ONOSbench.buckBuild()
-
-        main.step( "Installing ONOS package" )
-        onos1InstallResult = main.ONOSbench.onosInstall( options="-f",
-                                                           node=ONOS1Ip )
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.ONOSbench.onosSecureSSH( node=ONOS1Ip )
-
-        main.step( "Checking if ONOS is up yet" )
-        for i in range( 2 ):
-            onos1Isup = main.ONOSbench.isup( ONOS1Ip, timeout=420 )
-            if onos1Isup:
-                break
-        if not onos1Isup:
-            main.log.report( "ONOS1 didn't start!" )
-
-        cliResult = main.ONOScli.startOnosCli( ONOS1Ip,
-                commandlineTimeout=100, onosStartTimeout=600)
-
-        case1Result = ( packageResult and cellResult and
-                        verifyResult and onos1InstallResult and
-                        onos1Isup and secureSshResult and
-                        cliResult )
-
-        utilities.assert_equals( expect=main.TRUE, actual=case1Result,
-                                 onpass="ONOS startup successful",
-                                 onfail="ONOS startup NOT successful" )
+        case1Result = main.testSetUp.ONOSSetUp( "", newCell=False, cellname=cellName )
 
         if case1Result == main.FALSE:
             main.cleanup()
@@ -97,15 +64,15 @@
         time.sleep( 10 )
 
         main.step( "Get devices in the network" )
-        listResult = main.ONOScli.devices( jsonFormat=False )
+        listResult = main.ONOScli1.devices( jsonFormat=False )
         main.log.info( listResult )
 
         main.step( "Get links in the network" )
-        listResult = main.ONOScli.links ( jsonFormat=False )
+        listResult = main.ONOScli1.links ( jsonFormat=False )
         main.log.info( listResult )
 
         main.log.info( "Activate sdn-ip application" )
-        main.ONOScli.activateApp( "org.onosproject.sdnip" )
+        main.ONOScli1.activateApp( "org.onosproject.sdnip" )
 
         main.step("Sleep 1200 seconds")
         # wait until SDN-IP receives all routes and ONOS installs all intents
@@ -116,7 +83,7 @@
         main.log.info( "Total route number expected is:" )
         main.log.info( routeNumberExpected )
 
-        routeNumberActual = main.ONOScli.ipv4RouteNumber()
+        routeNumberActual = main.ONOScli1.ipv4RouteNumber()
         main.log.info("Total route  number actual is: ")
         main.log.info(routeNumberActual)
 
@@ -131,7 +98,7 @@
         main.log.info( "MultiPointToSinglePoint intent number expected is:" )
         main.log.info( m2SIntentsNumberExpected )
 
-        m2SIntentsNumberActual = main.ONOScli.m2SIntentInstalledNumber()
+        m2SIntentsNumberActual = main.ONOScli1.m2SIntentInstalledNumber()
         main.log.info( "MultiPointToSinglePoint intent number actual is:" )
         main.log.info(m2SIntentsNumberActual)
 
diff --git a/TestON/tests/USECASE/SDNIPperf/SDNIPperf.topo b/TestON/tests/USECASE/SDNIPperf/SDNIPperf.topo
index 8706d85..e5f3087 100644
--- a/TestON/tests/USECASE/SDNIPperf/SDNIPperf.topo
+++ b/TestON/tests/USECASE/SDNIPperf/SDNIPperf.topo
@@ -12,7 +12,7 @@
             </COMPONENTS>
         </ONOSbench>
 
-        <ONOScli>
+        <ONOScli1>
             <host>10.128.4.53</host>
             <user>sdn</user>
             <password>rocks</password>
@@ -23,7 +23,7 @@
                 <karaf_password></karaf_password>
                 <prompt></prompt>
             </COMPONENTS>
-        </ONOScli>
+        </ONOScli1>
 
         <ONOS1>
             <host>10.254.1.201</host>
diff --git a/TestON/tests/USECASE/SegmentRouting/SRClusterRestart/SRClusterRestart.topo b/TestON/tests/USECASE/SegmentRouting/SRClusterRestart/SRClusterRestart.topo
index 5ad1b13..4d4ce2d 100755
--- a/TestON/tests/USECASE/SegmentRouting/SRClusterRestart/SRClusterRestart.topo
+++ b/TestON/tests/USECASE/SegmentRouting/SRClusterRestart/SRClusterRestart.topo
@@ -8,7 +8,7 @@
             <type>OnosDriver</type>
             <connect_order>1</connect_order>
             <COMPONENTS>
-                <nodes>1</nodes>
+                <nodes>3</nodes>
                 <prompt></prompt>
             </COMPONENTS>
         </ONOSbench>
diff --git a/TestON/tests/USECASE/SegmentRouting/SRDynamic/SRDynamic.topo b/TestON/tests/USECASE/SegmentRouting/SRDynamic/SRDynamic.topo
index 5ad1b13..4d4ce2d 100755
--- a/TestON/tests/USECASE/SegmentRouting/SRDynamic/SRDynamic.topo
+++ b/TestON/tests/USECASE/SegmentRouting/SRDynamic/SRDynamic.topo
@@ -8,7 +8,7 @@
             <type>OnosDriver</type>
             <connect_order>1</connect_order>
             <COMPONENTS>
-                <nodes>1</nodes>
+                <nodes>3</nodes>
                 <prompt></prompt>
             </COMPONENTS>
         </ONOSbench>
diff --git a/TestON/tests/USECASE/SegmentRouting/SRHighAvailability/SRHighAvailability.topo b/TestON/tests/USECASE/SegmentRouting/SRHighAvailability/SRHighAvailability.topo
index e0328c2..6c83bb2 100644
--- a/TestON/tests/USECASE/SegmentRouting/SRHighAvailability/SRHighAvailability.topo
+++ b/TestON/tests/USECASE/SegmentRouting/SRHighAvailability/SRHighAvailability.topo
@@ -8,7 +8,7 @@
             <type>OnosDriver</type>
             <connect_order>1</connect_order>
             <COMPONENTS>
-                <nodes>1</nodes>
+                <nodes>3</nodes>
                 <prompt></prompt>
             </COMPONENTS>
         </ONOSbench>
diff --git a/TestON/tests/USECASE/SegmentRouting/SRLinkFailure/SRLinkFailure.topo b/TestON/tests/USECASE/SegmentRouting/SRLinkFailure/SRLinkFailure.topo
index f63a8c2..28c6820 100755
--- a/TestON/tests/USECASE/SegmentRouting/SRLinkFailure/SRLinkFailure.topo
+++ b/TestON/tests/USECASE/SegmentRouting/SRLinkFailure/SRLinkFailure.topo
@@ -8,7 +8,7 @@
             <type>OnosDriver</type>
             <connect_order>1</connect_order>
             <COMPONENTS>
-                <nodes>1</nodes>
+                <nodes>3</nodes>
             </COMPONENTS>
         </ONOSbench>
 
diff --git a/TestON/tests/USECASE/SegmentRouting/SROnosFailure/SROnosFailure.topo b/TestON/tests/USECASE/SegmentRouting/SROnosFailure/SROnosFailure.topo
index 5ad1b13..4d4ce2d 100755
--- a/TestON/tests/USECASE/SegmentRouting/SROnosFailure/SROnosFailure.topo
+++ b/TestON/tests/USECASE/SegmentRouting/SROnosFailure/SROnosFailure.topo
@@ -8,7 +8,7 @@
             <type>OnosDriver</type>
             <connect_order>1</connect_order>
             <COMPONENTS>
-                <nodes>1</nodes>
+                <nodes>3</nodes>
                 <prompt></prompt>
             </COMPONENTS>
         </ONOSbench>
diff --git a/TestON/tests/USECASE/SegmentRouting/SRSanity/SRSanity.topo b/TestON/tests/USECASE/SegmentRouting/SRSanity/SRSanity.topo
index 5ad1b13..4d4ce2d 100755
--- a/TestON/tests/USECASE/SegmentRouting/SRSanity/SRSanity.topo
+++ b/TestON/tests/USECASE/SegmentRouting/SRSanity/SRSanity.topo
@@ -8,7 +8,7 @@
             <type>OnosDriver</type>
             <connect_order>1</connect_order>
             <COMPONENTS>
-                <nodes>1</nodes>
+                <nodes>3</nodes>
                 <prompt></prompt>
             </COMPONENTS>
         </ONOSbench>
diff --git a/TestON/tests/USECASE/SegmentRouting/SRSwitchFailure/SRSwitchFailure.topo b/TestON/tests/USECASE/SegmentRouting/SRSwitchFailure/SRSwitchFailure.topo
index 04f480a..b4b41ee 100755
--- a/TestON/tests/USECASE/SegmentRouting/SRSwitchFailure/SRSwitchFailure.topo
+++ b/TestON/tests/USECASE/SegmentRouting/SRSwitchFailure/SRSwitchFailure.topo
@@ -8,7 +8,7 @@
             <type>OnosDriver</type>
             <connect_order>1</connect_order>
             <COMPONENTS>
-                <nodes>1</nodes>
+                <nodes>3</nodes>
                 <prompt></prompt>
             </COMPONENTS>
         </ONOSbench>
diff --git a/TestON/tests/USECASE/SegmentRouting/dependencies/Testcaselib.py b/TestON/tests/USECASE/SegmentRouting/dependencies/Testcaselib.py
index 08eb9c9..1bdaea2 100755
--- a/TestON/tests/USECASE/SegmentRouting/dependencies/Testcaselib.py
+++ b/TestON/tests/USECASE/SegmentRouting/dependencies/Testcaselib.py
@@ -21,52 +21,41 @@
             - Install ONOS package
             - Build ONOS package
         """
-        main.step( "Constructing test variables" )
-        # Test variables
-        main.cellName = main.params[ 'ENV' ][ 'cellName' ]
-        main.apps = main.params[ 'ENV' ][ 'cellApps' ]
-        main.diff = main.params[ 'ENV' ][ 'diffApps' ]
-        gitBranch = main.params[ 'GIT' ][ 'branch' ]
-        main.path = os.path.dirname( main.testFile )
-        main.dependencyPath = main.path + "/../dependencies/"
-        main.topology = main.params[ 'DEPENDENCY' ][ 'topology' ]
-        wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
-        main.scale = (main.params[ 'SCALE' ][ 'size' ]).split( "," )
-        main.maxNodes = int( main.params[ 'SCALE' ][ 'max' ] )
-        # main.ONOSport = main.params[ 'CTRL' ][ 'port' ]
-        main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
-        main.cellData = { }  # for creating cell file
-        main.CLIs = [ ]
-        main.ONOSip = [ ]
-        main.RESTs = [ ]
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        main.testSetUp.envSetupDescription()
+        stepResult = main.FALSE
+        try:
+            main.step( "Constructing test variables" )
+            # Test variables
+            main.cellName = main.params[ 'ENV' ][ 'cellName' ]
+            main.apps = main.params[ 'ENV' ][ 'cellApps' ]
+            main.diff = main.params[ 'ENV' ][ 'diffApps' ]
+            main.path = os.path.dirname( main.testFile )
+            main.dependencyPath = main.path + "/../dependencies/"
+            main.topology = main.params[ 'DEPENDENCY' ][ 'topology' ]
+            wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
+            main.scale = (main.params[ 'SCALE' ][ 'size' ]).split( "," )
+            main.maxNodes = int( main.params[ 'SCALE' ][ 'max' ] )
+            # main.ONOSport = main.params[ 'CTRL' ][ 'port' ]
+            main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
+            # -- INIT SECTION, ONLY RUNS ONCE -- #
 
-        # Assigning ONOS cli handles to a list
-        for i in range( 1, main.maxNodes + 1 ):
-            main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
-            main.RESTs.append( getattr( main, 'ONOSrest' + str( i ) ) )
-            main.ONOSip.append( main.CLIs[ i - 1 ].ip_address )
-        # -- INIT SECTION, ONLY RUNS ONCE -- #
-        main.startUp = imp.load_source( wrapperFile1,
-                                        main.dependencyPath +
-                                        wrapperFile1 +
-                                        ".py" )
+            copyResult1 = main.ONOSbench.scp( main.Mininet1,
+                                              main.dependencyPath +
+                                              main.topology,
+                                              main.Mininet1.home,
+                                              direction="to" )
+            stepResult = main.testSetUp.envSetup( hasRest=True )
+        except Exception as e:
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
 
-        copyResult1 = main.ONOSbench.scp( main.Mininet1,
-                                          main.dependencyPath +
-                                          main.topology,
-                                          main.Mininet1.home,
-                                          direction="to" )
-        if main.CLIs:
-            stepResult = main.TRUE
-        else:
-            main.log.error( "Did not properly created list of ONOS CLI handle" )
-            stepResult = main.FALSE
 
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully construct " +
-                                        "test variables ",
-                                 onfail="Failed to construct test variables" )
 
     @staticmethod
     def installOnos( main, vlanCfg=True ):
@@ -82,83 +71,29 @@
         - Connect to cli
         """
         # main.scale[ 0 ] determines the current number of ONOS controller
-        apps = main.apps
         if main.diff:
-            apps = main.apps + "," + main.diff
+            main.apps = main.apps + "," + main.diff
         else:
             main.log.error( "App list is empty" )
         print "NODE COUNT = ", main.numCtrls
         print main.ONOSip
-        tempOnosIp = [ ]
         main.dynamicHosts = [ 'in1', 'out1' ]
-        for i in range( main.numCtrls ):
-            tempOnosIp.append( main.ONOSip[ i ] )
-        onosUser = main.params[ 'ENV' ][ 'cellUser' ]
-        main.step( "Create and Apply cell file" )
-        main.ONOSbench.createCellFile( main.ONOSbench.ip_address,
-                                       "temp",
-                                       main.Mininet1.ip_address,
-                                       apps,
-                                       tempOnosIp,
-                                       onosUser,
-                                       useSSH=Testcaselib.useSSH )
-        cellResult = main.ONOSbench.setCell( "temp" )
-        verifyResult = main.ONOSbench.verifyCell( )
-        stepResult = cellResult and verifyResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully applied cell to " + \
-                                        "environment",
-                                 onfail="Failed to apply cell to environment " )
+        main.testSetUp.createApplyCell( newCell=True, cellName=main.cellName,
+                                        Mininet=main.Mininet1, useSSH=Testcaselib.useSSH )
         # kill off all onos processes
         main.log.info( "Safety check, killing all ONOS processes" +
                        " before initiating environment setup" )
         for i in range( main.maxNodes ):
             main.ONOSbench.onosDie( main.ONOSip[ i ] )
-        main.step( "Create and Install ONOS package" )
-        packageResult = main.ONOSbench.buckBuild()
 
-        onosInstallResult = main.TRUE
-        for i in range( main.numCtrls ):
-            onosInstallResult = onosInstallResult and \
-                                main.ONOSbench.onosInstall(
-                                        node=main.ONOSip[ i ] )
-        stepResult = onosInstallResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="Successfully installed ONOS package",
-                                 onfail="Failed to install ONOS package" )
-        if Testcaselib.useSSH:
-            for i in range( main.numCtrls ):
-                onosInstallResult = onosInstallResult and \
-                                    main.ONOSbench.onosSecureSSH(
-                                            node=main.ONOSip[ i ] )
-            stepResult = onosInstallResult
-            utilities.assert_equals( expect=main.TRUE,
-                                     actual=stepResult,
-                                     onpass="Successfully secure SSH",
-                                     onfail="Failed to secure SSH" )
-        main.step( "Starting ONOS service" )
-        stopResult, startResult, onosIsUp = main.TRUE, main.TRUE, main.TRUE,
-        for i in range( main.numCtrls ):
-            onosIsUp = onosIsUp and main.ONOSbench.isup( main.ONOSip[ i ] )
-        if onosIsUp == main.TRUE:
-            main.log.report( "ONOS instance is up and ready" )
-        else:
-            main.log.report( "ONOS instance may not be up, stop and " +
-                             "start ONOS again " )
-            for i in range( main.numCtrls ):
-                stopResult = stopResult and \
-                             main.ONOSbench.onosStop( main.ONOSip[ i ] )
-            for i in range( main.numCtrls ):
-                startResult = startResult and \
-                              main.ONOSbench.onosStart( main.ONOSip[ i ] )
-        stepResult = onosIsUp and stopResult and startResult
+        main.testSetUp.buildOnos()
 
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=stepResult,
-                                 onpass="ONOS service is ready",
-                                 onfail="ONOS service did not start properly" )
+        main.testSetUp.installOnos( False )
+
+        main.testSetUp.setupSsh()
+
+        main.testSetUp.checkOnosService()
+
         main.step( "Checking if ONOS CLI is ready" )
         for i in range( main.numCtrls ):
             main.CLIs[ i ].startCellCli( )
@@ -172,7 +107,7 @@
         main.active = 0
         for i in range( 10 ):
             ready = True
-            output = main.CLIs[ main.active ].summary( )
+            output = main.CLIs[ main.active ].summary()
             if not output:
                 ready = False
             if ready:
@@ -437,11 +372,20 @@
         Stops Mininet
         Copies ONOS log
         """
-        main.Mininet1.stopNet( )
-        main.ONOSbench.scp( main.ONOScli1, "/opt/onos/log/karaf.log",
-                            "/tmp/karaf.log", direction="from" )
-        main.ONOSbench.cpLogsToDir( "/tmp/karaf.log", main.logdir,
-                                    copyFileName="karaf.log." + main.cfgName )
+        try:
+            from tests.dependencies.utils import Utils
+        except ImportError:
+            main.log.error( "Utils not found exiting the test" )
+            main.exit()
+        try:
+            main.Utils
+        except ( NameError, AttributeError ):
+            main.Utils = Utils()
+
+        main.utils.mininetCleanup( main.Mininet1 )
+
+        main.utils.copyKarafLog()
+
         for i in range( main.numCtrls ):
             main.ONOSbench.onosStop( main.ONOSip[ i ] )
 
diff --git a/TestON/tests/USECASE/SegmentRouting/dependencies/startUp.py b/TestON/tests/USECASE/SegmentRouting/dependencies/startUp.py
deleted file mode 100755
index 501cbb3..0000000
--- a/TestON/tests/USECASE/SegmentRouting/dependencies/startUp.py
+++ /dev/null
@@ -1,38 +0,0 @@
-"""
-    This wrapper function is use for starting up onos instance
-"""
-
-import time
-import os
-import json
-
-def onosBuild( main, gitBranch ):
-    """
-        This includes pulling ONOS and building it using maven install
-    """
-
-    buildResult = main.FALSE
-
-    # Git checkout a branch of ONOS
-    checkOutResult = main.ONOSbench.gitCheckout( gitBranch )
-    # Does the git pull on the branch that was checked out
-    if not checkOutResult:
-        main.log.warn( "Failed to checked out " + gitBranch +
-                                           " branch")
-    else:
-        main.log.info( "Successfully checked out " + gitBranch +
-                                           " branch")
-    gitPullResult = main.ONOSbench.gitPull()
-    if gitPullResult == main.ERROR:
-        main.log.error( "Error pulling git branch" )
-    else:
-        main.log.info( "Successfully pulled " + gitBranch + " branch" )
-
-    # buck build
-    buildResult = main.ONOSbench.buckBuild()
-
-    return buildResult
-
-
-
-
diff --git a/TestON/tests/USECASE/USECASE_SdnipFunction/USECASE_SdnipFunction.params b/TestON/tests/USECASE/USECASE_SdnipFunction/USECASE_SdnipFunction.params
index 104fe3f..8b401d6 100644
--- a/TestON/tests/USECASE/USECASE_SdnipFunction/USECASE_SdnipFunction.params
+++ b/TestON/tests/USECASE/USECASE_SdnipFunction/USECASE_SdnipFunction.params
@@ -14,7 +14,10 @@
         <ip1>OC1</ip1>
         <port1>6653</port1>
     </CTRL>
-
+    <GIT>
+        <pull>False</pull>
+        <branch>master</branch>
+    </GIT>
     <DEPENDENCY>
         <path>/USECASE/USECASE_SdnipFunction/dependencies/</path>
         <topology>USECASE_SdnipI2MN.py</topology>
diff --git a/TestON/tests/USECASE/USECASE_SdnipFunction/USECASE_SdnipFunction.py b/TestON/tests/USECASE/USECASE_SdnipFunction/USECASE_SdnipFunction.py
index fbbdee8..f8c8185 100644
--- a/TestON/tests/USECASE/USECASE_SdnipFunction/USECASE_SdnipFunction.py
+++ b/TestON/tests/USECASE/USECASE_SdnipFunction/USECASE_SdnipFunction.py
@@ -28,13 +28,11 @@
             main.exit()
         main.step( "Connect switches to controller" )
 
-        global ONOS1Ip
-        ONOS1Ip = os.getenv( main.params[ 'CTRL' ][ 'ip1' ] )
         # connect all switches to controller
         swResult = main.TRUE
         for i in range ( 1, int( main.params['config']['switchNum'] ) + 1 ):
             sw = "sw%s" % ( i )
-            swResult = swResult and main.Mininet.assignSwController( sw, ONOS1Ip )
+            swResult = swResult and main.Mininet.assignSwController( sw, main.ONOSip[ 0 ] )
         utilities.assert_equals( expect=main.TRUE,
                                  actual=swResult,
                                  onpass="Successfully connect all switches to ONOS",
@@ -44,9 +42,9 @@
             main.exit()
 
         main.step( "Set up tunnel from Mininet node to onos node" )
-        forwarding1 = '%s:2000:%s:2000' % ( '1.1.1.2', ONOS1Ip )
+        forwarding1 = '%s:2000:%s:2000' % ( '1.1.1.2', main.ONOSip[ 0 ] )
         command = 'ssh -nNT -o "PasswordAuthentication no" \
-        -o "StrictHostKeyChecking no" -l sdn -L %s %s & ' % ( forwarding1, ONOS1Ip )
+        -o "StrictHostKeyChecking no" -l sdn -L %s %s & ' % ( forwarding1, main.ONOSip[ 0 ] )
 
         tunnelResult = main.TRUE
         tunnelResult = main.Mininet.node( "root", command )
@@ -70,119 +68,17 @@
         """
         import time
         import os
-
-        main.case( "Setting up ONOS environment" )
-
-        cellName = main.params[ 'ENV' ][ 'cellName' ]
-        global ONOS1Ip
-        ONOS1Ip = os.getenv( main.params[ 'CTRL' ][ 'ip1' ] )
-        ipList = [ ONOS1Ip ]
-
-        main.step( "Copying config files" )
-        src = os.path.dirname( main.testFile ) + "/network-cfg.json"
-        dst = main.ONOSbench.home + "/tools/package/config/network-cfg.json"
-        status = main.ONOSbench.scp( main.ONOSbench, src, dst, direction="to" )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=status,
-                                 onpass="Copy config file succeeded",
-                                 onfail="Copy config file failed" )
-
-        main.step( "Create cell file" )
-        cellAppString = main.params[ 'ENV' ][ 'appString' ]
-        main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
-                                       main.Mininet.ip_address,
-                                       cellAppString, ipList, main.ONOScli1.karafUser )
-
-        main.step( "Applying cell variable to environment" )
-        cellResult = main.ONOSbench.setCell( cellName )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=cellResult,
-                                 onpass="Set cell succeeded",
-                                 onfail="Set cell failed" )
-
-        main.step( "Verify cell connectivity" )
-        verifyResult = main.ONOSbench.verifyCell()
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=verifyResult,
-                                 onpass="Verify cell succeeded",
-                                 onfail="Verify cell failed" )
-
-        branchName = main.ONOSbench.getBranchName()
-        main.log.report( "ONOS is on branch: " + branchName )
-
-        main.step( "Uninstalling ONOS" )
-        uninstallResult = main.ONOSbench.onosUninstall( ONOS1Ip )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=uninstallResult,
-                                 onpass="Uninstall ONOS succeeded",
-                                 onfail="Uninstall ONOS failed" )
-        '''
-        main.step( "Git pull" )
-        gitPullResult = main.ONOSbench.gitPull()
-        main.log.info( "gitPullResult" )
-        main.log.info( gitPullResult )
-        gitPullResult2 = ( gitPullResult == main.TRUE ) or ( gitPullResult == 3 )
-        utilities.assert_equals( expect=True,
-                                 actual=gitPullResult2,
-                                 onpass="Git pull ONOS succeeded",
-                                 onfail="Git pull ONOS failed" )
-        '''
-
-        main.ONOSbench.getVersion( report=True )
-
-        main.step( "Creating ONOS package" )
-        packageResult = main.ONOSbench.buckBuild()
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=packageResult,
-                                 onpass="Package ONOS succeeded",
-                                 onfail="Package ONOS failed" )
-
-        main.step( "Installing ONOS package" )
-        onos1InstallResult = main.ONOSbench.onosInstall( options="-f",
-                                                         node=ONOS1Ip )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=onos1InstallResult,
-                                 onpass="Install ONOS succeeded",
-                                 onfail="Install ONOS failed" )
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.ONOSbench.onosSecureSSH( node=ONOS1Ip )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=secureSshResult,
-                                 onpass="Set up ONOS secure SSH succeeded",
-                                 onfail="Set up ONOS secure SSH failed " )
-
-        main.step( "Checking if ONOS is up yet" )
-        onos1UpResult = main.ONOSbench.isup( ONOS1Ip, timeout=420 )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=onos1UpResult,
-                                 onpass="ONOS is up",
-                                 onfail="ONOS is NOT up" )
-
-        main.step( "Checking if ONOS CLI is ready" )
-        cliResult = main.ONOScli.startOnosCli( ONOS1Ip,
-                commandlineTimeout=100, onosStartTimeout=600 )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=cliResult,
-                                 onpass="ONOS CLI is ready",
-                                 onfail="ONOS CLI is not ready" )
-
-        for i in range( 10 ):
-            ready = True
-            output = main.ONOScli.summary()
-            if not output:
-                ready = False
-            if ready:
-                break
-            time.sleep( 30 )
-        utilities.assert_equals( expect=True, actual=ready,
-                                 onpass="ONOS summary command succeded",
-                                 onfail="ONOS summary command failed" )
-
-        if not ready:
-            main.log.error( "ONOS startup failed!" )
-            main.cleanup()
+        try:
+            from tests.USECASE.dependencies.sdnipBaseFunction import SdnBase
+        except ImportError:
+            main.log.error( "sdnBase not found. exiting the test" )
             main.exit()
+        try:
+            main.sdnBase
+        except ( NameError, AttributeError ):
+            main.sdnBase = SdnBase()
+
+        main.sdnBase.initSetup()
 
     def CASE200( self, main ):
         import json
@@ -193,20 +89,20 @@
         time.sleep( int( main.params['timers']['TopoDiscovery'] ) )
 
         main.log.info( "Get links in the network" )
-        summaryResult = main.ONOScli.summary()
+        summaryResult = main.ONOScli1.summary()
         linkNum = json.loads( summaryResult )[ "links" ]
-        listResult = main.ONOScli.links( jsonFormat=False )
+        listResult = main.ONOScli1.links( jsonFormat=False )
         main.log.info( listResult )
         if linkNum < 100:
             main.log.error( "Link number is wrong!" )
             time.sleep( int( main.params['timers']['TopoDiscovery'] ) )
-            listResult = main.ONOScli.links( jsonFormat=False )
+            listResult = main.ONOScli1.links( jsonFormat=False )
             main.log.info( listResult )
             main.cleanup()
             main.exit()
 
         main.step( "Activate sdn-ip application" )
-        activeSDNIPresult = main.ONOScli.activateApp( "org.onosproject.sdnip" )
+        activeSDNIPresult = main.ONOScli1.activateApp( "org.onosproject.sdnip" )
         utilities.assert_equals( expect=main.TRUE,
                                  actual=activeSDNIPresult,
                                  onpass="Activate SDN-IP succeeded",
@@ -263,104 +159,25 @@
         '''
         point-to-point intents test for each BGP peer and BGP speaker pair
         '''
-        import time
-        from operator import eq
-
-        main.case( "Check point-to-point intents" )
-        main.log.info( "There are %s BGP peers in total "
-                       % main.params[ 'config' ][ 'peerNum' ] )
-        main.step( "Check P2P intents number from ONOS CLI" )
-
-        getIntentsResult = main.ONOScli.intents( jsonFormat=True )
-        bgpIntentsActualNum = \
-            main.QuaggaCliSpeaker1.extractActualBgpIntentNum( getIntentsResult )
-        bgpIntentsExpectedNum = int( main.params[ 'config' ][ 'peerNum' ] ) * 6
-        if bgpIntentsActualNum != bgpIntentsExpectedNum:
-            time.sleep( int( main.params['timers']['RouteDelivery'] ) )
-            getIntentsResult = main.ONOScli.intents( jsonFormat=True )
-            bgpIntentsActualNum = \
-                main.QuaggaCliSpeaker1.extractActualBgpIntentNum( getIntentsResult )
-        main.log.info( "bgpIntentsExpected num is:" )
-        main.log.info( bgpIntentsExpectedNum )
-        main.log.info( "bgpIntentsActual num is:" )
-        main.log.info( bgpIntentsActualNum )
-        utilities.assertEquals( \
-            expect=True,
-            actual=eq( bgpIntentsExpectedNum, bgpIntentsActualNum ),
-            onpass="PointToPointIntent Intent Num is correct!",
-            onfail="PointToPointIntent Intent Num is wrong!" )
+        main.sdnBase.pToPIntentTest( 6 )
 
 
     def CASE3( self, main ):
         '''
         routes and intents check to all BGP peers
         '''
-        import time
         main.case( "Check routes and M2S intents to all BGP peers" )
 
         allRoutesExpected = []
         allRoutesExpected.append( "4.0.0.0/24" + "/" + "10.0.4.1" )
         allRoutesExpected.append( "5.0.0.0/24" + "/" + "10.0.5.1" )
         allRoutesExpected.append( "6.0.0.0/24" + "/" + "10.0.6.1" )
-
         allRoutesExpected.append( "7.0.0.0/24" + "/" + "10.0.7.1" )
         allRoutesExpected.append( "8.0.0.0/24" + "/" + "10.0.8.1" )
         allRoutesExpected.append( "9.0.0.0/24" + "/" + "10.0.9.1" )
         allRoutesExpected.append( "20.0.0.0/24" + "/" + "10.0.20.1" )
 
-        getRoutesResult = main.ONOScli.routes( jsonFormat=True )
-        allRoutesActual = \
-            main.QuaggaCliSpeaker1.extractActualRoutesMaster( getRoutesResult )
-        allRoutesStrExpected = str( sorted( allRoutesExpected ) )
-        allRoutesStrActual = str( allRoutesActual ).replace( 'u', "" )
-        if allRoutesStrActual != allRoutesStrExpected:
-            time.sleep( int( main.params['timers']['RouteDelivery'] ) )
-            getRoutesResult = main.ONOScli.routes( jsonFormat=True )
-            allRoutesActual = \
-                main.QuaggaCliSpeaker1.extractActualRoutesMaster( getRoutesResult )
-            allRoutesStrActual = str( allRoutesActual ).replace( 'u', "" )
-
-        main.step( "Check routes installed" )
-        main.log.info( "Routes expected:" )
-        main.log.info( allRoutesStrExpected )
-        main.log.info( "Routes get from ONOS CLI:" )
-        main.log.info( allRoutesStrActual )
-        utilities.assertEquals( \
-            expect=allRoutesStrExpected, actual=allRoutesStrActual,
-            onpass="Routes are correct!",
-            onfail="Routes are wrong!" )
-
-        main.step( "Check M2S intents installed" )
-        getIntentsResult = main.ONOScli.intents( jsonFormat=True )
-        routeIntentsActualNum = \
-            main.QuaggaCliSpeaker1.extractActualRouteIntentNum( getIntentsResult )
-        routeIntentsExpectedNum = 7
-        if routeIntentsActualNum != routeIntentsExpectedNum:
-            time.sleep( int( main.params['timers']['RouteDelivery'] ) )
-            getIntentsResult = main.ONOScli.intents( jsonFormat=True )
-            routeIntentsActualNum = \
-                main.QuaggaCliSpeaker1.extractActualRouteIntentNum( getIntentsResult )
-
-        main.log.info( "MultiPointToSinglePoint Intent Num expected is:" )
-        main.log.info( routeIntentsExpectedNum )
-        main.log.info( "MultiPointToSinglePoint Intent NUM Actual is:" )
-        main.log.info( routeIntentsActualNum )
-        utilities.assertEquals( \
-            expect=routeIntentsExpectedNum,
-            actual=routeIntentsActualNum,
-            onpass="MultiPointToSinglePoint Intent Num is correct!",
-            onfail="MultiPointToSinglePoint Intent Num is wrong!" )
-
-        main.step( "Check whether all flow status are ADDED" )
-        flowCheck = utilities.retry( main.ONOScli.checkFlowsState,
-                                     main.FALSE,
-                                     kwargs={'isPENDING':False},
-                                     attempts=10 )
-        utilities.assertEquals( \
-            expect=main.TRUE,
-            actual=flowCheck,
-            onpass="Flow status is correct!",
-            onfail="Flow status is wrong!" )
+        main.sdnBase.routeAndIntentCheck( allRoutesExpected, 7 )
 
 
     def CASE4( self, main ):
@@ -386,151 +203,20 @@
         '''
         Cut links to peers one by one, check routes/intents
         '''
-        import time
-        main.case( "Bring down links and check routes/intents" )
-        main.step( "Bring down the link between sw32 and p64514" )
-        linkResult1 = main.Mininet.link( END1="sw32", END2="p64514",
-                                         OPTION="down" )
-        utilities.assertEquals( expect=main.TRUE,
-                                actual=linkResult1,
-                                onpass="Bring down link succeeded!",
-                                onfail="Bring down link failed!" )
-
-        if linkResult1 == main.TRUE:
-            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 6 ) #We have 7 links between peers and sw. After one link down, 7-1=6.
-            main.Functions.checkM2SintentNum( main, 6 )
-        else:
-            main.log.error( "Bring down link failed!" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Bring down the link between sw8 and p64515" )
-        linkResult2 = main.Mininet.link( END1="sw8", END2="p64515",
-                                         OPTION="down" )
-        utilities.assertEquals( expect=main.TRUE,
-                                actual=linkResult2,
-                                onpass="Bring down link succeeded!",
-                                onfail="Bring down link failed!" )
-        if linkResult2 == main.TRUE:
-            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 5 ) #2 links down, 7-2=5.
-            main.Functions.checkM2SintentNum( main, 5 )
-        else:
-            main.log.error( "Bring down link failed!" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Bring down the link between sw28 and p64516" )
-        linkResult3 = main.Mininet.link( END1="sw28", END2="p64516",
-                                         OPTION="down" )
-        utilities.assertEquals( expect=main.TRUE,
-                                actual=linkResult3,
-                                onpass="Bring down link succeeded!",
-                                onfail="Bring down link failed!" )
-        if linkResult3 == main.TRUE:
-            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 4 ) #3 links downs 7-3=4
-            main.Functions.checkM2SintentNum( main, 4 )
-        else:
-            main.log.error( "Bring down link failed!" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Check whether all flow status are ADDED" )
-        flowCheck = utilities.retry( main.ONOScli.checkFlowsState,
-                                     main.FALSE,
-                                     kwargs={'isPENDING':False},
-                                     attempts=10 )
-        utilities.assertEquals( \
-            expect=main.TRUE,
-            actual=flowCheck,
-            onpass="Flow status is correct!",
-            onfail="Flow status is wrong!" )
-
-        # Ping test
-        main.Functions.pingSpeakerToPeer( main, speakers=["spk1"],
-                                          peers=["p64514", "p64515", "p64516"],
-                                          expectAllSuccess=False )
-
-        main.Functions.pingHostToHost( main,
-                                       hosts=["h64514", "h64515", "h64516"],
-                                       expectAllSuccess=False )
+        main.sdnBase.linkUpDownCheck( "p64514", "p64515", "p64516",
+                                      6, 6, 5, 5, 4, 4,
+                                      "spk1", [ "h64514", "h64515", "h64516" ],
+                                      "down" )
 
 
     def CASE6( self, main ):
         '''
         Recover links to peers one by one, check routes/intents
         '''
-        import time
-        main.case( "Bring up links and check routes/intents" )
-        main.step( "Bring up the link between sw32 and p64514" )
-        linkResult1 = main.Mininet.link( END1="sw32", END2="p64514",
-                                         OPTION="up" )
-        utilities.assertEquals( expect=main.TRUE,
-                                actual=linkResult1,
-                                onpass="Bring up link succeeded!",
-                                onfail="Bring up link failed!" )
-        if linkResult1 == main.TRUE:
-            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 5 ) #one links up, 4+1=5
-            main.Functions.checkM2SintentNum( main, 5 )
-        else:
-            main.log.error( "Bring up link failed!" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Bring up the link between sw8 and p64515" )
-        linkResult2 = main.Mininet.link( END1="sw8", END2="p64515",
-                                         OPTION="up" )
-        utilities.assertEquals( expect=main.TRUE,
-                                actual=linkResult2,
-                                onpass="Bring up link succeeded!",
-                                onfail="Bring up link failed!" )
-        if linkResult2 == main.TRUE:
-            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 6 )
-            main.Functions.checkM2SintentNum( main, 6 )
-        else:
-            main.log.error( "Bring up link failed!" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Bring up the link between sw28 and p64516" )
-        linkResult3 = main.Mininet.link( END1="sw28", END2="p64516",
-                                         OPTION="up" )
-        utilities.assertEquals( expect=main.TRUE,
-                                actual=linkResult3,
-                                onpass="Bring up link succeeded!",
-                                onfail="Bring up link failed!" )
-        if linkResult3 == main.TRUE:
-            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 7 )
-            main.Functions.checkM2SintentNum( main, 7 )
-        else:
-            main.log.error( "Bring up link failed!" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Check whether all flow status are ADDED" )
-        flowCheck = utilities.retry( main.ONOScli.checkFlowsState,
-                                     main.FALSE,
-                                     kwargs={'isPENDING':False},
-                                     attempts=10 )
-        utilities.assertEquals( \
-            expect=main.TRUE,
-            actual=flowCheck,
-            onpass="Flow status is correct!",
-            onfail="Flow status is wrong!" )
-
-        # Ping test
-        main.Functions.pingSpeakerToPeer( main, speakers=["spk1"],
-                       peers=["p64514", "p64515", "p64516"],
-                       expectAllSuccess=True )
-        main.Functions.pingHostToHost( main,
-                        hosts=["h64514", "h64515", "h64516"],
-                        expectAllSuccess=True )
-
+        main.sdnBase.linkUpDownCheck( "p64514", "p64515", "p64516",
+                                      5, 5, 6, 6, 7, 7,
+                                      "spk1", [ "h64514", "h64515", "h64516" ],
+                                      "up" )
 
     def CASE7( self, main ):
         '''
@@ -585,7 +271,7 @@
             main.exit()
 
         main.step( "Check whether all flow status are ADDED" )
-        flowCheck = utilities.retry( main.ONOScli.checkFlowsState,
+        flowCheck = utilities.retry( main.ONOScli1.checkFlowsState,
                                      main.FALSE,
                                      kwargs={'isPENDING':False},
                                      attempts=10 )
@@ -611,7 +297,7 @@
             onpass="Starting switch succeeded!",
             onfail="Starting switch failed!" )
 
-        result2 = main.Mininet.assignSwController( "sw32", ONOS1Ip )
+        result2 = main.Mininet.assignSwController( "sw32", main.ONOSip[ 0 ] )
         utilities.assertEquals( \
             expect=main.TRUE,
             actual=result2,
@@ -629,7 +315,7 @@
             main.exit()
 
         main.step( "Check whether all flow status are ADDED" )
-        flowCheck = utilities.retry( main.ONOScli.checkFlowsState,
+        flowCheck = utilities.retry( main.ONOScli1.checkFlowsState,
                                      main.FALSE,
                                      kwargs={'isPENDING':False},
                                      attempts=10 )
@@ -681,7 +367,7 @@
             main.exit()
 
         main.step( "Check whether all flow status are ADDED" )
-        flowCheck = utilities.retry( main.ONOScli.checkFlowsState,
+        flowCheck = utilities.retry( main.ONOScli1.checkFlowsState,
                                      main.FALSE,
                                      kwargs={'isPENDING':False},
                                      attempts=10 )
@@ -718,7 +404,7 @@
         utilities.assertEquals( expect=main.TRUE, actual=result1,
                                 onpass="Starting switch succeeded!",
                                 onfail="Starting switch failed!" )
-        result2 = main.Mininet.assignSwController( "sw11", ONOS1Ip )
+        result2 = main.Mininet.assignSwController( "sw11", main.ONOSip[ 0 ] )
         utilities.assertEquals( expect=main.TRUE, actual=result2,
                                 onpass="Connect switch to ONOS succeeded!",
                                 onfail="Connect switch to ONOS failed!" )
@@ -737,7 +423,7 @@
             main.exit()
 
         main.step( "Check whether all flow status are ADDED" )
-        flowCheck = utilities.retry( main.ONOScli.checkFlowsState,
+        flowCheck = utilities.retry( main.ONOScli1.checkFlowsState,
                                      main.FALSE,
                                      kwargs={'isPENDING':False},
                                      attempts=10 )
diff --git a/TestON/tests/USECASE/USECASE_SdnipFunction/USECASE_SdnipFunction.topo b/TestON/tests/USECASE/USECASE_SdnipFunction/USECASE_SdnipFunction.topo
index b0f884b..9f2ed34 100644
--- a/TestON/tests/USECASE/USECASE_SdnipFunction/USECASE_SdnipFunction.topo
+++ b/TestON/tests/USECASE/USECASE_SdnipFunction/USECASE_SdnipFunction.topo
@@ -12,7 +12,7 @@
             </COMPONENTS>
         </ONOSbench>
 
-        <ONOScli>
+        <ONOScli1>
             <host>127.0.0.1</host>
             <user>sdn</user>
             <password>rocks</password>
@@ -23,7 +23,7 @@
                 <karaf_password></karaf_password>
                 <prompt></prompt>
             </COMPONENTS>
-        </ONOScli>
+        </ONOScli1>
 
         <ONOS1>
             <host>OC1</host>
diff --git a/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/Functions.py b/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/Functions.py
index 10c3675..a86bb39 100644
--- a/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/Functions.py
+++ b/TestON/tests/USECASE/USECASE_SdnipFunction/dependencies/Functions.py
@@ -7,10 +7,10 @@
     main.log.info( routeNumExpected )
     main.log.info( "Route number from ONOS CLI:" )
 
-    routeNumActual = main.ONOScli.ipv4RouteNumber()
+    routeNumActual = main.ONOScli1.ipv4RouteNumber()
     if routeNumActual != routeNumExpected:
         time.sleep( wait )
-        routeNumActual = main.ONOScli.ipv4RouteNumber()
+        routeNumActual = main.ONOScli1.ipv4RouteNumber()
     main.log.info( routeNumActual )
     utilities.assertEquals( \
         expect = routeNumExpected, actual = routeNumActual,
@@ -21,7 +21,7 @@
     import time
     main.step( "Check M2S intents installed" )
     wait = int( main.params['timers']['PathAvailable'] )
-    jsonResult = main.ONOScli.intents( jsonFormat = True, summary = True,
+    jsonResult = main.ONOScli1.intents( jsonFormat = True, summary = True,
                                        TYPE = "multiPointToSinglePoint" )
     try:
         intentNumActual = jsonResult['installed']
@@ -30,7 +30,7 @@
         main.log.error( e )
     if intentNumActual != intentNumExpected:
         time.sleep( wait )
-        jsonResult = main.ONOScli.intents( jsonFormat = True, summary = True,
+        jsonResult = main.ONOScli1.intents( jsonFormat = True, summary = True,
                                            TYPE = "multiPointToSinglePoint" )
         try:
             intentNumActual = jsonResult['installed']
@@ -48,7 +48,7 @@
     import time
     main.step( "Check P2P intents installed" )
     wait = int( main.params['timers']['PathAvailable'] )
-    jsonResult = main.ONOScli.intents( jsonFormat = True, summary = True,
+    jsonResult = main.ONOScli1.intents( jsonFormat = True, summary = True,
                                        TYPE = "pointToPoint" )
     try:
         intentNumActual = jsonResult['installed']
@@ -58,7 +58,7 @@
 
     if intentNumActual != intentNumExpected:
         time.sleep( wait )
-        jsonResult = main.ONOScli.intents( jsonFormat = True, summary = True,
+        jsonResult = main.ONOScli1.intents( jsonFormat = True, summary = True,
                                            TYPE = "pointToPoint" )
         try:
             intentNumActual = jsonResult['installed']
diff --git a/TestON/tests/USECASE/USECASE_SdnipFunctionCluster/USECASE_SdnipFunctionCluster.params b/TestON/tests/USECASE/USECASE_SdnipFunctionCluster/USECASE_SdnipFunctionCluster.params
index 0d6014f..e25086a 100644
--- a/TestON/tests/USECASE/USECASE_SdnipFunctionCluster/USECASE_SdnipFunctionCluster.params
+++ b/TestON/tests/USECASE/USECASE_SdnipFunctionCluster/USECASE_SdnipFunctionCluster.params
@@ -14,7 +14,10 @@
         <ip3>OC3</ip3>
         <port1>6653</port1>
     </CTRL>
-
+    <GIT>
+        <pull>False</pull>
+        <branch>master</branch>
+    </GIT>
     <DEPENDENCY>
         <path>/USECASE/USECASE_SdnipFunctionCluster/dependencies/</path>
         <topology>USECASE_SdnipI2MN_Cluster.py</topology>
diff --git a/TestON/tests/USECASE/USECASE_SdnipFunctionCluster/USECASE_SdnipFunctionCluster.py b/TestON/tests/USECASE/USECASE_SdnipFunctionCluster/USECASE_SdnipFunctionCluster.py
index c96fa40..a1fb405 100644
--- a/TestON/tests/USECASE/USECASE_SdnipFunctionCluster/USECASE_SdnipFunctionCluster.py
+++ b/TestON/tests/USECASE/USECASE_SdnipFunctionCluster/USECASE_SdnipFunctionCluster.py
@@ -32,8 +32,7 @@
         swResult = main.TRUE
         for i in range ( 1, int( main.params['config']['switchNum'] ) + 1 ):
             sw = "sw%s" % ( i )
-            swResult = swResult and main.Mininet.assignSwController( sw,
-                                                 [ONOS1Ip, ONOS2Ip, ONOS3Ip] )
+            swResult = swResult and main.Mininet.assignSwController( sw, main.ONOSip )
         utilities.assert_equals( expect=main.TRUE,
                                  actual=swResult,
                                  onpass="Successfully connect all switches to ONOS",
@@ -57,143 +56,24 @@
         import time
         import os
         from operator import eq
-
-        main.case( "Setting up ONOS environment" )
-
-        cellName = main.params[ 'ENV' ][ 'cellName' ]
-        global ONOS1Ip
-        global ONOS2Ip
-        global ONOS3Ip
-        ONOS1Ip = os.getenv( main.params[ 'CTRL' ][ 'ip1' ] )
-        ONOS2Ip = os.getenv( main.params[ 'CTRL' ][ 'ip2' ] )
-        ONOS3Ip = os.getenv( main.params[ 'CTRL' ][ 'ip3' ] )
-        ipList = [ ONOS1Ip, ONOS2Ip, ONOS3Ip ]
-
         global p64514
         global p64515
         global p64516
-        p64514 = main.params['config']['p64514']
-        p64515 = main.params['config']['p64515']
-        p64516 = main.params['config']['p64516']
+        p64514 = main.params[ 'config' ][ 'p64514' ]
+        p64515 = main.params[ 'config' ][ 'p64515' ]
+        p64516 = main.params[ 'config' ][ 'p64516' ]
 
-        main.step( "Copying config files" )
-        src = os.path.dirname( main.testFile ) + "/network-cfg.json"
-        dst = main.ONOSbench.home + "/tools/package/config/network-cfg.json"
-        status = main.ONOSbench.scp( main.ONOSbench, src, dst, direction="to" )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=status,
-                                 onpass="Copy config file succeeded",
-                                 onfail="Copy config file failed" )
-
-        main.step( "Create cell file" )
-        cellAppString = main.params[ 'ENV' ][ 'appString' ]
-        main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
-                                       main.Mininet.ip_address,
-                                       cellAppString, ipList, main.ONOScli1.karafUser )
-
-        main.step( "Applying cell variable to environment" )
-        cellResult = main.ONOSbench.setCell( cellName )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=cellResult,
-                                 onpass="Set cell succeeded",
-                                 onfail="Set cell failed" )
-
-        main.step( "Verify cell connectivity" )
-        verifyResult = main.ONOSbench.verifyCell()
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=verifyResult,
-                                 onpass="Verify cell succeeded",
-                                 onfail="Verify cell failed" )
-
-        branchName = main.ONOSbench.getBranchName()
-        main.log.report( "ONOS is on branch: " + branchName )
-
-        main.step( "Uninstalling ONOS" )
-        uninstallResult = main.ONOSbench.onosUninstall( ONOS1Ip ) \
-                          and main.ONOSbench.onosUninstall( ONOS2Ip ) \
-                          and main.ONOSbench.onosUninstall( ONOS3Ip )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=uninstallResult,
-                                 onpass="Uninstall ONOS from nodes succeeded",
-                                 onfail="Uninstall ONOS form nodes failed" )
-
-        main.ONOSbench.getVersion( report=True )
-
-        main.step( "Creating ONOS package" )
-        packageResult = main.ONOSbench.buckBuild()
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=packageResult,
-                                 onpass="Package ONOS succeeded",
-                                 onfail="Package ONOS failed" )
-
-        main.step( "Installing ONOS package" )
-        onos1InstallResult = main.ONOSbench.onosInstall( options="-f",
-                                                         node=ONOS1Ip )
-        onos2InstallResult = main.ONOSbench.onosInstall( options="-f",
-                                                         node=ONOS2Ip )
-        onos3InstallResult = main.ONOSbench.onosInstall( options="-f",
-                                                         node=ONOS3Ip )
-        onosInstallResult = onos1InstallResult and onos2InstallResult \
-                            and onos3InstallResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=onosInstallResult,
-                                 onpass="Install ONOS to nodes succeeded",
-                                 onfail="Install ONOS to nodes failed" )
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.ONOSbench.onosSecureSSH( node=ONOS1Ip )
-        secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=ONOS2Ip )
-        secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=ONOS3Ip )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=secureSshResult,
-                                 onpass="Set up ONOS secure SSH succeeded",
-                                 onfail="Set up ONOS secure SSH failed " )
-
-        main.step( "Checking if ONOS is up yet" )
-        onos1UpResult = main.ONOSbench.isup( ONOS1Ip, timeout=420 )
-        onos2UpResult = main.ONOSbench.isup( ONOS2Ip, timeout=420 )
-        onos3UpResult = main.ONOSbench.isup( ONOS3Ip, timeout=420 )
-        onosUpResult = onos1UpResult and onos2UpResult and onos3UpResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=onosUpResult,
-                                 onpass="ONOS nodes are up",
-                                 onfail="ONOS nodes are NOT up" )
-
-        main.step( "Checking if ONOS CLI is ready" )
-        main.CLIs = []
-        cliResult1 = main.ONOScli1.startOnosCli( ONOS1Ip,
-                commandlineTimeout=100, onosStartTimeout=600 )
-        main.CLIs.append( main.ONOScli1 )
-        cliResult2 = main.ONOScli2.startOnosCli( ONOS2Ip,
-                commandlineTimeout=100, onosStartTimeout=600 )
-        main.CLIs.append( main.ONOScli2 )
-        cliResult3 = main.ONOScli3.startOnosCli( ONOS3Ip,
-                commandlineTimeout=100, onosStartTimeout=600 )
-        main.CLIs.append( main.ONOScli3 )
-        cliResult = cliResult1 and cliResult2 and cliResult3
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=cliResult,
-                                 onpass="ONOS CLIs are ready",
-                                 onfail="ONOS CLIs are not ready" )
-
-        main.step( "Checking if ONOS CLI is ready for issuing commands" )
-        for i in range( 10 ):
-            ready = True
-            for cli in main.CLIs:
-                output = cli.summary()
-                if not output:
-                    ready = False
-            if ready:
-                break
-            time.sleep( 30 )
-        utilities.assert_equals( expect=True, actual=ready,
-                                 onpass="ONOS summary command succeded",
-                                 onfail="ONOS summary command failed" )
-
-        if not ready:
-            main.log.error( "ONOS startup failed!" )
-            main.cleanup()
+        try:
+            from tests.USECASE.dependencies.sdnipBaseFunction import SdnBase
+        except ImportError:
+            main.log.error( "sdnBase not found. exiting the test" )
             main.exit()
+        try:
+            main.sdnBase
+        except ( NameError, AttributeError ):
+            main.sdnBase = SdnBase()
+
+        main.sdnBase.initSetup()
 
     def CASE200( self, main ):
         main.case( "Activate sdn-ip application" )
@@ -229,7 +109,6 @@
             main.cleanup()
             main.exit()
 
-
     def CASE102( self, main ):
         '''
         This test case is to load the methods from other Python files, and create
@@ -244,9 +123,8 @@
                                           wrapperFile1 +
                                           ".py" )
         # Create tunnels
-        main.Functions.setupTunnel( main, '1.1.1.2', 2000, ONOS1Ip, 2000 )
-        main.Functions.setupTunnel( main, '1.1.1.4', 2000, ONOS2Ip, 2000 )
-        main.Functions.setupTunnel( main, '1.1.1.6', 2000, ONOS3Ip, 2000 )
+        for i in range ( len( main.ONOSip ) ):
+            main.Functions.setupTunnel( main, '1.1.1.' + str( ( i + 1 ) * 2 ), 2000, main.ONOSip[ i ], 2000 )
 
         main.log.info( "Wait SDN-IP to finish installing connectivity intents \
         and the BGP paths in data plane are ready..." )
@@ -282,29 +160,7 @@
         '''
         point-to-point intents test for each BGP peer and BGP speaker pair
         '''
-        import time
-        main.case( "Check point-to-point intents" )
-        main.log.info( "There are %s BGP peers in total "
-                       % main.params[ 'config' ][ 'peerNum' ] )
-        main.step( "Check P2P intents number from ONOS CLI" )
-
-        getIntentsResult = main.ONOScli1.intents( jsonFormat=True )
-        bgpIntentsActualNum = \
-            main.QuaggaCliSpeaker1.extractActualBgpIntentNum( getIntentsResult )
-        bgpIntentsExpectedNum = int( main.params[ 'config' ][ 'peerNum' ] ) * 6 * 2
-        if bgpIntentsActualNum != bgpIntentsExpectedNum:
-            time.sleep( int( main.params['timers']['RouteDelivery'] ) )
-            getIntentsResult = main.ONOScli1.intents( jsonFormat=True )
-            bgpIntentsActualNum = \
-                main.QuaggaCliSpeaker1.extractActualBgpIntentNum( getIntentsResult )
-        main.log.info( "bgpIntentsExpected num is:" )
-        main.log.info( bgpIntentsExpectedNum )
-        main.log.info( "bgpIntentsActual num is:" )
-        main.log.info( bgpIntentsActualNum )
-        utilities.assert_equals( expect=bgpIntentsExpectedNum,
-                                 actual=bgpIntentsActualNum,
-                                 onpass="PointToPointIntent Intent Num is correct!",
-                                 onfail="PointToPointIntent Intent Num is wrong!" )
+        main.sdnBase.pToPIntentTest( 12 )
 
     def CASE3( self, main ):
         '''
@@ -323,56 +179,7 @@
         allRoutesExpected.append( "9.0.0.0/24" + "/" + "10.0.9.1" )
         allRoutesExpected.append( "20.0.0.0/24" + "/" + "10.0.20.1" )
 
-        getRoutesResult = main.ONOScli1.routes( jsonFormat=True )
-        allRoutesActual = \
-            main.QuaggaCliSpeaker1.extractActualRoutesMaster( getRoutesResult )
-        allRoutesStrExpected = str( sorted( allRoutesExpected ) )
-        allRoutesStrActual = str( allRoutesActual ).replace( 'u', "" )
-        if allRoutesStrActual != allRoutesStrExpected:
-            time.sleep( int( main.params['timers']['RouteDelivery'] ) )
-            getRoutesResult = main.ONOScli1.routes( jsonFormat=True )
-            allRoutesActual = \
-                main.QuaggaCliSpeaker1.extractActualRoutesMaster( getRoutesResult )
-            allRoutesStrActual = str( allRoutesActual ).replace( 'u', "" )
-
-        main.log.info( "Routes expected:" )
-        main.log.info( allRoutesStrExpected )
-        main.log.info( "Routes get from ONOS CLI:" )
-        main.log.info( allRoutesStrActual )
-        utilities.assert_equals( expect=allRoutesStrExpected,
-                                 actual=allRoutesStrActual,
-                                 onpass="Routes are correct!",
-                                 onfail="Routes are wrong!" )
-
-        main.step( "Check M2S intents installed" )
-        getIntentsResult = main.ONOScli1.intents( jsonFormat=True )
-        routeIntentsActualNum = \
-            main.QuaggaCliSpeaker1.extractActualRouteIntentNum( getIntentsResult )
-        routeIntentsExpectedNum = 7
-        if routeIntentsActualNum != routeIntentsExpectedNum:
-            time.sleep( int( main.params['timers']['RouteDelivery'] ) )
-            getIntentsResult = main.ONOScli1.intents( jsonFormat=True )
-            routeIntentsActualNum = \
-                main.QuaggaCliSpeaker1.extractActualRouteIntentNum( getIntentsResult )
-
-        main.log.info( "MultiPointToSinglePoint Intent Num expected is:" )
-        main.log.info( routeIntentsExpectedNum )
-        main.log.info( "MultiPointToSinglePoint Intent NUM Actual is:" )
-        main.log.info( routeIntentsActualNum )
-        utilities.assert_equals( expect=routeIntentsExpectedNum,
-                                 actual=routeIntentsActualNum,
-                                 onpass="MultiPointToSinglePoint Intent Num is correct!",
-                                 onfail="MultiPointToSinglePoint Intent Num is wrong!" )
-
-        main.step( "Check whether all flow status are ADDED" )
-        flowCheck = utilities.retry( main.ONOScli1.checkFlowsState,
-                                     main.FALSE,
-                                     kwargs={'isPENDING':False},
-                                     attempts=10 )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=flowCheck,
-                                 onpass="Flow status is correct!",
-                                 onfail="Flow status is wrong!" )
+        main.sdnBase.routeAndIntentCheck( allRoutesExpected, 7 )
 
 
     def CASE4( self, main ):
@@ -386,154 +193,27 @@
         main.Functions.pingHostToHost(main,
                                       hosts=["h64517", "h64518"],
                                       expectAllSuccess=True)
-        main.Functions.pingHostToHost(main,
-                                      hosts=["h64519", "h64520"],
-                                      expectAllSuccess=True)
+        main.Functions.pingHostToHost( main,
+                                       hosts=[ "h64519", "h64520" ],
+                                       expectAllSuccess=True )
 
     def CASE5( self, main ):
         '''
         Cut links to peers one by one, check routes/intents
         '''
-        import time
-        main.case( "Bring down links and check routes/intents" )
-        main.step( "Bring down the link between sw32 and p64514" )
-        linkResult1 = main.Mininet.link( END1="sw32", END2="p64514",
-                                         OPTION="down" )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=linkResult1,
-                                 onpass="Bring down link succeeded!",
-                                 onfail="Bring down link failed!" )
-
-        if linkResult1 == main.TRUE:
-            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 6 )
-            main.Functions.checkM2SintentNum( main, 6 )
-        else:
-            main.log.error( "Bring down link failed!" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Bring down the link between sw8 and p64515" )
-        linkResult2 = main.Mininet.link( END1="sw8", END2="p64515",
-                                         OPTION="down" )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=linkResult2,
-                                 onpass="Bring down link succeeded!",
-                                 onfail="Bring down link failed!" )
-        if linkResult2 == main.TRUE:
-            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 5 )
-            main.Functions.checkM2SintentNum( main, 5 )
-        else:
-            main.log.error( "Bring down link failed!" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Bring down the link between sw28 and p64516" )
-        linkResult3 = main.Mininet.link( END1="sw28", END2="p64516",
-                                         OPTION="down" )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=linkResult3,
-                                 onpass="Bring down link succeeded!",
-                                 onfail="Bring down link failed!" )
-        if linkResult3 == main.TRUE:
-            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 4 )
-            main.Functions.checkM2SintentNum( main, 4 )
-        else:
-            main.log.error( "Bring down link failed!" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Check whether all flow status are ADDED" )
-        flowCheck = utilities.retry( main.ONOScli1.checkFlowsState,
-                                     main.FALSE,
-                                     kwargs={'isPENDING':False},
-                                     attempts=10 )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=flowCheck,
-                                 onpass="Flow status is correct!",
-                                 onfail="Flow status is wrong!" )
-
-        # Ping test
-        main.Functions.pingSpeakerToPeer( main, speakers=["spk1"],
-                       peers=["p64514", "p64515", "p64516"],
-                       expectAllSuccess=False )
-        main.Functions.pingHostToHost( main,
-                        hosts=["h64514", "h64515", "h64516"],
-                        expectAllSuccess=False )
+        main.sdnBase.linkUpDownCheck( "p64514", "p64515", "p64516",
+                                      6, 6, 5, 5, 4, 4,
+                                      "spk1", [ "h64514", "h64515", "h64516" ],
+                                      "down" )
 
     def CASE6( self, main ):
         '''
         Recover links to peers one by one, check routes/intents
         '''
-        import time
-        main.case( "Bring up links and check routes/intents" )
-        main.step( "Bring up the link between sw32 and p64514" )
-        linkResult1 = main.Mininet.link( END1="sw32", END2="p64514",
-                                         OPTION="up" )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=linkResult1,
-                                 onpass="Bring up link succeeded!",
-                                 onfail="Bring up link failed!" )
-        if linkResult1 == main.TRUE:
-            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 5 )
-            main.Functions.checkM2SintentNum( main, 5 )
-        else:
-            main.log.error( "Bring up link failed!" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Bring up the link between sw8 and p64515" )
-        linkResult2 = main.Mininet.link( END1="sw8", END2="p64515",
-                                         OPTION="up" )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=linkResult2,
-                                 onpass="Bring up link succeeded!",
-                                 onfail="Bring up link failed!" )
-        if linkResult2 == main.TRUE:
-            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 6 )
-            main.Functions.checkM2SintentNum( main, 6 )
-        else:
-            main.log.error( "Bring up link failed!" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Bring up the link between sw28 and p64516" )
-        linkResult3 = main.Mininet.link( END1="sw28", END2="p64516",
-                                         OPTION="up" )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=linkResult3,
-                                 onpass="Bring up link succeeded!",
-                                 onfail="Bring up link failed!" )
-        if linkResult3 == main.TRUE:
-            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 7 )
-            main.Functions.checkM2SintentNum( main, 7 )
-        else:
-            main.log.error( "Bring up link failed!" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Check whether all flow status are ADDED" )
-        flowCheck = utilities.retry( main.ONOScli1.checkFlowsState,
-                                     main.FALSE,
-                                     kwargs={'isPENDING':False},
-                                     attempts=10 )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=flowCheck,
-                                 onpass="Flow status is correct!",
-                                 onfail="Flow status is wrong!" )
-
-        # Ping test
-        main.Functions.pingSpeakerToPeer( main, speakers=["spk1"],
-                       peers=["p64514", "p64515", "p64516"],
-                       expectAllSuccess=True )
-        main.Functions.pingHostToHost( main,
-                        hosts=["h64514", "h64515", "h64516"],
-                        expectAllSuccess=True )
+        main.sdnBase.linkUpDownCheck( "p64514", "p64515", "p64516",
+                                      5, 5, 6, 6, 7, 7,
+                                      "spk1", [ "h64514", "h64515", "h64516" ],
+                                      "up" )
 
     def CASE7( self, main ):
         '''
@@ -627,7 +307,7 @@
                                  onpass="Starting switch succeeded!",
                                  onfail="Starting switch failed!" )
 
-        result2 = main.Mininet.assignSwController( "sw32", ONOS1Ip )
+        result2 = main.Mininet.assignSwController( "sw32", main.ONOSip[ 0 ] )
         utilities.assert_equals( expect=main.TRUE,
                                  actual=result2,
                                  onpass="Connect switch to ONOS succeeded!",
@@ -738,7 +418,7 @@
         utilities.assert_equals( expect=main.TRUE, actual=result1,
                                  onpass="Starting switch succeeded!",
                                  onfail="Starting switch failed!" )
-        result2 = main.Mininet.assignSwController( "sw11", ONOS1Ip )
+        result2 = main.Mininet.assignSwController( "sw11", main.ONOSip[ 0 ] )
         utilities.assert_equals( expect=main.TRUE, actual=result2,
                                  onpass="Connect switch to ONOS succeeded!",
                                  onfail="Connect switch to ONOS failed!" )
@@ -874,12 +554,9 @@
                 main.log.info( leaderIP )
 
         main.step( "Uninstall ONOS/SDN-IP leader node" )
-        if leaderIP == ONOS1Ip:
-            uninstallResult = main.ONOSbench.onosStop( ONOS1Ip )
-        elif leaderIP == ONOS2Ip:
-            uninstallResult = main.ONOSbench.onosStop( ONOS2Ip )
-        else:
-            uninstallResult = main.ONOSbench.onosStop( ONOS3Ip )
+        for ip in main.ONOSip:
+            if leaderIP == ip:
+                uninstallResult = main.ONOSbench.onosStop( ip )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=uninstallResult,
@@ -890,7 +567,7 @@
             main.exit()
         time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
 
-        if leaderIP == ONOS1Ip:
+        if leaderIP == main.ONOSip[ 0 ]:
             main.Functions.checkRouteNum( main, 7, ONOScli="ONOScli2" )
             main.Functions.checkM2SintentNum( main, 7, ONOScli="ONOScli2" )
             main.Functions.checkP2PintentNum( main, 30 * 2, ONOScli="ONOScli2" )
diff --git a/TestON/tests/USECASE/USECASE_SdnipFunctionCluster_fsfw/USECASE_SdnipFunctionCluster_fsfw.params b/TestON/tests/USECASE/USECASE_SdnipFunctionCluster_fsfw/USECASE_SdnipFunctionCluster_fsfw.params
index 54c42be..4cea2c8 100644
--- a/TestON/tests/USECASE/USECASE_SdnipFunctionCluster_fsfw/USECASE_SdnipFunctionCluster_fsfw.params
+++ b/TestON/tests/USECASE/USECASE_SdnipFunctionCluster_fsfw/USECASE_SdnipFunctionCluster_fsfw.params
@@ -19,7 +19,10 @@
         <fsfwPort>6633</fsfwPort>
         <port1>6653</port1>
     </CTRL>
-
+    <GIT>
+        <pull>False</pull>
+        <branch>master</branch>
+    </GIT>
     <DEPENDENCY>
         <path>/USECASE/USECASE_SdnipFunctionCluster_fsfw/dependencies/</path>
         <topology>USECASE_SdnipI2MN_Cluster.py</topology>
diff --git a/TestON/tests/USECASE/USECASE_SdnipFunctionCluster_fsfw/USECASE_SdnipFunctionCluster_fsfw.py b/TestON/tests/USECASE/USECASE_SdnipFunctionCluster_fsfw/USECASE_SdnipFunctionCluster_fsfw.py
index 5197ba6..1508a7e 100644
--- a/TestON/tests/USECASE/USECASE_SdnipFunctionCluster_fsfw/USECASE_SdnipFunctionCluster_fsfw.py
+++ b/TestON/tests/USECASE/USECASE_SdnipFunctionCluster_fsfw/USECASE_SdnipFunctionCluster_fsfw.py
@@ -57,18 +57,6 @@
         import time
         import os
         from operator import eq
-
-        main.case( "Setting up ONOS environment" )
-
-        cellName = main.params[ 'ENV' ][ 'cellName' ]
-        global ONOS1Ip
-        global ONOS2Ip
-        global ONOS3Ip
-        ONOS1Ip = os.getenv( main.params[ 'CTRL' ][ 'ip1' ] )
-        ONOS2Ip = os.getenv( main.params[ 'CTRL' ][ 'ip2' ] )
-        ONOS3Ip = os.getenv( main.params[ 'CTRL' ][ 'ip3' ] )
-        ipList = [ ONOS1Ip, ONOS2Ip, ONOS3Ip ]
-
         global pr64514
         global pr64515
         global pr64516
@@ -81,123 +69,18 @@
         fsfwIp = main.params[ 'CTRL' ][ 'fsfwIp' ]
         fsfwPort = main.params[ 'CTRL' ][ 'fsfwPort' ]
 
-        main.step( "Copying config files" )
-        src = os.path.dirname( main.testFile ) + "/network-cfg.json"
-        dst = main.ONOSbench.home + "/tools/package/config/network-cfg.json"
-        status = main.ONOSbench.scp( main.ONOSbench, src, dst, direction="to" )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=status,
-                                 onpass="Copy config file succeeded",
-                                 onfail="Copy config file failed" )
-
-        main.step( "Create cell file" )
-        cellAppString = main.params[ 'ENV' ][ 'appString' ]
-        main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
-                                       main.Mininet.ip_address,
-                                       cellAppString, ipList, main.ONOScli1.karafUser )
-
-        main.step( "Applying cell variable to environment" )
-        cellResult = main.ONOSbench.setCell( cellName )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=cellResult,
-                                 onpass="Set cell succeeded",
-                                 onfail="Set cell failed" )
-
-        main.step( "Verify cell connectivity" )
-        verifyResult = main.ONOSbench.verifyCell()
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=verifyResult,
-                                 onpass="Verify cell succeeded",
-                                 onfail="Verify cell failed" )
-
-        branchName = main.ONOSbench.getBranchName()
-        main.log.report( "ONOS is on branch: " + branchName )
-
-        main.step( "Uninstalling ONOS" )
-        uninstallResult = main.ONOSbench.onosUninstall( ONOS1Ip ) \
-                          and main.ONOSbench.onosUninstall( ONOS2Ip ) \
-                          and main.ONOSbench.onosUninstall( ONOS3Ip )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=uninstallResult,
-                                 onpass="Uninstall ONOS from nodes succeeded",
-                                 onfail="Uninstall ONOS form nodes failed" )
-
-        main.ONOSbench.getVersion( report=True )
-
-        main.step( "Creating ONOS package" )
-        packageResult = main.ONOSbench.buckBuild()
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=packageResult,
-                                 onpass="Package ONOS succeeded",
-                                 onfail="Package ONOS failed" )
-
-        main.step( "Installing ONOS package" )
-        onos1InstallResult = main.ONOSbench.onosInstall( options="-f",
-                                                         node=ONOS1Ip )
-        onos2InstallResult = main.ONOSbench.onosInstall( options="-f",
-                                                         node=ONOS2Ip )
-        onos3InstallResult = main.ONOSbench.onosInstall( options="-f",
-                                                         node=ONOS3Ip )
-        onosInstallResult = onos1InstallResult and onos2InstallResult \
-                            and onos3InstallResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=onosInstallResult,
-                                 onpass="Install ONOS to nodes succeeded",
-                                 onfail="Install ONOS to nodes failed" )
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.ONOSbench.onosSecureSSH( node=ONOS1Ip )
-        secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=ONOS2Ip )
-        secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=ONOS3Ip )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=secureSshResult,
-                                 onpass="Set up ONOS secure SSH succeeded",
-                                 onfail="Set up ONOS secure SSH failed " )
-
-        main.step( "Checking if ONOS is up yet" )
-        onos1UpResult = main.ONOSbench.isup( ONOS1Ip, timeout=420 )
-        onos2UpResult = main.ONOSbench.isup( ONOS2Ip, timeout=420 )
-        onos3UpResult = main.ONOSbench.isup( ONOS3Ip, timeout=420 )
-        onosUpResult = onos1UpResult and onos2UpResult and onos3UpResult
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=onosUpResult,
-                                 onpass="ONOS nodes are up",
-                                 onfail="ONOS nodes are NOT up" )
-
-        main.step( "Checking if ONOS CLI is ready" )
-        main.CLIs = []
-        cliResult1 = main.ONOScli1.startOnosCli( ONOS1Ip,
-                commandlineTimeout=100, onosStartTimeout=600 )
-        main.CLIs.append( main.ONOScli1 )
-        cliResult2 = main.ONOScli2.startOnosCli( ONOS2Ip,
-                commandlineTimeout=100, onosStartTimeout=600 )
-        main.CLIs.append( main.ONOScli2 )
-        cliResult3 = main.ONOScli3.startOnosCli( ONOS3Ip,
-                commandlineTimeout=100, onosStartTimeout=600 )
-        main.CLIs.append( main.ONOScli3 )
-        cliResult = cliResult1 and cliResult2 and cliResult3
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=cliResult,
-                                 onpass="ONOS CLIs are ready",
-                                 onfail="ONOS CLIs are not ready" )
-
-        for i in range( 10 ):
-            ready = True
-            for cli in main.CLIs:
-                output = cli.summary()
-                if not output:
-                    ready = False
-            if ready:
-                break
-            time.sleep( 30 )
-        utilities.assert_equals( expect=True, actual=ready,
-                                 onpass="ONOS summary command succeded",
-                                 onfail="ONOS summary command failed" )
-
-        if not ready:
-            main.log.error( "ONOS startup failed!" )
-            main.cleanup()
+        try:
+            from tests.USECASE.dependencies.sdnipBaseFunction import SdnBase
+        except ImportError:
+            main.log.error( "sdnBase not found. exiting the test" )
             main.exit()
+        try:
+            main.sdnBase
+        except ( NameError, AttributeError ):
+            main.sdnBase = SdnBase()
+
+        main.sdnBase.initSetup()
+
 
     def CASE200( self, main ):
         main.case( "Activate sdn-ip application" )
@@ -243,9 +126,8 @@
                                           wrapperFile1 +
                                           ".py" )
         # Create tunnels
-        main.Functions.setupTunnel( main, '1.1.1.2', 2000, ONOS1Ip, 2000 )
-        main.Functions.setupTunnel( main, '1.1.1.4', 2000, ONOS2Ip, 2000 )
-        main.Functions.setupTunnel( main, '1.1.1.6', 2000, ONOS3Ip, 2000 )
+        for i in range ( len( main.ONOSip ) ):
+            main.Functions.setupTunnel( main, '1.1.1.' + str( ( i + 1 ) * 2 ), 2000, main.ONOSip[ i ], 2000 )
 
         main.log.info( "Wait SDN-IP to finish installing connectivity intents \
         and the BGP paths in data plane are ready..." )
@@ -272,30 +154,7 @@
         '''
         point-to-point intents test for each BGP peer and BGP speaker pair
         '''
-        import time
-        main.case( "Check point-to-point intents" )
-        main.log.info( "There are %s BGP peers in total "
-                       % main.params[ 'config' ][ 'peerNum' ] )
-        main.step( "Check P2P intents number from ONOS CLI" )
-
-        getIntentsResult = main.ONOScli1.intents( jsonFormat=True )
-        bgpIntentsActualNum = \
-            main.QuaggaCliSpeaker1.extractActualBgpIntentNum( getIntentsResult )
-        bgpIntentsExpectedNum = int( main.params[ 'config' ][ 'peerNum' ] ) * 6 * 2
-        if bgpIntentsActualNum != bgpIntentsExpectedNum:
-            time.sleep( int( main.params['timers']['RouteDelivery'] ) )
-            getIntentsResult = main.ONOScli1.intents( jsonFormat=True )
-            bgpIntentsActualNum = \
-                main.QuaggaCliSpeaker1.extractActualBgpIntentNum( getIntentsResult )
-        main.log.info( "bgpIntentsExpected num is:" )
-        main.log.info( bgpIntentsExpectedNum )
-        main.log.info( "bgpIntentsActual num is:" )
-        main.log.info( bgpIntentsActualNum )
-        utilities.assertEquals( \
-            expect=True,
-            actual=eq( bgpIntentsExpectedNum, bgpIntentsActualNum ),
-            onpass="PointToPointIntent Intent Num is correct!",
-            onfail="PointToPointIntent Intent Num is wrong!" )
+        main.sdnBase.pToPIntentTest( 12 )
 
 
     def CASE3( self, main ):
@@ -310,59 +169,7 @@
         allRoutesExpected.append( "5.0.0.0/24" + "/" + "10.0.5.1" )
         allRoutesExpected.append( "6.0.0.0/24" + "/" + "10.0.6.1" )
 
-        getRoutesResult = main.ONOScli1.routes( jsonFormat=True )
-        allRoutesActual = \
-            main.QuaggaCliSpeaker1.extractActualRoutesMaster( getRoutesResult )
-        allRoutesStrExpected = str( sorted( allRoutesExpected ) )
-        allRoutesStrActual = str( allRoutesActual ).replace( 'u', "" )
-        if allRoutesStrActual != allRoutesStrExpected:
-            time.sleep( int( main.params['timers']['RouteDelivery'] ) )
-            getRoutesResult = main.ONOScli1.routes( jsonFormat=True )
-            allRoutesActual = \
-                main.QuaggaCliSpeaker1.extractActualRoutesMaster( getRoutesResult )
-            allRoutesStrActual = str( allRoutesActual ).replace( 'u', "" )
-
-        main.step( "Check routes installed" )
-        main.log.info( "Routes expected:" )
-        main.log.info( allRoutesStrExpected )
-        main.log.info( "Routes get from ONOS CLI:" )
-        main.log.info( allRoutesStrActual )
-        utilities.assertEquals( \
-            expect=allRoutesStrExpected, actual=allRoutesStrActual,
-            onpass="Routes are correct!",
-            onfail="Routes are wrong!" )
-
-        main.step( "Check M2S intents installed" )
-        getIntentsResult = main.ONOScli1.intents( jsonFormat=True )
-        routeIntentsActualNum = \
-            main.QuaggaCliSpeaker1.extractActualRouteIntentNum( getIntentsResult )
-        routeIntentsExpectedNum = 3
-        if routeIntentsActualNum != routeIntentsExpectedNum:
-            time.sleep( int( main.params['timers']['RouteDelivery'] ) )
-            getIntentsResult = main.ONOScli1.intents( jsonFormat=True )
-            routeIntentsActualNum = \
-                main.QuaggaCliSpeaker1.extractActualRouteIntentNum( getIntentsResult )
-
-        main.log.info( "MultiPointToSinglePoint Intent Num expected is:" )
-        main.log.info( routeIntentsExpectedNum )
-        main.log.info( "MultiPointToSinglePoint Intent NUM Actual is:" )
-        main.log.info( routeIntentsActualNum )
-        utilities.assertEquals( \
-            expect=routeIntentsExpectedNum,
-            actual=routeIntentsActualNum,
-            onpass="MultiPointToSinglePoint Intent Num is correct!",
-            onfail="MultiPointToSinglePoint Intent Num is wrong!" )
-
-        main.step( "Check whether all flow status are ADDED" )
-        flowCheck = utilities.retry( main.ONOScli1.checkFlowsState,
-                                     main.FALSE,
-                                     kwargs={'isPENDING':False},
-                                     attempts=10 )
-        utilities.assertEquals( \
-            expect=main.TRUE,
-            actual=flowCheck,
-            onpass="Flow status is correct!",
-            onfail="Flow status is wrong!" )
+        main.sdnBase.routeAndIntentCheck( allRoutesExpected, 3 )
 
 
     def CASE4( self, main ):
@@ -374,159 +181,23 @@
                         hosts=["host64514", "host64515", "host64516"],
                         expectAllSuccess=True )
 
-
     def CASE5( self, main ):
         '''
         Cut links to peers one by one, check routes/intents
         '''
-        import time
-        main.case( "Bring down links and check routes/intents" )
-        main.step( "Bring down the link between sw32 and peer64514" )
-        linkResult1 = main.Mininet.link( END1="sw32", END2="pr64514",
-                                         OPTION="down" )
-        # When bring down a link, Mininet will bring down both the interfaces
-        # at the two sides of the link. Here we do not want to bring down the
-        # host side interface, since I noticed when bring up in CASE6, some of
-        # the configuration information will lost.
-        utilities.assertEquals( expect=main.TRUE,
-                                actual=linkResult1,
-                                onpass="Bring down link succeeded!",
-                                onfail="Bring down link failed!" )
-
-        if linkResult1 == main.TRUE:
-            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 2 )
-            main.Functions.checkM2SintentNum( main, 2 )
-        else:
-            main.log.error( "Bring down link failed!" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Bring down the link between sw8 and peer64515" )
-        linkResult2 = main.Mininet.link( END1="sw8", END2="pr64515",
-                                         OPTION="down" )
-        utilities.assertEquals( expect=main.TRUE,
-                                actual=linkResult2,
-                                onpass="Bring down link succeeded!",
-                                onfail="Bring down link failed!" )
-        if linkResult2 == main.TRUE:
-            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 1 )
-            main.Functions.checkM2SintentNum( main, 1 )
-        else:
-            main.log.error( "Bring down link failed!" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Bring down the link between sw28 and peer64516" )
-        linkResult3 = main.Mininet.link( END1="sw28", END2="pr64516",
-                                         OPTION="down" )
-        utilities.assertEquals( expect=main.TRUE,
-                                actual=linkResult3,
-                                onpass="Bring down link succeeded!",
-                                onfail="Bring down link failed!" )
-        if linkResult3 == main.TRUE:
-            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 0 )
-            main.Functions.checkM2SintentNum( main, 0 )
-        else:
-            main.log.error( "Bring down link failed!" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Check whether all flow status are ADDED" )
-        flowCheck = utilities.retry( main.ONOScli1.checkFlowsState,
-                                     main.FALSE,
-                                     kwargs={'isPENDING':False},
-                                     attempts=10 )
-        utilities.assertEquals( \
-            expect=main.TRUE,
-            actual=flowCheck,
-            onpass="Flow status is correct!",
-            onfail="Flow status is wrong!" )
-
-        # Ping test
-        main.Functions.pingSpeakerToPeer( main, speakers=["speaker1"],
-                       peers=["pr64514", "pr64515", "pr64516"],
-                       expectAllSuccess=False )
-        main.Functions.pingHostToHost( main,
-                        hosts=["host64514", "host64515", "host64516"],
-                        expectAllSuccess=False )
-
+        main.sdnBase.linkUpDownCheck( "pr64514", "pr64515", "pr64516",
+                                      2, 2, 1, 1, 0, 0,
+                                      "speaker1", [ "host64514", "host64515", "host64516" ],
+                                      "down" )
 
     def CASE6( self, main ):
         '''
         Recover links to peers one by one, check routes/intents
         '''
-        import time
-        main.case( "Bring up links and check routes/intents" )
-        main.step( "Bring up the link between sw32 and peer64514" )
-        linkResult1 = main.Mininet.link( END1="sw32", END2="pr64514",
-                                         OPTION="up" )
-        utilities.assertEquals( expect=main.TRUE,
-                                actual=linkResult1,
-                                onpass="Bring up link succeeded!",
-                                onfail="Bring up link failed!" )
-        if linkResult1 == main.TRUE:
-            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 1 )
-            main.Functions.checkM2SintentNum( main, 1 )
-        else:
-            main.log.error( "Bring up link failed!" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Bring up the link between sw8 and peer64515" )
-        linkResult2 = main.Mininet.link( END1="sw8", END2="pr64515",
-                                         OPTION="up" )
-        utilities.assertEquals( expect=main.TRUE,
-                                actual=linkResult2,
-                                onpass="Bring up link succeeded!",
-                                onfail="Bring up link failed!" )
-        if linkResult2 == main.TRUE:
-            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 2 )
-            main.Functions.checkM2SintentNum( main, 2 )
-        else:
-            main.log.error( "Bring up link failed!" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Bring up the link between sw28 and peer64516" )
-        linkResult3 = main.Mininet.link( END1="sw28", END2="pr64516",
-                                         OPTION="up" )
-        utilities.assertEquals( expect=main.TRUE,
-                                actual=linkResult3,
-                                onpass="Bring up link succeeded!",
-                                onfail="Bring up link failed!" )
-        if linkResult3 == main.TRUE:
-            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 3 )
-            main.Functions.checkM2SintentNum( main, 3 )
-        else:
-            main.log.error( "Bring up link failed!" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Check whether all flow status are ADDED" )
-        flowCheck = utilities.retry( main.ONOScli1.checkFlowsState,
-                                     main.FALSE,
-                                     kwargs={'isPENDING':False},
-                                     attempts=10 )
-        utilities.assertEquals( \
-            expect=main.TRUE,
-            actual=flowCheck,
-            onpass="Flow status is correct!",
-            onfail="Flow status is wrong!" )
-
-        # Ping test
-        main.Functions.pingSpeakerToPeer( main, speakers=["speaker1"],
-                       peers=["pr64514", "pr64515", "pr64516"],
-                       expectAllSuccess=True )
-        main.Functions.pingHostToHost( main,
-                        hosts=["host64514", "host64515", "host64516"],
-                        expectAllSuccess=True )
-
+        main.sdnBase.linkUpDownCheck( "pr64514", "pr64515", "pr64516",
+                                      1, 1, 2, 2, 3, 3,
+                                      "speaker1", [ "host64514", "host64515", "host64516" ],
+                                      "up" )
 
     def CASE7( self, main ):
         '''
@@ -876,13 +547,10 @@
                 main.log.info( "leaderIP is: " )
                 main.log.info( leaderIP )
 
-        main.step( "Uninstall ONOS/SDN-IP leader node" )
-        if leaderIP == ONOS1Ip:
-            uninstallResult = main.ONOSbench.onosStop( ONOS1Ip )
-        elif leaderIP == ONOS2Ip:
-            uninstallResult = main.ONOSbench.onosStop( ONOS2Ip )
-        else:
-            uninstallResult = main.ONOSbench.onosStop( ONOS3Ip )
+                main.step( "Uninstall ONOS/SDN-IP leader node" )
+        for ip in main.ONOSip:
+            if leaderIP == ip:
+                uninstallResult = main.ONOSbench.onosStop( ip )
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=uninstallResult,
@@ -893,7 +561,7 @@
             main.exit()
         time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
 
-        if leaderIP == ONOS1Ip:
+        if leaderIP == main.ONOSip[ 0 ]:
             main.Functions.checkRouteNum( main, 3, ONOScli="ONOScli2" )
             main.Functions.checkM2SintentNum( main, 3, ONOScli="ONOScli2" )
             main.Functions.checkP2PintentNum( main, 18 * 2, ONOScli="ONOScli2" )
diff --git a/TestON/tests/USECASE/USECASE_SdnipFunction_fsfw/USECASE_SdnipFunction_fsfw.params b/TestON/tests/USECASE/USECASE_SdnipFunction_fsfw/USECASE_SdnipFunction_fsfw.params
index b1c2f8f..7fc2d27 100644
--- a/TestON/tests/USECASE/USECASE_SdnipFunction_fsfw/USECASE_SdnipFunction_fsfw.params
+++ b/TestON/tests/USECASE/USECASE_SdnipFunction_fsfw/USECASE_SdnipFunction_fsfw.params
@@ -17,7 +17,10 @@
         <fsfwPort>6633</fsfwPort>
         <port1>6653</port1>
     </CTRL>
-
+    <GIT>
+        <pull>False</pull>
+        <branch>master</branch>
+    </GIT>
     <DEPENDENCY>
         <path>/USECASE/USECASE_SdnipFunction_fsfw/dependencies/</path>
         <topology>USECASE_SdnipI2MN.py</topology>
diff --git a/TestON/tests/USECASE/USECASE_SdnipFunction_fsfw/USECASE_SdnipFunction_fsfw.py b/TestON/tests/USECASE/USECASE_SdnipFunction_fsfw/USECASE_SdnipFunction_fsfw.py
index da38107..505a602 100644
--- a/TestON/tests/USECASE/USECASE_SdnipFunction_fsfw/USECASE_SdnipFunction_fsfw.py
+++ b/TestON/tests/USECASE/USECASE_SdnipFunction_fsfw/USECASE_SdnipFunction_fsfw.py
@@ -29,8 +29,6 @@
             main.exit()
         main.step( "Connect switches to FSFW" )
 
-        global ONOS1Ip
-        ONOS1Ip = os.getenv( main.params[ 'CTRL' ][ 'ip1' ] )
         global fsfwIp
         # TDOO: there is some setup sequence issue, will fix it later
         # fsfwIp = os.getenv( main.params[ 'CTRL' ][ 'ipN' ] )
@@ -53,10 +51,10 @@
             main.exit()
 
         main.step( "Set up tunnel from Mininet node to onos node" )
-        forwarding1 = '%s:2000:%s:2000' % ( '1.1.1.2', ONOS1Ip )
+        forwarding1 = '%s:2000:%s:2000' % ( '1.1.1.2', main.ONOSip[ 0 ] )
         command = 'ssh -nNT -o "PasswordAuthentication no"'
         command += ' -o "StrictHostKeyChecking no" -l sdn'
-        command += ' -L %s %s & ' % ( forwarding1, ONOS1Ip )
+        command += ' -L %s %s & ' % ( forwarding1, main.ONOSip[ 0 ] )
 
         tunnelResult = main.TRUE
         tunnelResult = main.Mininet.node( "root", command )
@@ -83,108 +81,17 @@
         import os
         from operator import eq
 
-        main.case( "Setting up ONOS environment" )
-
-        cellName = main.params[ 'ENV' ][ 'cellName' ]
-        global ONOS1Ip
-        ONOS1Ip = os.getenv( main.params[ 'CTRL' ][ 'ip1' ] )
-        ipList = [ ONOS1Ip ]
-
-        main.step( "Copying config files" )
-        src = os.path.dirname( main.testFile ) + "/network-cfg.json"
-        dst = main.ONOSbench.home + "/tools/package/config/network-cfg.json"
-        status = main.ONOSbench.scp( main.ONOSbench, src, dst, direction="to" )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=status,
-                                 onpass="Copy config file succeeded",
-                                 onfail="Copy config file failed" )
-
-        main.step( "Create cell file" )
-        cellAppString = main.params[ 'ENV' ][ 'appString' ]
-        main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
-                                       main.Mininet.ip_address,
-                                       cellAppString, ipList, main.ONOScli1.karafUser )
-
-        main.step( "Applying cell variable to environment" )
-        cellResult = main.ONOSbench.setCell( cellName )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=cellResult,
-                                 onpass="Set cell succeeded",
-                                 onfail="Set cell failed" )
-
-        main.step( "Verify cell connectivity" )
-        verifyResult = main.ONOSbench.verifyCell()
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=verifyResult,
-                                 onpass="Verify cell succeeded",
-                                 onfail="Verify cell failed" )
-
-        branchName = main.ONOSbench.getBranchName()
-        main.log.report( "ONOS is on branch: " + branchName )
-
-        main.step( "Uninstalling ONOS" )
-        uninstallResult = main.ONOSbench.onosUninstall( ONOS1Ip )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=uninstallResult,
-                                 onpass="Uninstall ONOS succeeded",
-                                 onfail="Uninstall ONOS failed" )
-
-        main.ONOSbench.getVersion( report=True )
-
-        main.step( "Creating ONOS package" )
-        packageResult = main.ONOSbench.buckBuild()
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=packageResult,
-                                 onpass="Package ONOS succeeded",
-                                 onfail="Package ONOS failed" )
-
-        main.step( "Installing ONOS package" )
-        onos1InstallResult = main.ONOSbench.onosInstall( options="-f",
-                                                         node=ONOS1Ip )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=onos1InstallResult,
-                                 onpass="Install ONOS succeeded",
-                                 onfail="Install ONOS failed" )
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.ONOSbench.onosSecureSSH( node=ONOS1Ip )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=secureSshResult,
-                                 onpass="Set up ONOS secure SSH succeeded",
-                                 onfail="Set up ONOS secure SSH failed " )
-
-        main.step( "Checking if ONOS is up yet" )
-        onos1UpResult = main.ONOSbench.isup( ONOS1Ip, timeout=420 )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=onos1UpResult,
-                                 onpass="ONOS is up",
-                                 onfail="ONOS is NOT up" )
-
-        main.step( "Checking if ONOS CLI is ready" )
-        cliResult = main.ONOScli1.startOnosCli( ONOS1Ip,
-                                               commandlineTimeout=100,
-                                               onosStartTimeout=600 )
-        utilities.assert_equals( expect=main.TRUE,
-                                 actual=cliResult,
-                                 onpass="ONOS CLI is ready",
-                                 onfail="ONOS CLI is not ready" )
-
-        for i in range( 10 ):
-            ready = True
-            output = main.ONOScli1.summary()
-            if not output:
-                ready = False
-            if ready:
-                break
-            time.sleep( 30 )
-        utilities.assert_equals( expect=True, actual=ready,
-                                 onpass="ONOS summary command succeded",
-                                 onfail="ONOS summary command failed" )
-
-        if not ready:
-            main.log.error( "ONOS startup failed!" )
-            main.cleanup()
+        try:
+            from tests.USECASE.dependencies.sdnipBaseFunction import SdnBase
+        except ImportError:
+            main.log.error( "sdnBase not found. exiting the test" )
             main.exit()
+        try:
+            main.sdnBase
+        except ( NameError, AttributeError ):
+            main.sdnBase = SdnBase()
+
+        main.sdnBase.initSetup()
 
         main.log.info( "Get links in the network" )
         time.sleep( int ( main.params['timers']['TopoDiscovery'] ) )
@@ -249,30 +156,7 @@
         '''
         point-to-point intents test for each BGP peer and BGP speaker pair
         '''
-        import time
-        main.case( "Check point-to-point intents" )
-        main.log.info( "There are %s BGP peers in total "
-                       % main.params[ 'config' ][ 'peerNum' ] )
-        main.step( "Check P2P intents number from ONOS CLI" )
-
-        getIntentsResult = main.ONOScli1.intents( jsonFormat=True )
-        bgpIntentsActualNum = \
-            main.QuaggaCliSpeaker1.extractActualBgpIntentNum( getIntentsResult )
-        bgpIntentsExpectedNum = int( main.params[ 'config' ][ 'peerNum' ] ) * 6
-        if bgpIntentsActualNum != bgpIntentsExpectedNum:
-            time.sleep( int( main.params['timers']['RouteDelivery'] ) )
-            getIntentsResult = main.ONOScli1.intents( jsonFormat=True )
-            bgpIntentsActualNum = \
-                main.QuaggaCliSpeaker1.extractActualBgpIntentNum( getIntentsResult )
-        main.log.info( "bgpIntentsExpected num is:" )
-        main.log.info( bgpIntentsExpectedNum )
-        main.log.info( "bgpIntentsActual num is:" )
-        main.log.info( bgpIntentsActualNum )
-        utilities.assertEquals( \
-            expect=True,
-            actual=eq( bgpIntentsExpectedNum, bgpIntentsActualNum ),
-            onpass="PointToPointIntent Intent Num is correct!",
-            onfail="PointToPointIntent Intent Num is wrong!" )
+        main.sdnBase.pToPIntentTest( 6 )
 
 
     def CASE3( self, main ):
@@ -287,60 +171,7 @@
         allRoutesExpected.append( "5.0.0.0/24" + "/" + "10.0.5.1" )
         allRoutesExpected.append( "6.0.0.0/24" + "/" + "10.0.6.1" )
 
-        getRoutesResult = main.ONOScli1.routes( jsonFormat=True )
-        allRoutesActual = \
-            main.QuaggaCliSpeaker1.extractActualRoutesMaster( getRoutesResult )
-        allRoutesStrExpected = str( sorted( allRoutesExpected ) )
-        allRoutesStrActual = str( allRoutesActual ).replace( 'u', "" )
-        if allRoutesStrActual != allRoutesStrExpected:
-            time.sleep( int( main.params['timers']['RouteDelivery'] ) )
-            getRoutesResult = main.ONOScli1.routes( jsonFormat=True )
-            allRoutesActual = \
-                main.QuaggaCliSpeaker1.extractActualRoutesMaster( getRoutesResult )
-            allRoutesStrActual = str( allRoutesActual ).replace( 'u', "" )
-
-        main.step( "Check routes installed" )
-        main.log.info( "Routes expected:" )
-        main.log.info( allRoutesStrExpected )
-        main.log.info( "Routes get from ONOS CLI:" )
-        main.log.info( allRoutesStrActual )
-        utilities.assertEquals( \
-            expect=allRoutesStrExpected, actual=allRoutesStrActual,
-            onpass="Routes are correct!",
-            onfail="Routes are wrong!" )
-
-        main.step( "Check M2S intents installed" )
-        getIntentsResult = main.ONOScli1.intents( jsonFormat=True )
-        routeIntentsActualNum = \
-            main.QuaggaCliSpeaker1.extractActualRouteIntentNum( getIntentsResult )
-        routeIntentsExpectedNum = 3
-        if routeIntentsActualNum != routeIntentsExpectedNum:
-            time.sleep( int( main.params['timers']['RouteDelivery'] ) )
-            getIntentsResult = main.ONOScli1.intents( jsonFormat=True )
-            routeIntentsActualNum = \
-                main.QuaggaCliSpeaker1.extractActualRouteIntentNum( getIntentsResult )
-
-        main.log.info( "MultiPointToSinglePoint Intent Num expected is:" )
-        main.log.info( routeIntentsExpectedNum )
-        main.log.info( "MultiPointToSinglePoint Intent NUM Actual is:" )
-        main.log.info( routeIntentsActualNum )
-        utilities.assertEquals( \
-            expect=routeIntentsExpectedNum,
-            actual=routeIntentsActualNum,
-            onpass="MultiPointToSinglePoint Intent Num is correct!",
-            onfail="MultiPointToSinglePoint Intent Num is wrong!" )
-
-        main.step( "Check whether all flow status are ADDED" )
-        flowCheck = utilities.retry( main.ONOScli1.checkFlowsState,
-                                     main.FALSE,
-                                     kwargs={'isPENDING':False},
-                                     attempts=10 )
-        utilities.assertEquals( \
-            expect=main.TRUE,
-            actual=flowCheck,
-            onpass="Flow status is correct!",
-            onfail="Flow status is wrong!" )
-
+        main.sdnBase.routeAndIntentCheck( allRoutesExpected, 3 )
 
     def CASE4( self, main ):
         '''
@@ -356,150 +187,19 @@
         '''
         Cut links to peers one by one, check routes/intents
         '''
-        import time
-        main.case( "Bring down links and check routes/intents" )
-        main.step( "Bring down the link between sw32 and peer64514" )
-        linkResult1 = main.Mininet.link( END1="sw32", END2="pr64514",
-                                         OPTION="down" )
-        utilities.assertEquals( expect=main.TRUE,
-                                actual=linkResult1,
-                                onpass="Bring down link succeeded!",
-                                onfail="Bring down link failed!" )
-
-        if linkResult1 == main.TRUE:
-            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 2 )
-            main.Functions.checkM2SintentNum( main, 2 )
-        else:
-            main.log.error( "Bring down link failed!" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Bring down the link between sw8 and peer64515" )
-        linkResult2 = main.Mininet.link( END1="sw8", END2="pr64515",
-                                         OPTION="down" )
-        utilities.assertEquals( expect=main.TRUE,
-                                actual=linkResult2,
-                                onpass="Bring down link succeeded!",
-                                onfail="Bring down link failed!" )
-        if linkResult2 == main.TRUE:
-            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 1 )
-            main.Functions.checkM2SintentNum( main, 1 )
-        else:
-            main.log.error( "Bring down link failed!" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Bring down the link between sw28 and peer64516" )
-        linkResult3 = main.Mininet.link( END1="sw28", END2="pr64516",
-                                         OPTION="down" )
-        utilities.assertEquals( expect=main.TRUE,
-                                actual=linkResult3,
-                                onpass="Bring down link succeeded!",
-                                onfail="Bring down link failed!" )
-        if linkResult3 == main.TRUE:
-            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 0 )
-            main.Functions.checkM2SintentNum( main, 0 )
-        else:
-            main.log.error( "Bring down link failed!" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Check whether all flow status are ADDED" )
-        flowCheck = utilities.retry( main.ONOScli1.checkFlowsState,
-                                     main.FALSE,
-                                     kwargs={'isPENDING':False},
-                                     attempts=10 )
-        utilities.assertEquals( \
-            expect=main.TRUE,
-            actual=flowCheck,
-            onpass="Flow status is correct!",
-            onfail="Flow status is wrong!" )
-
-        # Ping test
-        main.Functions.pingSpeakerToPeer( main, speakers=["speaker1"],
-                       peers=["pr64514", "pr64515", "pr64516"],
-                       expectAllSuccess=False )
-        main.Functions.pingHostToHost( main,
-                        hosts=["host64514", "host64515", "host64516"],
-                        expectAllSuccess=False )
-
+        main.sdnBase.linkUpDownCheck( "pr64514", "pr64515", "pr64516",
+                                      2, 2, 1, 1, 0, 0,
+                                      "speaker1", [ "host64514", "host64515", "host64516" ],
+                                      "down" )
 
     def CASE6( self, main ):
         '''
         Recover links to peers one by one, check routes/intents
         '''
-        import time
-        main.case( "Bring up links and check routes/intents" )
-        main.step( "Bring up the link between sw32 and peer64514" )
-        linkResult1 = main.Mininet.link( END1="sw32", END2="pr64514",
-                                         OPTION="up" )
-        utilities.assertEquals( expect=main.TRUE,
-                                actual=linkResult1,
-                                onpass="Bring up link succeeded!",
-                                onfail="Bring up link failed!" )
-        if linkResult1 == main.TRUE:
-            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 1 )
-            main.Functions.checkM2SintentNum( main, 1 )
-        else:
-            main.log.error( "Bring up link failed!" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Bring up the link between sw8 and peer64515" )
-        linkResult2 = main.Mininet.link( END1="sw8", END2="pr64515",
-                                         OPTION="up" )
-        utilities.assertEquals( expect=main.TRUE,
-                                actual=linkResult2,
-                                onpass="Bring up link succeeded!",
-                                onfail="Bring up link failed!" )
-        if linkResult2 == main.TRUE:
-            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 2 )
-            main.Functions.checkM2SintentNum( main, 2 )
-        else:
-            main.log.error( "Bring up link failed!" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Bring up the link between sw28 and peer64516" )
-        linkResult3 = main.Mininet.link( END1="sw28", END2="pr64516",
-                                         OPTION="up" )
-        utilities.assertEquals( expect=main.TRUE,
-                                actual=linkResult3,
-                                onpass="Bring up link succeeded!",
-                                onfail="Bring up link failed!" )
-        if linkResult3 == main.TRUE:
-            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
-            main.Functions.checkRouteNum( main, 3 )
-            main.Functions.checkM2SintentNum( main, 3 )
-        else:
-            main.log.error( "Bring up link failed!" )
-            main.cleanup()
-            main.exit()
-
-        main.step( "Check whether all flow status are ADDED" )
-        flowCheck = utilities.retry( main.ONOScli1.checkFlowsState,
-                                     main.FALSE,
-                                     kwargs={'isPENDING':False},
-                                     attempts=10 )
-        utilities.assertEquals( \
-            expect=main.TRUE,
-            actual=flowCheck,
-            onpass="Flow status is correct!",
-            onfail="Flow status is wrong!" )
-
-        # Ping test
-        main.Functions.pingSpeakerToPeer( main, speakers=["speaker1"],
-                       peers=["pr64514", "pr64515", "pr64516"],
-                       expectAllSuccess=True )
-        main.Functions.pingHostToHost( main,
-                        hosts=["host64514", "host64515", "host64516"],
-                        expectAllSuccess=True )
-
+        main.sdnBase.linkUpDownCheck( "pr64514", "pr64515", "pr64516",
+                                      1, 1, 2, 2, 3, 3,
+                                      "speaker1", [ "host64514", "host64515", "host64516" ],
+                                      "up" )
 
     def CASE7( self, main ):
         '''
diff --git a/TestON/tests/USECASE/VPLS/VPLSBasic/VPLSBasic.py b/TestON/tests/USECASE/VPLS/VPLSBasic/VPLSBasic.py
index 62889c9..f60e004 100644
--- a/TestON/tests/USECASE/VPLS/VPLSBasic/VPLSBasic.py
+++ b/TestON/tests/USECASE/VPLS/VPLSBasic/VPLSBasic.py
@@ -29,50 +29,29 @@
         import imp
         import time
         import json
-        main.case( "Setting up test environment" )
-        main.caseExplanation = "Setup the test environment including " +\
-                                "installing ONOS, starting Mininet and ONOS" +\
-                                "cli sessions."
 
-        # load some variables from the params file
-        cellName = main.params[ 'ENV' ][ 'cellName' ]
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except ImportError:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+        main.testSetUp.envSetupDescription()
+        stepResult = main.FALSE
+        try:
+            # load some variables from the params file
+            cellName = main.params[ 'ENV' ][ 'cellName' ]
 
-        main.numCtrls = int( main.params[ 'num_controllers' ] )
+            main.apps = main.params[ 'ENV' ][ 'cellApps' ]
+            main.numCtrls = int( main.params[ 'num_controllers' ] )
 
-        ofPort = main.params[ 'CTRL' ][ 'port' ]
+            ofPort = main.params[ 'CTRL' ][ 'port' ]
+            stepResult = main.testSetUp.envSetup( hasRest=True, hasNode=True )
+        except Exception as e:
+            main.testSetUp.envSetupException( e )
+        main.testSetUp.evnSetupConclusion( stepResult )
 
-        main.CLIs = []
-        main.RESTs = []
-        main.nodes = []
-        ipList = []
-        for i in range( 1, main.numCtrls + 1 ):
-            try:
-                main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
-                main.RESTs.append( getattr( main, 'ONOSrest' + str( i ) ) )
-                main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
-                ipList.append( main.nodes[ -1 ].ip_address )
-            except AttributeError:
-                break
-
-        main.step( "Create cell file" )
-        cellAppString = main.params[ 'ENV' ][ 'cellApps' ]
-        main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
-                                       main.Mininet1.ip_address,
-                                       cellAppString, ipList, main.ONOScli1.karafUser )
-        main.step( "Applying cell variable to environment" )
-        cellResult = main.ONOSbench.setCell( cellName )
-        verifyResult = main.ONOSbench.verifyCell()
-
-        main.log.info( "Uninstalling ONOS" )
-        for node in main.nodes:
-            main.ONOSbench.onosUninstall( node.ip_address )
-
-        # Make sure ONOS is DEAD
-        main.log.info( "Killing any ONOS processes" )
-        killResults = main.TRUE
-        for node in main.nodes:
-            killed = main.ONOSbench.onosKill( node.ip_address )
-            killResults = killResults and killed
+        main.testSetUp.ONOSSetUp( main.Mininet1, cellName=cellName )
 
         main.step( "Starting Mininet" )
         # scp topo file to mininet
@@ -94,63 +73,6 @@
                                  onpass="Mininet Started",
                                  onfail="Error starting Mininet" )
 
-        main.ONOSbench.getVersion( report=True )
-
-        main.step( "Creating ONOS package" )
-        packageResult = main.ONOSbench.buckBuild()
-        utilities.assert_equals( expect=main.TRUE, actual=packageResult,
-                                 onpass="ONOS package successful",
-                                 onfail="ONOS package failed" )
-
-        main.step( "Installing ONOS package" )
-        onosInstallResult = main.TRUE
-        for node in main.nodes:
-            tmpResult = main.ONOSbench.onosInstall( options="-f",
-                                                    node=node.ip_address )
-            onosInstallResult = onosInstallResult and tmpResult
-        utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
-                                 onpass="ONOS install successful",
-                                 onfail="ONOS install failed" )
-
-        main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.TRUE
-        for node in main.nodes:
-            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=node.ip_address )
-        utilities.assert_equals( expect=main.TRUE, actual=secureSshResult,
-                                 onpass="Test step PASS",
-                                 onfail="Test step FAIL" )
-
-        main.step( "Checking if ONOS is up yet" )
-        for i in range( 2 ):
-            onosIsupResult = main.TRUE
-            for node in main.nodes:
-                started = main.ONOSbench.isup( node.ip_address )
-                if not started:
-                    main.log.error( node.name + " hasn't started" )
-                onosIsupResult = onosIsupResult and started
-            if onosIsupResult == main.TRUE:
-                break
-        utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
-                                 onpass="ONOS startup successful",
-                                 onfail="ONOS startup failed" )
-
-        main.step( "Starting ONOS CLI sessions" )
-        cliResults = main.TRUE
-        threads = []
-        for i in range( main.numCtrls ):
-            t = main.Thread( target=main.CLIs[ i ].startOnosCli,
-                             name="startOnosCli-" + str( i ),
-                             args=[ main.nodes[ i ].ip_address ] )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            cliResults = cliResults and t.result
-        utilities.assert_equals( expect=main.TRUE, actual=cliResults,
-                                 onpass="ONOS cli startup successful",
-                                 onfail="ONOS cli startup failed" )
-
         main.activeNodes = [ i for i in range( 0, len( main.CLIs ) ) ]
 
         main.step( "Activate apps defined in the params file" )
diff --git a/TestON/tests/USECASE/VPLS/VPLSBasic/VPLSBasic.topo b/TestON/tests/USECASE/VPLS/VPLSBasic/VPLSBasic.topo
index 476d986..03e451b 100755
--- a/TestON/tests/USECASE/VPLS/VPLSBasic/VPLSBasic.topo
+++ b/TestON/tests/USECASE/VPLS/VPLSBasic/VPLSBasic.topo
@@ -8,7 +8,7 @@
             <type>OnosDriver</type>
             <connect_order>1</connect_order>
             <COMPONENTS>
-                <nodes>1</nodes>
+                <nodes>3</nodes>
                 <prompt></prompt>
             </COMPONENTS>
         </ONOSbench>
diff --git a/TestON/tests/USECASE/dependencies/sdnipBaseFunction.py b/TestON/tests/USECASE/dependencies/sdnipBaseFunction.py
new file mode 100644
index 0000000..1dfe2e9
--- /dev/null
+++ b/TestON/tests/USECASE/dependencies/sdnipBaseFunction.py
@@ -0,0 +1,215 @@
+class SdnBase:
+    def __init__(self):
+        self.default = ''
+    def initSetup( self ):
+        import json
+        import time
+        import os
+        from operator import eq
+        main.case( "Setting up ONOS environment" )
+        try:
+            from tests.dependencies.ONOSSetup import ONOSSetup
+            main.testSetUp = ONOSSetup()
+        except Exception:
+            main.log.error( "ONOSSetup not found. exiting the test" )
+            main.exit()
+
+        main.testSetUp.envSetup()
+        main.apps = main.params[ 'ENV' ][ 'appString' ]
+        cellName = main.params[ 'ENV' ][ 'cellName' ]
+
+
+
+
+        main.step( "Copying config files" )
+        src = os.path.dirname( main.testFile ) + "/network-cfg.json"
+        dst = main.ONOSbench.home + "/tools/package/config/network-cfg.json"
+        status = main.ONOSbench.scp( main.ONOSbench, src, dst, direction="to" )
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=status,
+                                 onpass="Copy config file succeeded",
+                                 onfail="Copy config file failed" )
+        main.testSetUp.ONOSSetUp( main.Mininet, cellName=cellName )
+
+        main.step( "Checking if ONOS CLI is ready for issuing commands" )
+        for i in range( 10 ):
+            ready = True
+            for cli in main.CLIs:
+                output = cli.summary()
+                if not output:
+                    ready = False
+            if ready:
+                break
+            time.sleep( 30 )
+        utilities.assert_equals( expect=True, actual=ready,
+                                 onpass="ONOS summary command succeded",
+                                 onfail="ONOS summary command failed" )
+
+        if not ready:
+            main.log.error( "ONOS startup failed!" )
+            main.cleanup()
+            main.exit()
+
+    def pToPIntentTest( self, intentExpectedNum ):
+        '''
+        point-to-point intents test for each BGP peer and BGP speaker pair
+        '''
+        import time
+        main.case( "Check point-to-point intents" )
+        main.log.info( "There are %s BGP peers in total "
+                       % main.params[ 'config' ][ 'peerNum' ] )
+        main.step( "Check P2P intents number from ONOS CLI" )
+
+        getIntentsResult = main.ONOScli1.intents( jsonFormat=True )
+        bgpIntentsActualNum = \
+            main.QuaggaCliSpeaker1.extractActualBgpIntentNum( getIntentsResult )
+        bgpIntentsExpectedNum = int( main.params[ 'config' ][ 'peerNum' ] ) * intentExpectedNum
+        if bgpIntentsActualNum != bgpIntentsExpectedNum:
+            time.sleep( int( main.params['timers']['RouteDelivery'] ) )
+            getIntentsResult = main.ONOScli1.intents( jsonFormat=True )
+            bgpIntentsActualNum = \
+                main.QuaggaCliSpeaker1.extractActualBgpIntentNum( getIntentsResult )
+        main.log.info( "bgpIntentsExpected num is:" )
+        main.log.info( bgpIntentsExpectedNum )
+        main.log.info( "bgpIntentsActual num is:" )
+        main.log.info( bgpIntentsActualNum )
+        utilities.assert_equals( expect=bgpIntentsExpectedNum,
+                                 actual=bgpIntentsActualNum,
+                                 onpass="PointToPointIntent Intent Num is correct!",
+                                 onfail="PointToPointIntent Intent Num is wrong!" )
+
+    def routeAndIntentCheck( self, allRoutesExpected, routeIntentsExpectedNum ):
+        '''
+        routes and intents check to all BGP peers
+        '''
+        import time
+        getRoutesResult = main.ONOScli1.routes( jsonFormat=True )
+        allRoutesActual = \
+            main.QuaggaCliSpeaker1.extractActualRoutesMaster( getRoutesResult )
+        allRoutesStrExpected = str( sorted( allRoutesExpected ) )
+        allRoutesStrActual = str( allRoutesActual ).replace( 'u', "" )
+        if allRoutesStrActual != allRoutesStrExpected:
+            time.sleep( int( main.params['timers']['RouteDelivery'] ) )
+            getRoutesResult = main.ONOScli1.routes( jsonFormat=True )
+            allRoutesActual = \
+                main.QuaggaCliSpeaker1.extractActualRoutesMaster( getRoutesResult )
+            allRoutesStrActual = str( allRoutesActual ).replace( 'u', "" )
+
+        main.step( "Check routes installed" )
+        main.log.info( "Routes expected:" )
+        main.log.info( allRoutesStrExpected )
+        main.log.info( "Routes get from ONOS CLI:" )
+        main.log.info( allRoutesStrActual )
+        utilities.assertEquals( \
+            expect=allRoutesStrExpected, actual=allRoutesStrActual,
+            onpass="Routes are correct!",
+            onfail="Routes are wrong!" )
+
+        main.step( "Check M2S intents installed" )
+        getIntentsResult = main.ONOScli1.intents( jsonFormat=True )
+        routeIntentsActualNum = \
+            main.QuaggaCliSpeaker1.extractActualRouteIntentNum( getIntentsResult )
+        if routeIntentsActualNum != routeIntentsExpectedNum:
+            time.sleep( int( main.params['timers']['RouteDelivery'] ) )
+            getIntentsResult = main.ONOScli1.intents( jsonFormat=True )
+            routeIntentsActualNum = \
+                main.QuaggaCliSpeaker1.extractActualRouteIntentNum( getIntentsResult )
+
+        main.log.info( "MultiPointToSinglePoint Intent Num expected is:" )
+        main.log.info( routeIntentsExpectedNum )
+        main.log.info( "MultiPointToSinglePoint Intent NUM Actual is:" )
+        main.log.info( routeIntentsActualNum )
+        utilities.assertEquals( \
+            expect=routeIntentsExpectedNum,
+            actual=routeIntentsActualNum,
+            onpass="MultiPointToSinglePoint Intent Num is correct!",
+            onfail="MultiPointToSinglePoint Intent Num is wrong!" )
+
+        main.step( "Check whether all flow status are ADDED" )
+        flowCheck = utilities.retry( main.ONOScli1.checkFlowsState,
+                                     main.FALSE,
+                                     kwargs={'isPENDING':False},
+                                     attempts=10 )
+        utilities.assertEquals( \
+            expect=main.TRUE,
+            actual=flowCheck,
+            onpass="Flow status is correct!",
+            onfail="Flow status is wrong!" )
+
+    def linkUpDownCheck( self, link1Peer, link2Peer, link3Peer,
+                         link1RouteNum, link1IntentNum,
+                         link2RouteNum, link2IntentNum,
+                         link3RouteNum, link3IntentNum,
+                         speakers, hosts, upOrDown ):
+        '''
+        Cut/Recover links to peers one by one, check routes/intents
+        upOrDown - "up" or "down"
+        '''
+        import time
+        main.case( "Bring " + upOrDown + " links and check routes/intents" )
+        main.step( "Bring " + upOrDown + " the link between sw32 and " + link1Peer )
+        linkResult1 = main.Mininet.link( END1="sw32", END2=link1Peer,
+                                         OPTION=upOrDown )
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=linkResult1,
+                                 onpass="Bring down link succeeded!",
+                                 onfail="Bring down link failed!" )
+
+        if linkResult1 == main.TRUE:
+            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
+            main.Functions.checkRouteNum( main, link1RouteNum )
+            main.Functions.checkM2SintentNum( main, link1IntentNum )
+        else:
+            main.log.error( "Bring " + upOrDown + " link failed!" )
+            main.cleanup()
+            main.exit()
+
+        main.step( "Bring " + upOrDown + " the link between sw8 and " + link2Peer )
+        linkResult2 = main.Mininet.link( END1="sw8", END2=link2Peer,
+                                         OPTION=upOrDown )
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=linkResult2,
+                                 onpass="Bring " + upOrDown + " link succeeded!",
+                                 onfail="Bring " + upOrDown + " link failed!" )
+        if linkResult2 == main.TRUE:
+            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
+            main.Functions.checkRouteNum( main, link2RouteNum )
+            main.Functions.checkM2SintentNum( main, link2IntentNum )
+        else:
+            main.log.error( "Bring " + upOrDown + " link failed!" )
+            main.cleanup()
+            main.exit()
+
+        main.step( "Bring " + upOrDown + " the link between sw28 and "+ link3Peer )
+        linkResult3 = main.Mininet.link( END1="sw28", END2=link3Peer,
+                                         OPTION=upOrDown )
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=linkResult3,
+                                 onpass="Bring " + upOrDown + " link succeeded!",
+                                 onfail="Bring " + upOrDown + " link failed!" )
+        if linkResult3 == main.TRUE:
+            time.sleep( int( main.params[ 'timers' ][ 'RouteDelivery' ] ) )
+            main.Functions.checkRouteNum( main, link3RouteNum )
+            main.Functions.checkM2SintentNum( main, link3IntentNum )
+        else:
+            main.log.error( "Bring " + upOrDown + " link failed!" )
+            main.cleanup()
+            main.exit()
+
+        main.step( "Check whether all flow status are ADDED" )
+        flowCheck = utilities.retry( main.ONOScli1.checkFlowsState,
+                                     main.FALSE,
+                                     kwargs={'isPENDING':False},
+                                     attempts=10 )
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=flowCheck,
+                                 onpass="Flow status is correct!",
+                                 onfail="Flow status is wrong!" )
+
+        # Ping test
+        main.Functions.pingSpeakerToPeer( main, speakers=[ speakers ],
+                       peers=[ link1Peer, link2Peer, link3Peer ],
+                       expectAllSuccess=False )
+        main.Functions.pingHostToHost( main,
+                        hosts=hosts,
+                        expectAllSuccess=False )
\ No newline at end of file
diff --git a/TestON/tests/dependencies/ONOSSetup.py b/TestON/tests/dependencies/ONOSSetup.py
new file mode 100644
index 0000000..70fe3c2
--- /dev/null
+++ b/TestON/tests/dependencies/ONOSSetup.py
@@ -0,0 +1,321 @@
+
+import time
+import re
+import imp
+
+class ONOSSetup:
+    main = None
+    def __init__( self ):
+        self.default = ''
+    def envSetupDescription ( self ):
+        main.case( "Constructing test variables and building ONOS package" )
+        main.step( "Constructing test variables" )
+        main.caseExplanation = "For loading from params file, and pull" + \
+                               " and build the latest ONOS package"
+        main.testOnDirectory = re.sub( "(/tests)$", "", main.testDir )
+
+    def gitPulling( self ):
+        main.case( "Pull onos branch and build onos on Teststation." )
+        gitPull = main.params[ 'GIT' ][ 'pull' ]
+        gitBranch = main.params[ 'GIT' ][ 'branch' ]
+        if gitPull == 'True':
+            main.step( "Git Checkout ONOS branch: " + gitBranch )
+            stepResult = main.ONOSbench.gitCheckout( branch=gitBranch )
+            utilities.assert_equals( expect=main.TRUE,
+                                     actual=stepResult,
+                                     onpass="Successfully checkout onos branch.",
+                                     onfail="Failed to checkout onos branch. Exiting test..." )
+            if not stepResult: main.exit()
+
+            main.step( "Git Pull on ONOS branch:" + gitBranch )
+            stepResult = main.ONOSbench.gitPull()
+            utilities.assert_equals( expect=main.TRUE,
+                                     actual=stepResult,
+                                     onpass="Successfully pull onos. ",
+                                     onfail="Failed to pull onos. Exiting test ..." )
+            if not stepResult: main.exit()
+
+        else:
+            main.log.info( "Skipped git checkout and pull as they are disabled in params file" )
+
+        return main.TRUE
+
+    def setRest( self, hasRest, i ):
+        if hasRest:
+            main.RESTs.append( getattr( main, "ONOSrest" + str( i ) ) )
+
+    def setNode( self, hasNode, i ):
+        if hasNode:
+            main.nodes.append( getattr( main, 'ONOS' + str(i)) )
+
+    def setCli( self, hasCli, i ):
+        if hasCli:
+            main.CLIs.append( getattr ( main, "ONOScli" + str( i ) ) )
+
+    def getNumNode( self, hasCli, hasNode, hasRest ):
+        if hasCli:
+            return len( main.CLIs )
+        if hasNode:
+            return len( main.nodes )
+        if hasRest:
+            return len( main.RESTs )
+
+    def envSetup ( self, hasMultiNodeRounds=False, hasRest=False, hasNode=False,
+                   hasCli=True, specificIp="", includeGitPull=True, makeMaxNodes=True ):
+        if includeGitPull :
+            self.gitPulling()
+        if main.ONOSbench.maxNodes:
+            main.maxNodes = int( main.ONOSbench.maxNodes )
+        else:
+            main.maxNodes = 0
+        main.cellData = {}  # For creating cell file
+        if hasCli:
+            main.CLIs = []
+        if hasRest:
+            main.RESTs = []
+        if hasNode:
+            main.nodes = []
+        main.ONOSip = []  # List of IPs of active ONOS nodes. CASE 2
+
+        if specificIp == "":
+            if makeMaxNodes:
+                main.ONOSip = main.ONOSbench.getOnosIps()
+        else:
+            main.ONOSip.append( specificIp )
+
+        # Assigning ONOS cli handles to a list
+        try:
+            for i in range( 1, ( main.maxNodes if makeMaxNodes else main.numCtrls ) + 1 ):
+                self.setCli( hasCli, i )
+                self.setRest( hasRest, i )
+                self.setNode( hasNode, i )
+                if not makeMaxNodes:
+                    main.ONOSip.append( main.ONOSbench.getOnosIps()[ i - 1 ] )
+        except AttributeError:
+            numNode = self.getNumNode( hasCli, hasNode, hasRest )
+            main.log.warn( "A " + str( main.maxNodes ) + " node cluster " +
+                          "was defined in env variables, but only " +
+                          str( numNode ) +
+                          " nodes were defined in the .topo file. " +
+                          "Using " + str( numNode ) +
+                          " nodes for the test." )
+            main.maxNodes = numNode
+
+        main.log.debug( "Found ONOS ips: {}".format( main.ONOSip ) )
+        if ( not hasCli or main.CLIs ) and ( not hasRest or main.RESTs )\
+                and ( not hasNode or main.nodes ):
+            return main.TRUE
+        else:
+            main.log.error( "Did not properly created list of ONOS CLI handle" )
+            return main.FALSE
+
+    def envSetupException ( self, e ):
+        main.log.exception( e )
+        main.cleanup()
+        main.exit()
+
+    def evnSetupConclusion ( self, stepResult ):
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully construct " +
+                                        "test variables ",
+                                 onfail="Failed to construct test variables" )
+
+        main.commit = main.ONOSbench.getVersion( report=True )
+
+    def getNumCtrls( self, hasMultiNodeRounds ):
+        if hasMultiNodeRounds:
+            try:
+                main.cycle
+            except Exception:
+                main.cycle = 0
+            main.cycle += 1
+            # main.scale[ 0 ] determines the current number of ONOS controller
+            main.numCtrls = int( main.scale.pop( 0 ) )
+        else:
+            main.numCtrls = main.maxNodes
+
+    def killingAllOnos( self, killRemoveMax, stopOnos ):
+        # kill off all onos processes
+        main.log.info( "Safety check, killing all ONOS processes" +
+                      " before initiating environment setup" )
+
+        for i in range( main.maxNodes if killRemoveMax else main.numCtrls ):
+            if stopOnos:
+                main.ONOSbench.onosStop( main.ONOSip[ i ] )
+            main.ONOSbench.onosKill( main.ONOSip[ i ] )
+
+    def createApplyCell( self, newCell, cellName, Mininet, useSSH ):
+        if newCell:
+            tempOnosIp = []
+            for i in range( main.numCtrls ):
+                tempOnosIp.append( main.ONOSip[i] )
+
+            main.ONOSbench.createCellFile( main.ONOSbench.ip_address,
+                                           cellName,
+                                           Mininet if isinstance( Mininet, str ) else
+                                           Mininet.ip_address,
+                                           main.apps,
+                                           tempOnosIp,
+                                           main.ONOScli1.karafUser,
+                                           useSSH=useSSH )
+        main.step( "Apply cell to environment" )
+        cellResult = main.ONOSbench.setCell( cellName )
+        verifyResult = main.ONOSbench.verifyCell()
+        stepResult = cellResult and verifyResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully applied cell to " +
+                                       "environment",
+                                 onfail="Failed to apply cell to environment " )
+        return stepResult
+
+    def uninstallOnos( self, killRemoveMax ):
+        main.step( "Uninstalling ONOS package" )
+        onosUninstallResult = main.TRUE
+        for i in range( main.maxNodes if killRemoveMax else main.numCtrls ):
+            onosUninstallResult = onosUninstallResult and \
+                                  main.ONOSbench.onosUninstall( nodeIp=main.ONOSip[ i ] )
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=onosUninstallResult,
+                                 onpass="Successfully uninstalled ONOS package",
+                                 onfail="Failed to uninstall ONOS package" )
+        return onosUninstallResult
+
+    def buildOnos( self ):
+        main.step( "Creating ONOS package" )
+        packageResult = main.ONOSbench.buckBuild()
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=packageResult,
+                                 onpass="Successfully created ONOS package",
+                                 onfail="Failed to create ONOS package" )
+        return packageResult
+
+    def installOnos( self, installMax ):
+        main.step( "Installing ONOS package" )
+        onosInstallResult = main.TRUE
+
+        for i in range( main.ONOSbench.maxNodes if installMax else main.numCtrls ):
+            options = "-f"
+            if installMax and i >= main.numCtrls:
+                options = "-nf"
+            onosInstallResult = onosInstallResult and \
+                                main.ONOSbench.onosInstall( node=main.ONOSip[ i ], options=options )
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=onosInstallResult,
+                                 onpass="Successfully installed ONOS package",
+                                 onfail="Failed to install ONOS package" )
+        if not onosInstallResult:
+            main.cleanup()
+            main.exit()
+        return onosInstallResult
+
+    def setupSsh( self ):
+        main.step( "Set up ONOS secure SSH" )
+        secureSshResult = main.TRUE
+        for i in range( main.numCtrls ):
+            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=main.ONOSip[ i ] )
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=secureSshResult,
+                                 onpass="Test step PASS",
+                                 onfail="Test step FAIL" )
+        return secureSshResult
+
+    def checkOnosService( self ):
+        stopResult = main.TRUE
+        startResult = main.TRUE
+        onosIsUp = main.TRUE
+        main.step( "Starting ONOS service" )
+        for i in range( main.numCtrls ):
+            onosIsUp = onosIsUp and main.ONOSbench.isup( main.ONOSip[ i ] )
+            if onosIsUp == main.TRUE:
+                main.log.report( "ONOS instance {0} is up and ready".format( i + 1 ) )
+            else:
+                main.log.report( "ONOS instance {0} may not be up, stop and ".format( i + 1 ) +
+                                 "start ONOS again " )
+                stopResult = stopResult and main.ONOSbench.onosStop( main.ONOSip[ i ] )
+                startResult = startResult and main.ONOSbench.onosStart( main.ONOSip[ i ] )
+                if not startResult or stopResult:
+                    main.log.report( "ONOS instance {0} did not start correctly.".format( i + 1 ) )
+        stepResult = onosIsUp and stopResult and startResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="ONOS service is ready on all nodes",
+                                 onfail="ONOS service did not start properly on all nodes" )
+        return stepResult
+
+    def startOnosClis( self ):
+        startCliResult = main.TRUE
+        main.step( "Starting ONOS CLI sessions" )
+        pool = []
+        main.threadID = 0
+        for i in range( main.numCtrls ):
+            t = main.Thread( target=main.CLIs[ i ].startOnosCli,
+                            threadID=main.threadID,
+                            name="startOnosCli-" + str( i ),
+                            args=[ main.ONOSip[ i ] ] )
+            pool.append( t )
+            t.start()
+            main.threadID = main.threadID + 1
+        for t in pool:
+            t.join()
+            startCliResult = startCliResult and t.result
+        if not startCliResult:
+            main.log.info( "ONOS CLI did not start up properly" )
+            main.cleanup()
+            main.exit()
+        else:
+            main.log.info( "Successful CLI startup" )
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=startCliResult,
+                                 onpass="Successfully start ONOS cli",
+                                 onfail="Failed to start ONOS cli" )
+        return startCliResult
+
+    def ONOSSetUp( self, Mininet, hasMultiNodeRounds=False, hasCli=True, newCell=True,
+                   cellName="temp", removeLog=False, extraApply=None, arg=None, extraClean=None,
+                   skipPack=False, installMax=False, useSSH=True, killRemoveMax=True,
+                   CtrlsSet=True, stopOnos=False ):
+        if CtrlsSet:
+            self.getNumCtrls( hasMultiNodeRounds )
+
+        main.case( "Starting up " + str( main.numCtrls ) +
+                  " node(s) ONOS cluster" )
+        main.caseExplanation = "Set up ONOS with " + str( main.numCtrls ) + \
+                               " node(s) ONOS cluster"
+        self.killingAllOnos( killRemoveMax, stopOnos )
+
+        main.log.info( "NODE COUNT = " + str( main.numCtrls ) )
+        cellResult = True
+        packageResult = True
+        onosUninstallResult = True
+        onosCliResult = True
+        if not skipPack:
+            cellResult = self.createApplyCell( newCell, cellName, Mininet, useSSH )
+
+            if removeLog:
+                main.log.info("Removing raft logs")
+                main.ONOSbench.onosRemoveRaftLogs()
+
+            onosUninstallResult = self.uninstallOnos( killRemoveMax )
+
+            if extraApply is not None:
+                extraApply( metadataMethod=arg ) if arg is not None else extraApply()
+
+            packageResult = self.buildOnos()
+
+        onosInstallResult = self.installOnos( installMax )
+
+        if extraClean is not None:
+            extraClean()
+        secureSshResult = True
+        if useSSH:
+            secureSshResult = self.setupSsh()
+
+        onosServiceResult = self.checkOnosService()
+
+        if hasCli:
+            onosCliResult = self.startOnosClis()
+
+        return cellResult and packageResult and onosUninstallResult and \
+               onosInstallResult and secureSshResult and onosServiceResult and onosCliResult
\ No newline at end of file
diff --git a/TestON/tests/dependencies/__init__.py b/TestON/tests/dependencies/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/TestON/tests/dependencies/__init__.py
diff --git a/TestON/tests/dependencies/topology.py b/TestON/tests/dependencies/topology.py
new file mode 100644
index 0000000..f9ce3ff
--- /dev/null
+++ b/TestON/tests/dependencies/topology.py
@@ -0,0 +1,237 @@
+import time
+import re
+import imp
+import json
+class Topology:
+
+    def __init__( self ):
+        self.default = ''
+    """
+        These functions can be used for topology comparisons
+    """
+    def getAllDevices( self, numNode, needRetry, kwargs={} ):
+        """
+            Return a list containing the devices output from each ONOS node
+        """
+        devices = []
+        threads = []
+        for i in ( range ( numNode ) if isinstance( numNode, int ) else numNode ):
+            t = main.Thread( target=utilities.retry if needRetry else main.CLIs[ i ].devices,
+                             name="devices-" + str( i ),
+                             args=[main.CLIs[ i ].devices, [ None ] ] if needRetry else [],
+                             kwargs=kwargs )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            devices.append( t.result )
+        return devices
+
+    def getAllHosts( self, numNode, needRetry, kwargs={}, inJson=False ):
+        """
+            Return a list containing the hosts output from each ONOS node
+        """
+        hosts = []
+        ipResult = main.TRUE
+        threads = []
+        for i in ( range ( numNode ) if isinstance( numNode, int ) else numNode ):
+            t = main.Thread( target=utilities.retry if needRetry else main.CLIs[ i ].hosts,
+                             name="hosts-" + str( i ),
+                             args=[main.CLIs[ i ].hosts, [ None ] ] if needRetry else [],
+                             kwargs=kwargs )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            if inJson:
+                try:
+                    hosts.append( json.loads( t.result ) )
+                except ( ValueError, TypeError ):
+                    main.log.exception( "Error parsing hosts results" )
+                    main.log.error( repr( t.result ) )
+                    hosts.append( None )
+            else:
+                hosts.append( t.result )
+        return hosts
+
+    def getAllPorts( self, numNode, needRetry, kwargs={} ):
+        """
+            Return a list containing the ports output from each ONOS node
+        """
+        ports = []
+        threads = []
+        for i in ( range ( numNode ) if isinstance( numNode, int ) else numNode ):
+            t = main.Thread( target=utilities.retry if needRetry else main.CLIs[ i ].ports,
+                             name="ports-" + str( i ),
+                             args=[ main.CLIs[ i ].ports, [ None ] ] if needRetry else [],
+                             kwargs=kwargs )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            ports.append( t.result )
+        return ports
+
+    def getAllLinks( self, numNode, needRetry, kwargs={} ):
+        """
+            Return a list containing the links output from each ONOS node
+        """
+        links = []
+        threads = []
+        print numNode
+        for i in ( range ( numNode ) if isinstance( numNode, int ) else numNode ):
+            t = main.Thread( target=utilities.retry if needRetry else main.CLIs[ i ].links,
+                             name="links-" + str( i ),
+                             args=[main.CLIs[ i ].links, [ None ] ] if needRetry else [],
+                             kwargs=kwargs )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            links.append( t.result )
+        print links
+        return links
+
+    def getAllClusters( self, numNode, needRetry, kwargs={} ):
+        """
+            Return a list containing the clusters output from each ONOS node
+        """
+        clusters = []
+        threads = []
+        for i in ( range ( numNode ) if isinstance( numNode, int ) else numNode ):
+            t = main.Thread( target=utilities.retry if needRetry else main.CLIs[ i ].clusters,
+                             name="clusters-" + str( i ),
+                             args=[main.CLIs[ i ].clusters, [ None ] ] if needRetry else [],
+                             kwargs=kwargs )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            clusters.append( t.result )
+        return clusters
+
+    def compareDevicePort( self, Mininet, controller, mnSwitches, devices, ports ):
+        if devices[ controller ] and ports[ controller ] and \
+                        "Error" not in devices[ controller ] and \
+                        "Error" not in ports[ controller ]:
+            try:
+                currentDevicesResult = Mininet.compareSwitches(
+                    mnSwitches,
+                    json.loads( devices[ controller ] ),
+                    json.loads( ports[ controller ] ) )
+            except(TypeError, ValueError):
+                main.log.error(
+                    "Could not load json: {0} or {1}".format( str( devices[ controller ] )
+                                                            , str( ports[ controller ] ) ) )
+                currentDevicesResult = main.FALSE
+        else:
+            currentDevicesResult = main.FALSE
+        return currentDevicesResult
+
+    def compareBase( self, compareElem, controller, compareF, compareArg ):
+        if compareElem[ controller ] and "Error" not in compareElem[ controller ]:
+            try:
+                if isinstance( compareArg, list ):
+                    compareArg.append( json.loads( compareElem[ controller ] ) )
+                else:
+                    compareArg = [compareArg, json.loads( compareElem[ controller ] ) ]
+
+                currentCompareResult = compareF( *compareArg )
+            except(TypeError, ValueError):
+                main.log.error(
+                    "Could not load json: {0} or {1}".format( str( compareElem[ controller ] ) ) )
+                currentCompareResult = main.FALSE
+        else:
+            currentCompareResult = main.FALSE
+
+        return currentCompareResult
+
+    def compareTopos( self, Mininet, attempts=1 ):
+
+        main.case( "Compare ONOS Topology view to Mininet topology" )
+        main.caseExplanation = "Compare topology elements between Mininet" +\
+                                " and ONOS"
+        main.log.info( "Gathering topology information from Mininet" )
+        devicesResults = main.FALSE  # Overall Boolean for device correctness
+        linksResults = main.FALSE  # Overall Boolean for link correctness
+        hostsResults = main.FALSE  # Overall Boolean for host correctness
+        deviceFails = []  # Nodes where devices are incorrect
+        linkFails = []  # Nodes where links are incorrect
+        hostFails = []  # Nodes where hosts are incorrect
+
+        mnSwitches = Mininet.getSwitches()
+        mnLinks = Mininet.getLinks()
+        mnHosts = Mininet.getHosts()
+
+        main.step( "Comparing Mininet topology to ONOS topology" )
+
+        while ( attempts >= 0 ) and\
+                ( not devicesResults or not linksResults or not hostsResults ):
+            main.log.info( "Sleeping {} seconds".format( 2 ) )
+            time.sleep( 2 )
+            if not devicesResults:
+                devices = self.getAllDevices( main.numCtrls, False )
+                ports = self.getAllPorts( main.numCtrls, False )
+                devicesResults = main.TRUE
+                deviceFails = []  # Reset for each failed attempt
+            if not linksResults:
+                links = self.getAllLinks( main.numCtrls, False )
+                linksResults = main.TRUE
+                linkFails = []  # Reset for each failed attempt
+            if not hostsResults:
+                hosts = self.getAllHosts( main.numCtrls, False )
+                hostsResults = main.TRUE
+                hostFails = []  # Reset for each failed attempt
+
+            #  Check for matching topology on each node
+            for controller in range( main.numCtrls ):
+                controllerStr = str( controller + 1 )  # ONOS node number
+                # Compare Devices
+                currentDevicesResult = self.compareDevicePort( Mininet, controller,
+                                                          mnSwitches,
+                                                          devices, ports )
+                if not currentDevicesResult:
+                    deviceFails.append( controllerStr )
+                devicesResults = devicesResults and currentDevicesResult
+                # Compare Links
+                currentLinksResult = self.compareBase( links, controller,
+                                                        Mininet.compareLinks,
+                                                        [ mnSwitches, mnLinks ] )
+                if not currentLinksResult:
+                    linkFails.append( controllerStr )
+                linksResults = linksResults and currentLinksResult
+                # Compare Hosts
+                currentHostsResult = self.compareBase( hosts, controller,
+                                                           Mininet.compareHosts,
+                                                           mnHosts )
+                if not currentHostsResult:
+                    hostFails.append( controllerStr )
+                hostsResults = hostsResults and currentHostsResult
+            # Decrement Attempts Remaining
+            attempts -= 1
+
+        utilities.assert_equals( expect=[],
+                                 actual=deviceFails,
+                                 onpass="ONOS correctly discovered all devices",
+                                 onfail="ONOS incorrectly discovered devices on nodes: " +
+                                 str( deviceFails ) )
+        utilities.assert_equals( expect=[],
+                                 actual=linkFails,
+                                 onpass="ONOS correctly discovered all links",
+                                 onfail="ONOS incorrectly discovered links on nodes: " +
+                                 str( linkFails ) )
+        utilities.assert_equals( expect=[],
+                                 actual=hostFails,
+                                 onpass="ONOS correctly discovered all hosts",
+                                 onfail="ONOS incorrectly discovered hosts on nodes: " +
+                                 str( hostFails ) )
+        topoResults = hostsResults and linksResults and devicesResults
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=topoResults,
+                                 onpass="ONOS correctly discovered the topology",
+                                 onfail="ONOS incorrectly discovered the topology" )
diff --git a/TestON/tests/dependencies/utils.py b/TestON/tests/dependencies/utils.py
new file mode 100644
index 0000000..d82ae04
--- /dev/null
+++ b/TestON/tests/dependencies/utils.py
@@ -0,0 +1,50 @@
+class Utils:
+    def __init__( self ):
+        self.default = ''
+
+    def mininetCleanIntro( self ):
+        main.log.report( "Stop Mininet" )
+
+        main.case( "Stop Mininet" )
+        main.caseExplanation = "Stopping the current mininet to start up fresh"
+
+    def mininetCleanup( self, Mininet, timeout=5 ):
+        main.step( "Stopping Mininet" )
+        topoResult = Mininet.stopNet( timeout=timeout )
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=topoResult,
+                                 onpass="Successfully stopped mininet",
+                                 onfail="Failed to stopped mininet" )
+        return topoResult
+
+    def copyKarafLog( self ):
+        """
+            Copy the karaf.log files after each testcase cycle
+        """
+        main.log.report( "Copy karaf logs" )
+        main.case( "Copy karaf logs" )
+        main.caseExplanation = "Copying the karaf logs to preserve them through" +\
+                               "reinstalling ONOS"
+        main.step( "Copying karaf logs" )
+        stepResult = main.TRUE
+        scpResult = main.TRUE
+        copyResult = main.TRUE
+        for i in range( main.numCtrls ):
+            main.node = main.CLIs[ i ]
+            ip = main.ONOSip[ i ]
+            main.node.ip_address = ip
+            scpResult = scpResult and main.ONOSbench.scp( main.node,
+                                                          "/opt/onos/log/karaf.log",
+                                                          "/tmp/karaf.log",
+                                                          direction="from" )
+            copyResult = copyResult and main.ONOSbench.cpLogsToDir( "/tmp/karaf.log", main.logdir,
+                                                                    copyFileName=( "karaf.log.node{0}.cycle{1}".format(
+                                                                        str( i + 1 ), str( main.cycle ) ) ) )
+            if scpResult and copyResult:
+                stepResult = main.TRUE and stepResult
+            else:
+                stepResult = main.FALSE and stepResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully copied remote ONOS logs",
+                                 onfail="Failed to copy remote ONOS logs" )
\ No newline at end of file