Merge "Added ping6Host to run across a pair of v6 hosts with options specified"
diff --git a/TestON/bin/cleanup.sh b/TestON/bin/cleanup.sh
index 2d78b1e..abeb2e9 100755
--- a/TestON/bin/cleanup.sh
+++ b/TestON/bin/cleanup.sh
@@ -1,6 +1,7 @@
-#!/bin/bash 
+#!/bin/bash
 # This script will kill any TestON, ssh, and Mininet sessions that are running.
 sudo kill -9 `ps -ef | grep "./cli.py" | grep -v grep | awk '{print $2}'`
 sudo kill -9 `ps -ef | grep "bin/teston" | grep -v grep | awk '{print $2}'`
 sudo kill -9 `ps -ef | grep "ssh -X" | grep -v grep | awk '{print $2}'`
 sudo mn -c
+sudo pkill -f mn.pid
diff --git a/TestON/core/teston.py b/TestON/core/teston.py
index ae6fc4e..c2cb118 100644
--- a/TestON/core/teston.py
+++ b/TestON/core/teston.py
@@ -39,7 +39,7 @@
 global path, drivers_path, core_path, tests_path,logs_path
 location = os.path.abspath( os.path.dirname( __file__ ) )
 path = re.sub( "(core|bin)$", "", location )
-drivers_path = path+"drivers/"
+drivers_path = path+"drivers"
 core_path = path+"core"
 tests_path = path+"tests"
 logs_path = path+"logs/"
@@ -527,9 +527,8 @@
             try :
                 import json
                 response_dict = json.loads(response)
-            except Exception, e:
-                self.log.exception( e )
-                self.log.error("Json Parser is unable to parse the string")
+            except Exception:
+                self.log.exception( "Json Parser is unable to parse the string" )
             return response_dict
         elif ini_match :
             self.log.info(" Response is in 'INI' format and Converting to '"+return_format+"' format")
diff --git a/TestON/drivers/common/api/controller/onosrestdriver.py b/TestON/drivers/common/api/controller/onosrestdriver.py
index 42b7680..66cd8b4 100644
--- a/TestON/drivers/common/api/controller/onosrestdriver.py
+++ b/TestON/drivers/common/api/controller/onosrestdriver.py
@@ -27,11 +27,11 @@
 class OnosRestDriver( Controller ):
 
     def __init__( self ):
+        self.pwd = None
+        self.user_name = "user"
         super( Controller, self ).__init__()
         self.ip_address = "localhost"
         self.port = "8080"
-        self.user_name = "user"
-        self.password = "CHANGEME"
 
     def connect( self, **connectargs ):
         try:
@@ -56,7 +56,7 @@
         return self.handle
 
     def send( self, ip, port, url, base="/onos/v1", method="GET",
-              query=None, data=None ):
+              query=None, data=None, debug=False ):
         """
         Arguments:
             str ip: ONOS IP Address
@@ -76,12 +76,19 @@
         # ANSWER: Not yet, but potentially https with certificates
         try:
             path = "http://" + str( ip ) + ":" + str( port ) + base + url
+            if self.user_name and self.pwd:
+                auth = (self.user_name, self.pwd)
+            else:
+                auth=None
             main.log.info( "Sending request " + path + " using " +
                            method.upper() + " method." )
             response = requests.request( method.upper(),
                                          path,
                                          params=query,
-                                         data=data )
+                                         data=data,
+                                         auth=auth )
+            if debug:
+                main.log.debug( response )
             return ( response.status_code, response.text.encode( 'utf8' ) )
         except requests.exceptions:
             main.log.exception( "Error sending request." )
@@ -147,7 +154,7 @@
                 main.log.warn( "No ip given, reverting to ip from topo file" )
                 ip = self.ip_address
             if port == "DEFAULT":
-                main.log.warn( "No port given, reverting to port" +
+                main.log.warn( "No port given, reverting to port " +
                                "from topo file" )
                 port = self.port
             # NOTE: REST url requires the intent id to be in decimal form
@@ -207,8 +214,8 @@
                 main.log.warn( "No ip given, reverting to ip from topo file" )
                 ip = self.ip_address
             if port == "DEFAULT":
-                main.log.warn( "No port given, reverting to port \
-                               from topo file" )
+                main.log.warn( "No port given, reverting to port " +
+                               "from topo file" )
                 port = self.port
             response = self.send( ip, port, url="/applications" )
             if response:
@@ -244,7 +251,7 @@
                 main.log.warn( "No ip given, reverting to ip from topo file" )
                 ip = self.ip_address
             if port == "DEFAULT":
-                main.log.warn( "No port given, reverting to port" +
+                main.log.warn( "No port given, reverting to port " +
                                "from topo file" )
                 port = self.port
             query = "/" + str( appName ) + "/active"
@@ -296,7 +303,7 @@
                 main.log.warn( "No ip given, reverting to ip from topo file" )
                 ip = self.ip_address
             if port == "DEFAULT":
-                main.log.warn( "No port given, reverting to port" +
+                main.log.warn( "No port given, reverting to port " +
                                "from topo file" )
                 port = self.port
             query = "/" + str( appName ) + "/active"
@@ -346,7 +353,7 @@
                 main.log.warn( "No ip given, reverting to ip from topo file" )
                 ip = self.ip_address
             if port == "DEFAULT":
-                main.log.warn( "No port given, reverting to port" +
+                main.log.warn( "No port given, reverting to port " +
                                "from topo file" )
                 port = self.port
             query = "/" + project + str( appName )
@@ -673,8 +680,8 @@
                 main.log.warn( "No ip given, reverting to ip from topo file" )
                 ip = self.ip_address
             if port == "DEFAULT":
-                main.log.warn( "No port given, reverting to port \
-                               from topo file" )
+                main.log.warn( "No port given, reverting to port " +
+                               "from topo file" )
                 port = self.port
             response = self.send( ip, port, url="/hosts" )
             if response:
@@ -713,8 +720,8 @@
                 main.log.warn( "No ip given, reverting to ip from topo file" )
                 ip = self.ip_address
             if port == "DEFAULT":
-                main.log.warn( "No port given, reverting to port \
-                               from topo file" )
+                main.log.warn( "No port given, reverting to port " +
+                               "from topo file" )
                 port = self.port
             query = "/" + mac + "/" + vlan
             response = self.send( ip, port, url="/hosts" + query )
@@ -749,8 +756,8 @@
                 main.log.warn( "No ip given, reverting to ip from topo file" )
                 ip = self.ip_address
             if port == "DEFAULT":
-                main.log.warn( "No port given, reverting to port \
-                               from topo file" )
+                main.log.warn( "No port given, reverting to port " +
+                               "from topo file" )
                 port = self.port
             response = self.send( ip, port, url="/topology" )
             if response:
@@ -903,8 +910,8 @@
                 main.log.warn( "No ip given, reverting to ip from topo file" )
                 ip = self.ip_address
             if port == "DEFAULT":
-                main.log.warn( "No port given, reverting to port \
-                               from topo file" )
+                main.log.warn( "No port given, reverting to port " +
+                               "from topo file" )
                 port = self.port
             response = self.send( ip, port, url="/flows" )
             if response:
@@ -937,8 +944,8 @@
                 main.log.warn( "No ip given, reverting to ip from topo file" )
                 ip = self.ip_address
             if port == "DEFAULT":
-                main.log.warn( "No port given, reverting to port \
-                               from topo file" )
+                main.log.warn( "No port given, reverting to port " +
+                               "from topo file" )
                 port = self.port
             url = "/flows/" + device
             if flowId:
diff --git a/TestON/drivers/common/cli/onosclidriver.py b/TestON/drivers/common/cli/onosclidriver.py
index b33a5a9..7ff0cd1 100644
--- a/TestON/drivers/common/cli/onosclidriver.py
+++ b/TestON/drivers/common/cli/onosclidriver.py
@@ -3852,7 +3852,6 @@
             main.cleanup()
             main.exit()
 
-
     def summary( self, jsonFormat=True ):
         """
         Description: Execute summary command in onos
@@ -3886,3 +3885,128 @@
             main.log.exception( self.name + ": Uncaught exception!" )
             main.cleanup()
             main.exit()
+
+    def transactionalMapGet( self, keyName, inMemory=False ):
+        """
+        CLI command to get the value of a key in a consistent map using
+        transactions. This a test function and can only get keys from the
+        test map hard coded into the cli command
+        Required arguments:
+            keyName - The name of the key to get
+        Optional arguments:
+            inMemory - use in memory map for the counter
+        returns:
+            The string value of the key or
+            None on Error
+        """
+        try:
+            keyName = str( keyName )
+            cmdStr = "transactional-map-test-get "
+            if inMemory:
+                cmdStr += "-i "
+            cmdStr += keyName
+            output = self.sendline( cmdStr )
+            try:
+                # TODO: Maybe make this less hardcoded
+                # ConsistentMap Exceptions
+                assert "org.onosproject.store.service" not in output
+                # Node not leader
+                assert "java.lang.IllegalStateException" not in output
+            except AssertionError:
+                main.log.error( "Error in processing '" + cmdStr + "' " +
+                                "command: " + str( output ) )
+                return None
+            pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
+            if "Key " + keyName + " not found." in output:
+                return None
+            else:
+                match = re.search( pattern, output )
+                if match:
+                    return match.groupdict()[ 'value' ]
+                else:
+                    main.log.error( self.name + ": transactionlMapGet did not" +
+                                    " match expected output." )
+                    main.log.debug( self.name + " expected: " + pattern )
+                    main.log.debug( self.name + " actual: " + repr( output ) )
+                    return None
+        except TypeError:
+            main.log.exception( self.name + ": Object not as expected" )
+            return None
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
+
+    def transactionalMapPut( self, numKeys, value, inMemory=False ):
+        """
+        CLI command to put a value into 'numKeys' number of keys in a
+        consistent map using transactions. This a test function and can only
+        put into keys named 'Key#' of the test map hard coded into the cli command
+        Required arguments:
+            numKeys - Number of keys to add the value to
+            value - The string value to put into the keys
+        Optional arguments:
+            inMemory - use in memory map for the counter
+        returns:
+            A dictionary whose keys are the name of the keys put into the map
+            and the values of the keys are dictionaries whose key-values are
+            'value': value put into map and optionaly
+            'oldValue': Previous value in the key or
+            None on Error
+
+            Example output
+            { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
+              'Key2': {'value': 'Testing'} }
+        """
+        try:
+            numKeys = str( numKeys )
+            value = str( value )
+            cmdStr = "transactional-map-test-put "
+            if inMemory:
+                cmdStr += "-i "
+            cmdStr += numKeys + " " + value
+            output = self.sendline( cmdStr )
+            try:
+                # TODO: Maybe make this less hardcoded
+                # ConsistentMap Exceptions
+                assert "org.onosproject.store.service" not in output
+                # Node not leader
+                assert "java.lang.IllegalStateException" not in output
+            except AssertionError:
+                main.log.error( "Error in processing '" + cmdStr + "' " +
+                                "command: " + str( output ) )
+                return None
+            newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
+            updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
+            results = {}
+            for line in output.splitlines():
+                new = re.search( newPattern, line )
+                updated = re.search( updatedPattern, line )
+                if new:
+                    results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
+                elif updated:
+                    results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
+                                                            'oldValue': updated.groupdict()[ 'oldValue' ] }
+                else:
+                    main.log.error( self.name + ": transactionlMapGet did not" +
+                                    " match expected output." )
+                    main.log.debug( self.name + " expected: " + pattern )
+                    main.log.debug( self.name + " actual: " + repr( output ) )
+            return results
+        except TypeError:
+            main.log.exception( self.name + ": Object not as expected" )
+            return None
+        except pexpect.EOF:
+            main.log.error( self.name + ": EOF exception found" )
+            main.log.error( self.name + ":    " + self.handle.before )
+            main.cleanup()
+            main.exit()
+        except Exception:
+            main.log.exception( self.name + ": Uncaught exception!" )
+            main.cleanup()
+            main.exit()
diff --git a/TestON/tests/FUNCintent/FUNCintent.py b/TestON/tests/FUNCintent/FUNCintent.py
index 6aafd10..797a91a 100644
--- a/TestON/tests/FUNCintent/FUNCintent.py
+++ b/TestON/tests/FUNCintent/FUNCintent.py
@@ -7,7 +7,6 @@
 
     def CASE1( self, main ):
         import time
-        import os
         import imp
         import re
 
@@ -249,8 +248,8 @@
         main.caseExplanation = "Compare topology elements between Mininet" +\
                                 " and ONOS"
 
-        main.step( "Gathering topology information" )
-        # TODO: add a paramaterized sleep here
+        main.log.info( "Gathering topology information" )
+
         devicesResults = main.TRUE
         linksResults = main.TRUE
         hostsResults = main.TRUE
diff --git a/TestON/tests/FUNCintentRest/FUNCintentRest.py b/TestON/tests/FUNCintentRest/FUNCintentRest.py
index 0bc5c3c..e97bc9a 100644
--- a/TestON/tests/FUNCintentRest/FUNCintentRest.py
+++ b/TestON/tests/FUNCintentRest/FUNCintentRest.py
@@ -11,8 +11,8 @@
 
     def CASE1( self, main ):
         import time
-        import os
         import imp
+        import re
 
         """
         - Construct tests variables
@@ -33,7 +33,7 @@
 
         # Test variables
         try:
-            main.testOnDirectory = os.path.dirname( os.getcwd ( ) )
+            main.testOnDirectory = re.sub( "(/tests)$", "", main.testDir )
             main.apps = main.params[ 'ENV' ][ 'cellApps' ]
             gitBranch = main.params[ 'GIT' ][ 'branch' ]
             main.dependencyPath = main.testOnDirectory + \
@@ -64,8 +64,16 @@
             main.ONOSip = main.ONOSbench.getOnosIps()
 
             # Assigning ONOS cli handles to a list
-            for i in range( 1,  main.maxNodes + 1 ):
-                main.CLIs.append( getattr( main, 'ONOSrest' + str( i ) ) )
+            try:
+                for i in range( 1,  main.maxNodes + 1 ):
+                    main.CLIs.append( getattr( main, 'ONOSrest' + str( i ) ) )
+            except AttributeError:
+                main.log.warn( "A " + str( main.maxNodes ) + " node cluster " +
+                               "was defined in env variables, but only " +
+                               str( len( main.CLIs ) ) +
+                               " nodes were defined in the .topo file. " +
+                               "Using " + str( len( main.CLIs ) ) +
+                               " nodes for the test." )
 
             # -- INIT SECTION, ONLY RUNS ONCE -- #
             main.startUp = imp.load_source( wrapperFile1,
@@ -83,10 +91,11 @@
                                          wrapperFile3 +
                                          ".py" )
 
-            copyResult = main.ONOSbench.copyMininetFile( main.topology,
-                                                         main.dependencyPath,
-                                                         main.Mininet1.user_name,
-                                                         main.Mininet1.ip_address )
+            copyResult1 = main.ONOSbench.scp( main.Mininet1,
+                                              main.dependencyPath +
+                                              main.topology,
+                                              main.Mininet1.home,
+                                              direction="to" )
             if main.CLIs:
                 stepResult = main.TRUE
             else:
@@ -179,9 +188,9 @@
         time.sleep( main.startUpSleep )
         main.step( "Uninstalling ONOS package" )
         onosUninstallResult = main.TRUE
-        for i in range( main.numCtrls ):
+        for ip in main.ONOSip:
             onosUninstallResult = onosUninstallResult and \
-                    main.ONOSbench.onosUninstall( nodeIp=main.ONOSip[ i ] )
+                    main.ONOSbench.onosUninstall( nodeIp=ip )
         stepResult = onosUninstallResult
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
diff --git a/TestON/tests/FUNCintentRest/FUNCintentRest.topo b/TestON/tests/FUNCintentRest/FUNCintentRest.topo
index 647bdc6..efed3d6 100755
--- a/TestON/tests/FUNCintentRest/FUNCintentRest.topo
+++ b/TestON/tests/FUNCintentRest/FUNCintentRest.topo
@@ -14,8 +14,8 @@
         <ONOSrest1>
             <host>OC1</host>
             <port>8181</port>
-            <user>admin</user>
-            <password>onos_test</password>
+            <user>onos</user>
+            <password>rocks</password>
             <type>OnosRestDriver</type>
             <connect_order>2</connect_order>
             <COMPONENTS>
@@ -25,8 +25,8 @@
         <ONOSrest2>
             <host>OC2</host>
             <port>8181</port>
-            <user>admin</user>
-            <password>onos_test</password>
+            <user>onos</user>
+            <password>rocks</password>
             <type>OnosRestDriver</type>
             <connect_order>3</connect_order>
             <COMPONENTS>
@@ -36,8 +36,8 @@
         <ONOSrest3>
             <host>OC3</host>
             <port>8181</port>
-            <user>admin</user>
-            <password>onos_test</password>
+            <user>onos</user>
+            <password>rocks</password>
             <type>OnosRestDriver</type>
             <connect_order>4</connect_order>
             <COMPONENTS>
diff --git a/TestON/tests/FUNCovsdbtest/FUNCovsdbtest.topo b/TestON/tests/FUNCovsdbtest/FUNCovsdbtest.topo
index f788471..ae748d2 100644
--- a/TestON/tests/FUNCovsdbtest/FUNCovsdbtest.topo
+++ b/TestON/tests/FUNCovsdbtest/FUNCovsdbtest.topo
@@ -3,7 +3,7 @@
 
         <ONOSbench>
             <host>OCN</host>
-            <user>onos</user>
+            <user>admin</user>
             <password></password>
             <type>OnosDriver</type>
             <connect_order>1</connect_order>
@@ -13,7 +13,7 @@
 
         <ONOScli1>
             <host>OCN</host>
-            <user>onos</user>
+            <user>admin</user>
             <password></password>
             <type>OnosCliDriver</type>
             <connect_order>2</connect_order>
@@ -22,7 +22,7 @@
 
         <ONOS1>
             <host>OC1</host>
-            <user>onos</user>
+            <user>sdn</user>
             <password></password>
             <type>OnosDriver</type>
             <connect_order>3</connect_order>
@@ -31,7 +31,7 @@
 
         <ONOSrest>
             <host>OC1</host>
-            <user>onos</user>
+            <user>sdn</user>
             <password></password>
             <type>OnosRestDriver</type>
             <connect_order>4</connect_order>
@@ -40,7 +40,7 @@
 
         <OVSDB1>
             <host>OCN</host>
-            <user>onos</user>
+            <user>admin</user>
             <password></password>
             <type>OvsdbDriver</type>
             <connect_order>5</connect_order>
@@ -49,7 +49,7 @@
 
         <OVSDB2>
             <host>OC1</host>
-            <user>onos</user>
+            <user>sdn</user>
             <password></password>
             <type>OvsdbDriver</type>
             <connect_order>6</connect_order>
diff --git a/TestON/tests/HAclusterRestart/HAclusterRestart.params b/TestON/tests/HAclusterRestart/HAclusterRestart.params
index 213fc0d..627bec2 100644
--- a/TestON/tests/HAclusterRestart/HAclusterRestart.params
+++ b/TestON/tests/HAclusterRestart/HAclusterRestart.params
@@ -1,4 +1,22 @@
 <PARAMS>
+    #CASE1: Compile ONOS and push it to the test machines
+    #CASE2: Assign devices to controllers
+    #CASE21: Assign mastership to controllers
+    #CASE3: Assign intents
+    #CASE4: Ping across added host intents
+    #CASE5: Reading state of ONOS
+    #CASE6: The Failure case.
+    #CASE7: Check state after control plane failure
+    #CASE8: Compare topo
+    #CASE9: Link s3-s28 down
+    #CASE10: Link s3-s28 up
+    #CASE11: Switch down
+    #CASE12: Switch up
+    #CASE13: Clean up
+    #CASE14: start election app on all onos nodes
+    #CASE15: Check that Leadership Election is still functional
+    #CASE16: Install Distributed Primitives app
+    #CASE17: Check for basic functionality with distributed primitives
     <testcases>1,2,8,3,8,4,5,14,16,17,[6],8,3,7,4,15,17,9,8,4,10,8,4,11,8,4,12,8,4,13</testcases>
     <imports>
         <path> /home/admin/OnosSystemTest/TestON/tests/HAclusterRestart/dependencies/ </path>
@@ -49,8 +67,8 @@
         <target10>10.0.0.27</target10>
     </PING>
     <timers>
-        <LinkDiscovery>.2</LinkDiscovery>
-        <SwitchDiscovery>.2</SwitchDiscovery>
+        <LinkDiscovery>12</LinkDiscovery>
+        <SwitchDiscovery>12</SwitchDiscovery>
     </timers>
     <kill>
         <switch> s5 </switch>
diff --git a/TestON/tests/HAclusterRestart/HAclusterRestart.py b/TestON/tests/HAclusterRestart/HAclusterRestart.py
index d138096..352009f 100644
--- a/TestON/tests/HAclusterRestart/HAclusterRestart.py
+++ b/TestON/tests/HAclusterRestart/HAclusterRestart.py
@@ -2811,6 +2811,17 @@
     def CASE15( self, main ):
         """
         Check that Leadership Election is still functional
+            15.1 Run election on each node
+            15.2 Check that each node has the same leaders and candidates
+            15.3 Find current leader and withdraw
+            15.4 Check that a new node was elected leader
+            15.5 Check that that new leader was the candidate of old leader
+            15.6 Run for election on old leader
+            15.7 Check that oldLeader is a candidate, and leader if only 1 node
+            15.8 Make sure that the old leader was added to the candidate list
+
+            old and new variable prefixes refer to data from before vs after
+                withdrawl and later before withdrawl vs after re-election
         """
         import time
         assert main.numCtrls, "main.numCtrls not defined"
@@ -2819,113 +2830,148 @@
         assert main.CLIs, "main.CLIs not defined"
         assert main.nodes, "main.nodes not defined"
 
-        leaderResult = main.TRUE
         description = "Check that Leadership Election is still functional"
         main.case( description )
         # NOTE: Need to re-run since being a canidate is not persistant
+        # TODO: add check for "Command not found:" in the driver, this
+        #       means the election test app isn't loaded
+
+        oldLeaders = []  # leaders by node before withdrawl from candidates
+        newLeaders = []  # leaders by node after withdrawl from candidates
+        oldAllCandidates = []  # list of lists of each nodes' candidates before
+        newAllCandidates = []  # list of lists of each nodes' candidates after
+        oldCandidates = []  # list of candidates from node 0 before withdrawl
+        newCandidates = []  # list of candidates from node 0 after withdrawl
+        oldLeader = ''  # the old leader from oldLeaders, None if not same
+        newLeader = ''  # the new leaders fron newLoeaders, None if not same
+        oldLeaderCLI = None  # the CLI of the old leader used for re-electing
+
         main.step( "Run for election on each node" )
-        leaderResult = main.TRUE
-        leaders = []
-        for cli in main.CLIs:
-            cli.electionTestRun()
-        for cli in main.CLIs:
-            leader = cli.electionTestLeader()
-            if leader is None or leader == main.FALSE:
-                main.log.error( cli.name + ": Leader for the election app " +
-                                 "should be an ONOS node, instead got '" +
-                                 str( leader ) + "'" )
-                leaderResult = main.FALSE
-            leaders.append( leader )
+        electionResult = main.TRUE
+
+        for cli in main.CLIs:  # run test election on each node
+            if cli.electionTestRun() == main.FALSE:
+                electionResult = main.FALSE
+
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=leaderResult,
-            onpass="Successfully ran for leadership",
-            onfail="Failed to run for leadership" )
+            actual=electionResult,
+            onpass="All nodes successfully ran for leadership",
+            onfail="At least one node failed to run for leadership" )
 
-        main.step( "Check that each node shows the same leader" )
-        sameLeader = main.TRUE
-        if len( set( leaders ) ) != 1:
-            sameLeader = main.FALSE
-            main.log.error( "Results of electionTestLeader is order of main.CLIs:" +
-                            str( leaders ) )
+        main.step( "Check that each node shows the same leader and candidates" )
+        sameResult = main.TRUE
+        failMessage = "Nodes have different leaders"
+        for cli in main.CLIs:
+            node = cli.specificLeaderCandidate( 'org.onosproject.election' )
+            oldAllCandidates.append( node )
+            oldLeaders.append( node[ 0 ] )
+        oldCandidates = oldAllCandidates[ 0 ]
+
+        # Check that each node has the same leader. Defines oldLeader
+        if len( set( oldLeaders ) ) != 1:
+            sameResult = main.FALSE
+            main.log.error( "Results of electionTestLeader is order of " +
+                "main.CLIs:" + str( oldLeaders ) )
+            oldLeader = None
+        else:
+            oldLeader = oldLeaders[ 0 ]
+
+        # Check that each node's candidate list is the same
+        for candidates in oldAllCandidates:
+            if set( candidates ) != set( oldCandidates ):
+                sameResult = main.FALSE
+                failMessage += "and candidates"
+
         utilities.assert_equals(
             expect=main.TRUE,
             actual=sameLeader,
             onpass="Leadership is consistent for the election topic",
-            onfail="Nodes have different leaders" )
+            onfail=failMessage )
 
         main.step( "Find current leader and withdraw" )
-        leader = main.ONOScli1.electionTestLeader()
+        withdrawResult = main.TRUE
         # do some sanity checking on leader before using it
-        withdrawResult = main.FALSE
-        if leader is None or leader == main.FALSE:
-            main.log.error(
-                "Leader for the election app should be an ONOS node," +
-                "instead got '" + str( leader ) + "'" )
-            leaderResult = main.FALSE
-            oldLeader = None
+        if oldLeader is None:
+            main.log.error( "Leadership isn't consistent." )
+            withdrawResult = main.FALSE
+        # Get the CLI of the oldLeader
         for i in range( len( main.CLIs ) ):
-            if leader == main.nodes[ i ].ip_address:
-                oldLeader = main.CLIs[ i ]
+            if oldLeader == main.nodes[ i ].ip_address:
+                oldLeaderCLI = main.CLIs[ i ]
                 break
         else:  # FOR/ELSE statement
             main.log.error( "Leader election, could not find current leader" )
         if oldLeader:
-            withdrawResult = oldLeader.electionTestWithdraw()
+            withdrawResult = oldLeaderCLI.electionTestWithdraw()
         utilities.assert_equals(
             expect=main.TRUE,
             actual=withdrawResult,
             onpass="Node was withdrawn from election",
             onfail="Node was not withdrawn from election" )
 
-        main.step( "Make sure new leader is elected" )
+        main.step( "Check that a new node was elected leader" )
         # FIXME: use threads
-        leaderList = []
+        newLeaderResult = main.TRUE
+        failMessage = "Nodes have different leaders"
+
+        # Get new leaders and candidates
         for cli in main.CLIs:
-            leaderN = cli.electionTestLeader()
-            leaderList.append( leaderN )
-            if leaderN == leader:
-                main.log.error(  cli.name + " still sees " + str( leader ) +
-                                  " as leader after they withdrew" )
-                leaderResult = main.FALSE
-            elif leaderN == main.FALSE:
-                # error in  response
-                # TODO: add check for "Command not found:" in the driver, this
-                #       means the app isn't loaded
-                main.log.error( "Something is wrong with " +
-                                 "electionTestLeader function, " +
-                                 "check the error logs" )
-                leaderResult = main.FALSE
-            elif leaderN is None:
-                # node may not have recieved the event yet
-                time.sleep(7)
-                leaderN = cli.electionTestLeader()
-                leaderList.pop()
-                leaderList.append( leaderN )
-        consistentLeader = main.FALSE
-        if len( set( leaderList ) ) == 1:
-            main.log.info( "Each Election-app sees '" +
-                           str( leaderList[ 0 ] ) +
-                           "' as the leader" )
-            consistentLeader = main.TRUE
+            node = cli.specificLeaderCandidate( 'org.onosproject.election' )
+            if node[ 0 ] == 'none':  # election might no have finished yet
+                main.log.info( "Node has no leader, waiting 5 seconds to be " +
+                    "sure elections are complete." )
+                time.sleep(5)
+                node = cli.specificLeaderCandidate( 'org.onosproject.election' )
+            if node[ 0 ] == 'none':  # election still isn't done, errors
+                main.log.error( "No leader was elected on at least one node" )
+                newLeaderResult = main.FALSE
+            newAllCandidates.append( node )
+            newLeaders.append( node[ 0 ] )
+        newCandidates = newAllCandidates[ 0 ]
+
+        # Check that each node has the same leader. Defines newLeader
+        if len( set( newLeaders ) ) != 1:
+            newLeaderResult = main.FALSE
+            main.log.error( "Nodes have different leaders: " +
+                            str( newLeaders ) )
+            newLeader = None
         else:
-            main.log.error(
-                "Inconsistent responses for leader of Election-app:" )
-            for n in range( len( leaderList ) ):
-                main.log.error( "ONOS" + str( n + 1 ) + " response: " +
-                                 str( leaderList[ n ] ) )
-        leaderResult = leaderResult and consistentLeader
+            newLeader = newLeaders[ 0 ]
+
+        # Check that the new leader is not the older leader, which was withdrawn
+        if newLeader == oldLeader:
+            newLeaderResult = main.FALSE
+            main.log.error( "All nodes still see old leader: " + oldLeader +
+                " as the current leader" )
+
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=leaderResult,
+            actual=newLeaderResult,
             onpass="Leadership election passed",
             onfail="Something went wrong with Leadership election" )
 
+        main.step( "Check that that new leader was the candidate of old leader")
+        # candidates[ 2 ] should be come the top candidate after withdrawl
+        correctCandidateResult = main.TRUE
+
+        if newLeader != oldCandidates[ 2 ]:
+            correctCandidateResult = main.FALSE
+            main.log.error( "Candidate " + newLeader + " was elected. " +
+                oldCandidates[ 2 ] + " should have had priority." )
+
+        utilities.assert_equals(
+            expect=main.TRUE,
+            actual=correctCandidateResult,
+            onpass="Correct Candidate Elected",
+            onfail="Incorrect Candidate Elected" )
+
         main.step( "Run for election on old leader( just so everyone " +
                    "is in the hat )" )
-        if oldLeader:
-            runResult = oldLeader.electionTestRun()
+        if oldLeaderCLI is not None:
+            runResult = oldLeaderCLI.electionTestRun()
         else:
+            main.log.error( "No old leader to re-elect" )
             runResult = main.FALSE
         utilities.assert_equals(
             expect=main.TRUE,
@@ -2933,17 +2979,51 @@
             onpass="App re-ran for election",
             onfail="App failed to run for election" )
 
-        main.step( "Leader did not change when old leader re-ran" )
-        afterRun = main.ONOScli1.electionTestLeader()
+
+
+        main.step(
+            "Check that oldLeader is a candidate, and leader if only 1 node" )
         # verify leader didn't just change
-        if afterRun == leaderList[ 0 ]:
-            afterResult = main.TRUE
+        positionResult = main.TRUE
+        # Get new leaders and candidates, wait if oldLeader is not a candidate yet
+
+        # Reset and reuse the new candidate and leaders lists
+        newAllCandidates = []
+        newCandidates = []
+        newLeaders = []
+        for cli in main.CLIs:
+            node = cli.specificLeaderCandidate( 'org.onosproject.election' )
+            if oldLeader not in node:  # election might no have finished yet
+                main.log.info( "Old Leader not elected, waiting 5 seconds to " +
+                    "be sure elections are complete" )
+                time.sleep(5)
+                node = cli.specificLeaderCandidate( 'org.onosproject.election' )
+            if oldLeader not in node:  # election still isn't done, errors
+                main.log.error(
+                    "Old leader was not elected on at least one node" )
+                positionResult = main.FALSE
+            newAllCandidates.append( node )
+            newLeaders.append( node[ 0 ] )
+        newCandidates = newAllCandidates[ 0 ]
+
+        # Check that each node has the same leader. Defines newLeader
+        if len( set( newLeaders ) ) != 1:
+            positionResult = main.FALSE
+            main.log.error( "Nodes have different leaders: " +
+                            str( newLeaders ) )
+            newLeader = None
         else:
-            afterResult = main.FALSE
+            newLeader = newLeaders[ 0 ]
+
+        # Check that the re-elected node is last on the candidate List
+        if oldLeader != newCandidates[ -1 ]:
+            main.log.error( "Old Leader ("  + oldLeader + ") not in the proper position " +
+                str( newCandidates ) )
+            positionResult = main.FALSE
 
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=afterResult,
+            actual=positionResult,
             onpass="Old leader successfully re-ran for election",
             onfail="Something went wrong with Leadership election after " +
                    "the old leader re-ran for election" )
@@ -4284,3 +4364,94 @@
                                  onpass="Set retain correct",
                                  onfail="Set retain was incorrect" )
 
+        # Transactional maps
+        main.step( "Partitioned Transactional maps put" )
+        tMapValue = "Testing"
+        numKeys = 100
+        putResult = True
+        putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue )
+        if len( putResponses ) == 100:
+            for i in putResponses:
+                if putResponses[ i ][ 'value' ] != tMapValue:
+                    putResult = False
+        else:
+            putResult = False
+        if not putResult:
+            main.log.debug( "Put response values: " + str( putResponses ) )
+        utilities.assert_equals( expect=True,
+                                 actual=putResult,
+                                 onpass="Partitioned Transactional Map put successful",
+                                 onfail="Partitioned Transactional Map put values are incorrect" )
+
+        main.step( "Partitioned Transactional maps get" )
+        getCheck = True
+        for n in range( 1, numKeys + 1 ):
+            getResponses = []
+            threads = []
+            valueCheck = True
+            for i in range( main.numCtrls ):
+                t = main.Thread( target=main.CLIs[i].transactionalMapGet,
+                                 name="TMap-get-" + str( i ),
+                                 args=[ "Key" + str ( n ) ] )
+                threads.append( t )
+                t.start()
+            for t in threads:
+                t.join()
+                getResponses.append( t.result )
+            for node in getResponses:
+                if node != tMapValue:
+                    valueCheck = False
+            if not valueCheck:
+                main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
+                main.log.warn( getResponses )
+            getCheck = getCheck and valueCheck
+        utilities.assert_equals( expect=True,
+                                 actual=getCheck,
+                                 onpass="Partitioned Transactional Map get values were correct",
+                                 onfail="Partitioned Transactional Map values incorrect" )
+
+        main.step( "In-memory Transactional maps put" )
+        tMapValue = "Testing"
+        numKeys = 100
+        putResult = True
+        putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue, inMemory=True )
+        if len( putResponses ) == 100:
+            for i in putResponses:
+                if putResponses[ i ][ 'value' ] != tMapValue:
+                    putResult = False
+        else:
+            putResult = False
+        if not putResult:
+            main.log.debug( "Put response values: " + str( putResponses ) )
+        utilities.assert_equals( expect=True,
+                                 actual=putResult,
+                                 onpass="In-Memory Transactional Map put successful",
+                                 onfail="In-Memory Transactional Map put values are incorrect" )
+
+        main.step( "In-Memory Transactional maps get" )
+        getCheck = True
+        for n in range( 1, numKeys + 1 ):
+            getResponses = []
+            threads = []
+            valueCheck = True
+            for i in range( main.numCtrls ):
+                t = main.Thread( target=main.CLIs[i].transactionalMapGet,
+                                 name="TMap-get-" + str( i ),
+                                 args=[ "Key" + str ( n ) ],
+                                 kwargs={ "inMemory": True } )
+                threads.append( t )
+                t.start()
+            for t in threads:
+                t.join()
+                getResponses.append( t.result )
+            for node in getResponses:
+                if node != tMapValue:
+                    valueCheck = False
+            if not valueCheck:
+                main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
+                main.log.warn( getResponses )
+            getCheck = getCheck and valueCheck
+        utilities.assert_equals( expect=True,
+                                 actual=getCheck,
+                                 onpass="In-Memory Transactional Map get values were correct",
+                                 onfail="In-Memory Transactional Map values incorrect" )
diff --git a/TestON/tests/HAminorityRestart/HAminorityRestart.params b/TestON/tests/HAminorityRestart/HAminorityRestart.params
index 87d1cea..1e08a6b 100644
--- a/TestON/tests/HAminorityRestart/HAminorityRestart.params
+++ b/TestON/tests/HAminorityRestart/HAminorityRestart.params
@@ -49,8 +49,8 @@
         <target10>10.0.0.27</target10>
     </PING>
     <timers>
-        <LinkDiscovery>.2</LinkDiscovery>
-        <SwitchDiscovery>.2</SwitchDiscovery>
+        <LinkDiscovery>12</LinkDiscovery>
+        <SwitchDiscovery>12</SwitchDiscovery>
     </timers>
     <kill>
         <switch> s5 </switch>
diff --git a/TestON/tests/HAminorityRestart/HAminorityRestart.py b/TestON/tests/HAminorityRestart/HAminorityRestart.py
index c9d3e6d..5fee9b1 100644
--- a/TestON/tests/HAminorityRestart/HAminorityRestart.py
+++ b/TestON/tests/HAminorityRestart/HAminorityRestart.py
@@ -4215,3 +4215,94 @@
                                  onpass="Set retain correct",
                                  onfail="Set retain was incorrect" )
 
+        # Transactional maps
+        main.step( "Partitioned Transactional maps put" )
+        tMapValue = "Testing"
+        numKeys = 100
+        putResult = True
+        putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue )
+        if len( putResponses ) == 100:
+            for i in putResponses:
+                if putResponses[ i ][ 'value' ] != tMapValue:
+                    putResult = False
+        else:
+            putResult = False
+        if not putResult:
+            main.log.debug( "Put response values: " + str( putResponses ) )
+        utilities.assert_equals( expect=True,
+                                 actual=putResult,
+                                 onpass="Partitioned Transactional Map put successful",
+                                 onfail="Partitioned Transactional Map put values are incorrect" )
+
+        main.step( "Partitioned Transactional maps get" )
+        getCheck = True
+        for n in range( 1, numKeys + 1 ):
+            getResponses = []
+            threads = []
+            valueCheck = True
+            for i in range( main.numCtrls ):
+                t = main.Thread( target=main.CLIs[i].transactionalMapGet,
+                                 name="TMap-get-" + str( i ),
+                                 args=[ "Key" + str ( n ) ] )
+                threads.append( t )
+                t.start()
+            for t in threads:
+                t.join()
+                getResponses.append( t.result )
+            for node in getResponses:
+                if node != tMapValue:
+                    valueCheck = False
+            if not valueCheck:
+                main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
+                main.log.warn( getResponses )
+            getCheck = getCheck and valueCheck
+        utilities.assert_equals( expect=True,
+                                 actual=getCheck,
+                                 onpass="Partitioned Transactional Map get values were correct",
+                                 onfail="Partitioned Transactional Map values incorrect" )
+
+        main.step( "In-memory Transactional maps put" )
+        tMapValue = "Testing"
+        numKeys = 100
+        putResult = True
+        putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue, inMemory=True )
+        if len( putResponses ) == 100:
+            for i in putResponses:
+                if putResponses[ i ][ 'value' ] != tMapValue:
+                    putResult = False
+        else:
+            putResult = False
+        if not putResult:
+            main.log.debug( "Put response values: " + str( putResponses ) )
+        utilities.assert_equals( expect=True,
+                                 actual=putResult,
+                                 onpass="In-Memory Transactional Map put successful",
+                                 onfail="In-Memory Transactional Map put values are incorrect" )
+
+        main.step( "In-Memory Transactional maps get" )
+        getCheck = True
+        for n in range( 1, numKeys + 1 ):
+            getResponses = []
+            threads = []
+            valueCheck = True
+            for i in range( main.numCtrls ):
+                t = main.Thread( target=main.CLIs[i].transactionalMapGet,
+                                 name="TMap-get-" + str( i ),
+                                 args=[ "Key" + str ( n ) ],
+                                 kwargs={ "inMemory": True } )
+                threads.append( t )
+                t.start()
+            for t in threads:
+                t.join()
+                getResponses.append( t.result )
+            for node in getResponses:
+                if node != tMapValue:
+                    valueCheck = False
+            if not valueCheck:
+                main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
+                main.log.warn( getResponses )
+            getCheck = getCheck and valueCheck
+        utilities.assert_equals( expect=True,
+                                 actual=getCheck,
+                                 onpass="In-Memory Transactional Map get values were correct",
+                                 onfail="In-Memory Transactional Map values incorrect" )
diff --git a/TestON/tests/HAsanity/HAsanity.params b/TestON/tests/HAsanity/HAsanity.params
index abc5385..0aefe97 100644
--- a/TestON/tests/HAsanity/HAsanity.params
+++ b/TestON/tests/HAsanity/HAsanity.params
@@ -68,8 +68,8 @@
         <target10>10.0.0.27</target10>
     </PING>
     <timers>
-        <LinkDiscovery>.2</LinkDiscovery>
-        <SwitchDiscovery>.2</SwitchDiscovery>
+        <LinkDiscovery>12</LinkDiscovery>
+        <SwitchDiscovery>12</SwitchDiscovery>
     </timers>
     <kill>
         <switch> s5 </switch>
diff --git a/TestON/tests/HAsanity/HAsanity.py b/TestON/tests/HAsanity/HAsanity.py
index c2a1872..e404da4 100644
--- a/TestON/tests/HAsanity/HAsanity.py
+++ b/TestON/tests/HAsanity/HAsanity.py
@@ -4178,3 +4178,94 @@
                                  onpass="Set retain correct",
                                  onfail="Set retain was incorrect" )
 
+        # Transactional maps
+        main.step( "Partitioned Transactional maps put" )
+        tMapValue = "Testing"
+        numKeys = 100
+        putResult = True
+        putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue )
+        if len( putResponses ) == 100:
+            for i in putResponses:
+                if putResponses[ i ][ 'value' ] != tMapValue:
+                    putResult = False
+        else:
+            putResult = False
+        if not putResult:
+            main.log.debug( "Put response values: " + str( putResponses ) )
+        utilities.assert_equals( expect=True,
+                                 actual=putResult,
+                                 onpass="Partitioned Transactional Map put successful",
+                                 onfail="Partitioned Transactional Map put values are incorrect" )
+
+        main.step( "Partitioned Transactional maps get" )
+        getCheck = True
+        for n in range( 1, numKeys + 1 ):
+            getResponses = []
+            threads = []
+            valueCheck = True
+            for i in range( main.numCtrls ):
+                t = main.Thread( target=main.CLIs[i].transactionalMapGet,
+                                 name="TMap-get-" + str( i ),
+                                 args=[ "Key" + str ( n ) ] )
+                threads.append( t )
+                t.start()
+            for t in threads:
+                t.join()
+                getResponses.append( t.result )
+            for node in getResponses:
+                if node != tMapValue:
+                    valueCheck = False
+            if not valueCheck:
+                main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
+                main.log.warn( getResponses )
+            getCheck = getCheck and valueCheck
+        utilities.assert_equals( expect=True,
+                                 actual=getCheck,
+                                 onpass="Partitioned Transactional Map get values were correct",
+                                 onfail="Partitioned Transactional Map values incorrect" )
+
+        main.step( "In-memory Transactional maps put" )
+        tMapValue = "Testing"
+        numKeys = 100
+        putResult = True
+        putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue, inMemory=True )
+        if len( putResponses ) == 100:
+            for i in putResponses:
+                if putResponses[ i ][ 'value' ] != tMapValue:
+                    putResult = False
+        else:
+            putResult = False
+        if not putResult:
+            main.log.debug( "Put response values: " + str( putResponses ) )
+        utilities.assert_equals( expect=True,
+                                 actual=putResult,
+                                 onpass="In-Memory Transactional Map put successful",
+                                 onfail="In-Memory Transactional Map put values are incorrect" )
+
+        main.step( "In-Memory Transactional maps get" )
+        getCheck = True
+        for n in range( 1, numKeys + 1 ):
+            getResponses = []
+            threads = []
+            valueCheck = True
+            for i in range( main.numCtrls ):
+                t = main.Thread( target=main.CLIs[i].transactionalMapGet,
+                                 name="TMap-get-" + str( i ),
+                                 args=[ "Key" + str ( n ) ],
+                                 kwargs={ "inMemory": True } )
+                threads.append( t )
+                t.start()
+            for t in threads:
+                t.join()
+                getResponses.append( t.result )
+            for node in getResponses:
+                if node != tMapValue:
+                    valueCheck = False
+            if not valueCheck:
+                main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
+                main.log.warn( getResponses )
+            getCheck = getCheck and valueCheck
+        utilities.assert_equals( expect=True,
+                                 actual=getCheck,
+                                 onpass="In-Memory Transactional Map get values were correct",
+                                 onfail="In-Memory Transactional Map values incorrect" )
diff --git a/TestON/tests/HAsingleInstanceRestart/HAsingleInstanceRestart.params b/TestON/tests/HAsingleInstanceRestart/HAsingleInstanceRestart.params
index b0b644e..ce0abe0 100644
--- a/TestON/tests/HAsingleInstanceRestart/HAsingleInstanceRestart.params
+++ b/TestON/tests/HAsingleInstanceRestart/HAsingleInstanceRestart.params
@@ -58,8 +58,8 @@
         <target10>10.0.0.27</target10>
     </PING>
     <timers>
-        <LinkDiscovery>.2</LinkDiscovery>
-        <SwitchDiscovery>.2</SwitchDiscovery>
+        <LinkDiscovery>12</LinkDiscovery>
+        <SwitchDiscovery>12</SwitchDiscovery>
     </timers>
     <kill>
         <switch> s5 </switch>
diff --git a/TestON/tests/HAsingleInstanceRestart/HAsingleInstanceRestart.py b/TestON/tests/HAsingleInstanceRestart/HAsingleInstanceRestart.py
index 14a90af..2b81175 100644
--- a/TestON/tests/HAsingleInstanceRestart/HAsingleInstanceRestart.py
+++ b/TestON/tests/HAsingleInstanceRestart/HAsingleInstanceRestart.py
@@ -1882,12 +1882,24 @@
         assert main.numCtrls, "main.numCtrls not defined"
         assert main, "main not defined"
         assert utilities.assert_equals, "utilities.assert_equals not defined"
-        leaderResult = main.TRUE
+        electionResult = main.TRUE
+        candidateElected = main.TRUE
         description = "Check that Leadership Election is still functional"
         main.case( description )
         main.step( "Find current leader and withdraw" )
         leader = main.ONOScli1.electionTestLeader()
-        # do some sanity checking on leader before using it
+
+        # save candidate status before leader withdraw
+        candidateList = main.ONOScli1.specificLeaderCandidate(
+            'org.onosproject.election' )
+        # if there is only one leader available
+        onlyOneLeader = False
+        if len( candidateList ) == 2:
+            main.log.info( "Leader and Candidate are the same, " +
+                "assuming only 1 leader exists" )
+            onlyOneLeader = True
+
+        # withdraw the current leader
         withdrawResult = main.FALSE
         if leader == main.nodes[0].ip_address:
             oldLeader = getattr( main, "ONOScli1" )
@@ -1909,29 +1921,41 @@
             onpass="Node was withdrawn from election",
             onfail="Node was not withdrawn from election" )
 
-        main.step( "Make sure new leader is elected" )
-        leaderN = main.ONOScli1.electionTestLeader()
-        if leaderN == leader:
+        main.step( "Checking Leadership Withdrawl and Election Result" )
+        leaderN = main.ONOScli1.electionTestLeader()  # Get new leader
+        candidatePassMessage = ""
+        # Check that the candidate was elected (if there was one)
+        if leaderN == leader: # Case Fails
             main.log.error( "ONOS still sees " + str( leaderN ) +
                              " as leader after they withdrew" )
-            leaderResult = main.FALSE
-        elif leaderN == main.FALSE:
+            electionResult = main.FALSE
+        elif onlyOneLeader and ( leaderN == None ):  # Case Passes
+            candidateElected = main.TRUE
+            candidatePassMessage = ( "No leader after only leader was " +
+                "withdrawn. Election passed." )
+        elif leaderN == candidateList[ 1 ]:
+            # Case Passes
+            candidateElected = main.TRUE
+            candidatePassMessage = "Old leader's candidate elected to leader"
+        elif leaderN == main.FALSE:  # Case Fails
             # error in  response
             # TODO: add check for "Command not found:" in the driver, this
             # means the app isn't loaded
             main.log.error( "Something is wrong with electionTestLeader " +
                              "function, check the error logs" )
-            leaderResult = main.FALSE
-        elif leaderN is None:
-            main.log.info(
-                "There is no leader after the app withdrew from election" )
-            leaderResult = main.TRUE
+            electionResult = main.FALSE
+        else:  # Case Fails
+            # Catches weird cases like
+            # leaderN = None when there was multiple leaders
+            candidateElected = main.FALSE
         utilities.assert_equals(
             expect=main.TRUE,
-            actual=leaderResult,
-            onpass="Leadership election passed",
-            onfail="Something went wrong with Leadership election" )
+            actual=electionResult and candidateElected,
+            onpass=candidatePassMessage,
+            onfail="The new leader was not the old leader election candidate"
+        )
 
+        # Elect oldLeader back
         main.step( "Run for election on old leader( just so everyone " +
                    "is in the hat )" )
         if oldLeader:
@@ -3293,3 +3317,94 @@
                                  onpass="Set retain correct",
                                  onfail="Set retain was incorrect" )
 
+        # Transactional maps
+        main.step( "Partitioned Transactional maps put" )
+        tMapValue = "Testing"
+        numKeys = 100
+        putResult = True
+        putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue )
+        if len( putResponses ) == 100:
+            for i in putResponses:
+                if putResponses[ i ][ 'value' ] != tMapValue:
+                    putResult = False
+        else:
+            putResult = False
+        if not putResult:
+            main.log.debug( "Put response values: " + str( putResponses ) )
+        utilities.assert_equals( expect=True,
+                                 actual=putResult,
+                                 onpass="Partitioned Transactional Map put successful",
+                                 onfail="Partitioned Transactional Map put values are incorrect" )
+
+        main.step( "Partitioned Transactional maps get" )
+        getCheck = True
+        for n in range( 1, numKeys + 1 ):
+            getResponses = []
+            threads = []
+            valueCheck = True
+            for i in range( main.numCtrls ):
+                t = main.Thread( target=main.CLIs[i].transactionalMapGet,
+                                 name="TMap-get-" + str( i ),
+                                 args=[ "Key" + str ( n ) ] )
+                threads.append( t )
+                t.start()
+            for t in threads:
+                t.join()
+                getResponses.append( t.result )
+            for node in getResponses:
+                if node != tMapValue:
+                    valueCheck = False
+            if not valueCheck:
+                main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
+                main.log.warn( getResponses )
+            getCheck = getCheck and valueCheck
+        utilities.assert_equals( expect=True,
+                                 actual=getCheck,
+                                 onpass="Partitioned Transactional Map get values were correct",
+                                 onfail="Partitioned Transactional Map values incorrect" )
+
+        main.step( "In-memory Transactional maps put" )
+        tMapValue = "Testing"
+        numKeys = 100
+        putResult = True
+        putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue, inMemory=True )
+        if len( putResponses ) == 100:
+            for i in putResponses:
+                if putResponses[ i ][ 'value' ] != tMapValue:
+                    putResult = False
+        else:
+            putResult = False
+        if not putResult:
+            main.log.debug( "Put response values: " + str( putResponses ) )
+        utilities.assert_equals( expect=True,
+                                 actual=putResult,
+                                 onpass="In-Memory Transactional Map put successful",
+                                 onfail="In-Memory Transactional Map put values are incorrect" )
+
+        main.step( "In-Memory Transactional maps get" )
+        getCheck = True
+        for n in range( 1, numKeys + 1 ):
+            getResponses = []
+            threads = []
+            valueCheck = True
+            for i in range( main.numCtrls ):
+                t = main.Thread( target=main.CLIs[i].transactionalMapGet,
+                                 name="TMap-get-" + str( i ),
+                                 args=[ "Key" + str ( n ) ],
+                                 kwargs={ "inMemory": True } )
+                threads.append( t )
+                t.start()
+            for t in threads:
+                t.join()
+                getResponses.append( t.result )
+            for node in getResponses:
+                if node != tMapValue:
+                    valueCheck = False
+            if not valueCheck:
+                main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
+                main.log.warn( getResponses )
+            getCheck = getCheck and valueCheck
+        utilities.assert_equals( expect=True,
+                                 actual=getCheck,
+                                 onpass="In-Memory Transactional Map get values were correct",
+                                 onfail="In-Memory Transactional Map values incorrect" )
diff --git a/TestON/tests/SCPFmaxIntents/Dependency/maxIntentFunctions.py b/TestON/tests/SCPFmaxIntents/Dependency/maxIntentFunctions.py
new file mode 100644
index 0000000..55a5478
--- /dev/null
+++ b/TestON/tests/SCPFmaxIntents/Dependency/maxIntentFunctions.py
@@ -0,0 +1,98 @@
+'''
+    Wrapper functions for maxIntent
+'''
+
+import json
+import time
+
+def __init__( self ):
+    self.default = ""
+
+def getIntents( main, state="INSTALLED", sleep=1, timeout=120 ):
+    cmd = "intents | grep " + state + " | wc -l"
+    main.log.info("Sending: " + cmd)
+    main.CLIs[0].handle.sendline(cmd)
+
+    time.sleep(sleep)
+
+    main.CLIs[0].handle.expect("onos>", timeout=timeout)
+    raw = main.CLIs[0].handle.before
+    intents = int(main.CLIs[0].handle.before.split()[7])
+    main.log.info(state + "intents: " + str(intents))
+    return intents
+
+
+def getFlows( main, state="ADDED", sleep=1, timeout=120 ):
+    cmd = "flows | grep " + state + " | wc -l"
+    main.log.info("Sending: " + cmd)
+    main.CLIs[0].handle.sendline(cmd)
+
+    time.sleep(sleep)
+
+    main.CLIs[0].handle.expect("onos>", timeout=timeout)
+    raw = main.CLIs[0].handle.before
+    flows = int(main.CLIs[0].handle.before.split()[7])
+    main.log.info(state + "flows: " + str(flows))
+    return flows
+
+
+def pushIntents( main,
+                 switch,
+                 ingress,
+                 egress,
+                 batch,
+                 offset,
+                 sleep=1,
+                 options="",
+                 timeout=120):
+    '''
+        Description
+    '''
+    cmd = "push-test-intents " + options + " " + switch + ingress + " " +\
+            switch + egress + " " + str(batch) + " " + str(offset)
+    main.log.info("Installing " + str(offset+batch) + " intents")
+    main.log.debug("Sending: " + cmd)
+    main.CLIs[0].handle.sendline(cmd)
+    time.sleep(sleep)
+    main.CLIs[0].handle.expect("onos>", timeout=timeout)
+
+    raw = main.CLIs[0].handle.before
+    if "Failure:" in raw or "GC" in raw:
+        return main.FALSE
+    return main.TRUE
+
+def verifyFlows( main, expectedFlows, state="ADDED", sleep=1,  timeout=120):
+    '''
+        This function returns main.TRUE if the number of expected flows are in
+        the specified state
+
+        @params
+            expectedFlows: the flows you expect to see in the specified state
+            state: the state of the flow to check for
+            timeout: the timeout for pexpect
+    '''
+    cmd = "flows | grep " + state + " | wc -l"
+    for i in range(10):
+        flows = getFlows( main, state, sleep, timeout )
+        if expectedFlows == flows:
+            return main.TRUE
+
+    return main.FALSE
+
+def verifyIntents( main, expectedIntents, state="INSTALLED", sleep=1, timeout=120):
+    '''
+        This function returns main.TRUE if the number of expected intents are in
+        the specified state
+
+        @params
+            expectedFlows: the intents you expect to see in the specified state
+            state: the state of the intent to check for
+            timeout: the timeout for pexpect
+    '''
+    cmd = "intents | grep " + state + " | wc -l"
+    for i in range(10):
+        intents = getIntents( main, state, sleep, timeout )
+        if expectedIntents == intents:
+            return main.TRUE
+
+    return main.FALSE
diff --git a/TestON/tests/SCPFmaxIntents/Dependency/rerouteTopo.py b/TestON/tests/SCPFmaxIntents/Dependency/rerouteTopo.py
new file mode 100755
index 0000000..a2fe9fe
--- /dev/null
+++ b/TestON/tests/SCPFmaxIntents/Dependency/rerouteTopo.py
@@ -0,0 +1,53 @@
+#!/usr/bin/python
+
+"""
+Custom topology for Mininet
+"""
+from mininet.topo import Topo
+from mininet.net import Mininet
+from mininet.node import Host, RemoteController
+from mininet.node import Node
+from mininet.link import TCLink
+from mininet.cli import CLI
+from mininet.log import setLogLevel
+from mininet.util import dumpNodeConnections
+from mininet.node import ( UserSwitch, OVSSwitch, IVSSwitch )
+
+class MyTopo( Topo ):
+
+    def __init__( self ):
+        # Initialize topology
+        Topo.__init__( self )
+
+        host1 = self.addHost('h1', ip='10.1.0.1/24')
+        host2 = self.addHost('h2', ip='10.1.0.2/24')
+        host3 = self.addHost('h3', ip='10.1.0.3/24')
+
+        s1 = self.addSwitch( 's1' )
+        s2 = self.addSwitch( 's2' )
+        s3 = self.addSwitch( 's3' )
+
+        self.addLink(s1, host1)
+        self.addLink(s2, host2)
+        self.addLink(s3, host3)
+
+        self.addLink(s1,s2)
+        self.addLink(s1,s3)
+        self.addLink(s2,s3)
+
+        topos = { 'mytopo': ( lambda: MyTopo() ) }
+
+# HERE THE CODE DEFINITION OF THE TOPOLOGY ENDS
+
+def setupNetwork():
+    "Create network"
+    topo = MyTopo()
+    network = Mininet(topo=topo, autoSetMacs=True, controller=None)
+    network.start()
+    CLI( network )
+    network.stop()
+
+if __name__ == '__main__':
+    setLogLevel('info')
+    #setLogLevel('debug')
+    setupNetwork()
diff --git a/TestON/tests/SAMPscaleTopo/Dependency/startUp.py b/TestON/tests/SCPFmaxIntents/Dependency/startUp.py
similarity index 100%
copy from TestON/tests/SAMPscaleTopo/Dependency/startUp.py
copy to TestON/tests/SCPFmaxIntents/Dependency/startUp.py
diff --git a/TestON/tests/SCPFmaxIntents/SCPFmaxIntents.params b/TestON/tests/SCPFmaxIntents/SCPFmaxIntents.params
new file mode 100755
index 0000000..97e32c3
--- /dev/null
+++ b/TestON/tests/SCPFmaxIntents/SCPFmaxIntents.params
@@ -0,0 +1,50 @@
+<PARAMS>
+
+    # 0-init, 1-setup, 10-null provider setup,
+    # 11-mininet setup, 20-pushing intents,
+    # 21-rerouting intents
+    <testcases>0,1,10,20,1,11,20,1,10,21,1,11,21,100</testcases>
+
+    <SCALE>
+        <size>1</size>
+        <max>1</max>
+    </SCALE>
+
+    <DEPENDENCY>
+        <path>/tests/SCPFmaxIntents/Dependency/</path>
+        <wrapper1>startUp</wrapper1>
+        <wrapper2>maxIntentFunctions</wrapper2>
+        <topology>rerouteTopo.py</topology>
+    </DEPENDENCY>
+
+    <ENV>
+        <cellName>productionCell</cellName>
+        <cellApps>drivers</cellApps>
+    </ENV>
+
+    <GIT>
+        <pull>False</pull>
+        <branch>master</branch>
+    </GIT>
+
+    <CTRL>
+        <port>6633</port>
+    </CTRL>
+
+    <SLEEP>
+        <startup>3</startup>
+        <install>5</install>
+        <verify>15</verify>
+        <reroute>15</reroute>
+        # timeout for pexpect
+        <timeout>120</timeout>
+    </SLEEP>
+
+    <TEST>
+        <batch_size>1000</batch_size>
+        <min_intents>500000</min_intents>
+        <max_intents>1000000</max_intents>
+        <check_interval>1000</check_interval>
+    </TEST>
+
+</PARAMS>
diff --git a/TestON/tests/SCPFmaxIntents/SCPFmaxIntents.py b/TestON/tests/SCPFmaxIntents/SCPFmaxIntents.py
new file mode 100644
index 0000000..793d5ea
--- /dev/null
+++ b/TestON/tests/SCPFmaxIntents/SCPFmaxIntents.py
@@ -0,0 +1,534 @@
+
+# This is a performance scale intent that test onos to see how many intents can
+# be installed and rerouted using the null provider and mininet.
+
+class SCPFmaxIntents:
+
+    def __init__( self ):
+        self.default = ''
+
+    def CASE0( self, main ):
+        import time
+        import os
+        import imp
+
+        """
+        - Construct tests variables
+        - GIT ( optional )
+            - Checkout ONOS master branch
+            - Pull latest ONOS code
+        - Building ONOS ( optional )
+            - Install ONOS package
+            - Build ONOS package
+        """
+
+        main.case( "Constructing test variables and building ONOS package" )
+        main.step( "Constructing test variables" )
+        stepResult = main.FALSE
+
+        # Test variables
+        main.testOnDirectory = os.path.dirname( os.getcwd ( ) )
+        main.dependencyPath = main.testOnDirectory + \
+                main.params['DEPENDENCY']['path']
+        main.cellName = main.params[ 'ENV' ][ 'cellName' ]
+        main.apps = main.params[ 'ENV' ][ 'cellApps' ]
+        gitBranch = main.params[ 'GIT' ][ 'branch' ]
+        main.topology = main.params[ 'DEPENDENCY' ][ 'topology' ]
+        main.scale = ( main.params[ 'SCALE' ][ 'size' ] ).split( "," )
+        main.maxNodes = int( main.params[ 'SCALE' ][ 'max' ] )
+        main.ONOSport = main.params[ 'CTRL' ][ 'port' ]
+        main.timeout = int(main.params['SLEEP']['timeout'])
+        main.minIntents = int(main.params['TEST']['min_intents'])
+        main.maxIntents = int(main.params['TEST']['max_intents'])
+        main.checkInterval = int(main.params['TEST']['check_interval'])
+        wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
+        wrapperFile2 = main.params[ 'DEPENDENCY' ][ 'wrapper2' ]
+        main.startUpSleep = int( main.params[ 'SLEEP' ][ 'startup' ] )
+        main.installSleep = int( main.params[ 'SLEEP' ][ 'install' ] )
+        main.verifySleep = int( main.params[ 'SLEEP' ][ 'verify' ] )
+        main.rerouteSleep = int ( main.params['SLEEP']['reroute'] )
+        gitPull = main.params[ 'GIT' ][ 'pull' ]
+        main.batchSize = int(main.params['TEST']['batch_size'])
+        main.cellData = {} # for creating cell file
+        main.CLIs = []
+        main.ONOSip = []
+        main.maxNumBatch = 0
+
+        main.ONOSip = main.ONOSbench.getOnosIps()
+        main.log.info(main.ONOSip)
+
+        # Assigning ONOS cli handles to a list
+        for i in range( 1,  main.maxNodes + 1 ):
+            main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
+
+        # -- INIT SECTION, ONLY RUNS ONCE -- #
+        main.startUp = imp.load_source( wrapperFile1,
+                                        main.dependencyPath +
+                                        wrapperFile1 +
+                                        ".py" )
+
+        main.intentFunctions = imp.load_source( wrapperFile2,
+                                               main.dependencyPath +
+                                               wrapperFile2 +
+                                               ".py" )
+
+        copyResult = main.ONOSbench.copyMininetFile( main.topology,
+                                                    main.dependencyPath,
+                                                    main.Mininet1.user_name,
+                                                    main.Mininet1.ip_address )
+
+        if main.CLIs:
+            stepResult = main.TRUE
+        else:
+            main.log.error( "Did not properly created list of ONOS CLI handle" )
+            stepResult = main.FALSE
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully construct " +
+                                        "test variables ",
+                                 onfail="Failed to construct test variables" )
+
+        if gitPull == 'True':
+            main.step( "Building ONOS in " + gitBranch + " branch" )
+            onosBuildResult = main.startUp.onosBuild( main, gitBranch )
+            stepResult = onosBuildResult
+            utilities.assert_equals( expect=main.TRUE,
+                                     actual=stepResult,
+                                     onpass="Successfully compiled " +
+                                            "latest ONOS",
+                                     onfail="Failed to compile " +
+                                            "latest ONOS" )
+        else:
+            main.log.warn( "Did not pull new code so skipping mvn " +
+                           "clean install" )
+
+    def CASE1( self, main ):
+        """
+        - Set up cell
+            - Create cell file
+            - Set cell file
+            - Verify cell file
+        - Kill ONOS process
+        - Uninstall ONOS cluster
+        - Verify ONOS start up
+        - Install ONOS cluster
+        - Connect to cli
+        """
+
+        # main.scale[ 0 ] determines the current number of ONOS controller
+        main.numCtrls = int( main.scale[ 0 ] )
+
+        main.case( "Starting up " + str( main.numCtrls ) +
+                   " node(s) ONOS cluster" )
+
+        # kill off all onos processes
+        main.log.info( "Safety check, killing all ONOS processes" +
+                       " before initiating enviornment setup" )
+
+        for i in range( main.maxNodes ):
+            main.ONOSbench.onosDie( main.ONOSip[ i ] )
+
+        main.log.info( "NODE COUNT = " + str( main.numCtrls))
+
+        tempOnosIp = []
+        for i in range( main.numCtrls ):
+            tempOnosIp.append( main.ONOSip[i] )
+
+        main.ONOSbench.createCellFile( main.ONOSbench.ip_address,
+                                       "temp",
+                                       main.Mininet1.ip_address,
+                                       main.apps,
+                                       tempOnosIp )
+
+        main.step( "Apply cell to environment" )
+        cellResult = main.ONOSbench.setCell( "temp" )
+        verifyResult = main.ONOSbench.verifyCell()
+        stepResult = cellResult and verifyResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully applied cell to " + \
+                                        "environment",
+                                 onfail="Failed to apply cell to environment " )
+
+        main.step( "Creating ONOS package" )
+        packageResult = main.ONOSbench.onosPackage()
+        stepResult = packageResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully created ONOS package",
+                                 onfail="Failed to create ONOS package" )
+
+        main.step( "Uninstalling ONOS package" )
+        onosUninstallResult = main.TRUE
+        for i in range( main.maxNodes ):
+            onosUninstallResult = onosUninstallResult and \
+                    main.ONOSbench.onosUninstall( nodeIp=main.ONOSip[ i ] )
+        stepResult = onosUninstallResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully uninstalled ONOS package",
+                                 onfail="Failed to uninstall ONOS package" )
+
+        time.sleep( main.startUpSleep )
+        main.step( "Installing ONOS package" )
+        onosInstallResult = main.TRUE
+        for i in range( main.numCtrls ):
+            onosInstallResult = onosInstallResult and \
+                    main.ONOSbench.onosInstall( node=main.ONOSip[ i ] )
+        stepResult = onosInstallResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully installed ONOS package",
+                                 onfail="Failed to install ONOS package" )
+
+        main.step( "Starting ONOS service" )
+        stopResult = main.TRUE
+        startResult = main.TRUE
+        onosIsUp = main.TRUE
+
+        for i in range( main.numCtrls ):
+            onosIsUp = onosIsUp and main.ONOSbench.isup( main.ONOSip[ i ] )
+        if onosIsUp == main.TRUE:
+            main.log.report( "ONOS instance is up and ready" )
+        else:
+            main.log.report( "ONOS instance may not be up, stop and " +
+                             "start ONOS again " )
+            for i in range( main.numCtrls ):
+                stopResult = stopResult and \
+                        main.ONOSbench.onosStop( main.ONOSip[ i ] )
+            for i in range( main.numCtrls ):
+                startResult = startResult and \
+                        main.ONOSbench.onosStart( main.ONOSip[ i ] )
+        stepResult = onosIsUp and stopResult and startResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="ONOS service is ready",
+                                 onfail="ONOS service did not start properly" )
+
+        main.step( "Start ONOS cli" )
+        cliResult = main.TRUE
+        for i in range( main.numCtrls ):
+            cliResult = cliResult and \
+                        main.CLIs[ i ].startOnosCli( main.ONOSip[ i ] )
+        stepResult = cliResult
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully start ONOS cli",
+                                 onfail="Failed to start ONOS cli" )
+
+    def CASE10( self, main ):
+        """
+            Setting up null-provider
+        """
+        import json
+        import pexpect
+
+        # Activate apps
+        main.log.step("Activating apps")
+        stepResult = main.CLIs[0].activateApp('org.onosproject.null')
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully activated null-provider",
+                                 onfail="Failed to activate null-provider")
+
+        # Setup the null-provider
+        main.log.step("Configuring null-provider")
+        stepResult = main.FALSE
+        for i in range(3):
+            main.ONOSbench.onosCfgSet( main.ONOSip[0],
+                                                    'org.onosproject.provider.nil.NullProviders',
+                                                    'deviceCount 3' )
+            main.ONOSbench.onosCfgSet( main.ONOSip[0],
+                                                    'org.onosproject.provider.nil.NullProviders',
+                                                    'topoShape reroute' )
+            main.ONOSbench.onosCfgSet( main.ONOSip[0],
+                                                    'org.onosproject.provider.nil.NullProviders',
+                                                    'enabled true' )
+            # give onos some time to settle
+            time.sleep(main.startUpSleep)
+            jsonSum = json.loads(main.CLIs[0].summary())
+            if jsonSum['devices'] == 3 and jsonSum['SCC(s)'] == 1:
+                stepResult = main.TRUE
+                break
+        utilities.assert_equals( expect=stepResult,
+                                     actual=stepResult,
+                                     onpass="Successfully configured the null-provider",
+                                     onfail="Failed to configure the null-provider")
+
+
+        main.log.step("Get default flows")
+        jsonSum = json.loads(main.CLIs[0].summary())
+
+        # flows installed by the null-provider
+        main.defaultFlows = jsonSum["flows"]
+        main.ingress =  ":0000000000000001/3"
+        main.egress = ":0000000000000003/2"
+        main.switch = "null"
+        main.linkUpCmd = "null-link null:0000000000000001/3 null:0000000000000003/1 up"
+        main.linkDownCmd = "null-link null:0000000000000001/3 null:0000000000000003/1 down"
+
+    def CASE11( self, main ):
+        '''
+            Setting up mininet
+        '''
+        import json
+        import time
+
+        # Activate apps
+        main.log.step("Activating apps")
+        stepResult = main.CLIs[0].activateApp('org.onosproject.openflow')
+
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass="Successfully activated openflow",
+                                 onfail="Failed to activate openflow")
+        # give onos some time settle
+        time.sleep(main.startUpSleep)
+
+        main.log.step('Starting mininet topology')
+        main.Mininet1.startNet(topoFile='~/mininet/custom/rerouteTopo.py')
+        main.Mininet1.assignSwController(sw='s1', ip=main.ONOSip[0])
+        main.Mininet1.assignSwController(sw='s2', ip=main.ONOSip[0])
+        main.Mininet1.assignSwController(sw='s3', ip=main.ONOSip[0])
+        time.sleep(main.startUpSleep)
+
+        jsonSum = json.loads(main.CLIs[0].summary())
+        if jsonSum['devices'] == 3 and jsonSum['SCC(s)'] == 1:
+            stepResult = main.TRUE
+
+        utilities.assert_equals( expect=stepResult,
+                                     actual=stepResult,
+                                     onpass="Successfully assigned switches to their master",
+                                     onfail="Failed to assign switches")
+
+        main.log.step("Get default flows")
+        jsonSum = json.loads(main.CLIs[0].summary())
+
+        # flows installed by the null-provider
+        main.defaultFlows = jsonSum["flows"]
+        main.ingress =  ":0000000000000001/3"
+        main.egress = ":0000000000000003/2"
+        main.switch = "of"
+        main.linkDownCmd = 'link s1 s3 down'
+        main.linkUpCmd = 'link s1 s3 up'
+
+
+    def CASE20( self, main ):
+        import pexpect
+        '''
+            Pushing intents
+        '''
+        # the index where the next intents will be installed
+        offset = 0
+        # the number of intents we expect to be in the installed state
+        expectedIntents = 0
+        # the number of flows we expect to be in the added state
+        expectedFlows = main.defaultFlows
+        # limit for the number of intents that can be installed
+        limit = main.maxIntents / main.batchSize
+        try:
+            for i in range(limit):
+                # Push intents
+                main.log.step("Pushing intents")
+                stepResult = main.intentFunctions.pushIntents( main,
+                                                               main.switch,
+                                                               main.ingress,
+                                                               main.egress,
+                                                               main.batchSize,
+                                                               offset,
+                                                               sleep=main.installSleep,
+                                                               timeout=main.timeout,
+                                                               options="-i" )
+                utilities.assert_equals( expect=main.TRUE,
+                                     actual=stepResult,
+                                     onpass="Successfully pushed intents",
+                                     onfail="Failed to push intents")
+                if stepResult == main.FALSE:
+                    break
+
+                offset += main.batchSize
+                expectedIntents = offset
+                expectedFlows += main.batchSize*2
+
+                if offset >= main.minIntents and offset % main.checkInterval == 0:
+                    # Verifying intents
+                    main.log.step("Verifying intents")
+                    main.log.info("Expected intents: " + str(expectedIntents))
+                    stepResult = main.intentFunctions.verifyIntents( main,
+                                                                     expectedIntents,
+                                                                     sleep=main.verifySleep,
+                                                                     timeout=main.timeout)
+                    utilities.assert_equals( expect=main.TRUE,
+                                             actual=stepResult,
+                                             onpass="Successfully verified intents",
+                                             onfail="Failed to verify intents")
+
+                    if stepResult == main.FALSE:
+                        break
+
+                    # Verfying flows
+                    main.log.step("Verifying flows")
+                    main.log.info("Expected Flows: " + str(expectedFlows))
+                    stepResult = main.intentFunctions.verifyFlows( main,
+                                                                   expectedFlows,
+                                                                   sleep=main.verifySleep,
+                                                                   timeout=main.timeout)
+
+                    utilities.assert_equals( expect=main.TRUE,
+                                             actual=stepResult,
+                                             onpass="Successfully verified flows",
+                                             onfail="Failed to verify flows")
+
+                    if stepResult == main.FALSE:
+                        break
+
+        except pexpect.TIMEOUT:
+            main.log.exception("Timeout exception caught")
+
+        main.log.report("Done pushing intents")
+        main.log.info("Summary: Intents=" + str(expectedIntents) + " Flows=" + str(expectedFlows))
+        main.log.info("Installed intents: " + str(main.intentFunctions.getIntents(main)) +
+                      "\nAdded flows: " + str(main.intentFunctions.getFlows(main)))
+
+        # Stopping mininet
+        if main.switch == "of":
+            main.log.info("Stopping mininet")
+            main.Mininet1.stopNet()
+
+    def CASE21( self, main ):
+        import pexpect
+        import time
+        '''
+            Reroute
+        '''
+        # the index where the next intents will be installed
+        offset = 0
+        # the number of intents we expect to be in the installed state
+        expectedIntents = 0
+        # the number of flows we expect to be in the added state
+        expectedFlows = main.defaultFlows
+        # limit for the number of intents that can be installed
+        limit = main.maxIntents / main.batchSize
+        try:
+            for i in range(limit):
+                # Push intents
+                main.log.step("Pushing intents")
+                stepResult = main.intentFunctions.pushIntents( main,
+                                                               main.switch,
+                                                               main.ingress,
+                                                               main.egress,
+                                                               main.batchSize,
+                                                               offset,
+                                                               sleep=main.installSleep,
+                                                               options="-i",
+                                                               timeout=main.timeout )
+                utilities.assert_equals( expect=main.TRUE,
+                                     actual=stepResult,
+                                     onpass="Successfully pushed intents",
+                                     onfail="Failed to push intents")
+                if stepResult == main.FALSE:
+                    break
+
+                offset += main.batchSize
+                expectedIntents = offset
+                expectedFlows += main.batchSize*2
+
+                # Verifying intents
+                main.log.step("Verifying intents")
+                main.log.info("Expected intents: " + str(expectedIntents))
+                stepResult = main.intentFunctions.verifyIntents( main,
+                                                                 expectedIntents,
+                                                                 sleep=main.verifySleep,
+                                                                 timeout=main.timeout )
+                utilities.assert_equals( expect=main.TRUE,
+                                         actual=stepResult,
+                                         onpass="Successfully verified intents",
+                                         onfail="Failed to verify intents")
+
+                if stepResult == main.FALSE:
+                    break
+
+                # Verfying flows
+                main.log.step("Verifying flows")
+                main.log.info("Expected Flows: " + str(expectedFlows))
+                stepResult = main.intentFunctions.verifyFlows( main,
+                                                               expectedFlows,
+                                                               sleep=main.verifySleep,
+                                                               timeout=main.timeout )
+                utilities.assert_equals( expect=main.TRUE,
+                                         actual=stepResult,
+                                         onpass="Successfully verified flows",
+                                         onfail="Failed to verify flows")
+
+                if stepResult == main.FALSE:
+                    break
+
+                # tear down a link
+                main.log.step("Tearing down link")
+                if main.switch == "of":
+                    main.log.info("Sending: " + main.linkDownCmd)
+                    main.Mininet1.handle.sendline(main.linkDownCmd)
+                    main.Mininet1.handle.expect('mininet>')
+                else:
+                    main.log.info("Sending: " + main.linkDownCmd)
+                    main.CLIs[0].handle.sendline(main.linkDownCmd)
+                    main.CLIs[0].handle.expect('onos>')
+                time.sleep(main.rerouteSleep)
+
+                # rerouting adds a 1000 flows
+                expectedFlows += 1000
+
+                # Verfying flows
+                main.log.step("Verifying flows")
+                main.log.info("Expected Flows: " + str(expectedFlows))
+                stepResult = main.intentFunctions.verifyFlows( main,
+                                                               expectedFlows,
+                                                               sleep=main.verifySleep,
+                                                               timeout=main.timeout)
+                utilities.assert_equals( expect=main.TRUE,
+                                         actual=stepResult,
+                                         onpass="Successfully verified flows",
+                                         onfail="Failed to verify flows")
+
+                if stepResult == main.FALSE:
+                    break
+
+                # Bring link back up
+                main.log.step("Tearing down link")
+                if main.switch == "of":
+                    main.log.info("Sending: " + main.linkUpCmd)
+                    main.Mininet1.handle.sendline(main.linkUpCmd)
+                    main.Mininet1.handle.expect('mininet>')
+                else:
+                    main.log.info("Sending: " + main.linkUpCmd)
+                    main.CLIs[0].handle.sendline(main.linkUpCmd)
+                    main.CLIs[0].handle.expect('onos>')
+                time.sleep(main.rerouteSleep)
+
+        except pexpect.TIMEOUT:
+            main.log.exception("Timeout exception caught")
+
+        main.log.report("Done pushing intents")
+        main.log.info("Summary: Intents=" + str(expectedIntents) + " Flows=" + str(expectedFlows))
+        main.log.info("Installed intents: " + str(main.intentFunctions.getIntents(main)) +
+                      "\nAdded flows: " + str(main.intentFunctions.getFlows(main)))
+
+        # Stopping mininet
+        if main.switch == "of":
+            main.log.info("Stopping mininet")
+            main.Mininet1.stopNet()
+
+    def CASE100( self, main ):
+        '''
+            Report errors/warnings/exceptions
+        '''
+        main.log.info("Error report: \n")
+        main.ONOSbench.logReport( main.ONOSip[ 0 ],
+                                  [ "INFO",
+                                    "FOLLOWER",
+                                    "WARN",
+                                    "flow",
+                                    "ERROR",
+                                    "Except" ],
+                                  "s" )
diff --git a/TestON/tests/SCPFmaxIntents/SCPFmaxIntents.topo b/TestON/tests/SCPFmaxIntents/SCPFmaxIntents.topo
new file mode 100755
index 0000000..be3236a
--- /dev/null
+++ b/TestON/tests/SCPFmaxIntents/SCPFmaxIntents.topo
@@ -0,0 +1,35 @@
+<TOPOLOGY>
+    <COMPONENT>
+
+        <ONOSbench>
+            <host>localhost</host>
+            <user>admin</user>
+            <password></password>
+            <type>OnosDriver</type>
+            <connect_order>1</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </ONOSbench>
+
+        <ONOScli1>
+            <host>localhost</host>
+            <user>admin</user>
+            <password></password>
+            <type>OnosCliDriver</type>
+            <connect_order>2</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </ONOScli1>
+ 
+        <Mininet1>
+            <host>localhost</host>
+            <user>admin</user>
+            <password>onos_test</password>
+            <type>MininetCliDriver</type>
+            <connect_order>5</connect_order>
+            <COMPONENTS>
+            </COMPONENTS>
+        </Mininet1>
+
+    </COMPONENT>
+</TOPOLOGY>
diff --git a/TestON/tests/SAMPscaleTopo/__init__.py b/TestON/tests/SCPFmaxIntents/__init__.py
similarity index 100%
copy from TestON/tests/SAMPscaleTopo/__init__.py
copy to TestON/tests/SCPFmaxIntents/__init__.py
diff --git a/TestON/tests/SAMPscaleTopo/Dependency/multiovs.py b/TestON/tests/SCPFscaleTopo/Dependency/multiovs.py
similarity index 100%
rename from TestON/tests/SAMPscaleTopo/Dependency/multiovs.py
rename to TestON/tests/SCPFscaleTopo/Dependency/multiovs.py
diff --git a/TestON/tests/SAMPscaleTopo/Dependency/newFuncTopo.py b/TestON/tests/SCPFscaleTopo/Dependency/newFuncTopo.py
similarity index 100%
rename from TestON/tests/SAMPscaleTopo/Dependency/newFuncTopo.py
rename to TestON/tests/SCPFscaleTopo/Dependency/newFuncTopo.py
diff --git a/TestON/tests/SAMPscaleTopo/Dependency/scaleTopoFunction.py b/TestON/tests/SCPFscaleTopo/Dependency/scaleTopoFunction.py
similarity index 99%
rename from TestON/tests/SAMPscaleTopo/Dependency/scaleTopoFunction.py
rename to TestON/tests/SCPFscaleTopo/Dependency/scaleTopoFunction.py
index 95eb195..075f4f2 100644
--- a/TestON/tests/SAMPscaleTopo/Dependency/scaleTopoFunction.py
+++ b/TestON/tests/SCPFscaleTopo/Dependency/scaleTopoFunction.py
@@ -45,6 +45,8 @@
 
     # Starts topology
     startResult = startNewTopology( main, topoFile, args, mnCmd, timeout=timeout )
+    # onos needs time to see the links
+    time.sleep(15)
 
     # Gets list of switches in mininet
     #assignSwitch( main )
diff --git a/TestON/tests/SAMPscaleTopo/Dependency/spine.py b/TestON/tests/SCPFscaleTopo/Dependency/spine.py
similarity index 100%
rename from TestON/tests/SAMPscaleTopo/Dependency/spine.py
rename to TestON/tests/SCPFscaleTopo/Dependency/spine.py
diff --git a/TestON/tests/SAMPscaleTopo/Dependency/startUp.py b/TestON/tests/SCPFscaleTopo/Dependency/startUp.py
similarity index 100%
rename from TestON/tests/SAMPscaleTopo/Dependency/startUp.py
rename to TestON/tests/SCPFscaleTopo/Dependency/startUp.py
diff --git a/TestON/tests/SAMPscaleTopo/Dependency/topo.py b/TestON/tests/SCPFscaleTopo/Dependency/topo.py
similarity index 100%
rename from TestON/tests/SAMPscaleTopo/Dependency/topo.py
rename to TestON/tests/SCPFscaleTopo/Dependency/topo.py
diff --git a/TestON/tests/SAMPscaleTopo/SAMPscaleTopo.params b/TestON/tests/SCPFscaleTopo/SCPFscaleTopo.params
similarity index 69%
rename from TestON/tests/SAMPscaleTopo/SAMPscaleTopo.params
rename to TestON/tests/SCPFscaleTopo/SCPFscaleTopo.params
index 395b2fb..c593a74 100755
--- a/TestON/tests/SAMPscaleTopo/SAMPscaleTopo.params
+++ b/TestON/tests/SCPFscaleTopo/SCPFscaleTopo.params
@@ -1,23 +1,25 @@
 <PARAMS>
 
-    <testcases>1</testcases>
+    <testcases>1,2,1001,8,1002,8</testcases>
 
     <SCALE>
-        <size>1,2,3</size>
+        <size>3</size>
         <max>3</max>
     </SCALE>
 
     <DEPENDENCY>
-        <path>/tests/SAMPscaleTopo/Dependency/</path>
+        <path>/tests/SCPFscaleTopo/Dependency/</path>
         <wrapper1>startUp</wrapper1>
         <wrapper2>scaleTopoFunction</wrapper2>
         <wrapper3>topo</wrapper3>
         <topology>spine.py</topology>
         <multiovs>multiovs.py</multiovs>
+        <spine>spine,3,6</spine>
+        <torus>torus,5,5</torus>
     </DEPENDENCY>
 
     <ENV>
-        <cellApps>drivers,openflow,proxyarp,mobility</cellApps>
+        <cellApps>drivers,openflow,fwd</cellApps>
     </ENV>
 
     <GIT>
diff --git a/TestON/tests/SAMPscaleTopo/SAMPscaleTopo.py b/TestON/tests/SCPFscaleTopo/SCPFscaleTopo.py
similarity index 92%
rename from TestON/tests/SAMPscaleTopo/SAMPscaleTopo.py
rename to TestON/tests/SCPFscaleTopo/SCPFscaleTopo.py
index 5801fcd..5e391d6 100644
--- a/TestON/tests/SAMPscaleTopo/SAMPscaleTopo.py
+++ b/TestON/tests/SCPFscaleTopo/SCPFscaleTopo.py
@@ -2,7 +2,7 @@
 # Testing network scalability, this test suite scales up a network topology
 # using mininet and verifies ONOS stability
 
-class SAMPscaleTopo:
+class SCPFscaleTopo:
 
     def __init__( self ):
         self.default = ''
@@ -35,6 +35,8 @@
                                   main.params[ 'DEPENDENCY' ][ 'path' ]
             main.topology = main.params[ 'DEPENDENCY' ][ 'topology' ]
             main.multiovs = main.params[ 'DEPENDENCY' ][ 'multiovs' ]
+            main.torus = main.params[ 'DEPENDENCY' ][ 'torus' ]
+            main.spine = main.params[ 'DEPENDENCY' ][ 'spine' ]
             main.scale = ( main.params[ 'SCALE' ][ 'size' ] ).split( "," )
             if main.ONOSbench.maxNodes:
                 main.maxNodes = int( main.ONOSbench.maxNodes )
@@ -79,13 +81,13 @@
                                               main.topology,
                                               main.Mininet1.home,
                                               direction="to" )
-
+            time.sleep(3)
             copyResult2 = main.ONOSbench.scp( main.Mininet1,
                                               main.dependencyPath +
                                               main.multiovs,
                                               main.Mininet1.home,
                                               direction="to" )
-
+            time.sleep(3)
             if main.CLIs:
                 stepResult = main.TRUE
             else:
@@ -189,7 +191,7 @@
 
 
         # Remove the first element in main.scale list
-        main.scale.remove( main.scale[ 0 ] )
+        #main.scale.remove( main.scale[ 0 ] )
 
     def CASE8( self, main ):
         """
@@ -284,6 +286,7 @@
         main.log.case( "Start Mininet topology" )
 
         main.step( "Starting Mininet Topology" )
+        topology = main.dependencyPath + main.topology
         topoResult = main.Mininet1.startNet( topoFile=topology )
         stepResult = topoResult
         utilities.assert_equals( expect=main.TRUE,
@@ -306,7 +309,7 @@
         mnCmd = "sudo mn --custom " + main.dependencyPath +\
                 main.multiovs + " --switch=ovsm --custom " +\
                 main.dependencyPath + main.topology +\
-                " --topo spine,3,6 --controller=remote,ip=" +\
+                " --topo " + main.spine + " --controller=remote,ip=" +\
                 main.ONOSip[ 0 ] + " --mac"
 
         stepResult = main.scaleTopoFunction.testTopology( main,
@@ -314,10 +317,11 @@
                                                           timeout=900,
                                                           clean=False )
 
+        time.sleep(3)
         main.ONOSbench.scp( main.Mininet1,
-                            "~/mininet/custom/spine.json",
-                            "/tmp/",
-                            direction="to" )
+                           "~/mininet/custom/spine.json",
+                           "/tmp/",
+                           direction="to" )
 
         time.sleep(10)
 
@@ -326,27 +330,27 @@
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
-                                 onpass=main.topoName + " topology successful",
-                                 onfail=main.topoName +
-                                 "Torus 5-5 topology failed" )
+                                 onpass=main.spine + " topology successful",
+                                 onfail=main.spine +
+                                 "Spine topology failed" )
         time.sleep(60)
 
     def CASE1002( self, main ):
         """
             Topology test
         """
-        main.topoName = "TORUS10-10"
+        main.topoName = "TORUS"
         main.case( "Topology discovery test" )
         stepResult = main.TRUE
-        main.step( main.topoName + " topology" )
-        mnCmd = "sudo mn --custom=mininet/examples/multiovs.py " +\
-                "--switch=ovsm --topo=torus,10,10 " +\
-                "--controller=remote,ip=10.128.10.21 --mac"
+        main.step( main.torus + " topology" )
+        mnCmd = "sudo mn --custom=mininet/custom/multiovs.py " +\
+                "--switch=ovsm --topo " + main.torus +\
+                " --controller=remote,ip=" + main.ONOSip[ 0 ]  +" --mac"
         stepResult = main.scaleTopoFunction.testTopology( main,
                                                           mnCmd=mnCmd,
                                                           timeout=900,
-                                                          clean=True )
+                                                          clean=False )
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
-                                 onpass=main.topoName + " topology successful",
-                                 onfail=main.topoName + "Torus 5-5 topology failed" )
+                                 onpass=main.torus + " topology successful",
+                                 onfail=main.torus + " topology failed" )
diff --git a/TestON/tests/SAMPscaleTopo/SAMPscaleTopo.topo b/TestON/tests/SCPFscaleTopo/SCPFscaleTopo.topo
similarity index 85%
rename from TestON/tests/SAMPscaleTopo/SAMPscaleTopo.topo
rename to TestON/tests/SCPFscaleTopo/SCPFscaleTopo.topo
index 499e966..5fc6c09 100755
--- a/TestON/tests/SAMPscaleTopo/SAMPscaleTopo.topo
+++ b/TestON/tests/SCPFscaleTopo/SCPFscaleTopo.topo
@@ -4,7 +4,7 @@
         <ONOSbench>
             <host>localhost</host>
             <user>admin</user>
-            <password>onos_test</password>
+            <password></password>
             <type>OnosDriver</type>
             <connect_order>1</connect_order>
             <COMPONENTS>
@@ -15,7 +15,7 @@
         <ONOScli1>
             <host>localhost</host>
             <user>admin</user>
-            <password>onos_test</password>
+            <password></password>
             <type>OnosCliDriver</type>
             <connect_order>2</connect_order>
             <COMPONENTS>
@@ -25,7 +25,7 @@
         <ONOScli2>
             <host>localhost</host>
             <user>admin</user>
-            <password>onos_test</password>
+            <password></password>
             <type>OnosCliDriver</type>
             <connect_order>3</connect_order>
             <COMPONENTS>
@@ -35,7 +35,7 @@
          <ONOScli3>
             <host>localhost</host>
             <user>admin</user>
-            <password>onos_test</password>
+            <password></password>
             <type>OnosCliDriver</type>
             <connect_order>4</connect_order>
             <COMPONENTS>
@@ -45,7 +45,7 @@
         <Mininet1>
             <host>OCN</host>
             <user>admin</user>
-            <password>onos_test</password>
+            <password></password>
             <type>MininetCliDriver</type>
             <connect_order>5</connect_order>
             <COMPONENTS>
diff --git a/TestON/tests/SAMPscaleTopo/__init__.py b/TestON/tests/SCPFscaleTopo/__init__.py
similarity index 100%
rename from TestON/tests/SAMPscaleTopo/__init__.py
rename to TestON/tests/SCPFscaleTopo/__init__.py
diff --git a/TestON/tests/SDNIPperf/SDNIPperf.py b/TestON/tests/SDNIPperf/SDNIPperf.py
index cd41ea6..471acfb 100644
--- a/TestON/tests/SDNIPperf/SDNIPperf.py
+++ b/TestON/tests/SDNIPperf/SDNIPperf.py
@@ -40,13 +40,13 @@
         #Need to push some new code to ONOS before using the git pull
         #gitPullResult = main.ONOSbench.gitPull()
 
-        main.step( "Using mvn clean & install" )
+        main.step( "Using mvn clean install" )
         if gitPullResult == main.TRUE:
-            cleanInstallResult = main.ONOSbench.cleanInstall()
+            #cleanInstallResult = main.ONOSbench.cleanInstall()
+            cleanInstallResult = main.ONOSbench.cleanInstall( skipTest=True)
         else:
              main.log.warn( "Did not pull new code so skipping mvn " +
                              "clean install" )
-        cleanInstallResult = main.ONOSbench.cleanInstall( mciTimeout= 300 )
         main.ONOSbench.getVersion( report=True )
 
         main.step( "Creating ONOS package" )
@@ -116,7 +116,7 @@
 
         main.step("Sleep 1200 seconds")
         # wait until SDN-IP receives all routes and ONOS installs all intents
-        time.sleep( float(main.params[ 'timers' ][ 'SystemBoot' ]) )
+        time.sleep( int(main.params[ 'timers' ][ 'SystemBoot' ]) )
 
         main.step( "Checking routes installed" )
 
diff --git a/TestON/tests/SDNIPperf/SDNIPperf.topo b/TestON/tests/SDNIPperf/SDNIPperf.topo
index 50629d1..9932966 100644
--- a/TestON/tests/SDNIPperf/SDNIPperf.topo
+++ b/TestON/tests/SDNIPperf/SDNIPperf.topo
@@ -2,7 +2,7 @@
     <COMPONENT>
 
         <ONOSbench>
-            <host>10.128.4.60</host>
+            <host>10.128.4.53</host>
             <user>admin</user>
             <password></password>
             <type>OnosDriver</type>
@@ -11,7 +11,7 @@
         </ONOSbench>
 
         <ONOScli>
-            <host>10.128.4.60</host>
+            <host>10.128.4.53</host>
             <user>admin</user>
             <password></password>
             <type>OnosCliDriver</type>