Update Cluster Driver

Change-Id: I8a3a57e19637ff210548e57d41178e6f194cf694
diff --git a/TestON/tests/dependencies/Cluster.py b/TestON/tests/dependencies/Cluster.py
index 01dc767..6b18b8b 100644
--- a/TestON/tests/dependencies/Cluster.py
+++ b/TestON/tests/dependencies/Cluster.py
@@ -27,33 +27,104 @@
     def __repr__( self ):
         #TODO use repr of cli's?
         controllers = []
+        runningNodes = []
         for ctrl in self.controllers:
             controllers.append( str( ctrl ) )
         return "%s[%s]" % ( self.name, ", ".join( controllers ) )
 
 
     def __init__( self, ctrlList=[], name="Cluster" ):
-        #assert isInstance( ctrlList, Controller ), "ctrlList should be a list of ONOS Controllers"
+        '''
+            controllers : All the nodes
+            runningNodes : Node that are specifically running from the test.
+                ie) When the test is testing different number of nodes on each
+                    run.
+            numCtrls : number of runningNodes
+            maxCtrls : number of controllers
+        '''
         self.controllers = ctrlList
+        self.runningNodes = ctrlList
+        self.numCtrls = len( self.runningNodes )
+        self.maxCtrls = len( self.controllers )
         self.name = str( name )
         self.iterator = iter( self.active() )
 
-    def getIps( self, activeOnly=False):
+    def getIps( self, activeOnly=False, allNode=False ):
+        """
+        Description:
+            get the list of the ip. Default to get ips of running nodes.
+        Required:
+            * activeOnly - True for getting ips of active nodes
+            * allNode - True for getting ips of all nodes
+        Returns:
+            Retruns ips of active nodes if activeOnly is True.
+            Returns ips of all nodes if allNode is True.
+        """
         ips = []
-        if activeOnly:
-            nodeList = self.active()
-        else:
+        if allNode:
             nodeList = self.controllers
+        else:
+            if activeOnly:
+                nodeList = self.active()
+            else:
+                nodeList = self.runningNodes
+
         for ctrl in nodeList:
             ips.append( ctrl.ipAddress )
+
         return ips
 
-    def active( self ):
+    def resetActive( self ):
         """
-        Return a list of active controllers in the cluster
+        Description:
+            reset the activeness of the runningNodes to be false
+        Required:
+        Returns:
         """
-        return [ ctrl for ctrl in self.controllers
+        for ctrl in self.runningNodes:
+            ctrl.active = False
+
+    def getRunningPos( self ):
+        """
+        Description:
+            get the position of the active running nodes.
+        Required:
+        Returns:
+            Retruns the list of the position of the active
+            running nodes.
+        """
+        return [ ctrl.pos for ctrl in self.runningNodes
+                 if ctrl.active ]
+
+    def setRunningNode( self, numCtrls ):
+        """
+        Description:
+            Set running nodes of n number of nodes.
+            It will create new list of runningNodes.
+            If numCtrls is a list, it will add the nodes of the
+            list.
+        Required:
+            * numCtrls - number of nodes to be set.
+        Returns:
+        """
+        self.runningNodes = []
+        for i in numCtrls if isinstance( numCtrls, list ) else range( numCtrls ) :
+            self.runningNodes.append( self.controllers[ i ] )
+        self.numCtrls = len( numCtrls ) if isinstance( numCtrls, list ) else numCtrls
+
+    def active( self, node=None ):
+        """
+        Description:
+            get the list/controller of the active controller.
+        Required:
+            * node - position of the node to get from the active controller.
+        Returns:
+            Return a list of active controllers in the cluster if node is None
+            if not, it will return the nth controller.
+        """
+        result = [ ctrl for ctrl in self.runningNodes
                       if ctrl.active ]
+        return result if node is None else result[ node % len( result ) ]
 
     def next( self ):
         """
@@ -80,24 +151,151 @@
         """
         self.iterator = iter( self.active() )
 
-    def install( self ):
+    def createCell( self, cellName, Mininet, useSSH, ips ):
         """
-        Install ONOS on all controller nodes in the cluster
+        Description:
+            create a new cell
+        Required:
+            * cellName - The name of the cell.
+            * Mininet - a mininet driver that will be used.
+            * useSSH - True for using ssh when creating a cell
+            * ips - ip(s) of the node(s).
+        Returns:
+        """
+        main.ONOSbench.createCellFile( main.ONOSbench.ip_address,
+                                       cellName,
+                                       Mininet if isinstance( Mininet, str ) else
+                                       Mininet.ip_address,
+                                       main.apps,
+                                       ips,
+                                       main.ONOScell.karafUser,
+                                       useSSH=useSSH )
+
+    def uninstall( self, uninstallMax ):
+        """
+        Description:
+            uninstalling onos
+        Required:
+            * uninstallMax - True for uninstalling max number of nodes
+            False for uninstalling the current running nodes.
+        Returns:
+            Returns main.TRUE if it successfully uninstalled.
+        """
+        onosUninstallResult = main.TRUE
+        for ctrl in self.controllers if uninstallMax else self.runningNodes:
+            onosUninstallResult = onosUninstallResult and \
+                                  main.ONOSbench.onosUninstall( nodeIp=ctrl.ipAddress )
+        return onosUninstallResult
+
+    def applyCell( self, cellName ):
+        """
+        Description:
+            apply the cell with cellName. It will also verify the
+            cell.
+        Required:
+            * cellName - The name of the cell.
+        Returns:
+            Returns main.TRUE if it successfully set and verify cell.
+        """
+        cellResult = main.ONOSbench.setCell( cellName )
+        verifyResult = main.ONOSbench.verifyCell()
+        return cellResult and verifyResult
+
+    def checkService( self ):
+        """
+        Description:
+            Checking if the onos service is up. If not, it will
+            start the onos service manually.
+        Required:
+        Returns:
+            Returns main.TRUE if it successfully checked
+        """
+        stopResult = main.TRUE
+        startResult = main.TRUE
+        onosIsUp = main.TRUE
+        i = 0
+        for ctrl in self.runningNodes:
+            onosIsUp = onosIsUp and main.ONOSbench.isup( ctrl.ipAddress )
+            if onosIsUp == main.TRUE:
+                main.log.report( "ONOS instance {0} is up and ready".format( i + 1 ) )
+            else:
+                main.log.report( "ONOS instance {0} may not be up, stop and ".format( i + 1 ) +
+                                 "start ONOS again " )
+                stopResult = stopResult and main.ONOSbench.onosStop( ctrl.ipAddress )
+                startResult = startResult and main.ONOSbench.onosStart( ctrl.ipAddress )
+                if not startResult or stopResult:
+                    main.log.report( "ONOS instance {0} did not start correctly.".format( i + 1 ) )
+            i += 1
+        return onosIsUp and stopResult and startResult
+
+    def kill( self, killMax, stopOnos ):
+        """
+        Description:
+            killing the onos. It will either kill the current runningnodes or
+            max number of the nodes.
+        Required:
+            * killRemoveMax - The boolean that will decide either to kill
+            only running nodes (False) or max number of nodes (True).
+            * stopOnos - If wish to stop onos before killing it. True for
+            enable stop , False for disable stop.
+        Returns:
+            Returns main.TRUE if successfully killing it.
         """
         result = main.TRUE
-        # FIXME: use the correct onosdriver function
-        # TODO: Use threads to install in parallel, maybe have an option for sequential installs
-        for ctrl in self.controllers:
-            result &= ctrl.installOnos( ctrl.ipAddress )
+        for ctrl in self.controllers if killMax else self.runningNodes:
+            if stopOnos:
+                result = result and main.ONOSbench.onosStop( ctrl.ipAddress )
+            result = result and main.ONOSbench.onosKill( ctrl.ipAddress )
+            ctrl.active = False
+        return result
+
+    def ssh( self ):
+        """
+        Description:
+            set up ssh to the onos
+        Required:
+        Returns:
+            Returns main.TRUE if it successfully setup the ssh to
+            the onos.
+        """
+        secureSshResult = main.TRUE
+        for ctrl in self.runningNodes:
+            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=ctrl.ipAddress )
+        return secureSshResult
+
+    def install( self, installMax=True ):
+        """
+        Description:
+            Installing onos.
+        Required:
+            * installMax - True for installing max number of nodes
+            False for installing current running nodes only.
+        Returns:
+            Returns main.TRUE if it successfully installed
+        """
+        result = main.TRUE
+        threads = []
+        i = 0
+        for ctrl in self.controllers if installMax else self.runningNodes:
+            options = "-f"
+            if installMax and i >= self.numCtrls:
+                options = "-nf"
+            result = result and \
+                            main.ONOSbench.onosInstall( node=ctrl.ipAddress, options=options )
+
         return result
 
     def startCLIs( self ):
         """
-        Start the ONOS cli on all controller nodes in the cluster
+        Description:
+            starting Onos using onosCli driver
+        Required:
+        Returns:
+            Returns main.TRUE if it successfully started.
         """
         cliResults =  main.TRUE
         threads = []
-        for ctrl in self.controllers:
+        for ctrl in self.runningNodes:
             t = main.Thread( target=ctrl.CLI.startOnosCli,
                              name="startCli-" + ctrl.name,
                              args=[ ctrl.ipAddress ] )
@@ -110,14 +308,106 @@
             cliResults = cliResults and t.result
         return cliResults
 
-    def command( self, function, args=(), kwargs={} ):
+    def printResult( self, results, activeList, logLevel="debug" ):
+        """
+        Description:
+            Print the value of the list.
+        Required:
+            * results - list of the result
+            * activeList - list of the acitve nodes.
+            * logLevel - Type of log level you want it to be printed.
+        Returns:
+        """
+        f = getattr( main.log, logLevel )
+        for i in range ( len ( results ) ):
+            f( activeList[ i ].name + "'s result : " + str ( results[ i ] ) )
+
+    def allTrueResultCheck( self, results, activeList ):
+        """
+        Description:
+            check if all the result has main.TRUE.
+        Required:
+            * results - list of the result
+            * activeList - list of the acitve nodes.
+        Returns:
+            Returns True if all == main.TRUE else
+            returns False
+        """
+        self.printResult( results, activeList )
+        return all( result == main.TRUE for result in results )
+
+    def notEmptyResultCheck( self, results, activeList ):
+        """
+        Description:
+            check if all the result has any contents
+        Required:
+            * results - list of the result
+            * activeList - list of the acitve nodes.
+        Returns:
+            Returns True if all the results has
+            something else returns False
+        """
+        self.printResult( results, activeList )
+        return all( result for result in results )
+
+    def identicalResultsCheck( self, results, activeList ):
+        """
+        Description:
+            check if all the results has same output.
+        Required:
+            * results - list of the result
+            * activeList - list of the acitve nodes.
+        Returns:
+            Returns True if all the results has
+            same result else returns False
+        """
+        self.printResult( results, activeList )
+        resultOne = results[ 0 ]
+        return all( resultOne == result for result in results )
+
+    def command( self, function, args=(), kwargs={}, returnBool=False, specificDriver=0, contentCheck=False ):
+        """
+        Description:
+            execute some function of the active nodes.
+        Required:
+            * function - name of the function
+            * args - argument of the function
+            * kwargs - kwargs of the funciton
+            * returnBool - True if wish to check all the result has main.TRUE
+            * specificDriver - specific driver to execute the function. Since
+            some of the function can be used in different drivers, it is important
+            to specify which driver it will be executed from.
+                0 - any type of driver
+                1 - from bench
+                2 - from cli
+                3 - from rest
+            * contentCheck - If this is True, it will check if the result has some
+            contents.
+        Returns:
+            Returns results if not returnBool and not contentCheck
+            Returns checkTruthValue of the result if returnBool
+            Returns resultContent of the result if contentCheck
+        """
         """
         Send a command to all ONOS nodes and return the results as a list
+        specificDriver:
+            0 - any type of driver
+            1 - from bench
+            2 - from cli
+            3 - from rest
         """
         threads = []
+        drivers = [ None, "Bench", "CLI", "REST" ]
         results = []
         for ctrl in self.active():
-            f = getattr( ctrl, function )
+            try:
+                f = getattr( ( ctrl if not specificDriver else
+                             getattr( ctrl, drivers[ specificDriver ] ) ), function )
+            except AttributeError:
+                main.log.error( "Function " + function + " not found. Exiting the Test." )
+                main.cleanup()
+                main.exit()
+
             t = main.Thread( target=f,
                              name=function + "-" + ctrl.name,
                              args=args,
@@ -128,4 +418,8 @@
         for t in threads:
             t.join()
             results.append( t.result )
-        return results
+        if returnBool:
+            return self.allTrueResultCheck( results, self.active() )
+        elif contentCheck:
+            return self.notEmptyResultCheck( results, self.active() )
+        return results
\ No newline at end of file
diff --git a/TestON/tests/dependencies/ONOSSetup.py b/TestON/tests/dependencies/ONOSSetup.py
index bf3bfd1..ddf0570 100644
--- a/TestON/tests/dependencies/ONOSSetup.py
+++ b/TestON/tests/dependencies/ONOSSetup.py
@@ -1,4 +1,23 @@
+"""
+Copyright 2016 Open Networking Foundation (ONF)
 
+Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
+the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
+or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
+
+    TestON is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 2 of the License, or
+    (at your option) any later version.
+
+    TestON is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+"""
 import time
 import re
 import imp
@@ -8,13 +27,29 @@
     def __init__( self ):
         self.default = ''
     def envSetupDescription ( self ):
+        """
+        Introduction part of the test. It will initialize some basic vairables.
+        """
         main.case( "Constructing test variables and building ONOS package" )
         main.step( "Constructing test variables" )
         main.caseExplanation = "For loading from params file, and pull" + \
                                " and build the latest ONOS package"
+        try:
+            from tests.dependencies.Cluster import Cluster
+        except ImportError:
+            main.log.error( "Cluster not found. exiting the test" )
+            main.exit()
+        try:
+            main.Cluster
+        except ( NameError, AttributeError ):
+            main.Cluster = Cluster( main.ONOScell.nodes )
+        main.ONOSbench = main.Cluster.controllers[ 0 ].Bench
         main.testOnDirectory = re.sub( "(/tests)$", "", main.testDir )
 
     def gitPulling( self ):
+        """
+        it will do git checkout or pull if they are enabled from the params file.
+        """
         main.case( "Pull onos branch and build onos on Teststation." )
         gitPull = main.params[ 'GIT' ][ 'pull' ]
         gitBranch = main.params[ 'GIT' ][ 'branch' ]
@@ -38,34 +73,50 @@
         else:
             main.log.info( "Skipped git checkout and pull as they are disabled in params file" )
 
-    def envSetup( self, cluster, hasMultiNodeRounds=False, hasRest=False, hasNode=False,
-                  hasCli=True, specificIp="", includeGitPull=True ):
+    def envSetup( self, includeGitPull=True ):
+        """
+        Description:
+            some environment setup for the test.
+        Required:
+            * includeGitPull - if wish to git pulling function to be executed.
+        Returns:
+            Returns main.TRUE
+        """
         if includeGitPull :
             self.gitPulling()
 
-        ONOSbench = cluster.controllers[0].Bench
-        if ONOSbench.maxNodes:
-            main.maxNodes = int( ONOSbench.maxNodes )
-        else:
-            main.maxNodes = 0
+        try:
+            from tests.dependencies.Cluster import Cluster
+        except ImportError:
+            main.log.error( "Cluster not found. exiting the test" )
+            main.exit()
+        try:
+            main.Cluster
+        except ( NameError, AttributeError ):
+            main.Cluster = Cluster( main.ONOScell.nodes )
+
         main.cellData = {}  # For creating cell file
-        main.ONOSip = cluster.getIps()  # List of IPs of active ONOS nodes. CASE 2
 
-        # FIXME: Do we need this?
-        #        We should be able to just use Cluster.getIps()
-        if specificIp != "":
-            main.ONOSip.append( specificIp )
-
-        # Assigning ONOS cli handles to a list
-        main.maxNodes = len( cluster.controllers )
         return main.TRUE
 
     def envSetupException( self, e ):
+        """
+        Description:
+            handles the exception that might occur from the environment setup.
+        Required:
+            * includeGitPull - exceeption code e.
+        """
         main.log.exception( e )
         main.cleanup()
         main.exit()
 
     def evnSetupConclusion( self, stepResult ):
+        """
+        Description:
+            compare the result of the envSetup of the test.
+        Required:
+            * stepResult - Result of the envSetup.
+        """
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
                                  onpass="Successfully construct " +
@@ -74,7 +125,14 @@
 
         main.commit = main.ONOSbench.getVersion( report=True )
 
-    def getNumCtrls( self, hasMultiNodeRounds ):
+    def setNumCtrls( self, hasMultiNodeRounds ):
+        """
+        Description:
+            Set new number of controls if it uses different number of nodes.
+            different number of nodes should be pre-defined in main.scale.
+        Required:
+            * hasMultiNodeRouds - if the test is testing different number of nodes.
+        """
         if hasMultiNodeRounds:
             try:
                 main.cycle
@@ -82,58 +140,80 @@
                 main.cycle = 0
             main.cycle += 1
             # main.scale[ 0 ] determines the current number of ONOS controller
-            main.numCtrls = int( main.scale.pop( 0 ) )
-        else:
-            main.numCtrls = main.maxNodes
+            main.Cluster.setRunningNode( int( main.scale.pop( 0 ) ) )
 
-    def killingAllOnos( self, killRemoveMax, stopOnos ):
-        # kill off all onos processes
-        main.log.info( "Safety check, killing all ONOS processes" +
-                      " before initiating environment setup" )
+    def killingAllOnos( self, cluster, killRemoveMax, stopOnos ):
+        """
+        Description:
+            killing the onos. It will either kill the current runningnodes or
+            max number of the nodes.
+        Required:
+            * cluster - the cluster driver that will be used.
+            * killRemoveMax - The boolean that will decide either to kill
+            only running nodes (False) or max number of nodes (True).
+            * stopOnos - If wish to stop onos before killing it. True for
+            enable stop , False for disable stop.
+        Returns:
+            Returns main.TRUE if successfully killing it.
+        """
+        main.log.info( "Safety check, killing all ONOS processes" )
 
-        for i in range( main.maxNodes if killRemoveMax else main.numCtrls ):
-            if stopOnos:
-                main.ONOSbench.onosStop( main.ONOSip[ i ] )
-            main.ONOSbench.onosKill( main.ONOSip[ i ] )
+        return cluster.kill( killRemoveMax, stopOnos )
 
-    def createApplyCell( self, newCell, cellName, Mininet, useSSH ):
+    def createApplyCell( self, cluster, newCell, cellName, Mininet, useSSH, ips ):
+        """
+        Description:
+            create new cell ( optional ) and apply it. It will also verify the
+            cell.
+        Required:
+            * cluster - the cluster driver that will be used.
+            * newCell - True for making a new cell and False for not making it.
+            * cellName - The name of the cell.
+            * Mininet - a mininet driver that will be used.
+            * useSSH - True for using ssh when creating a cell
+            * ips - ip(s) of the node(s).
+        Returns:
+            Returns main.TRUE if it successfully executed.
+        """
         if newCell:
-            tempOnosIp = []
-            for i in range( main.numCtrls ):
-                tempOnosIp.append( main.ONOSip[i] )
-
-            main.ONOSbench.createCellFile( main.ONOSbench.ip_address,
-                                           cellName,
-                                           Mininet if isinstance( Mininet, str ) else
-                                           Mininet.ip_address,
-                                           main.apps,
-                                           tempOnosIp,
-                                           main.ONOScli1.karafUser,
-                                           useSSH=useSSH )
+            cluster.createCell( cellName, Mininet, useSSH, ips )
         main.step( "Apply cell to environment" )
-        cellResult = main.ONOSbench.setCell( cellName )
-        verifyResult = main.ONOSbench.verifyCell()
-        stepResult = cellResult and verifyResult
+        stepResult = cluster.applyCell( cellName )
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
                                  onpass="Successfully applied cell to " +
                                        "environment",
-                                 onfail="Failed to apply cell to environment " )
+                                 onfail="Failed to apply cell to environment" )
         return stepResult
 
-    def uninstallOnos( self, killRemoveMax ):
+    def uninstallOnos( self, cluster, uninstallMax ):
+        """
+        Description:
+            uninstalling onos and verify the result.
+        Required:
+            * cluster - a cluster driver that will be used.
+            * uninstallMax - True for uninstalling max number of nodes
+            False for uninstalling the current running nodes.
+        Returns:
+            Returns main.TRUE if it successfully uninstalled.
+        """
         main.step( "Uninstalling ONOS package" )
-        onosUninstallResult = main.TRUE
-        for i in range( main.maxNodes if killRemoveMax else main.numCtrls ):
-            onosUninstallResult = onosUninstallResult and \
-                                  main.ONOSbench.onosUninstall( nodeIp=main.ONOSip[ i ] )
+        onosUninstallResult = cluster.uninstall( uninstallMax )
         utilities.assert_equals( expect=main.TRUE,
                                  actual=onosUninstallResult,
                                  onpass="Successfully uninstalled ONOS package",
                                  onfail="Failed to uninstall ONOS package" )
         return onosUninstallResult
 
-    def buildOnos( self ):
+    def buildOnos( self, cluster ):
+        """
+        Description:
+            build the onos using buck build onos and verify the result
+        Required:
+            * cluster - the cluster driver that will be used.
+        Returns:
+            Returns main.TRUE if it successfully built.
+        """
         main.step( "Creating ONOS package" )
         packageResult = main.ONOSbench.buckBuild()
         utilities.assert_equals( expect=main.TRUE,
@@ -142,16 +222,21 @@
                                  onfail="Failed to create ONOS package" )
         return packageResult
 
-    def installOnos( self, installMax ):
+    def installOnos( self, cluster, installMax ):
+        """
+        Description:
+            Installing onos and verify the result
+        Required:
+            * cluster - the cluster driver that will be used.
+            * installMax - True for installing max number of nodes
+            False for installing current running nodes only.
+        Returns:
+            Returns main.TRUE if it successfully installed
+        """
         main.step( "Installing ONOS package" )
         onosInstallResult = main.TRUE
 
-        for i in range( main.ONOSbench.maxNodes if installMax else main.numCtrls ):
-            options = "-f"
-            if installMax and i >= main.numCtrls:
-                options = "-nf"
-            onosInstallResult = onosInstallResult and \
-                                main.ONOSbench.onosInstall( node=main.ONOSip[ i ], options=options )
+        cluster.install( installMax )
         utilities.assert_equals( expect=main.TRUE,
                                  actual=onosInstallResult,
                                  onpass="Successfully installed ONOS package",
@@ -161,34 +246,35 @@
             main.exit()
         return onosInstallResult
 
-    def setupSsh( self ):
+    def setupSsh( self, cluster ):
+        """
+        Description:
+            set up ssh to the onos and verify the result
+        Required:
+            * cluster - the cluster driver that will be used.
+        Returns:
+            Returns main.TRUE if it successfully setup the ssh to
+            the onos.
+        """
         main.step( "Set up ONOS secure SSH" )
-        secureSshResult = main.TRUE
-        for i in range( main.numCtrls ):
-            secureSshResult = secureSshResult and main.ONOSbench.onosSecureSSH( node=main.ONOSip[ i ] )
+        secureSshResult = cluster.ssh()
         utilities.assert_equals( expect=main.TRUE,
                                  actual=secureSshResult,
                                  onpass="Test step PASS",
                                  onfail="Test step FAIL" )
         return secureSshResult
 
-    def checkOnosService( self ):
-        stopResult = main.TRUE
-        startResult = main.TRUE
-        onosIsUp = main.TRUE
-        main.step( "Starting ONOS service" )
-        for i in range( main.numCtrls ):
-            onosIsUp = onosIsUp and main.ONOSbench.isup( main.ONOSip[ i ] )
-            if onosIsUp == main.TRUE:
-                main.log.report( "ONOS instance {0} is up and ready".format( i + 1 ) )
-            else:
-                main.log.report( "ONOS instance {0} may not be up, stop and ".format( i + 1 ) +
-                                 "start ONOS again " )
-                stopResult = stopResult and main.ONOSbench.onosStop( main.ONOSip[ i ] )
-                startResult = startResult and main.ONOSbench.onosStart( main.ONOSip[ i ] )
-                if not startResult or stopResult:
-                    main.log.report( "ONOS instance {0} did not start correctly.".format( i + 1 ) )
-        stepResult = onosIsUp and stopResult and startResult
+    def checkOnosService( self, cluster ):
+        """
+        Description:
+            Checking if the onos service is up and verify the result
+        Required:
+            * cluster - the cluster driver that will be used.
+        Returns:
+            Returns main.TRUE if it successfully checked
+        """
+        main.step( "Checking ONOS service" )
+        stepResult = cluster.checkService()
         utilities.assert_equals( expect=main.TRUE,
                                  actual=stepResult,
                                  onpass="ONOS service is ready on all nodes",
@@ -196,6 +282,15 @@
         return stepResult
 
     def startOnosClis( self, cluster ):
+        """
+        Description:
+            starting Onos using onosCli driver and verify the result
+        Required:
+            * cluster - the cluster driver that will be used.
+        Returns:
+            Returns main.TRUE if it successfully started. It will exit
+            the test if not started properly.
+        """
         main.step( "Starting ONOS CLI sessions" )
         startCliResult = cluster.startCLIs()
         if not startCliResult:
@@ -210,50 +305,95 @@
                                  onfail="Failed to start ONOS cli" )
         return startCliResult
 
-    def ONOSSetUp( self, Mininet, cluster, hasMultiNodeRounds=False, hasCli=True, newCell=True,
+    def ONOSSetUp( self, Mininet, cluster, hasMultiNodeRounds=False, startOnos=True, newCell=True,
                    cellName="temp", removeLog=False, extraApply=None, arg=None, extraClean=None,
                    skipPack=False, installMax=False, useSSH=True, killRemoveMax=True,
-                   CtrlsSet=True, stopOnos=False ):
-        if CtrlsSet:
-            self.getNumCtrls( hasMultiNodeRounds )
+                   stopOnos=False ):
+        """
+        Description:
+            Initial ONOS setting up of the tests. It will also verify the result of each steps.
+            The procedures will be:
+                killing onos
+                creating (optional) /applying cell
+                removing raft logs (optional)
+                uninstalling onos
+                extra procedure to be applied( optional )
+                building onos
+                installing onos
+                extra cleanup to be applied ( optional )
+                setting up ssh to the onos
+                checking the onos service
+                starting onos
+        Required:
+            * Mininet - the mininet driver that will be used
+            * cluster - the cluster driver that will be used.
+            * hasMultiNodeRouds - True if the test is testing different set of nodes
+            * startOnos - True if wish to start onos.
+            * newCell - True for making a new cell and False for not making it.
+            * cellName - Name of the cell that will be used.
+            * removeLog - True if wish to remove raft logs
+            * extraApply - Function(s) that will be applied. Default to None.
+            * arg - argument of the functon(s) of the extraApply. Should be in list.
+            * extraClean - extra Clean up process. Function(s) will be passed.
+            * skipPack - True if wish to skip some packing.
+            * installMax - True if wish to install onos max number of nodes
+            False if wish to install onos of running nodes only
+            * useSSH - True for using ssh when creating a cell
+            * killRemoveMax - True for removing/killing max number of nodes. False for
+            removing/killing running nodes only.
+            * stopOnos - True if wish to stop onos before killing it.
+        Returns:
+            Returns main.TRUE if it everything successfully proceeded.
+        """
+        self.setNumCtrls( hasMultiNodeRounds )
 
-        main.case( "Starting up " + str( main.numCtrls ) +
+        main.case( "Starting up " + str( cluster.numCtrls ) +
                   " node(s) ONOS cluster" )
-        main.caseExplanation = "Set up ONOS with " + str( main.numCtrls ) + \
+        main.caseExplanation = "Set up ONOS with " + str( cluster.numCtrls ) + \
                                " node(s) ONOS cluster"
-        self.killingAllOnos( killRemoveMax, stopOnos )
+        killResult = self.killingAllOnos( cluster, killRemoveMax, stopOnos )
 
-        main.log.info( "NODE COUNT = " + str( main.numCtrls ) )
-        cellResult = True
-        packageResult = True
-        onosUninstallResult = True
-        onosCliResult = True
+        main.log.info( "NODE COUNT = " + str( cluster.numCtrls ) )
+        cellResult = main.TRUE
+        packageResult = main.TRUE
+        onosUninstallResult = main.TRUE
+        onosCliResult = main.TRUE
         if not skipPack:
-            cellResult = self.createApplyCell( newCell, cellName, Mininet, useSSH )
-
+            tempOnosIp = []
+            for ctrl in cluster.runningNodes:
+                tempOnosIp.append( ctrl.ipAddress )
+            cellResult = self.createApplyCell( cluster, newCell,
+                                               cellName, Mininet,
+                                               useSSH, tempOnosIp )
             if removeLog:
                 main.log.info("Removing raft logs")
                 main.ONOSbench.onosRemoveRaftLogs()
 
-            onosUninstallResult = self.uninstallOnos( killRemoveMax )
+            onosUninstallResult = self.uninstallOnos( cluster, killRemoveMax )
 
             if extraApply is not None:
-                extraApply( metadataMethod=arg ) if arg is not None else extraApply()
+                if isinstance( extraApply, list ):
+                    i = 0
+                    for apply in extraApply:
+                        apply( *(arg[ i ]) ) if arg is not None \
+                                                            and arg[ i ] is not None else apply()
+                        i += 1
+                else:
+                    extraApply( *arg ) if arg is not None else extraApply()
 
-            packageResult = self.buildOnos()
 
-        onosInstallResult = self.installOnos( installMax )
+            packageResult = self.buildOnos( cluster )
+
+        onosInstallResult = self.installOnos( cluster, installMax )
 
         if extraClean is not None:
             extraClean()
-        secureSshResult = True
-        if useSSH:
-            secureSshResult = self.setupSsh()
+        secureSshResult = self.setupSsh( cluster )
 
-        onosServiceResult = self.checkOnosService()
+        onosServiceResult = self.checkOnosService( cluster )
 
-        if hasCli:
+        if startOnos:
             onosCliResult = self.startOnosClis( cluster )
 
-        return cellResult and packageResult and onosUninstallResult and \
+        return killResult and cellResult and packageResult and onosUninstallResult and \
                onosInstallResult and secureSshResult and onosServiceResult and onosCliResult
diff --git a/TestON/tests/dependencies/topology.py b/TestON/tests/dependencies/topology.py
index 7819fec..2a81987 100644
--- a/TestON/tests/dependencies/topology.py
+++ b/TestON/tests/dependencies/topology.py
@@ -1,3 +1,23 @@
+"""
+Copyright 2016 Open Networking Foundation (ONF)
+
+Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
+the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
+or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
+
+    TestON is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 2 of the License, or
+    (at your option) any later version.
+
+    TestON is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+"""
 import time
 import re
 import imp
@@ -6,39 +26,29 @@
 
     def __init__( self ):
         self.default = ''
+
     """
         These functions can be used for topology comparisons
     """
-    def getAllDevices( self, numNode, needRetry, kwargs={} ):
+    def getAll( self, function, needRetry=False, kwargs={}, inJson=False ):
         """
-            Return a list containing the devices output from each ONOS node
+        Description:
+            get all devices/links/hosts/ports of the onosCli
+        Required:
+            * function - name of the function
+            * needRetry - it will retry if this is true.
+            * kwargs - kwargs of the function
+            * inJson - True if want it in Json form
+        Returns:
+            Returns the list of the result.
         """
-        devices = []
+        returnList = []
         threads = []
         for ctrl in main.Cluster.active():
-            t = main.Thread( target=utilities.retry if needRetry else ctrl.devices,
-                             name="devices-" + str( ctrl ),
-                             args=[ ctrl.devices, [ None ] ] if needRetry else [],
-                             kwargs=kwargs )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            devices.append( t.result )
-        return devices
-
-    def getAllHosts( self, numNode, needRetry, kwargs={}, inJson=False ):
-        """
-            Return a list containing the hosts output from each ONOS node
-        """
-        hosts = []
-        ipResult = main.TRUE
-        threads = []
-        for ctrl in main.Cluster.active():
-            t = main.Thread( target=utilities.retry if needRetry else ctrl.hosts,
-                             name="hosts-" + str( ctrl ),
-                             args=[ ctrl.hosts, [ None ] ] if needRetry else [],
+            func = getattr( ctrl.CLI, function )
+            t = main.Thread( target=utilities.retry if needRetry else func,
+                             name= function + "-" + str( ctrl ),
+                             args=[ func, [ None ] ] if needRetry else [],
                              kwargs=kwargs )
             threads.append( t )
             t.start()
@@ -47,74 +57,29 @@
             t.join()
             if inJson:
                 try:
-                    hosts.append( json.loads( t.result ) )
+                    returnList.append( json.loads( t.result ) )
                 except ( ValueError, TypeError ):
                     main.log.exception( "Error parsing hosts results" )
                     main.log.error( repr( t.result ) )
-                    hosts.append( None )
+                    returnList.append( None )
             else:
-                hosts.append( t.result )
-        return hosts
-
-    def getAllPorts( self, numNode, needRetry, kwargs={} ):
-        """
-            Return a list containing the ports output from each ONOS node
-        """
-        ports = []
-        threads = []
-        for ctrl in main.Cluster.active():
-            t = main.Thread( target=utilities.retry if needRetry else ctrl.ports,
-                             name="ports-" + str( ctrl ),
-                             args=[ ctrl.ports, [ None ] ] if needRetry else [],
-                             kwargs=kwargs )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            ports.append( t.result )
-        return ports
-
-    def getAllLinks( self, numNode, needRetry, kwargs={} ):
-        """
-            Return a list containing the links output from each ONOS node
-        """
-        links = []
-        threads = []
-        for ctrl in main.Cluster.active():
-            t = main.Thread( target=utilities.retry if needRetry else ctrl.links,
-                             name="links-" + str( ctrl ),
-                             args=[ ctrl.links, [ None ] ] if needRetry else [],
-                             kwargs=kwargs )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            links.append( t.result )
-        print links
-        return links
-
-    def getAllClusters( self, numNode, needRetry, kwargs={} ):
-        """
-            Return a list containing the clusters output from each ONOS node
-        """
-        clusters = []
-        threads = []
-        for ctrl in main.Cluster.active():
-            t = main.Thread( target=utilities.retry if needRetry else ctrl.clusters,
-                             name="clusters-" + str( ctrl ),
-                             args=[ ctrl.clusters, [ None ] ] if needRetry else [],
-                             kwargs=kwargs )
-            threads.append( t )
-            t.start()
-
-        for t in threads:
-            t.join()
-            clusters.append( t.result )
-        return clusters
+                returnList.append( t.result )
+        return returnList
 
     def compareDevicePort( self, Mininet, controller, mnSwitches, devices, ports ):
+        """
+        Description:
+            compares the devices and port of the onos to the mininet.
+        Required:
+            * Mininet - mininet driver to use
+            * controller - controller position of the devices
+            * mnSwitches - switches of mininet
+            * devices - devices of the onos
+            * ports - ports of the onos
+        Returns:
+            Returns main.TRUE if the results are matching else
+            Returns main.FALSE
+        """
         if devices[ controller ] and ports[ controller ] and \
                         "Error" not in devices[ controller ] and \
                         "Error" not in ports[ controller ]:
@@ -133,6 +98,19 @@
         return currentDevicesResult
 
     def compareBase( self, compareElem, controller, compareF, compareArg ):
+        """
+        Description:
+            compares the links/hosts of the onos to the mininet.
+        Required:
+            * compareElem - list of links/hosts of the onos
+            * controller - controller position of the devices
+            * compareF - function of the mininet that will compare the
+            results
+            * compareArg - arg of the compareF.
+        Returns:
+            Returns main.TRUE if the results are matching else
+            Returns main.FALSE
+        """
         if compareElem[ controller ] and "Error" not in compareElem[ controller ]:
             try:
                 if isinstance( compareArg, list ):
@@ -151,7 +129,17 @@
         return currentCompareResult
 
     def compareTopos( self, Mininet, attempts=1 ):
-
+        """
+        Description:
+            compares the links and hosts and switches of the onos to the mininet.
+        Required:
+            * Mininet - Mininet driver to use.
+            * attempts - number of attempts to compare in case
+            the result is different after a certain time.
+        Returns:
+            Returns main.TRUE if the results are matching else
+            Returns main.FALSE
+        """
         main.case( "Compare ONOS Topology view to Mininet topology" )
         main.caseExplanation = "Compare topology elements between Mininet" +\
                                 " and ONOS"
@@ -174,21 +162,21 @@
             main.log.info( "Sleeping {} seconds".format( 2 ) )
             time.sleep( 2 )
             if not devicesResults:
-                devices = self.getAllDevices( main.numCtrls, False )
-                ports = self.getAllPorts( main.numCtrls, False )
+                devices = self.getAll( "devices", False )
+                ports = self.getAll( "ports", False )
                 devicesResults = main.TRUE
                 deviceFails = []  # Reset for each failed attempt
             if not linksResults:
-                links = self.getAllLinks( main.numCtrls, False )
+                links = self.getAll( "links", False )
                 linksResults = main.TRUE
                 linkFails = []  # Reset for each failed attempt
             if not hostsResults:
-                hosts = self.getAllHosts( main.numCtrls, False )
+                hosts = self.getAll( "hosts", False )
                 hostsResults = main.TRUE
                 hostFails = []  # Reset for each failed attempt
 
             #  Check for matching topology on each node
-            for controller in range( main.numCtrls ):
+            for controller in main.Cluster.getRunningPos():
                 controllerStr = str( controller + 1 )  # ONOS node number
                 # Compare Devices
                 currentDevicesResult = self.compareDevicePort( Mininet, controller,
@@ -234,3 +222,4 @@
                                  actual=topoResults,
                                  onpass="ONOS correctly discovered the topology",
                                  onfail="ONOS incorrectly discovered the topology" )
+        return topoResults
diff --git a/TestON/tests/dependencies/utils.py b/TestON/tests/dependencies/utils.py
index 075b9bd..240d4b2 100644
--- a/TestON/tests/dependencies/utils.py
+++ b/TestON/tests/dependencies/utils.py
@@ -1,14 +1,50 @@
+"""
+Copyright 2016 Open Networking Foundation (ONF)
+
+Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
+the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
+or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
+
+    TestON is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 2 of the License, or
+    (at your option) any later version.
+
+    TestON is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with TestON.  If not, see <http://www.gnu.org/licenses/>.
+"""
 class Utils:
     def __init__( self ):
         self.default = ''
 
     def mininetCleanIntro( self ):
+        """
+        Description:
+            Introduction information of the mininet clean up
+        Required:
+        Returns:
+        """
         main.log.report( "Stop Mininet" )
 
         main.case( "Stop Mininet" )
         main.caseExplanation = "Stopping the current mininet to start up fresh"
 
     def mininetCleanup( self, Mininet, timeout=5 ):
+        """
+        Description:
+            Clean up the mininet using stopNet and verify it.
+        Required:
+            * Mininet - mininet driver to use
+            * timeout - time out of mininet.stopNet.
+        Returns:
+            Returns main.TRUE if successfully stopping minient.
+            else returns main.FALSE
+        """
         main.step( "Stopping Mininet" )
         topoResult = Mininet.stopNet( timeout=timeout )
         utilities.assert_equals( expect=main.TRUE,
@@ -17,9 +53,14 @@
                                  onfail="Failed to stopped mininet" )
         return topoResult
 
-    def copyKarafLog( self ):
+    def copyKarafLog( self, copyFileName="" ):
         """
-            Copy the karaf.log files after each testcase cycle
+        Description:
+            copy the karaf log and verify it.
+        Required:
+            * copyFileName - name of the end portion of the
+            copyFileName.
+        Returns:
         """
         # TODO: Also grab the rotated karaf logs
         main.log.report( "Copy karaf logs" )
@@ -30,14 +71,14 @@
         stepResult = main.TRUE
         scpResult = main.TRUE
         copyResult = main.TRUE
-        for ctrl in main.Cluster.controllers:
-            scpResult = scpResult and main.ONOSbench.scp( ctrl.node,
+        for ctrl in main.Cluster.runningNodes:
+            scpResult = scpResult and main.ONOSbench.scp( ctrl,
                                                           "/opt/onos/log/karaf.log",
                                                           "/tmp/karaf.log",
                                                           direction="from" )
             copyResult = copyResult and main.ONOSbench.cpLogsToDir( "/tmp/karaf.log", main.logdir,
-                                                                    copyFileName=( "karaf.log.{0}.cycle{1}".format(
-                                                                        str( ctrl ), str( main.cycle ) ) ) )
+                                                                    copyFileName=( "karaf.log." + ctrl.name +
+                                                                                   "." + copyFileName ) )
             if scpResult and copyResult:
                 stepResult = main.TRUE and stepResult
             else: