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: