Update Cluster Driver

Change-Id: I8a3a57e19637ff210548e57d41178e6f194cf694
diff --git a/TestON/tests/SCPF/SCPFscaleTopo/SCPFscaleTopo.py b/TestON/tests/SCPF/SCPFscaleTopo/SCPFscaleTopo.py
index 6e45f81..71758f6 100644
--- a/TestON/tests/SCPF/SCPFscaleTopo/SCPFscaleTopo.py
+++ b/TestON/tests/SCPF/SCPFscaleTopo/SCPFscaleTopo.py
@@ -56,10 +56,9 @@
             main.dependencyPath = main.testOnDirectory + \
                                   main.params[ 'DEPENDENCY' ][ 'path' ]
             main.tsharkResultPath = main.params[ 'TsharkPath' ]
-            main.roleRequest = main.params[ 'SearchTerm' ]['roleRequest']
+            main.roleRequest = main.params[ 'SearchTerm' ][ 'roleRequest' ]
             main.multiovs = main.params[ 'DEPENDENCY' ][ 'multiovs' ]
             main.topoName = main.params[ 'TOPOLOGY' ][ 'topology' ]
-            main.numCtrls = int( main.params[ 'CTRL' ][ 'numCtrls' ] )
             main.topoScale = ( main.params[ 'TOPOLOGY' ][ 'scale' ] ).split( "," )
             main.topoScaleSize = len( main.topoScale )
             wrapperFile1 = main.params[ 'DEPENDENCY' ][ 'wrapper1' ]
@@ -74,14 +73,13 @@
             main.MNSleep = int( main.params[ 'SLEEP' ][ 'MNsleep' ] )
             main.pingTimeout = float( main.params[ 'TIMEOUT' ][ 'pingall' ] )
             main.hostDiscover = main.params[ 'TOPOLOGY' ][ 'host' ]
-            main.hostDiscoverSleep = float( main.params['SLEEP']['host'] )
+            main.hostDiscoverSleep = float( main.params[ 'SLEEP' ][ 'host' ] )
             if main.hostDiscover == 'True':
                 main.hostDiscover = True
             else:
                 main.hostDiscover = False
-            main.homeDir = os.path.expanduser('~')
+            main.homeDir = os.path.expanduser( '~' )
             main.hostsData = {}
-            main.activeNodes = []
 
 
             stepResult = main.testSetUp.envSetup()
@@ -99,7 +97,7 @@
 
             main.dbFilePath = main.params[ 'DATABASE' ][ 'dbPath' ]
             main.log.info( "Create Database file " + main.dbFilePath )
-            resultDB = open(main.dbFilePath, 'w+' )
+            resultDB = open( main.dbFilePath, 'w+' )
             resultDB.close()
 
             main.scaleTopoFunction = imp.load_source( wrapperFile2,
@@ -122,7 +120,7 @@
         main.testSetUp.evnSetupConclusion( stepResult )
         main.commit = main.commit.split( " " )[ 1 ]
 
-    def CASE2( self, main):
+    def CASE2( self, main ):
         """
         - Set up cell
             - Create cell file
@@ -145,10 +143,7 @@
         except ( NameError, AttributeError ):
             main.Utils = Utils()
         main.Utils.mininetCleanup( main.Mininet1 )
-        main.testSetUp.ONOSSetUp( main.Mininet1 )
-        main.activeNodes = []
-        for i in range( main.numCtrls ):
-            main.activeNodes.append( i )
+        main.testSetUp.ONOSSetUp( main.Mininet1, main.Cluster )
 
     def CASE10( self, main ):
         """
@@ -159,15 +154,15 @@
         main.caseExplanation = "Starting Mininet with a scalling topology and " +\
                 "comparing topology elements between Mininet and ONOS"
         if main.topoScale:
-            main.currScale = main.topoScale.pop(0)
+            main.currScale = main.topoScale.pop( 0 )
         else: main.log.error( "topology scale is empty" )
-        main.step( "Starting up TORUS %sx%s topology" % (main.currScale, main.currScale) )
+        main.step( "Starting up TORUS %sx%s topology" % ( main.currScale, main.currScale ) )
 
         main.log.info( "Constructing Mininet command" )
         mnCmd = " mn --custom " + main.Mininet1.home + main.multiovs + \
                 " --switch ovsm --topo " + main.topoName + "," + main.currScale + "," + main.currScale
-        for i in range( main.numCtrls ):
-                mnCmd += " --controller remote,ip=" + main.ONOSip[ i ]
+        for ctrl in main.Cluster.runningNodes:
+                mnCmd += " --controller remote,ip=" + ctrl.ipAddress
         stepResult = main.Mininet1.startNet( mnCmd=mnCmd )
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
@@ -178,11 +173,11 @@
 
         time.sleep( main.MNSleep )
         main.log.info( "Clean up Tshark" )
-        with open(main.tsharkResultPath, "w" ) as tshark:
+        with open( main.tsharkResultPath, "w" ) as tshark:
             tshark.write( "" )
         main.log.info( "Starting Tshark capture" )
         main.ONOSbench.tsharkGrep( main.roleRequest, main.tsharkResultPath, grepOptions='-E' )
-        main.CLIs[ 0 ].activateApp( "org.onosproject.openflow" )
+        main.Cluster.active( 0 ).CLI.activateApp( "org.onosproject.openflow" )
         time.sleep( main.MNSleep )
         main.log.info( "Stop Tshark" )
         main.ONOSbench.tsharkStop()
@@ -210,36 +205,35 @@
         # First capture
         for i in range( 3 ):
             # Calculate total time
-            main.allinfo[ 0 ][ 'info' + str( i )][ 'totalTime' ] = main.scaleTopoFunction.getInfoFromLog( main, main.searchTerm[ 'start' ], 'first', main.searchTerm[ 'end' ], 'last', index=i, funcMode='TD' )
+            main.allinfo[ 0 ][ 'info' + str( i ) ][ 'totalTime' ] = main.scaleTopoFunction.getInfoFromLog( main, main.searchTerm[ 'start' ], 'first', main.searchTerm[ 'end' ], 'last', index=i, funcMode='TD' )
             # Calculate switch connection time
-            main.allinfo[ 0 ][ 'info' + str( i )][ 'swConnection' ] = main.scaleTopoFunction.getInfoFromLog( main, main.searchTerm[ 'start' ], 'first', main.searchTerm[ 'start' ], 'last', index=i, funcMode='TD' )
+            main.allinfo[ 0 ][ 'info' + str( i ) ][ 'swConnection' ] = main.scaleTopoFunction.getInfoFromLog( main, main.searchTerm[ 'start' ], 'first', main.searchTerm[ 'start' ], 'last', index=i, funcMode='TD' )
             # Calculate the time from last switch connection to the last role request
-            main.allinfo[ 0 ][ 'info' + str( i )][ 'lastSwToLastRr' ] = main.scaleTopoFunction.compareTimeDiffWithRoleRequest( main, main.searchTerm[ 'start' ], 'last', index=i )
+            main.allinfo[ 0 ][ 'info' + str( i ) ][ 'lastSwToLastRr' ] = main.scaleTopoFunction.compareTimeDiffWithRoleRequest( main, main.searchTerm[ 'start' ], 'last', index=i )
             # Calculate the time from the last role request to the last topology
-            main.allinfo[ 0 ][ 'info' + str( i )][ 'lastRrToLastTopology' ] = main.scaleTopoFunction.compareTimeDiffWithRoleRequest( main, main.searchTerm[ 'end' ], 'last', index=i )
+            main.allinfo[ 0 ][ 'info' + str( i ) ][ 'lastRrToLastTopology' ] = main.scaleTopoFunction.compareTimeDiffWithRoleRequest( main, main.searchTerm[ 'end' ], 'last', index=i )
             # Calculate the disconnecti rate
-            main.allinfo[ 0 ][ 'info' + str( i )][ 'disconnectRate' ] = main.scaleTopoFunction.getInfoFromLog( main, main.searchTerm[ 'Disconnect' ], 'num', main.searchTerm[ 'start' ], 'num', index=i, funcMode='DR' )
+            main.allinfo[ 0 ][ 'info' + str( i ) ][ 'disconnectRate' ] = main.scaleTopoFunction.getInfoFromLog( main, main.searchTerm[ 'Disconnect' ], 'num', main.searchTerm[ 'start' ], 'num', index=i, funcMode='DR' )
         main.log.debug( "The data is " + str( main.allinfo[ 0 ] ) )
 
         main.case( "Verifying topology: TORUS %sx%s" % ( main.currScale, main.currScale ) )
         main.caseExplanation = "Pinging all hosts and comparing topology " +\
                 "elements between Mininet and ONOS"
 
-        main.log.info( "Gathering topology information")
+        main.log.info( "Gathering topology information" )
         time.sleep( main.MNSleep )
         stepResult = main.TRUE
         main.step( "Comparing MN topology to ONOS topology" )
         compareRetry = 0
         while compareRetry < 3:
             #While loop for retry
-            devices = main.topoRelated.getAllDevices( main.numCtrls, False )
-            ports = main.topoRelated.getAllPorts( main.numCtrls, False )
-            links = main.topoRelated.getAllLinks( main.numCtrls, False)
+            devices = main.topoRelated.getAll( "devices" )
+            ports = main.topoRelated.getAll( "ports" )
+            links = main.topoRelated.getAll( "links" )
             mnSwitches = main.Mininet1.getSwitches()
-            mnLinks = main.Mininet1.getLinks(timeout=180)
+            mnLinks = main.Mininet1.getLinks( timeout=180 )
 
-            for controller in range(len(main.activeNodes)):
-                # controllerStr = str( main.activeNodes[controller] + 1 )
+            for controller in range( len( main.Cluster.active() ) ):
                 currentDevicesResult = main.topoRelated.compareDevicePort(
                                                             main.Mininet1, controller,
                                                             mnSwitches,
@@ -253,10 +247,10 @@
             if stepResult:
                 break
             compareRetry += 1
-        utilities.assert_equals(expect=main.TRUE,
-                                actual=stepResult,
-                                onpass=" Topology match Mininet",
-                                onfail="ONOS Topology doesn't match Mininet")
+        utilities.assert_equals( expect=main.TRUE,
+                                 actual=stepResult,
+                                 onpass=" Topology match Mininet",
+                                 onfail="ONOS Topology doesn't match Mininet")
 
         if stepResult:
             if main.hostDiscover:
@@ -279,10 +273,10 @@
                 else:
                     main.log.warn( "Some hosts ware not discovered by ONOS... Topology doesn't match!" )
                     stepResult = main.FALSE
-                utilities.assert_equals(expect=main.TRUE,
-                                        actual=stepResult,
-                                        onpass=" Topology match Mininet",
-                                        onfail="ONOS Topology doesn't match Mininet")
+                utilities.assert_equals( expect=main.TRUE,
+                                         actual=stepResult,
+                                         onpass=" Topology match Mininet",
+                                         onfail="ONOS Topology doesn't match Mininet")
             main.log.info( "Finished this iteration, continue to scale next topology." )
         else:
             main.log.info( "Clean up and exit TestON. Finished this test." )
@@ -306,9 +300,9 @@
         # Printing purposes
         node = main.deadNode + 1
         main.log.info( "Stopping node %s" % node )
-        stepResult = main.ONOSbench.onosStop( main.ONOSip[ main.deadNode ] )
+        stepResult = main.ONOSbench.onosStop( main.Cluster.active( main.deadNode ).ipAddress )
         main.log.info( "Removing dead node from list of active nodes" )
-        main.activeNodes.pop( main.deadNode )
+        main.Cluster.runningNodes[ main.deadNode ].active = False
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
@@ -322,15 +316,15 @@
 
         main.case("Bring ONOS node 3 up: TORUS %sx%s" % (main.currScale, main.currScale))
         main.caseExplanation = "Bring node 3 back up and balance the masters"
-
+        ctrl = main.Cluster.runningNodes[ main.deadNode ]
         node = main.deadNode + 1
         main.log.info( "Starting node %s" % node )
-        stepResult = main.ONOSbench.onosStart( main.ONOSip[ main.deadNode ] )
+        stepResult = main.ONOSbench.onosStart( ctrl.ipAddress )
         main.log.info( "Starting onos cli" )
-        stepResult = stepResult and main.CLIs[ main.deadNode ].startOnosCli( main.ONOSip[ main.deadNode ] )
-
+        stepResult = stepResult and \
+                     ctrl.CLI.startOnosCli( ctrl.ipAddress )
         main.log.info( "Adding previously dead node to list of active nodes" )
-        main.activeNodes.append( main.deadNode )
+        ctrl.active = True
 
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
@@ -349,21 +343,19 @@
         main.step( "Balancing Masters" )
 
         stepResult = main.FALSE
-        if main.activeNodes:
-            controller = main.activeNodes[0]
-            stepResult = utilities.retry( main.CLIs[controller].balanceMasters,
+        if main.Cluster.active():
+            stepResult = utilities.retry( main.Cluster.next().CLI.balanceMasters,
                                           main.FALSE,
                                           [],
                                           sleep=3,
                                           attempts=3 )
-
         else:
             main.log.error( "List of active nodes is empty" )
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
                                  onpass="Balance masters was successfull",
                                  onfail="Failed to balance masters")
-        time.sleep(main.balanceSleep)
+        time.sleep( main.balanceSleep )
 
     def CASE1000( self, main ):
         '''
@@ -375,19 +367,43 @@
         # Second capture
         for i in range( 3 ):
             # Calculate total time
-            main.allinfo[ 1 ][ 'info' + str( i )][ 'totalTime' ] = main.scaleTopoFunction.getInfoFromLog( main, main.searchTerm[ 'start' ], 'first', main.searchTerm[ 'end' ], 'last', index=i, funcMode='TD' )
+            main.allinfo[ 1 ][ 'info' + str( i )][ 'totalTime' ] = main.scaleTopoFunction.getInfoFromLog( main,
+                                                                                                          main.searchTerm[ 'start' ],
+                                                                                                          'first',
+                                                                                                          main.searchTerm[ 'end' ],
+                                                                                                          'last',
+                                                                                                          index=i,
+                                                                                                          funcMode='TD' )
             # Compare the total time
             if main.allinfo[ 1 ][ 'info' + str( i ) ][ 'totalTime' ] > slowestTotalTime:
                 slowestTotalTime = main.allinfo[ 1 ][ 'info' + str( i ) ][ 'totalTime' ]
                 slowestNode = i
             # Calculate switch connection time
-            main.allinfo[ 1 ][ 'info' + str( i )][ 'swConnection' ] = main.scaleTopoFunction.getInfoFromLog( main, main.searchTerm[ 'start' ], 'first', main.searchTerm[ 'start' ], 'last', index=i, funcMode='TD' )
+            main.allinfo[ 1 ][ 'info' + str( i )][ 'swConnection' ] = main.scaleTopoFunction.getInfoFromLog( main,
+                                                                                                             main.searchTerm[ 'start' ],
+                                                                                                             'first',
+                                                                                                             main.searchTerm[ 'start' ],
+                                                                                                             'last',
+                                                                                                             index=i,
+                                                                                                             funcMode='TD' )
             # Calculate the time from last switch connection to the last role request
-            main.allinfo[ 1 ][ 'info' + str( i )][ 'lastSwToLastRr' ] = main.scaleTopoFunction.compareTimeDiffWithRoleRequest( main, main.searchTerm[ 'start' ], 'last', index=i )
+            main.allinfo[ 1 ][ 'info' + str( i )][ 'lastSwToLastRr' ] = main.scaleTopoFunction.compareTimeDiffWithRoleRequest( main,
+                                                                                                                               main.searchTerm[ 'start' ],
+                                                                                                                               'last',
+                                                                                                                               index=i )
             # Calculate the time from the last role request to the last topology
-            main.allinfo[ 1 ][ 'info' + str( i )][ 'lastRrToLastTopology' ] = main.scaleTopoFunction.compareTimeDiffWithRoleRequest( main, main.searchTerm[ 'end' ], 'last', index=i )
+            main.allinfo[ 1 ][ 'info' + str( i )][ 'lastRrToLastTopology' ] = main.scaleTopoFunction.compareTimeDiffWithRoleRequest( main,
+                                                                                                                                     main.searchTerm[ 'end' ],
+                                                                                                                                     'last',
+                                                                                                                                     index=i )
             # Calculate the disconnecti rate
-            main.allinfo[ 1 ][ 'info' + str( i )][ 'disconnectRate' ] = main.scaleTopoFunction.getInfoFromLog( main, main.searchTerm[ 'Disconnect' ], 'num', main.searchTerm[ 'start' ],'num', index=i, funcMode='DR' )
+            main.allinfo[ 1 ][ 'info' + str( i )][ 'disconnectRate' ] = main.scaleTopoFunction.getInfoFromLog( main,
+                                                                                                               main.searchTerm[ 'Disconnect' ],
+                                                                                                               'num',
+                                                                                                               main.searchTerm[ 'start' ],
+                                                                                                               'num',
+                                                                                                               index=i,
+                                                                                                               funcMode='DR' )
 
         if ( main.allinfo[ 0 ] != main.allinfo[ 1 ] ):
             main.log.error( "The results of two capture are different!" )
@@ -411,7 +427,7 @@
         main.writeData = 1
         main.case( "Checking logs for errors, warnings, and exceptions" )
         main.log.info( "Error report: \n" )
-        main.ONOSbench.logReport( main.ONOSip[ 0 ],
+        main.ONOSbench.logReport( main.Cluster.active( 0 ).ipAddress,
                                                             [ "INFO",
                                                               "FOLLOWER",
                                                               "WARN",
diff --git a/TestON/tests/SCPF/SCPFscaleTopo/SCPFscaleTopo.topo b/TestON/tests/SCPF/SCPFscaleTopo/SCPFscaleTopo.topo
index 36476f8..2461858 100755
--- a/TestON/tests/SCPF/SCPFscaleTopo/SCPFscaleTopo.topo
+++ b/TestON/tests/SCPF/SCPFscaleTopo/SCPFscaleTopo.topo
@@ -1,59 +1,32 @@
 <TOPOLOGY>
     <COMPONENT>
 
-        <ONOSbench>
-            <host>localhost</host>
+        <ONOScell>
+            <host>localhost</host>  # ONOS "bench" machine
             <user>sdn</user>
             <password>rocks</password>
-            <type>OnosDriver</type>
+            <type>OnosClusterDriver</type>
             <connect_order>1</connect_order>
             <COMPONENTS>
-                <nodes>3</nodes>
-                <prompt></prompt>
-            </COMPONENTS>
-        </ONOSbench>
-
-        <ONOScli1>
-            <host>localhost</host>
-            <user>sdn</user>
-            <password>rocks</password>
-            <type>OnosCliDriver</type>
-            <connect_order>2</connect_order>
-            <COMPONENTS>
+                <cluster_name></cluster_name>  # Used as a prefix for cluster components. Defaults to 'ONOS'
+                <diff_clihost></diff_clihost>  # if it has different host other than localhost for CLI. True or empty. OC# will be used if True.
                 <karaf_username></karaf_username>
                 <karaf_password></karaf_password>
-                <prompt></prompt>
+                <web_user></web_user>
+                <web_pass></web_pass>
+                <rest_port></rest_port>
+                <prompt></prompt>  # TODO: we technically need a few of these, one per component
+                <onos_home></onos_home>  # defines where onos home is
+                <nodes> 3 </nodes>  # number of nodes in the cluster
             </COMPONENTS>
-        </ONOScli1>
-
-        <ONOScli2>
-            <host>localhost</host>
-            <user>sdn</user>
-            <password>rocks</password>
-            <type>OnosCliDriver</type>
-            <connect_order>3</connect_order>
-            <COMPONENTS>
-                <prompt></prompt>
-            </COMPONENTS>
-        </ONOScli2>
-
-         <ONOScli3>
-            <host>localhost</host>
-            <user>sdn</user>
-            <password>rocks</password>
-            <type>OnosCliDriver</type>
-            <connect_order>4</connect_order>
-            <COMPONENTS>
-                <prompt></prompt>
-            </COMPONENTS>
-        </ONOScli3>
+        </ONOScell>
 
         <Mininet1>
             <host>OCN</host>
             <user>sdn</user>
             <password>rocks</password>
             <type>MininetCliDriver</type>
-            <connect_order>5</connect_order>
+            <connect_order>2</connect_order>
             <COMPONENTS>
                 <home>~/mininet/custom/</home>
                 <prompt></prompt>
diff --git a/TestON/tests/SCPF/SCPFscaleTopo/dependencies/scaleTopoFunction.py b/TestON/tests/SCPF/SCPFscaleTopo/dependencies/scaleTopoFunction.py
index 43f80eb..6f2647d 100644
--- a/TestON/tests/SCPF/SCPFscaleTopo/dependencies/scaleTopoFunction.py
+++ b/TestON/tests/SCPF/SCPFscaleTopo/dependencies/scaleTopoFunction.py
@@ -77,7 +77,7 @@
 
     '''
     try:
-        termInfo = main.CLIs[ index ].logSearch( mode=Mode, searchTerm=term )
+        termInfo = main.Cluster.active( index ).CLI.logSearch( mode=Mode, searchTerm=term )
         termTime = getTimestampFromString( main, termInfo[ 0 ] )
         roleRequestTime = getRoleRequestTimeFromTshark( main )
         if termTime == -1 or roleRequestTime == -1:
@@ -108,8 +108,8 @@
 
     '''
     try:
-        termInfo1 = main.CLIs[ index ].logSearch( mode=mode1, searchTerm=term1 )
-        termInfo2 = main.CLIs[ index ].logSearch( mode=mode2, searchTerm=term2 )
+        termInfo1 = main.Cluster.active( index ).CLI.logSearch( mode=mode1, searchTerm=term1 )
+        termInfo2 = main.Cluster.active( index ).CLI.logSearch( mode=mode2, searchTerm=term2 )
         if funcMode == 'TD':
             startTime = getTimestampFromString( main, termInfo1[0] )
             endTime = getTimestampFromString ( main, termInfo2[0] )
@@ -243,78 +243,16 @@
         Compare topology( devices, links, ports, hosts ) between ONOS and
         mininet using sts
     """
-    devices = []
-    links = []
-    ports = []
-    hosts = []
-    switchResult = []
-    linksResult = []
-    portsResult = []
-    hostsResult = []
-    mnSwitches = main.Mininet1.getSwitches()
-    mnLinks = main.Mininet1.getLinks()
-    mnHosts = main.Mininet1.getHosts()
-    compareTopoResult = main.TRUE
-
-    for i in range( main.numCtrls ):
-        devices.append( json.loads( main.CLIs[ i ].devices() ) )
-        links.append( json.loads( main.CLIs[ i ].links() ) )
-        ports.append( json.loads(  main.CLIs[ i ].ports() ) )
-        hosts.append( json.loads( main.CLIs[ i ].hosts() ) )
-
-    # Comparing switches
-    main.log.info( main.topoName + ": Comparing switches in each ONOS nodes" +
-                   " with Mininet" )
-    for i in range( main.numCtrls ):
-        tempResult = main.Mininet1.compareSwitches( mnSwitches,
-                                                    devices[ i ],
-                                                    ports[ i ] )
-        switchResult.append( tempResult )
-        if tempResult == main.FALSE:
-            main.log.error( main.topoName + ": ONOS-" + str( i + 1 ) +
-                            " switch view is incorrect " )
-
-    if all( result == main.TRUE for result in switchResult ):
-        main.log.info( main.topoName + ": Switch view in all ONOS nodes "+
-                       "are correct " )
-    else:
-        compareTopoResult = main.FALSE
-
-    # Comparing links
-    main.log.info( main.topoName + ": Comparing links in each ONOS nodes" +
-                   " with Mininet" )
-    for i in range( main.numCtrls ):
-        tempResult = main.Mininet1.compareLinks( mnSwitches,
-                                                 mnLinks,
-                                                 links[ i ] )
-        linksResult.append( tempResult )
-        if tempResult == main.FALSE:
-            main.log.error( main.topoName + ": ONOS-" + str( i + 1 ) +
-                            " links view are incorrect " )
-
-    if all( result == main.TRUE for result in linksResult ):
-        main.log.info( main.topoName + ": Links view in all ONOS nodes "+
-                       "are correct " )
-    else:
-        compareTopoResult = main.FALSE
-
-    # Comparing hosts
-    main.log.info( main.topoName + ": Comparing hosts in each ONOS nodes" +
-                   " with Mininet" )
-    for i in range( main.numCtrls ):
-        tempResult = main.Mininet1.compareHosts( mnHosts, hosts[ i ] )
-        hostsResult.append( tempResult )
-        if tempResult == main.FALSE:
-            main.log.error( main.topoName + ": ONOS-" + str( i + 1 ) +
-                            " hosts view are incorrect " )
-
-    if all( result == main.TRUE for result in hostsResult ):
-        main.log.info( main.topoName + ": Hosts view in all ONOS nodes "+
-                       "are correct " )
-    else:
-        compareTopoResult = main.FALSE
-
-    return compareTopoResult
+    try:
+        from tests.dependencies.topology import Topology
+    except ImportError:
+        main.log.error( "Topology not found exiting the test" )
+        main.exit()
+    try:
+        main.topoRelated
+    except ( NameError, AttributeError ):
+        main.topoRelated = Topology()
+    return main.topoRelated.compareTopos( main.Mininet1 )
 
 def assignSwitch( main ):
     """
@@ -324,12 +262,12 @@
     assignResult = main.TRUE
     switchList =  main.Mininet1.getSwitch()
     assignResult = main.Mininet1.assignSwController( sw=switchList,
-                                                     ip=main.ONOSip[ 0 ],
+                                                     ip=main.Cluster.active( 0 ).ipAddress,
                                                      port=6633 )
 
     for sw in switchList:
         response = main.Mininet1.getSwController( sw )
-        if re.search( "tcp:" + main.ONOSip[ 0 ], response ):
+        if re.search( "tcp:" + main.Cluster.active( 0 ).ipAddress, response ):
             assignResult = assignResult and main.TRUE
         else:
             assignResult = main.FALSE
@@ -344,15 +282,15 @@
     appCheck = main.TRUE
     getDataResult = main.TRUE
     main.log.info( main.topoName + ": Activating reactive forwarding app " )
-    activateResult = main.CLIs[ 0 ].activateApp( "org.onosproject.fwd" )
+    activateResult = main.Cluster.active( 0 ).activateApp( "org.onosproject.fwd" )
 
     if main.hostsData:
         main.hostsData = {}
-    for i in range( main.numCtrls ):
-        appCheck = appCheck and main.CLIs[ i ].appToIDCheck()
+    for ctrl in main.Cluster.active():
+        appCheck = appCheck and ctrl.CLI.appToIDCheck()
         if appCheck != main.TRUE:
-            main.log.warn( main.CLIs[ i ].apps() )
-            main.log.warn( main.CLIs[ i ].appIDs() )
+            main.log.warn( ctrl.CLI.apps() )
+            main.log.warn( ctrl.CLI.appIDs() )
 
     time.sleep( main.fwdSleep )
 
@@ -362,12 +300,12 @@
                                         acceptableFailed=acceptableFailed )
 
     main.log.info( main.topoName + ": Deactivate reactive forwarding app " )
-    activateResult = main.CLIs[ 0 ].deactivateApp( "org.onosproject.fwd" )
-    for i in range( main.numCtrls ):
-        appCheck = appCheck and main.CLIs[ i ].appToIDCheck()
+    activateResult = main.Cluster.active( 0 ).deactivateApp( "org.onosproject.fwd" )
+    for ctrl in main.Cluster.active():
+        appCheck = appCheck and ctrl.CLI.appToIDCheck()
         if appCheck != main.TRUE:
-            main.log.warn( main.CLIs[ i ].apps() )
-            main.log.warn( main.CLIs[ i ].appIDs() )
+            main.log.warn( ctrl.CLI.apps() )
+            main.log.warn( ctrl.CLI.appIDs() )
 
     return pingResult
 
@@ -379,21 +317,21 @@
     appCheck = main.TRUE
     getDataResult = main.TRUE
     main.log.info( main.topoName + ": Activating reactive forwarding app " )
-    activateResult = main.CLIs[ 0 ].activateApp( "org.onosproject.fwd" )
+    activateResult = main.Cluster.active( 0 ).CLI.activateApp( "org.onosproject.fwd" )
 
     if main.hostsData:
         main.hostsData = {}
-    for i in range( main.numCtrls ):
-        appCheck = appCheck and main.CLIs[ i ].appToIDCheck()
+    for ctrl in main.Cluster.active():
+        appCheck = appCheck and ctrl.CLI.appToIDCheck()
         if appCheck != main.TRUE:
-            main.log.warn( main.CLIs[ i ].apps() )
-            main.log.warn( main.CLIs[ i ].appIDs() )
+            main.log.warn( ctrl.CLI.apps() )
+            main.log.warn( ctrl.CLI.appIDs() )
 
     time.sleep( main.fwdSleep )
     # Discover hosts using pingall
     pingResult = main.Mininet1.pingall( timeout=900 )
 
-    hostsJson = json.loads( main.CLIs[ 0 ].hosts() )
+    hostsJson = json.loads( main.Cluster.active( 0 ).CLI.hosts() )
     hosts = main.Mininet1.getHosts().keys()
 
     for host in hosts:
@@ -419,12 +357,12 @@
         getDataResult = main.FALSE
 
     main.log.info( main.topoName + ": Deactivate reactive forwarding app " )
-    activateResult = main.CLIs[ 0 ].deactivateApp( "org.onosproject.fwd" )
-    for i in range( main.numCtrls ):
-        appCheck = appCheck and main.CLIs[ i ].appToIDCheck()
+    activateResult = main.Cluster.active( 0 ).CLI.deactivateApp( "org.onosproject.fwd" )
+    for ctrl in main.Cluster.active():
+        appCheck = appCheck and ctrl.CLI.appToIDCheck()
         if appCheck != main.TRUE:
-            main.log.warn( main.CLIs[ i ].apps() )
-            main.log.warn( main.CLIs[ i ].appIDs() )
+            main.log.warn( ctrl.CLI.apps() )
+            main.log.warn( ctrl.CLI.appIDs() )
 
     # This data can be use later for intents
     print main.hostsData
@@ -439,65 +377,40 @@
     Return:
         Retruns main.TRUE for a successful restart, main.FALSE otherwise.
     """
-    uninstallResult = []
-    installResult = []
     stopResult = []
     startResult = []
     onosIsUpResult = []
     restartResult = main.TRUE
 
-    main.log.info( main.topoName + ": Uninstall ONOS cluster" )
-    for ip in main.ONOSip:
-        uninstallResult.append( main.ONOSbench.onosUninstall( nodeIp=ip ) )
-
-    if all( result == main.TRUE for result in uninstallResult ):
-        main.log.info( main.topoName + ": Successfully uninstall ONOS cluster" )
-    else:
+    uninstallResult = main.testSetUp.uninstallOnos( main.Cluster, False )
+    if uninstallResult != main.TRUE:
         restartResult = main.FALSE
-        main.log.error( main.topoName + ": Failed to uninstall ONOS cluster" )
-
-    time.sleep( main.startUpSleep )
-
-    main.log.info( main.topoName + ": Installing ONOS cluster" )
-
-    for i in range( main.numCtrls ):
-        installResult.append( main.ONOSbench.onosInstall(
-                                                    node=main.ONOSip[ i ] ) )
-
-    if all( result == main.TRUE for result in installResult ):
-        main.log.info( main.topoName + ": Successfully installed ONOS cluster" )
-    else:
-        restartResult = main.FALSE
-        main.log.error( main.topoName + ": Failed to install ONOS cluster" )
-
-    main.log.info( main.topoName + ": set up ONOS secure SSH" )
-    secureSshResult = []
-    for i in range( int( main.numCtrls ) ):
-        secureSshResult.append( main.onosSecureSSH( node=main.ONOSip[i] ) )
-    if all( result == main.TRUE for result in secureSshResult ):
-        main.log.info( main.topoName + ": Successfully set up ONOS secure SSH" )
-    else:
-        main.log.error( main.topoName + ": Failed to set up ONOS secure SSH" )
+    installResult = main.testSetUp.installOnos( main.Cluster, False )
+    if installResult != main.TRUE:
         restartResult = main.FALSE
 
-    for i in range( main.numCtrls ):
-        onosIsUpResult.append( main.ONOSbench.isup( main.ONOSip[ i ] ) )
+    secureSshResult = main.testSetUp.setupSsh( main.Cluster )
+    if secureSshResult != main.TRUE:
+        restartResult = main.FALSE
+
+    for ctrl in main.Cluster.runningNodes:
+        onosIsUpResult.append( main.ONOSbench.isup( ctrl.ipAddress ) )
 
     if all( result == main.TRUE for result in onosIsUpResult ):
         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.append( main.ONOSbench.onosStop( main.ONOSip[ i ] ) )
+        for ctrl in main.Cluster.runningNodes:
+            stopResult.append( main.ONOSbench.onosStop( ctrl.ipAddress ) )
 
         if all( result == main.TRUE for result in stopResult ):
             main.log.info( main.topoName + ": Successfully stop ONOS cluster" )
         else:
             main.log.error( main.topoName + ": Failed to stop ONOS cluster" )
 
-        for i in range( main.numCtrls ):
-            startResult.append( main.ONOSbench.onosStart( main.ONOSip[ i ] ) )
+        for ctrl in main.Cluster.runningNodes:
+            startResult.append( main.ONOSbench.onosStart( ctrl.ipAddress ) )
 
         if all( result == main.TRUE for result in startResult ):
             main.log.info( main.topoName + ": Successfully start ONOS cluster" )
@@ -505,14 +418,8 @@
             main.log.error( main.topoName + ": Failed to start ONOS cluster" )
 
     main.log.info( main.topoName + ": Starting ONOS CLI" )
-    cliResult = []
-    for i in range( main.numCtrls ):
-        cliResult.append( main.CLIs[ i ].startOnosCli( main.ONOSip[ i ] ) )
-
-    if all( result == main.TRUE for result in cliResult ):
-        main.log.info( main.topoName + ": Successfully start ONOS cli" )
-    else:
-        main.log.error( main.topoName + ": Failed to start ONOS cli" )
+    cliResult = main.testSetUp.startOnosClis( main.Cluster )
+    if cliResult != main.TRUE:
         restartResult = main.FALSE
 
 
diff --git a/TestON/tests/SCPF/SCPFscaleTopo/dependencies/topo.py b/TestON/tests/SCPF/SCPFscaleTopo/dependencies/topo.py
index 74f8751..c5c1f88 100644
--- a/TestON/tests/SCPF/SCPFscaleTopo/dependencies/topo.py
+++ b/TestON/tests/SCPF/SCPFscaleTopo/dependencies/topo.py
@@ -43,7 +43,7 @@
         main.Mininet1.arping( srcHost=hostList, dstHost="10.0.0.1", output=main.FALSE, noResult=True )
     try:
         summaryStr = ""
-        summaryStr = json.loads( main.CLIs[0].summary().encode() )
+        summaryStr = json.loads( main.Cluster.active( 0 ).CLI.summary().encode() )
         hostNum = summaryStr.get( 'hosts' )
 
     except (TypeError, ValueError):