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