Merge branch 'master' of https://github.com/OPENNETWORKINGLAB/ONLabTest
diff --git a/TestON/drivers/common/cli/onosclidriver.py b/TestON/drivers/common/cli/onosclidriver.py
index a997933..ab37367 100644
--- a/TestON/drivers/common/cli/onosclidriver.py
+++ b/TestON/drivers/common/cli/onosclidriver.py
@@ -2357,8 +2357,6 @@
             "UNINSTALLED" - If app is not installed
             None - on error
         """
-        # FIXME also use app-ids to see if an uninstalled app is registered?
-        # FIXME "UNREGISTERED"?
         try:
             if not isinstance( appName, types.StringType ):
                 main.log.error( self.name + ".appStatus(): appName must be" +
@@ -2443,7 +2441,7 @@
                                 str( output ) )
             # NOTE: we may need to add more checks here
             # else: Command was successful
-            main.log.debug( "app response: " + repr( output ) )
+            #main.log.debug( "app response: " + repr( output ) )
             return main.TRUE
         except TypeError:
             main.log.exception( self.name + ": Object not as expected" )
@@ -2483,6 +2481,8 @@
                         if status == "ACTIVE":
                             return main.TRUE
                         else:
+                            main.log.debug( "The state of application " +
+                                            appName + " is " + status )
                             time.sleep( 1 )
                     return main.FALSE
                 else:  # not 'check' or command didn't succeed
@@ -2688,8 +2688,8 @@
                     result = main.FALSE
                 # get the entry in ids that has the same appID
                 current = filter(lambda item: item[ 'id' ] == appID, ids)
-                main.log.debug( "Comparing " + str( app ) + " to " +
-                                str( current ) )
+                # main.log.debug( "Comparing " + str( app ) + " to " +
+                #                 str( current ) )
                 if not current:  # if ids doesn't have this id
                     result = main.FALSE
                     main.log.error( "'app-ids' does not have the ID for " +
diff --git a/TestON/tests/HATestClusterRestart/HATestClusterRestart.py b/TestON/tests/HATestClusterRestart/HATestClusterRestart.py
index 0bd05ad..1205b11 100644
--- a/TestON/tests/HATestClusterRestart/HATestClusterRestart.py
+++ b/TestON/tests/HATestClusterRestart/HATestClusterRestart.py
@@ -162,9 +162,28 @@
             intf=main.params[ 'MNtcpdump' ][ 'intf' ],
             port=main.params[ 'MNtcpdump' ][ 'port' ] )
 
+        appCheck = main.TRUE
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].appToIDCheck,
+                             name="appToIDCheck-" + str( i ),
+                             args=[] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            appCheck = appCheck and t.result
+        utilities.assert_equals( expect=main.TRUE, actual=appCheck,
+                                 onpass="App Ids seem to be correct",
+                                 onfail="Something is wrong with app Ids" )
+        if appCheck != main.TRUE:
+            main.log.warn( CLIs[0].apps() )
+            main.log.warn( CLIs[0].appIDs() )
+
         case1Result = ( cleanInstallResult and packageResult and
                         cellResult and verifyResult and onosInstallResult
-                        and onosIsupResult and cliResults )
+                        and onosIsupResult and cliResults and appCheck)
 
         utilities.assert_equals( expect=main.TRUE, actual=case1Result,
                                  onpass="Test startup successful",
@@ -221,6 +240,9 @@
                 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
         if mastershipCheck == main.TRUE:
             main.log.report( "Switch mastership assigned correctly" )
@@ -229,138 +251,62 @@
             actual=mastershipCheck,
             onpass="Switch mastership assigned correctly",
             onfail="Switches not assigned correctly to controllers" )
-        #FIXME: turning off because of ONOS-1286
         # Manually assign mastership to the controller we want
         roleCall = main.TRUE
         roleCheck = main.TRUE
         try:
-            # Assign switch
-            ip = nodes[ 0 ].ip_address  # ONOS1
-            deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
-            assert deviceId, "No device id for s1 in ONOS"
-            roleCall = roleCall and main.ONOScli1.deviceRole(
-                deviceId,
-                ip )
-            # Check assignment
-            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-
-            # Assign switch
-            deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
-            assert deviceId, "No device id for s28 in ONOS"
-            roleCall = roleCall and main.ONOScli1.deviceRole(
-                deviceId,
-                ip )
-            # Check assignment
-            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-
-            ip = nodes[ 1 ].ip_address  # ONOS2
-            # Assign switch
-            deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
-            assert deviceId, "No device id for s2 in ONOS"
-            roleCall = roleCall and main.ONOScli1.deviceRole(
-                deviceId,
-                ip )
-            # Check assignment
-            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-
-            # Assign switch
-            deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
-            assert deviceId, "No device id for s3 in ONOS"
-            roleCall = roleCall and main.ONOScli1.deviceRole(
-                deviceId,
-                ip )
-            # Check assignment
-            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-
-            ip = nodes[ 2 ].ip_address  # ONOS3
-            # Assign switch
-            deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
-            assert deviceId, "No device id for s5 in ONOS"
-            roleCall = roleCall and main.ONOScli1.deviceRole(
-                deviceId,
-                ip )
-            # Check assignment
-            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-
-            # Assign switch
-            deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
-            assert deviceId, "No device id for s6 in ONOS"
-            roleCall = roleCall and main.ONOScli1.deviceRole(
-                deviceId,
-                ip )
-            # Check assignment
-            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-
-            ip = nodes[ 3 ].ip_address  # ONOS4
-            # Assign switch
-            deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
-            assert deviceId, "No device id for s4 in ONOS"
-            roleCall = roleCall and main.ONOScli1.deviceRole(
-                deviceId,
-                ip )
-            # Check assignment
-            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-
-            ip = nodes[ 4 ].ip_address  # ONOS5
-            for i in range( 8, 18 ):
-                dpid = '3' + str( i ).zfill( 3 )
-                deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
-                assert deviceId, "No device id for s%i in ONOS" % i
-                roleCall = roleCall and main.ONOScli1.deviceRole(
-                    deviceId,
-                    ip )
+            for i in range( 1, 29 ):  # switches 1 through 28
+                # set up correct variables:
+                if i == 1:
+                    ip = nodes[ 0 ].ip_address  # ONOS1
+                    deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
+                elif i == 2:
+                    ip = nodes[ 1 ].ip_address  # ONOS2
+                    deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
+                elif i == 3:
+                    ip = nodes[ 1 ].ip_address  # ONOS2
+                    deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
+                elif i == 4:
+                    ip = nodes[ 3 ].ip_address  # ONOS4
+                    deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
+                elif i == 5:
+                    ip = nodes[ 2 ].ip_address  # ONOS3
+                    deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
+                elif i == 6:
+                    ip = nodes[ 2 ].ip_address  # ONOS3
+                    deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
+                elif i == 7:
+                    ip = nodes[ 5 ].ip_address  # ONOS6
+                    deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
+                elif i >= 8 and i <= 17:
+                    ip = nodes[ 4 ].ip_address  # ONOS5
+                    dpid = '3' + str( i ).zfill( 3 )
+                    deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
+                elif i >= 18 and i <= 27:
+                    ip = nodes[ 6 ].ip_address  # ONOS7
+                    dpid = '6' + str( i ).zfill( 3 )
+                    deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
+                elif i == 28:
+                    ip = nodes[ 0 ].ip_address  # ONOS1
+                    deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
+                else:
+                    main.log.error( "You didn't write an else statement for " +
+                                    "switch s" + str( i ) )
+                # Assign switch
+                assert deviceId, "No device id for s" + str( i ) + " in ONOS"
+                # TODO: make this controller dynamic
+                roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
+                                                                  ip )
                 # Check assignment
-                if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+                master =  main.ONOScli1.getRole( deviceId ).get( 'master' )
+                if ip in master:
                     roleCheck = roleCheck and main.TRUE
                 else:
                     roleCheck = roleCheck and main.FALSE
-
-            ip = nodes[ 5 ].ip_address  # ONOS6
-            deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
-            assert deviceId, "No device id for s7 in ONOS"
-            roleCall = roleCall and main.ONOScli1.deviceRole(
-                deviceId,
-                ip )
-            # Check assignment
-            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-
-            ip = nodes[ 6 ].ip_address  # ONOS7
-            for i in range( 18, 28 ):
-                dpid = '6' + str( i ).zfill( 3 )
-                deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
-                assert deviceId, "No device id for s%i in ONOS" % i
-                roleCall = roleCall and main.ONOScli1.deviceRole(
-                    deviceId,
-                    ip )
-                # Check assignment
-                if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-                    roleCheck = roleCheck and main.TRUE
-                else:
-                    roleCheck = roleCheck and main.FALSE
+                    main.log.error( "Error, controller " + ip + " is not" +
+                                    " master " + "of device " +
+                                    str( deviceId ) + ". Master is " +
+                                    repr( master ) + "." )
         except ( AttributeError, AssertionError ):
             main.log.exception( "Something is wrong with ONOS device view" )
             main.log.info( main.ONOScli1.devices() )
@@ -403,18 +349,27 @@
 
         # install onos-app-fwd
         main.log.info( "Install reactive forwarding app" )
-        appResults = main.TRUE
+        appResults = CLIs[0].activateApp( "org.onosproject.fwd" )
+
+        # FIXME: add this to asserts
+        appCheck = main.TRUE
         threads = []
         for i in range( numControllers ):
-            t = main.Thread( target=CLIs[i].featureInstall,
-                             name="featureInstall-" + str( i ),
-                             args=["onos-app-fwd"] )
+            t = main.Thread( target=CLIs[i].appToIDCheck,
+                             name="appToIDCheck-" + str( i ),
+                             args=[] )
             threads.append( t )
             t.start()
 
         for t in threads:
             t.join()
-            appResults = appResults and t.result
+            appCheck = appCheck and t.result
+        utilities.assert_equals( expect=main.TRUE, actual=appCheck,
+                                 onpass="App Ids seem to be correct",
+                                 onfail="Something is wrong with app Ids" )
+        if appCheck != main.TRUE:
+            main.log.warn( CLIs[0].apps() )
+            main.log.warn( CLIs[0].appIDs() )
 
         # REACTIVE FWD test
         pingResult = main.FALSE
@@ -431,17 +386,24 @@
 
         # uninstall onos-app-fwd
         main.log.info( "Uninstall reactive forwarding app" )
+        appResults = appResults and CLIs[0].deactivateApp( "org.onosproject.fwd" )
         threads = []
         for i in range( numControllers ):
-            t = main.Thread( target=CLIs[i].featureUninstall,
-                             name="featureUninstall-" + str( i ),
-                             args=["onos-app-fwd"] )
+            t = main.Thread( target=CLIs[i].appToIDCheck,
+                             name="appToIDCheck-" + str( i ),
+                             args=[] )
             threads.append( t )
             t.start()
 
         for t in threads:
             t.join()
-            appResults = appResults and t.result
+            appCheck = appCheck and t.result
+        utilities.assert_equals( expect=main.TRUE, actual=appCheck,
+                                 onpass="App Ids seem to be correct",
+                                 onfail="Something is wrong with app Ids" )
+        if appCheck != main.TRUE:
+            main.log.warn( CLIs[0].apps() )
+            main.log.warn( CLIs[0].appIDs() )
 
         # timeout for fwd flows
         time.sleep( 11 )
@@ -489,6 +451,8 @@
                 except ( ValueError, TypeError ):
                     main.log.warn( repr( hosts ) )
                 hostResult = main.FALSE
+        # FIXME: DEBUG
+        intentStart = time.time()
         onosIds = main.ONOScli1.getAllIntentsId()
         main.log.info( "Submitted intents: " + str( intentIds ) )
         main.log.info( "Intents in ONOS: " + str( onosIds ) )
@@ -497,6 +461,11 @@
                 pass  # intent submitted is in onos
             else:
                 intentAddResult = False
+        # FIXME: DEBUG
+        if intentAddResult:
+            intentStop = time.time()
+        else:
+            intentStop = None
         # Print the intent states
         intents = main.ONOScli1.intents()
         intentStates = []
@@ -533,12 +502,9 @@
                                            indent=4,
                                            separators=( ',', ': ' ) ) )
                 # check for all intent partitions
-                # check for election
                 topics = []
                 for i in range( 14 ):
                     topics.append( "intent-partition-" + str( i ) )
-                # FIXME: this should only be after we start the app
-                topics.append( "org.onosproject.election" )
                 main.log.debug( topics )
                 ONOStopics = [ j['topic'] for j in parsedLeaders ]
                 for topic in topics:
@@ -587,6 +553,29 @@
             actual=intentAddResult,
             onpass="Pushed host intents to ONOS",
             onfail="Error in pushing host intents to ONOS" )
+        for i in range(100):
+            onosIds = main.ONOScli1.getAllIntentsId()
+            main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
+            main.log.info( "Intents in ONOS: " + str( sorted( onosIds ) ) )
+            if sorted(onosIds) == sorted(intentIds):
+                break
+            else:
+                time.sleep(1)
+        # FIXME: DEBUG
+        if not intentStop:
+            intentStop = time.time()
+        gossipTime = intentStop - intentStart
+        main.log.info( "It took about " + str( gossipTime ) +
+                        " seconds for all intents to appear on ONOS1" )
+        # FIXME: make this time configurable/calculate based off of number of
+        #        nodes and gossip rounds
+        utilities.assert_greater_equals(
+                expect=30, actual=gossipTime,
+                onpass="ECM anti-entropy for intents worked within " +
+                       "expected time",
+                onfail="Intent ECM anti-entropy took too long" )
+        if gossipTime <= 30:
+            intentAddResult = True
 
         if not intentAddResult or "key" in pendingMap:
             import time
@@ -1068,6 +1057,7 @@
             threads.append( t )
             t.start()
 
+        # NOTE: Flows command can take some time to run
         time.sleep(30)
         for t in threads:
             t.join()
@@ -1394,7 +1384,7 @@
         finalAssert = main.TRUE
         finalAssert = ( finalAssert and topoResult and flowCheck
                         and intentCheck and consistentMastership
-                        and rolesNotNull )
+                        and mastershipCheck and rolesNotNull )
         utilities.assert_equals( expect=main.TRUE, actual=finalAssert,
                                  onpass="State check successful",
                                  onfail="State check NOT successful" )
@@ -2024,6 +2014,40 @@
         if topoResult == main.TRUE:
             main.log.report( "ONOS topology view matches Mininet topology" )
 
+        # FIXME: move this to an ONOS state case
+        main.step( "Checking ONOS nodes" )
+        nodesOutput = []
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].nodes,
+                             name="nodes-" + str( i ),
+                             args=[ ] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            nodesOutput.append( t.result )
+        ips = [ node.ip_address for node in nodes ]
+        for i in nodesOutput:
+            try:
+                current = json.loads( i )
+                for node in current:
+                    if node['ip'] in ips:  # node in nodes() output is in cell
+                        if node['state'] == 'ACTIVE':
+                            pass  # as it should be
+                        else:
+                            main.log.error( "Error in ONOS node availability" )
+                            main.log.error(
+                                    json.dumps( current,
+                                                sort_keys=True,
+                                                indent=4,
+                                                separators=( ',', ': ' ) ) )
+                            break
+            except ( ValueError, TypeError ):
+                main.log.error( "Error parsing nodes output" )
+                main.log.warn( repr( i ) )
+
     def CASE9( self, main ):
         """
         Link s3-s28 down
@@ -2265,6 +2289,7 @@
         """
         start election app on all onos nodes
         """
+        import time
         assert numControllers, "numControllers not defined"
         assert main, "main not defined"
         assert utilities.assert_equals, "utilities.assert_equals not defined"
@@ -2272,58 +2297,21 @@
         assert nodes, "nodes not defined"
 
         leaderResult = main.TRUE
-        # install app on onos 1
         main.log.info( "Install leadership election app" )
-        main.ONOScli1.featureInstall( "onos-app-election" )
-        leader = nodes[0].ip_address
-        # wait for election
-        # check for leader
-        leader1 = main.ONOScli1.electionTestLeader()
-        # verify leader is ONOS1
-        if leader1 == leader:
-            # all is well
-            pass
-        elif leader1 is None:
-            # No leader elected
-            main.log.report( "No leader was elected" )
-            leaderResult = main.FALSE
-        elif leader1 == main.FALSE:
-            # error in  response
-            # TODO: add check for "Command not found:" in the driver, this
-            # means the app isn't loaded
-            main.log.report( "Something is wrong with electionTestLeader" +
-                             " function, check the error logs" )
-            leaderResult = main.FALSE
-        else:
-            # error in  response
-            main.log.report(
-                "Unexpected response from electionTestLeader function:'" +
-                str( leader1 ) + "'" )
-            leaderResult = main.FALSE
-
-        # install on other nodes and check for leader.
-        # Leader should be ONOS1 and each app should show the same leader
-        for cli in CLIs[ 1: ]:
-            cli.featureInstall( "onos-app-election" )
-            leaderN = cli.electionTestLeader()
-            # verify leader is ONOS1
-            if leaderN == leader:
-                # all is well
-                pass
-            elif leaderN == main.FALSE:
-                # error in  response
-                # TODO: add check for "Command not found:" in the driver, this
-                # means the app isn't loaded
-                main.log.report( "Something is wrong with " +
-                                 "electionTestLeader function, check the" +
-                                 " error logs" )
+        main.ONOScli1.activateApp( "org.onosproject.election" )
+        leaders = []
+        for cli in CLIs:
+            leader = cli.electionTestLeader()
+            if leader is None or leader == main.FALSE:
+                main.log.report( cli.name + ": Leader for the election app " +
+                                 "should be an ONOS node, instead got '" +
+                                 str( leader ) + "'" )
                 leaderResult = main.FALSE
-            elif leader != leaderN:
-                leaderResult = main.FALSE
-                main.log.report( cli.name + " sees " + str( leaderN ) +
-                                 " as the leader of the election app. Leader" +
-                                 " should be " +
-                                 str( leader ) )
+            leaders.append( leader )
+        if len( set( leaders ) ) != 1:
+            leaderResult = main.FALSE
+            main.log.error( "Results of electionTestLeader is order of CLIs:" +
+                            str( leaders ) )
         if leaderResult:
             main.log.report( "Leadership election tests passed( consistent " +
                              "view of leader across listeners and a leader " +
@@ -2350,7 +2338,7 @@
         main.case( description )
         main.step( "Find current leader and withdraw" )
         leader = main.ONOScli1.electionTestLeader()
-        # TODO: do some sanity checking on leader before using it
+        # do some sanity checking on leader before using it
         withdrawResult = main.FALSE
         if leader is None or leader == main.FALSE:
             main.log.report(
@@ -2362,7 +2350,7 @@
             if leader == nodes[ i ].ip_address:
                 oldLeader = CLIs[ i ]
                 break
-        else:
+        else:  # FOR/ELSE statement
             main.log.error( "Leader election, could not find current leader" )
         if oldLeader:
             withdrawResult = oldLeader.electionTestWithdraw()
@@ -2373,6 +2361,7 @@
             onfail="App was not withdrawn from election" )
 
         main.step( "Make sure new leader is elected" )
+        # FIXME: use threads
         leaderList = []
         for cli in CLIs:
             leaderN = cli.electionTestLeader()
@@ -2389,6 +2378,11 @@
                                  "electionTestLeader function, " +
                                  "check the error logs" )
                 leaderResult = main.FALSE
+            elif leaderN is None:
+                # node may not have recieved the event yet
+                leaderN = cli.electionTestLeader()
+                leaderList.pop()
+                leaderList.append( leaderN )
         consistentLeader = main.FALSE
         if len( set( leaderList ) ) == 1:
             main.log.info( "Each Election-app sees '" +
diff --git a/TestON/tests/HATestMinorityRestart/HATestMinorityRestart.py b/TestON/tests/HATestMinorityRestart/HATestMinorityRestart.py
index ba2b113..43dd995 100644
--- a/TestON/tests/HATestMinorityRestart/HATestMinorityRestart.py
+++ b/TestON/tests/HATestMinorityRestart/HATestMinorityRestart.py
@@ -162,9 +162,28 @@
             intf=main.params[ 'MNtcpdump' ][ 'intf' ],
             port=main.params[ 'MNtcpdump' ][ 'port' ] )
 
+        appCheck = main.TRUE
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].appToIDCheck,
+                             name="appToIDCheck-" + str( i ),
+                             args=[] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            appCheck = appCheck and t.result
+        utilities.assert_equals( expect=main.TRUE, actual=appCheck,
+                                 onpass="App Ids seem to be correct",
+                                 onfail="Something is wrong with app Ids" )
+        if appCheck != main.TRUE:
+            main.log.warn( CLIs[0].apps() )
+            main.log.warn( CLIs[0].appIDs() )
+
         case1Result = ( cleanInstallResult and packageResult and
                         cellResult and verifyResult and onosInstallResult
-                        and onosIsupResult and cliResults )
+                        and onosIsupResult and cliResults and appCheck)
 
         utilities.assert_equals( expect=main.TRUE, actual=case1Result,
                                  onpass="Test startup successful",
@@ -221,6 +240,9 @@
                 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
         if mastershipCheck == main.TRUE:
             main.log.report( "Switch mastership assigned correctly" )
@@ -229,138 +251,62 @@
             actual=mastershipCheck,
             onpass="Switch mastership assigned correctly",
             onfail="Switches not assigned correctly to controllers" )
-        #FIXME: turning off because of ONOS-1286
         # Manually assign mastership to the controller we want
         roleCall = main.TRUE
         roleCheck = main.TRUE
         try:
-            # Assign switch
-            ip = nodes[ 0 ].ip_address  # ONOS1
-            deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
-            assert deviceId, "No device id for s1 in ONOS"
-            roleCall = roleCall and main.ONOScli1.deviceRole(
-                deviceId,
-                ip )
-            # Check assignment
-            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-
-            # Assign switch
-            deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
-            assert deviceId, "No device id for s28 in ONOS"
-            roleCall = roleCall and main.ONOScli1.deviceRole(
-                deviceId,
-                ip )
-            # Check assignment
-            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-
-            ip = nodes[ 1 ].ip_address  # ONOS2
-            # Assign switch
-            deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
-            assert deviceId, "No device id for s2 in ONOS"
-            roleCall = roleCall and main.ONOScli1.deviceRole(
-                deviceId,
-                ip )
-            # Check assignment
-            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-
-            # Assign switch
-            deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
-            assert deviceId, "No device id for s3 in ONOS"
-            roleCall = roleCall and main.ONOScli1.deviceRole(
-                deviceId,
-                ip )
-            # Check assignment
-            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-
-            ip = nodes[ 2 ].ip_address  # ONOS3
-            # Assign switch
-            deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
-            assert deviceId, "No device id for s5 in ONOS"
-            roleCall = roleCall and main.ONOScli1.deviceRole(
-                deviceId,
-                ip )
-            # Check assignment
-            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-
-            # Assign switch
-            deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
-            assert deviceId, "No device id for s6 in ONOS"
-            roleCall = roleCall and main.ONOScli1.deviceRole(
-                deviceId,
-                ip )
-            # Check assignment
-            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-
-            ip = nodes[ 3 ].ip_address  # ONOS4
-            # Assign switch
-            deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
-            assert deviceId, "No device id for s4 in ONOS"
-            roleCall = roleCall and main.ONOScli1.deviceRole(
-                deviceId,
-                ip )
-            # Check assignment
-            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-
-            ip = nodes[ 4 ].ip_address  # ONOS5
-            for i in range( 8, 18 ):
-                dpid = '3' + str( i ).zfill( 3 )
-                deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
-                assert deviceId, "No device id for s%i in ONOS" % i
-                roleCall = roleCall and main.ONOScli1.deviceRole(
-                    deviceId,
-                    ip )
+            for i in range( 1, 29 ):  # switches 1 through 28
+                # set up correct variables:
+                if i == 1:
+                    ip = nodes[ 0 ].ip_address  # ONOS1
+                    deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
+                elif i == 2:
+                    ip = nodes[ 1 ].ip_address  # ONOS2
+                    deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
+                elif i == 3:
+                    ip = nodes[ 1 ].ip_address  # ONOS2
+                    deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
+                elif i == 4:
+                    ip = nodes[ 3 ].ip_address  # ONOS4
+                    deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
+                elif i == 5:
+                    ip = nodes[ 2 ].ip_address  # ONOS3
+                    deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
+                elif i == 6:
+                    ip = nodes[ 2 ].ip_address  # ONOS3
+                    deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
+                elif i == 7:
+                    ip = nodes[ 5 ].ip_address  # ONOS6
+                    deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
+                elif i >= 8 and i <= 17:
+                    ip = nodes[ 4 ].ip_address  # ONOS5
+                    dpid = '3' + str( i ).zfill( 3 )
+                    deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
+                elif i >= 18 and i <= 27:
+                    ip = nodes[ 6 ].ip_address  # ONOS7
+                    dpid = '6' + str( i ).zfill( 3 )
+                    deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
+                elif i == 28:
+                    ip = nodes[ 0 ].ip_address  # ONOS1
+                    deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
+                else:
+                    main.log.error( "You didn't write an else statement for " +
+                                    "switch s" + str( i ) )
+                # Assign switch
+                assert deviceId, "No device id for s" + str( i ) + " in ONOS"
+                # TODO: make this controller dynamic
+                roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
+                                                                  ip )
                 # Check assignment
-                if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+                master =  main.ONOScli1.getRole( deviceId ).get( 'master' )
+                if ip in master:
                     roleCheck = roleCheck and main.TRUE
                 else:
                     roleCheck = roleCheck and main.FALSE
-
-            ip = nodes[ 5 ].ip_address  # ONOS6
-            deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
-            assert deviceId, "No device id for s7 in ONOS"
-            roleCall = roleCall and main.ONOScli1.deviceRole(
-                deviceId,
-                ip )
-            # Check assignment
-            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-
-            ip = nodes[ 6 ].ip_address  # ONOS7
-            for i in range( 18, 28 ):
-                dpid = '6' + str( i ).zfill( 3 )
-                deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
-                assert deviceId, "No device id for s%i in ONOS" % i
-                roleCall = roleCall and main.ONOScli1.deviceRole(
-                    deviceId,
-                    ip )
-                # Check assignment
-                if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-                    roleCheck = roleCheck and main.TRUE
-                else:
-                    roleCheck = roleCheck and main.FALSE
+                    main.log.error( "Error, controller " + ip + " is not" +
+                                    " master " + "of device " +
+                                    str( deviceId ) + ". Master is " +
+                                    repr( master ) + "." )
         except ( AttributeError, AssertionError ):
             main.log.exception( "Something is wrong with ONOS device view" )
             main.log.info( main.ONOScli1.devices() )
@@ -401,18 +347,27 @@
 
         # install onos-app-fwd
         main.log.info( "Install reactive forwarding app" )
-        appResults = main.TRUE
+        appResults = CLIs[0].activateApp( "org.onosproject.fwd" )
+
+        # FIXME: add this to asserts
+        appCheck = main.TRUE
         threads = []
         for i in range( numControllers ):
-            t = main.Thread( target=CLIs[i].featureInstall,
-                             name="featureInstall-" + str( i ),
-                             args=["onos-app-fwd"] )
+            t = main.Thread( target=CLIs[i].appToIDCheck,
+                             name="appToIDCheck-" + str( i ),
+                             args=[] )
             threads.append( t )
             t.start()
 
         for t in threads:
             t.join()
-            appResults = appResults and t.result
+            appCheck = appCheck and t.result
+        utilities.assert_equals( expect=main.TRUE, actual=appCheck,
+                                 onpass="App Ids seem to be correct",
+                                 onfail="Something is wrong with app Ids" )
+        if appCheck != main.TRUE:
+            main.log.warn( CLIs[0].apps() )
+            main.log.warn( CLIs[0].appIDs() )
 
         # REACTIVE FWD test
         pingResult = main.FALSE
@@ -429,17 +384,24 @@
 
         # uninstall onos-app-fwd
         main.log.info( "Uninstall reactive forwarding app" )
+        appResults = appResults and CLIs[0].deactivateApp( "org.onosproject.fwd" )
         threads = []
         for i in range( numControllers ):
-            t = main.Thread( target=CLIs[i].featureUninstall,
-                             name="featureUninstall-" + str( i ),
-                             args=["onos-app-fwd"] )
+            t = main.Thread( target=CLIs[i].appToIDCheck,
+                             name="appToIDCheck-" + str( i ),
+                             args=[] )
             threads.append( t )
             t.start()
 
         for t in threads:
             t.join()
-            appResults = appResults and t.result
+            appCheck = appCheck and t.result
+        utilities.assert_equals( expect=main.TRUE, actual=appCheck,
+                                 onpass="App Ids seem to be correct",
+                                 onfail="Something is wrong with app Ids" )
+        if appCheck != main.TRUE:
+            main.log.warn( CLIs[0].apps() )
+            main.log.warn( CLIs[0].appIDs() )
 
         # timeout for fwd flows
         time.sleep( 11 )
@@ -487,6 +449,8 @@
                 except ( ValueError, TypeError ):
                     main.log.warn( repr( hosts ) )
                 hostResult = main.FALSE
+        # FIXME: DEBUG
+        intentStart = time.time()
         onosIds = main.ONOScli1.getAllIntentsId()
         main.log.info( "Submitted intents: " + str( intentIds ) )
         main.log.info( "Intents in ONOS: " + str( onosIds ) )
@@ -495,6 +459,11 @@
                 pass  # intent submitted is in onos
             else:
                 intentAddResult = False
+        # FIXME: DEBUG
+        if intentAddResult:
+            intentStop = time.time()
+        else:
+            intentStop = None
         # Print the intent states
         intents = main.ONOScli1.intents()
         intentStates = []
@@ -531,12 +500,9 @@
                                            indent=4,
                                            separators=( ',', ': ' ) ) )
                 # check for all intent partitions
-                # check for election
                 topics = []
                 for i in range( 14 ):
                     topics.append( "intent-partition-" + str( i ) )
-                # FIXME: this should only be after we start the app
-                topics.append( "org.onosproject.election" )
                 main.log.debug( topics )
                 ONOStopics = [ j['topic'] for j in parsedLeaders ]
                 for topic in topics:
@@ -585,6 +551,29 @@
             actual=intentAddResult,
             onpass="Pushed host intents to ONOS",
             onfail="Error in pushing host intents to ONOS" )
+        for i in range(100):
+            onosIds = main.ONOScli1.getAllIntentsId()
+            main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
+            main.log.info( "Intents in ONOS: " + str( sorted( onosIds ) ) )
+            if sorted(onosIds) == sorted(intentIds):
+                break
+            else:
+                time.sleep(1)
+        # FIXME: DEBUG
+        if not intentStop:
+            intentStop = time.time()
+        gossipTime = intentStop - intentStart
+        main.log.info( "It took about " + str( gossipTime ) +
+                        " seconds for all intents to appear on ONOS1" )
+        # FIXME: make this time configurable/calculate based off of number of
+        #        nodes and gossip rounds
+        utilities.assert_greater_equals(
+                expect=30, actual=gossipTime,
+                onpass="ECM anti-entropy for intents worked within " +
+                       "expected time",
+                onfail="Intent ECM anti-entropy took too long" )
+        if gossipTime <= 30:
+            intentAddResult = True
 
         if not intentAddResult or "key" in pendingMap:
             import time
@@ -1066,6 +1055,7 @@
             threads.append( t )
             t.start()
 
+        # NOTE: Flows command can take some time to run
         time.sleep(30)
         for t in threads:
             t.join()
@@ -1392,7 +1382,7 @@
         finalAssert = main.TRUE
         finalAssert = ( finalAssert and topoResult and flowCheck
                         and intentCheck and consistentMastership
-                        and rolesNotNull )
+                        and mastershipCheck and rolesNotNull )
         utilities.assert_equals( expect=main.TRUE, actual=finalAssert,
                                  onpass="State check successful",
                                  onfail="State check NOT successful" )
@@ -2024,6 +2014,40 @@
         if topoResult == main.TRUE:
             main.log.report( "ONOS topology view matches Mininet topology" )
 
+        # FIXME: move this to an ONOS state case
+        main.step( "Checking ONOS nodes" )
+        nodesOutput = []
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].nodes,
+                             name="nodes-" + str( i ),
+                             args=[ ] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            nodesOutput.append( t.result )
+        ips = [ node.ip_address for node in nodes ]
+        for i in nodesOutput:
+            try:
+                current = json.loads( i )
+                for node in current:
+                    if node['ip'] in ips:  # node in nodes() output is in cell
+                        if node['state'] == 'ACTIVE':
+                            pass  # as it should be
+                        else:
+                            main.log.error( "Error in ONOS node availability" )
+                            main.log.error(
+                                    json.dumps( current,
+                                                sort_keys=True,
+                                                indent=4,
+                                                separators=( ',', ': ' ) ) )
+                            break
+            except ( ValueError, TypeError ):
+                main.log.error( "Error parsing nodes output" )
+                main.log.warn( repr( i ) )
+
     def CASE9( self, main ):
         """
         Link s3-s28 down
@@ -2273,64 +2297,21 @@
         assert nodes, "nodes not defined"
 
         leaderResult = main.TRUE
-        # install app on onos 1
         main.log.info( "Install leadership election app" )
-        main.ONOScli1.featureInstall( "onos-app-election" )
-        leader = nodes[0].ip_address
-        # wait for election
-        # check for leader
-        for i in range(2):  # try this twice
-            leader1 = main.ONOScli1.electionTestLeader()
-            # verify leader is ONOS1
-            if leader1 == leader:
-                # all is well
-                # pass
-                if i > 0:
-                    main.log.warn( "It took ONOS sometime for leader to be" +
-                                   "elected" )
-                    main.log.debug( "I don't think this should be happening" )
-                break
-            elif leader1 is None:
-                # No leader elected
-                main.log.report( "No leader was elected" )
+        main.ONOScli1.activateApp( "org.onosproject.election" )
+        leaders = []
+        for cli in CLIs:
+            leader = cli.electionTestLeader()
+            if leader is None or leader == main.FALSE:
+                main.log.report( cli.name + ": Leader for the election app " +
+                                 "should be an ONOS node, instead got '" +
+                                 str( leader ) + "'" )
                 leaderResult = main.FALSE
-            elif leader1 == main.FALSE:
-                # error in  response
-                # TODO: add check for "Command not found:" in the driver, this
-                # means the app isn't loaded
-                main.log.report( "Something is wrong with electionTestLeader" +
-                                 " function, check the error logs" )
-                leaderResult = main.FALSE
-            else:
-                # error in  response
-                main.log.report(
-                    "Unexpected response from electionTestLeader function:'" +
-                    str( leader1 ) + "'" )
-                leaderResult = main.FALSE
-            time.sleep(2)
-        # install on other nodes and check for leader.
-        # Leader should be ONOS1 and each app should show the same leader
-        for cli in CLIs[ 1: ]:
-            cli.featureInstall( "onos-app-election" )
-            leaderN = cli.electionTestLeader()
-            # verify leader is ONOS1
-            if leaderN == leader:
-                # all is well
-                pass
-            elif leaderN == main.FALSE:
-                # error in  response
-                # TODO: add check for "Command not found:" in the driver, this
-                # means the app isn't loaded
-                main.log.report( "Something is wrong with " +
-                                 "electionTestLeader function, check the" +
-                                 " error logs" )
-                leaderResult = main.FALSE
-            elif leader != leaderN:
-                leaderResult = main.FALSE
-                main.log.report( cli.name + " sees " + str( leaderN ) +
-                                 " as the leader of the election app. Leader" +
-                                 " should be " +
-                                 str( leader ) )
+            leaders.append( leader )
+        if len( set( leaders ) ) != 1:
+            leaderResult = main.FALSE
+            main.log.error( "Results of electionTestLeader is order of CLIs:" +
+                            str( leaders ) )
         if leaderResult:
             main.log.report( "Leadership election tests passed( consistent " +
                              "view of leader across listeners and a leader " +
@@ -2357,7 +2338,7 @@
         main.case( description )
         main.step( "Find current leader and withdraw" )
         leader = main.ONOScli1.electionTestLeader()
-        # TODO: do some sanity checking on leader before using it
+        # do some sanity checking on leader before using it
         withdrawResult = main.FALSE
         if leader is None or leader == main.FALSE:
             main.log.report(
@@ -2369,7 +2350,7 @@
             if leader == nodes[ i ].ip_address:
                 oldLeader = CLIs[ i ]
                 break
-        else:
+        else:  # FOR/ELSE statement
             main.log.error( "Leader election, could not find current leader" )
         if oldLeader:
             withdrawResult = oldLeader.electionTestWithdraw()
@@ -2380,6 +2361,7 @@
             onfail="App was not withdrawn from election" )
 
         main.step( "Make sure new leader is elected" )
+        # FIXME: use threads
         leaderList = []
         for cli in CLIs:
             leaderN = cli.electionTestLeader()
@@ -2396,6 +2378,11 @@
                                  "electionTestLeader function, " +
                                  "check the error logs" )
                 leaderResult = main.FALSE
+            elif leaderN is None:
+                # node may not have recieved the event yet
+                leaderN = cli.electionTestLeader()
+                leaderList.pop()
+                leaderList.append( leaderN )
         consistentLeader = main.FALSE
         if len( set( leaderList ) ) == 1:
             main.log.info( "Each Election-app sees '" +
diff --git a/TestON/tests/HATestNetworkPartition/HATestNetworkPartition.py b/TestON/tests/HATestNetworkPartition/HATestNetworkPartition.py
index 332dd47..3c4541c 100644
--- a/TestON/tests/HATestNetworkPartition/HATestNetworkPartition.py
+++ b/TestON/tests/HATestNetworkPartition/HATestNetworkPartition.py
@@ -415,6 +415,8 @@
 
         # install onos-app-fwd
         main.log.info( "Install reactive forwarding app" )
+        appResults = CLIs[0].activateApp( "org.onosproject.fwd" )
+        '''
         main.ONOScli1.featureInstall( "onos-app-fwd" )
         main.ONOScli2.featureInstall( "onos-app-fwd" )
         main.ONOScli3.featureInstall( "onos-app-fwd" )
@@ -422,6 +424,7 @@
         main.ONOScli5.featureInstall( "onos-app-fwd" )
         main.ONOScli6.featureInstall( "onos-app-fwd" )
         main.ONOScli7.featureInstall( "onos-app-fwd" )
+        '''
 
         # REACTIVE FWD test
         pingResult = main.FALSE
@@ -437,6 +440,8 @@
 
         # uninstall onos-app-fwd
         main.log.info( "Uninstall reactive forwarding app" )
+        appResults = appResults and CLIs[0].deactivateApp( "org.onosproject.fwd" )
+        '''
         main.ONOScli1.featureUninstall( "onos-app-fwd" )
         main.ONOScli2.featureUninstall( "onos-app-fwd" )
         main.ONOScli3.featureUninstall( "onos-app-fwd" )
@@ -444,6 +449,7 @@
         main.ONOScli5.featureUninstall( "onos-app-fwd" )
         main.ONOScli6.featureUninstall( "onos-app-fwd" )
         main.ONOScli7.featureUninstall( "onos-app-fwd" )
+        '''
         # timeout for fwd flows
         time.sleep( 10 )
 
diff --git a/TestON/tests/HATestSanity/HATestSanity.py b/TestON/tests/HATestSanity/HATestSanity.py
index 5b3e125..20f6cc8 100644
--- a/TestON/tests/HATestSanity/HATestSanity.py
+++ b/TestON/tests/HATestSanity/HATestSanity.py
@@ -162,9 +162,28 @@
             intf=main.params[ 'MNtcpdump' ][ 'intf' ],
             port=main.params[ 'MNtcpdump' ][ 'port' ] )
 
+        appCheck = main.TRUE
+        threads = []
+        for i in range( numControllers ):
+            t = main.Thread( target=CLIs[i].appToIDCheck,
+                             name="appToIDCheck-" + str( i ),
+                             args=[] )
+            threads.append( t )
+            t.start()
+
+        for t in threads:
+            t.join()
+            appCheck = appCheck and t.result
+        utilities.assert_equals( expect=main.TRUE, actual=appCheck,
+                                 onpass="App Ids seem to be correct",
+                                 onfail="Something is wrong with app Ids" )
+        if appCheck != main.TRUE:
+            main.log.warn( CLIs[0].apps() )
+            main.log.warn( CLIs[0].appIDs() )
+
         case1Result = ( cleanInstallResult and packageResult and
                         cellResult and verifyResult and onosInstallResult
-                        and onosIsupResult and cliResults )
+                        and onosIsupResult and cliResults and appCheck)
 
         utilities.assert_equals( expect=main.TRUE, actual=case1Result,
                                  onpass="Test startup successful",
@@ -221,6 +240,9 @@
                 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
         if mastershipCheck == main.TRUE:
             main.log.report( "Switch mastership assigned correctly" )
@@ -229,138 +251,62 @@
             actual=mastershipCheck,
             onpass="Switch mastership assigned correctly",
             onfail="Switches not assigned correctly to controllers" )
-        #FIXME: turning off because of ONOS-1286
         # Manually assign mastership to the controller we want
         roleCall = main.TRUE
         roleCheck = main.TRUE
         try:
-            # Assign switch
-            ip = nodes[ 0 ].ip_address  # ONOS1
-            deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
-            assert deviceId, "No device id for s1 in ONOS"
-            roleCall = roleCall and main.ONOScli1.deviceRole(
-                deviceId,
-                ip )
-            # Check assignment
-            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-
-            # Assign switch
-            deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
-            assert deviceId, "No device id for s28 in ONOS"
-            roleCall = roleCall and main.ONOScli1.deviceRole(
-                deviceId,
-                ip )
-            # Check assignment
-            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-
-            ip = nodes[ 1 ].ip_address  # ONOS2
-            # Assign switch
-            deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
-            assert deviceId, "No device id for s2 in ONOS"
-            roleCall = roleCall and main.ONOScli1.deviceRole(
-                deviceId,
-                ip )
-            # Check assignment
-            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-
-            # Assign switch
-            deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
-            assert deviceId, "No device id for s3 in ONOS"
-            roleCall = roleCall and main.ONOScli1.deviceRole(
-                deviceId,
-                ip )
-            # Check assignment
-            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-
-            ip = nodes[ 2 ].ip_address  # ONOS3
-            # Assign switch
-            deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
-            assert deviceId, "No device id for s5 in ONOS"
-            roleCall = roleCall and main.ONOScli1.deviceRole(
-                deviceId,
-                ip )
-            # Check assignment
-            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-
-            # Assign switch
-            deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
-            assert deviceId, "No device id for s6 in ONOS"
-            roleCall = roleCall and main.ONOScli1.deviceRole(
-                deviceId,
-                ip )
-            # Check assignment
-            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-
-            ip = nodes[ 3 ].ip_address  # ONOS4
-            # Assign switch
-            deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
-            assert deviceId, "No device id for s4 in ONOS"
-            roleCall = roleCall and main.ONOScli1.deviceRole(
-                deviceId,
-                ip )
-            # Check assignment
-            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-
-            ip = nodes[ 4 ].ip_address  # ONOS5
-            for i in range( 8, 18 ):
-                dpid = '3' + str( i ).zfill( 3 )
-                deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
-                assert deviceId, "No device id for s%i in ONOS" % i
-                roleCall = roleCall and main.ONOScli1.deviceRole(
-                    deviceId,
-                    ip )
+            for i in range( 1, 29 ):  # switches 1 through 28
+                # set up correct variables:
+                if i == 1:
+                    ip = nodes[ 0 ].ip_address  # ONOS1
+                    deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
+                elif i == 2:
+                    ip = nodes[ 1 ].ip_address  # ONOS2
+                    deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
+                elif i == 3:
+                    ip = nodes[ 1 ].ip_address  # ONOS2
+                    deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
+                elif i == 4:
+                    ip = nodes[ 3 ].ip_address  # ONOS4
+                    deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
+                elif i == 5:
+                    ip = nodes[ 2 ].ip_address  # ONOS3
+                    deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
+                elif i == 6:
+                    ip = nodes[ 2 ].ip_address  # ONOS3
+                    deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
+                elif i == 7:
+                    ip = nodes[ 5 ].ip_address  # ONOS6
+                    deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
+                elif i >= 8 and i <= 17:
+                    ip = nodes[ 4 ].ip_address  # ONOS5
+                    dpid = '3' + str( i ).zfill( 3 )
+                    deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
+                elif i >= 18 and i <= 27:
+                    ip = nodes[ 6 ].ip_address  # ONOS7
+                    dpid = '6' + str( i ).zfill( 3 )
+                    deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
+                elif i == 28:
+                    ip = nodes[ 0 ].ip_address  # ONOS1
+                    deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
+                else:
+                    main.log.error( "You didn't write an else statement for " +
+                                    "switch s" + str( i ) )
+                # Assign switch
+                assert deviceId, "No device id for s" + str( i ) + " in ONOS"
+                # TODO: make this controller dynamic
+                roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
+                                                                  ip )
                 # Check assignment
-                if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
+                master =  main.ONOScli1.getRole( deviceId ).get( 'master' )
+                if ip in master:
                     roleCheck = roleCheck and main.TRUE
                 else:
                     roleCheck = roleCheck and main.FALSE
-
-            ip = nodes[ 5 ].ip_address  # ONOS6
-            deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
-            assert deviceId, "No device id for s7 in ONOS"
-            roleCall = roleCall and main.ONOScli1.deviceRole(
-                deviceId,
-                ip )
-            # Check assignment
-            if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-                roleCheck = roleCheck and main.TRUE
-            else:
-                roleCheck = roleCheck and main.FALSE
-
-            ip = nodes[ 6 ].ip_address  # ONOS7
-            for i in range( 18, 28 ):
-                dpid = '6' + str( i ).zfill( 3 )
-                deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
-                assert deviceId, "No device id for s%i in ONOS" % i
-                roleCall = roleCall and main.ONOScli1.deviceRole(
-                    deviceId,
-                    ip )
-                # Check assignment
-                if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
-                    roleCheck = roleCheck and main.TRUE
-                else:
-                    roleCheck = roleCheck and main.FALSE
+                    main.log.error( "Error, controller " + ip + " is not" +
+                                    " master " + "of device " +
+                                    str( deviceId ) + ". Master is " +
+                                    repr( master ) + "." )
         except ( AttributeError, AssertionError ):
             main.log.exception( "Something is wrong with ONOS device view" )
             main.log.info( main.ONOScli1.devices() )
@@ -401,18 +347,27 @@
 
         # install onos-app-fwd
         main.log.info( "Install reactive forwarding app" )
-        appResults = main.TRUE
+        appResults = CLIs[0].activateApp( "org.onosproject.fwd" )
+
+        # FIXME: add this to asserts
+        appCheck = main.TRUE
         threads = []
         for i in range( numControllers ):
-            t = main.Thread( target=CLIs[i].featureInstall,
-                             name="featureInstall-" + str( i ),
-                             args=["onos-app-fwd"] )
+            t = main.Thread( target=CLIs[i].appToIDCheck,
+                             name="appToIDCheck-" + str( i ),
+                             args=[] )
             threads.append( t )
             t.start()
 
         for t in threads:
             t.join()
-            appResults = appResults and t.result
+            appCheck = appCheck and t.result
+        utilities.assert_equals( expect=main.TRUE, actual=appCheck,
+                                 onpass="App Ids seem to be correct",
+                                 onfail="Something is wrong with app Ids" )
+        if appCheck != main.TRUE:
+            main.log.warn( CLIs[0].apps() )
+            main.log.warn( CLIs[0].appIDs() )
 
         # REACTIVE FWD test
         pingResult = main.FALSE
@@ -429,17 +384,24 @@
 
         # uninstall onos-app-fwd
         main.log.info( "Uninstall reactive forwarding app" )
+        appResults = appResults and CLIs[0].deactivateApp( "org.onosproject.fwd" )
         threads = []
         for i in range( numControllers ):
-            t = main.Thread( target=CLIs[i].featureUninstall,
-                             name="featureUninstall-" + str( i ),
-                             args=["onos-app-fwd"] )
+            t = main.Thread( target=CLIs[i].appToIDCheck,
+                             name="appToIDCheck-" + str( i ),
+                             args=[] )
             threads.append( t )
             t.start()
 
         for t in threads:
             t.join()
-            appResults = appResults and t.result
+            appCheck = appCheck and t.result
+        utilities.assert_equals( expect=main.TRUE, actual=appCheck,
+                                 onpass="App Ids seem to be correct",
+                                 onfail="Something is wrong with app Ids" )
+        if appCheck != main.TRUE:
+            main.log.warn( CLIs[0].apps() )
+            main.log.warn( CLIs[0].appIDs() )
 
         # timeout for fwd flows
         time.sleep( 11 )
@@ -538,13 +500,9 @@
                                            indent=4,
                                            separators=( ',', ': ' ) ) )
                 # check for all intent partitions
-                # check for election
                 topics = []
                 for i in range( 14 ):
                     topics.append( "intent-partition-" + str( i ) )
-                # FIXME: this should only be after we start the app
-                # FIXME: move this to the election test sections
-                topics.append( "org.onosproject.election" )
                 main.log.debug( topics )
                 ONOStopics = [ j['topic'] for j in parsedLeaders ]
                 for topic in topics:
@@ -607,13 +565,15 @@
         gossipTime = intentStop - intentStart
         main.log.info( "It took about " + str( gossipTime ) +
                         " seconds for all intents to appear on ONOS1" )
-        # FIXME: make this time configurable/calculate based off of # of nodes
-        #        and gossip rounds
+        # FIXME: make this time configurable/calculate based off of number of
+        #        nodes and gossip rounds
         utilities.assert_greater_equals(
                 expect=30, actual=gossipTime,
                 onpass="ECM anti-entropy for intents worked within " +
                        "expected time",
                 onfail="Intent ECM anti-entropy took too long" )
+        if gossipTime <= 30:
+            intentAddResult = True
 
         if not intentAddResult or "key" in pendingMap:
             import time
@@ -1095,7 +1055,7 @@
             threads.append( t )
             t.start()
 
-        # FIXME: why am I sleeping here?
+        # NOTE: Flows command can take some time to run
         time.sleep(30)
         for t in threads:
             t.join()
@@ -1422,7 +1382,7 @@
         finalAssert = main.TRUE
         finalAssert = ( finalAssert and topoResult and flowCheck
                         and intentCheck and consistentMastership
-                        and rolesNotNull )
+                        and mastershipCheck and rolesNotNull )
         utilities.assert_equals( expect=main.TRUE, actual=finalAssert,
                                  onpass="State check successful",
                                  onfail="State check NOT successful" )
@@ -2020,7 +1980,7 @@
         if topoResult == main.TRUE:
             main.log.report( "ONOS topology view matches Mininet topology" )
 
-        #FIXME: move this to an ONOS state case
+        # FIXME: move this to an ONOS state case
         main.step( "Checking ONOS nodes" )
         nodesOutput = []
         threads = []
@@ -2041,7 +2001,7 @@
                 for node in current:
                     if node['ip'] in ips:  # node in nodes() output is in cell
                         if node['state'] == 'ACTIVE':
-                            pass # as it should be
+                            pass  # as it should be
                         else:
                             main.log.error( "Error in ONOS node availability" )
                             main.log.error(
@@ -2295,6 +2255,7 @@
         """
         start election app on all onos nodes
         """
+        import time
         assert numControllers, "numControllers not defined"
         assert main, "main not defined"
         assert utilities.assert_equals, "utilities.assert_equals not defined"
@@ -2302,58 +2263,21 @@
         assert nodes, "nodes not defined"
 
         leaderResult = main.TRUE
-        # install app on onos 1
         main.log.info( "Install leadership election app" )
-        main.ONOScli1.featureInstall( "onos-app-election" )
-        leader = nodes[0].ip_address
-        # wait for election
-        # check for leader
-        leader1 = main.ONOScli1.electionTestLeader()
-        # verify leader is ONOS1
-        if leader1 == leader:
-            # all is well
-            pass
-        elif leader1 is None:
-            # No leader elected
-            main.log.report( "No leader was elected" )
-            leaderResult = main.FALSE
-        elif leader1 == main.FALSE:
-            # error in  response
-            # TODO: add check for "Command not found:" in the driver, this
-            # means the app isn't loaded
-            main.log.report( "Something is wrong with electionTestLeader" +
-                             " function, check the error logs" )
-            leaderResult = main.FALSE
-        else:
-            # error in  response
-            main.log.report(
-                "Unexpected response from electionTestLeader function:'" +
-                str( leader1 ) + "'" )
-            leaderResult = main.FALSE
-
-        # install on other nodes and check for leader.
-        # Leader should be ONOS1 and each app should show the same leader
-        for cli in CLIs[ 1: ]:
-            cli.featureInstall( "onos-app-election" )
-            leaderN = cli.electionTestLeader()
-            # verify leader is ONOS1
-            if leaderN == leader:
-                # all is well
-                pass
-            elif leaderN == main.FALSE:
-                # error in  response
-                # TODO: add check for "Command not found:" in the driver, this
-                # means the app isn't loaded
-                main.log.report( "Something is wrong with " +
-                                 "electionTestLeader function, check the" +
-                                 " error logs" )
+        main.ONOScli1.activateApp( "org.onosproject.election" )
+        leaders = []
+        for cli in CLIs:
+            leader = cli.electionTestLeader()
+            if leader is None or leader == main.FALSE:
+                main.log.report( cli.name + ": Leader for the election app " +
+                                 "should be an ONOS node, instead got '" +
+                                 str( leader ) + "'" )
                 leaderResult = main.FALSE
-            elif leader != leaderN:
-                leaderResult = main.FALSE
-                main.log.report( cli.name + " sees " + str( leaderN ) +
-                                 " as the leader of the election app. Leader" +
-                                 " should be " +
-                                 str( leader ) )
+            leaders.append( leader )
+        if len( set( leaders ) ) != 1:
+            leaderResult = main.FALSE
+            main.log.error( "Results of electionTestLeader is order of CLIs:" +
+                            str( leaders ) )
         if leaderResult:
             main.log.report( "Leadership election tests passed( consistent " +
                              "view of leader across listeners and a leader " +
@@ -2380,7 +2304,7 @@
         main.case( description )
         main.step( "Find current leader and withdraw" )
         leader = main.ONOScli1.electionTestLeader()
-        # TODO: do some sanity checking on leader before using it
+        # do some sanity checking on leader before using it
         withdrawResult = main.FALSE
         if leader is None or leader == main.FALSE:
             main.log.report(
@@ -2392,7 +2316,7 @@
             if leader == nodes[ i ].ip_address:
                 oldLeader = CLIs[ i ]
                 break
-        else:
+        else:  # FOR/ELSE statement
             main.log.error( "Leader election, could not find current leader" )
         if oldLeader:
             withdrawResult = oldLeader.electionTestWithdraw()
@@ -2403,6 +2327,7 @@
             onfail="App was not withdrawn from election" )
 
         main.step( "Make sure new leader is elected" )
+        # FIXME: use threads
         leaderList = []
         for cli in CLIs:
             leaderN = cli.electionTestLeader()
@@ -2419,6 +2344,11 @@
                                  "electionTestLeader function, " +
                                  "check the error logs" )
                 leaderResult = main.FALSE
+            elif leaderN is None:
+                # node may not have recieved the event yet
+                leaderN = cli.electionTestLeader()
+                leaderList.pop()
+                leaderList.append( leaderN )
         consistentLeader = main.FALSE
         if len( set( leaderList ) ) == 1:
             main.log.info( "Each Election-app sees '" +
diff --git a/TestON/tests/HATestSingleInstanceRestart/HATestSingleInstanceRestart.py b/TestON/tests/HATestSingleInstanceRestart/HATestSingleInstanceRestart.py
index d6e3daf..d2f0bc9 100644
--- a/TestON/tests/HATestSingleInstanceRestart/HATestSingleInstanceRestart.py
+++ b/TestON/tests/HATestSingleInstanceRestart/HATestSingleInstanceRestart.py
@@ -59,36 +59,32 @@
         # set global variables
         global ONOS1Ip
         global ONOS1Port
-        global ONOS2Ip
         global ONOS2Port
-        global ONOS3Ip
         global ONOS3Port
-        global ONOS4Ip
         global ONOS4Port
-        global ONOS5Ip
         global ONOS5Port
-        global ONOS6Ip
         global ONOS6Port
-        global ONOS7Ip
         global ONOS7Port
         global numControllers
         numControllers = int( main.params[ 'num_controllers' ] )
 
         ONOS1Ip = main.params[ 'CTRL' ][ 'ip1' ]
         ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
-        ONOS2Ip = main.params[ 'CTRL' ][ 'ip2' ]
         ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
-        ONOS3Ip = main.params[ 'CTRL' ][ 'ip3' ]
         ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
-        ONOS4Ip = main.params[ 'CTRL' ][ 'ip4' ]
         ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
-        ONOS5Ip = main.params[ 'CTRL' ][ 'ip5' ]
         ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
-        ONOS6Ip = main.params[ 'CTRL' ][ 'ip6' ]
         ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
-        ONOS7Ip = main.params[ 'CTRL' ][ 'ip7' ]
         ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
 
+        global CLIs
+        CLIs = []
+        global nodes
+        nodes = []
+        for i in range( 1, numControllers + 1 ):
+            CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
+            nodes.append( getattr( main, 'ONOS' + str( i ) ) )
+
         main.step( "Applying cell variable to environment" )
         cellResult = main.ONOSbench.setCell( cellName )
         verifyResult = main.ONOSbench.verifyCell()
@@ -96,14 +92,10 @@
         # FIXME:this is short term fix
         main.log.report( "Removing raft logs" )
         main.ONOSbench.onosRemoveRaftLogs()
+
         main.log.report( "Uninstalling ONOS" )
-        main.ONOSbench.onosUninstall( ONOS1Ip )
-        main.ONOSbench.onosUninstall( ONOS2Ip )
-        main.ONOSbench.onosUninstall( ONOS3Ip )
-        main.ONOSbench.onosUninstall( ONOS4Ip )
-        main.ONOSbench.onosUninstall( ONOS5Ip )
-        main.ONOSbench.onosUninstall( ONOS6Ip )
-        main.ONOSbench.onosUninstall( ONOS7Ip )
+        for node in nodes:
+            main.ONOSbench.onosUninstall( node.ip_address )
 
         cleanInstallResult = main.TRUE
         gitPullResult = main.TRUE
@@ -116,6 +108,8 @@
             main.step( "Git checkout and pull " + gitBranch )
             main.ONOSbench.gitCheckout( gitBranch )
             gitPullResult = main.ONOSbench.gitPull()
+            if gitPullResult == main.ERROR:
+                main.log.error( "Error pulling git branch" )
 
             main.step( "Using mvn clean & install" )
             cleanInstallResult = main.ONOSbench.cleanInstall()
@@ -206,6 +200,73 @@
             onpass="Switch mastership assigned correctly",
             onfail="Switches not assigned correctly to controllers" )
 
+        roleCall = main.TRUE
+        roleCheck = main.TRUE
+        try:
+            for i in range( 1, 29 ):  # switches 1 through 28
+                ip = nodes[ 0 ].ip_address  # ONOS1
+                # set up correct variables:
+                if i == 1:
+                    deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
+                elif i == 2:
+                    deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
+                elif i == 3:
+                    deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
+                elif i == 4:
+                    deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
+                elif i == 5:
+                    deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
+                elif i == 6:
+                    deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
+                elif i == 7:
+                    deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
+                elif i >= 8 and i <= 17:
+                    dpid = '3' + str( i ).zfill( 3 )
+                    deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
+                elif i >= 18 and i <= 27:
+                    dpid = '6' + str( i ).zfill( 3 )
+                    deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
+                elif i == 28:
+                    deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
+                else:
+                    main.log.error( "You didn't write an else statement for " +
+                                    "switch s" + str( i ) )
+                # Assign switch
+                assert deviceId, "No device id for s" + str( i ) + " in ONOS"
+                # TODO: make this controller dynamic
+                roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
+                                                                  ip )
+                # Check assignment
+                master =  main.ONOScli1.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 ) + "." )
+        except ( AttributeError, AssertionError ):
+            main.log.exception( "Something is wrong with ONOS device view" )
+            main.log.info( main.ONOScli1.devices() )
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=roleCall,
+            onpass="Re-assigned switch mastership to designated controller",
+            onfail="Something wrong with deviceRole calls" )
+
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=roleCheck,
+            onpass="Switches were successfully reassigned to designated " +
+                   "controller",
+            onfail="Switches were not successfully reassigned" )
+        mastershipCheck = mastershipCheck and roleCall and roleCheck
+        utilities.assert_equals( expect=main.TRUE, actual=mastershipCheck,
+                                 onpass="Switch mastership correctly assigned",
+                                 onfail="Error in (re)assigning switch" +
+                                 " mastership" )
+
     def CASE3( self, main ):
         """
         Assign intents
@@ -225,7 +286,13 @@
 
         # install onos-app-fwd
         main.log.info( "Install reactive forwarding app" )
-        main.ONOScli1.featureInstall( "onos-app-fwd" )
+        appResults = main.ONOScli1.activateApp( "org.onosproject.fwd" )
+
+        # FIXME: add this to asserts
+        appCheck = main.ONOScli1.appToIDCheck()
+        if appCheck != main.TRUE:
+            main.log.warn( CLIs[0].apps() )
+            main.log.warn( CLIs[0].appIDs() )
 
         # REACTIVE FWD test
         pingResult = main.FALSE
@@ -242,11 +309,16 @@
 
         # uninstall onos-app-fwd
         main.log.info( "Uninstall reactive forwarding app" )
-        main.ONOScli1.featureUninstall( "onos-app-fwd" )
-        # timeout for fwd flows
-        time.sleep( 10 )
+        appResults = appResults and main.ONOScli1.deactivateApp( "org.onosproject.fwd" )
+        appCheck2 = main.ONOScli1.appToIDCheck()
+        if appCheck2 != main.TRUE:
+            main.log.warn( CLIs[0].apps() )
+            main.log.warn( CLIs[0].appIDs() )
 
-        main.step( "Add  host intents" )
+        # timeout for fwd flows
+        time.sleep( 11 )
+
+        main.step( "Add host intents" )
         intentIds = []
         # TODO:  move the host numbers to params
         #        Maybe look at all the paths we ping?
@@ -268,33 +340,45 @@
                 host1Id = host1Dict.get( 'id', None )
                 host2Id = host2Dict.get( 'id', None )
             if host1Id and host2Id:
-                tmpId = main.ONOScli1.addHostIntent(
-                    host1Id,
-                    host2Id )
+                tmpId = main.ONOScli1.addHostIntent( host1Id, host2Id )
                 if tmpId:
                     main.log.info( "Added intent with id: " + tmpId )
                     intentIds.append( tmpId )
                 else:
-                    main.log.error( "addHostIntent reutrned None" )
+                    main.log.error( "addHostIntent returned: " +
+                                     repr( tmpId ) )
             else:
-                main.log.error( "Error, getHost() failed" )
-                main.log.warn( json.dumps( json.loads( main.ONOScli1.hosts() ),
-                                           sort_keys=True,
-                                           indent=4,
-                                           separators=( ',', ': ' ) ) )
+                main.log.error( "Error, getHost() failed for h" + str( i ) +
+                                " and/or h" + str( i + 10 ) )
+                hosts = main.ONOScli1.hosts()
+                main.log.warn( "Hosts output: " )
+                try:
+                    main.log.warn( json.dumps( json.loads( hosts ),
+                                               sort_keys=True,
+                                               indent=4,
+                                               separators=( ',', ': ' ) ) )
+                except ( ValueError, TypeError ):
+                    main.log.warn( repr( hosts ) )
                 hostResult = main.FALSE
+        # FIXME: DEBUG
+        intentStart = time.time()
         onosIds = main.ONOScli1.getAllIntentsId()
         main.log.info( "Submitted intents: " + str( intentIds ) )
         main.log.info( "Intents in ONOS: " + str( onosIds ) )
         for intent in intentIds:
             if intent in onosIds:
-                pass  # intent submitted is still in onos
+                pass  # intent submitted is in onos
             else:
                 intentAddResult = False
+        # FIXME: DEBUG
+        if intentAddResult:
+            intentStop = time.time()
+        else:
+            intentStop = None
         # Print the intent states
         intents = main.ONOScli1.intents()
         intentStates = []
-        installedCheck = True 
+        installedCheck = True
         main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
         count = 0
         try:
@@ -327,12 +411,9 @@
                                            indent=4,
                                            separators=( ',', ': ' ) ) )
                 # check for all intent partitions
-                # check for election
                 topics = []
                 for i in range( 14 ):
                     topics.append( "intent-partition-" + str( i ) )
-                # FIXME: this should only be after we start the app
-                topics.append( "org.onosproject.election" )
                 main.log.debug( topics )
                 ONOStopics = [ j['topic'] for j in parsedLeaders ]
                 for topic in topics:
@@ -476,6 +557,7 @@
         Ping across added host intents
         """
         import json
+        import time
         assert numControllers, "numControllers not defined"
         assert main, "main not defined"
         assert utilities.assert_equals, "utilities.assert_equals not defined"
@@ -678,7 +760,6 @@
         Reading state of ONOS
         """
         import json
-        import time
         assert numControllers, "numControllers not defined"
         assert main, "main not defined"
         assert utilities.assert_equals, "utilities.assert_equals not defined"
@@ -691,9 +772,9 @@
         # ( intents,flows, topology,... ) from each ONOS node
         # We can then compare them with each other and also with past states
 
-        main.step( "Get the Mastership of each switch from each controller" )
+        main.step( "Check that each switch has a master" )
         global mastershipState
-        mastershipState = []
+        mastershipState = '[]'
 
         # Assert that each device has a master
         rolesNotNull = main.ONOScli1.rolesNotNull()
@@ -1113,17 +1194,10 @@
         main.log.report( description )
         main.step( "Create TestONTopology object" )
         ctrls = []
-        count = 1
-        temp = ()
-        temp = temp + ( getattr( main, ( 'ONOS' + str( count ) ) ), )
-        temp = temp + ( "ONOS" + str( count ), )
-        temp = temp + ( main.params[ 'CTRL' ][ 'ip' + str( count ) ], )
-        temp = temp + \
-            ( eval( main.params[ 'CTRL' ][ 'port' + str( count ) ] ), )
+        node = main.ONOS1
+        temp = ( node, node.name, node.ip_address, 6633 )
         ctrls.append( temp )
-        MNTopo = TestONTopology(
-            main.Mininet1,
-            ctrls )  # can also add Intent API info for intent operations
+        MNTopo = TestONTopology( main.Mininet1, ctrls )
 
         main.step( "Comparing ONOS topology to MN" )
         devicesResults = main.TRUE
@@ -1137,9 +1211,9 @@
         startTime = time.time()
         # Give time for Gossip to work
         while topoResult == main.FALSE and elapsed < 60:
-            count = count + 1
+            count += 1
             if count > 1:
-                # TODO: Depricate STS usage
+                # TODO: Deprecate STS usage
                 MNTopo = TestONTopology( main.Mininet1, ctrls )
             cliStart = time.time()
             devices = []
@@ -1277,7 +1351,7 @@
                        " seconds for link down to be discovered" )
         time.sleep( linkSleep )
         utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
-                                 onpass="Link down succesful",
+                                 onpass="Link down successful",
                                  onfail="Failed to bring link down" )
         # TODO do some sort of check here
 
@@ -1304,7 +1378,7 @@
                        " seconds for link up to be discovered" )
         time.sleep( linkSleep )
         utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
-                                 onpass="Link up succesful",
+                                 onpass="Link up successful",
                                  onfail="Failed to bring link up" )
         # TODO do some sort of check here
 
@@ -1340,7 +1414,7 @@
         if device and device[ 'available' ] is False:
             result = main.TRUE
         utilities.assert_equals( expect=main.TRUE, actual=result,
-                                 onpass="Kill switch succesful",
+                                 onpass="Kill switch successful",
                                  onfail="Failed to kill switch?" )
 
     def CASE12( self, main ):
@@ -1371,7 +1445,6 @@
         main.step( "Add back " + switch )
         main.log.report( "Adding back " + switch )
         main.Mininet1.addSwitch( switch, dpid=switchDPID )
-        # TODO: New dpid or same? Ask Thomas?
         for peer in links:
             main.Mininet1.addLink( switch, peer )
         main.Mininet1.assignSwController( sw=switch.split( 's' )[ 1 ],
@@ -1387,7 +1460,7 @@
         if device and device[ 'available' ]:
             result = main.TRUE
         utilities.assert_equals( expect=main.TRUE, actual=result,
-                                 onpass="add switch succesful",
+                                 onpass="add switch successful",
                                  onfail="Failed to add switch?" )
 
     def CASE13( self, main ):
@@ -1400,25 +1473,15 @@
         assert main, "main not defined"
         assert utilities.assert_equals, "utilities.assert_equals not defined"
         # printing colors to terminal
-        colors = {}
-        colors[ 'cyan' ] = '\033[96m'
-        colors[ 'purple' ] = '\033[95m'
-        colors[ 'blue' ] = '\033[94m'
-        colors[ 'green' ] = '\033[92m'
-        colors[ 'yellow' ] = '\033[93m'
-        colors[ 'red' ] = '\033[91m'
-        colors[ 'end' ] = '\033[0m'
+        colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
+                   'blue': '\033[94m', 'green': '\033[92m',
+                   'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
         description = "Test Cleanup"
         main.log.report( description )
         main.case( description )
         main.step( "Killing tcpdumps" )
         main.Mininet2.stopTcpdump()
 
-        main.step( "Checking ONOS Logs for errors" )
-        print colors[ 'purple' ] + "Checking logs for errors on ONOS1:" + \
-            colors[ 'end' ]
-        print main.ONOSbench.checkLogs( ONOS1Ip )
-
         main.step( "Copying MN pcap and ONOS log files to test station" )
         testname = main.TEST
         teststationUser = main.params[ 'TESTONUSER' ]
@@ -1456,7 +1519,15 @@
             main.ONOSbench.handle.expect( "\$" )
         # sleep so scp can finish
         time.sleep( 10 )
+
+        main.step( "Stopping Mininet" )
         main.Mininet1.stopNet()
+
+        main.step( "Checking ONOS Logs for errors" )
+        print colors[ 'purple' ] + "Checking logs for errors on ONOS1:" + \
+            colors[ 'end' ]
+        print main.ONOSbench.checkLogs( ONOS1Ip )
+
         main.step( "Packing and rotating pcap archives" )
         os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
 
@@ -1472,11 +1543,10 @@
         assert numControllers, "numControllers not defined"
         assert main, "main not defined"
         assert utilities.assert_equals, "utilities.assert_equals not defined"
+
         leaderResult = main.TRUE
-        # install app on onos 1
         main.log.info( "Install leadership election app" )
-        main.ONOScli1.featureInstall( "onos-app-election" )
-        # wait for election
+        main.ONOScli1.activateApp( "org.onosproject.election" )
         # check for leader
         leader = main.ONOScli1.electionTestLeader()
         # verify leader is ONOS1
@@ -1502,32 +1572,6 @@
                 "'" )
             leaderResult = main.FALSE
 
-        # install on other nodes and check for leader.
-        # Should be onos1 and each app should show the same leader
-        for controller in range( 2, numControllers + 1 ):
-            # loop through ONOScli handlers
-            node = getattr( main, ( 'ONOScli' + str( controller ) ) )
-            node.featureInstall( "onos-app-election" )
-            leaderN = node.electionTestLeader()
-            # verify leader is ONOS1
-            if leaderN == ONOS1Ip:
-                # all is well
-                pass
-            elif leaderN == main.FALSE:
-                # error in  response
-                # TODO: add check for "Command not found:" in the driver, this
-                # means the app isn't loaded
-                main.log.report( "Something is wrong with " +
-                                 "electionTestLeader function, check the" +
-                                 " error logs" )
-                leaderResult = main.FALSE
-            elif leader != leaderN:
-                leaderResult = main.FALSE
-                main.log.report( "ONOS" + str( controller ) + " sees " +
-                                 str( leaderN ) +
-                                 " as the leader of the election app. Leader" +
-                                 " should be " +
-                                 str( leader ) )
         if leaderResult:
             main.log.report( "Leadership election tests passed( consistent " +
                              "view of leader across listeners and a leader " +
@@ -1551,7 +1595,7 @@
         main.case( description )
         main.step( "Find current leader and withdraw" )
         leader = main.ONOScli1.electionTestLeader()
-        # TODO: do some sanity checking on leader before using it
+        # do some sanity checking on leader before using it
         withdrawResult = main.FALSE
         if leader == ONOS1Ip:
             oldLeader = getattr( main, "ONOScli1" )
@@ -1572,7 +1616,6 @@
             onfail="App was not withdrawn from election" )
 
         main.step( "Make sure new leader is elected" )
-        leaderList = []
         leaderN = main.ONOScli1.electionTestLeader()
         if leaderN == leader:
             main.log.report( "ONOS still sees " + str( leaderN ) +