update my forked branch
diff --git a/TestON/drivers/common/cli/onosdriver.py b/TestON/drivers/common/cli/onosdriver.py
index ffed668..9734027 100644
--- a/TestON/drivers/common/cli/onosdriver.py
+++ b/TestON/drivers/common/cli/onosdriver.py
@@ -19,7 +19,6 @@
import sys
import time
import pexpect
-import traceback
import os.path
from requests.models import Response
sys.path.append( "../" )
@@ -32,6 +31,9 @@
"""
Initialize client
"""
+ self.name = None
+ self.home = None
+ self.handle = None
super( CLI, self ).__init__()
def connect( self, **connectargs ):
@@ -41,11 +43,13 @@
try:
for key in connectargs:
vars( self )[ key ] = connectargs[ key ]
- self.home = "~/ONOS"
+ self.home = "~/onos"
for key in self.options:
if key == "home":
self.home = self.options[ 'home' ]
break
+ if self.home is None or self.home == "":
+ self.home = "~/onos"
self.name = self.options[ 'name' ]
self.handle = super( OnosDriver, self ).connect(
@@ -67,10 +71,8 @@
main.log.error( self.name + ": " + self.handle.before )
main.cleanup()
main.exit()
- except:
- main.log.info( self.name + ":" * 30 )
- main.log.error( traceback.print_exc() )
- main.log.info( ":" * 30 )
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
main.cleanup()
main.exit()
@@ -78,17 +80,21 @@
"""
Called when Test is complete to disconnect the ONOS handle.
"""
- response = ''
+ response = main.TRUE
try:
- self.handle.sendline( "" )
- self.handle.expect( "\$" )
- self.handle.sendline( "exit" )
- self.handle.expect( "closed" )
+ if self.handle:
+ self.handle.sendline( "" )
+ self.handle.expect( "\$" )
+ self.handle.sendline( "exit" )
+ self.handle.expect( "closed" )
except pexpect.EOF:
main.log.error( self.name + ": EOF exception found" )
main.log.error( self.name + ": " + self.handle.before )
- except:
- main.log.error( self.name + ": Connection failed to the host" )
+ except ValueError:
+ main.log.exception( "Exception in disconnect of " + self.name )
+ response = main.TRUE
+ except Exception:
+ main.log.exception( self.name + ": Connection failed to the host" )
response = main.FALSE
return response
@@ -112,8 +118,8 @@
except pexpect.EOF:
main.log.error( self.name + ": EOF exception found" )
main.log.error( self.name + ": " + self.handle.before )
- except:
- main.log.error( "Failed to package ONOS" )
+ except Exception:
+ main.log.exception( "Failed to package ONOS" )
main.cleanup()
main.exit()
@@ -142,8 +148,8 @@
except pexpect.EOF:
main.log.error( self.name + ": EOF exception found" )
main.log.error( self.name + ": " + self.handle.before )
- except:
- main.log.error( "Failed to build ONOS" )
+ except Exception:
+ main.log.exception( "Failed to build ONOS" )
main.cleanup()
main.exit()
@@ -168,10 +174,11 @@
self.handle.expect( "mvn clean install" )
while True:
i = self.handle.expect( [
- 'There\sis\sinsufficient\smemory\sfor\sthe\sJava\s\
- Runtime\sEnvironment\sto\scontinue',
+ 'There\sis\sinsufficient\smemory\sfor\sthe\sJava\s' +
+ 'Runtime\sEnvironment\sto\scontinue',
'BUILD\sFAILURE',
'BUILD\sSUCCESS',
+ 'onos\$', #TODO: fix this to be more generic?
'ONOS\$',
pexpect.TIMEOUT ], mciTimeout )
if i == 0:
@@ -187,7 +194,7 @@
main.exit()
elif i == 2:
main.log.info( self.name + ": Build success!" )
- elif i == 3:
+ elif i == 3 or i == 4:
main.log.info( self.name + ": Build complete" )
# Print the build time
for line in self.handle.before.splitlines():
@@ -196,7 +203,7 @@
self.handle.sendline( "" )
self.handle.expect( "\$", timeout=60 )
return main.TRUE
- elif i == 4:
+ elif i == 5:
main.log.error(
self.name +
": mvn clean install TIMEOUT!" )
@@ -204,8 +211,8 @@
main.cleanup()
main.exit()
else:
- main.log.error( self.name + ": unexpected response from \
- mvn clean install" )
+ main.log.error( self.name + ": unexpected response from " +
+ "mvn clean install" )
# return main.FALSE
main.cleanup()
main.exit()
@@ -214,17 +221,19 @@
main.log.error( self.name + ": " + self.handle.before )
main.cleanup()
main.exit()
- except:
- main.log.info( self.name + ":" * 60 )
- main.log.error( traceback.print_exc() )
- main.log.info( ":" * 60 )
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
main.cleanup()
main.exit()
- def gitPull( self, comp1="" ):
+ def gitPull( self, comp1="", fastForward=True ):
"""
Assumes that "git pull" works without login
+ If the fastForward boolean is set to true, only git pulls that can
+ be fast forwarded will be performed. IE if you have not local commits
+ in your branch.
+
This function will perform a git pull on the ONOS instance.
If used as gitPull( "NODE" ) it will do git pull + NODE. This is
for the purpose of pulling from other nodes if necessary.
@@ -239,12 +248,13 @@
# main.log.info( self.name + ": Stopping ONOS" )
# self.stop()
self.handle.sendline( "cd " + self.home )
- self.handle.expect( "ONOS\$" )
- if comp1 == "":
- self.handle.sendline( "git pull" )
- else:
- self.handle.sendline( "git pull " + comp1 )
-
+ self.handle.expect( self.home + "\$" )
+ cmd = "git pull"
+ if comp1 != "":
+ cmd += ' ' + comp1
+ if fastForward:
+ cmd += ' ' + " --ff-only"
+ self.handle.sendline( cmd )
i = self.handle.expect(
[
'fatal',
@@ -253,10 +263,11 @@
'Already up-to-date',
'Aborting',
'You\sare\snot\scurrently\son\sa\sbranch',
- 'You\sasked\sme\sto\spull\swithout\stelling\sme\swhich\
- \sbranch\syou',
- 'Pull\sis\snot\spossible\sbecause\syou\shave\sunmerged\
- \sfiles',
+ 'You asked me to pull without telling me which branch you',
+ 'Pull is not possible because you have unmerged files',
+ 'Please enter a commit message to explain why this merge',
+ 'Found a swap file by the name',
+ 'Please, commit your changes before you can merge.',
pexpect.TIMEOUT ],
timeout=300 )
# debug
@@ -264,7 +275,11 @@
# "git pull response: " +
# str( self.handle.before ) + str( self.handle.after ) )
if i == 0:
- main.log.error( self.name + ": Git pull had some issue..." )
+ main.log.error( self.name + ": Git pull had some issue" )
+ output = self.handle.after
+ self.handle.expect( '\$' )
+ output += self.handle.before
+ main.log.warn( output )
return main.ERROR
elif i == 1:
main.log.error(
@@ -275,7 +290,7 @@
main.log.info(
self.name +
": Git Pull - pulling repository now" )
- self.handle.expect( "ONOS\$", 120 )
+ self.handle.expect( self.home + "\$", 120 )
# So that only when git pull is done, we do mvn clean compile
return main.TRUE
elif i == 3:
@@ -284,29 +299,51 @@
elif i == 4:
main.log.info(
self.name +
- ": Git Pull - Aborting...\
- Are there conflicting git files?" )
+ ": Git Pull - Aborting..." +
+ "Are there conflicting git files?" )
return main.ERROR
elif i == 5:
main.log.info(
self.name +
- ": Git Pull - You are not currently\
- on a branch so git pull failed!" )
+ ": Git Pull - You are not currently " +
+ "on a branch so git pull failed!" )
return main.ERROR
elif i == 6:
main.log.info(
self.name +
- ": Git Pull - You have not configured\
- an upstream branch to pull from\
- . Git pull failed!" )
+ ": Git Pull - You have not configured an upstream " +
+ "branch to pull from. Git pull failed!" )
return main.ERROR
elif i == 7:
main.log.info(
self.name +
- ": Git Pull - Pull is not possible\
- because you have unmerged files." )
+ ": Git Pull - Pull is not possible because " +
+ "you have unmerged files." )
return main.ERROR
elif i == 8:
+ # NOTE: abandoning test since we can't reliably handle this
+ # there could be different default text editors and we
+ # also don't know if we actually want to make the commit
+ main.log.error( "Git pull resulted in a merge commit message" +
+ ". Exiting test!" )
+ main.cleanup()
+ main.exit()
+ elif i == 9: # Merge commit message but swap file exists
+ main.log.error( "Git pull resulted in a merge commit message" +
+ " but a swap file exists." )
+ try:
+ self.handle.send( 'A' ) # Abort
+ self.handle.expect( "\$" )
+ return main.ERROR
+ except Exception:
+ main.log.exception( "Couldn't exit editor prompt!")
+ main.cleanup()
+ main.exit()
+ elif i == 10: # In the middle of a merge commit
+ main.log.error( "Git branch is in the middle of a merge. " )
+ main.log.warn( self.handle.before + self.handle.after )
+ return main.ERROR
+ elif i == 11:
main.log.error( self.name + ": Git Pull - TIMEOUT" )
main.log.error(
self.name + " Response was: " + str(
@@ -322,10 +359,8 @@
main.log.error( self.name + ": " + self.handle.before )
main.cleanup()
main.exit()
- except:
- main.log.info( self.name + ":" * 60 )
- main.log.error( traceback.print_exc() )
- main.log.info( ":" * 80 )
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
main.cleanup()
main.exit()
@@ -346,28 +381,24 @@
"""
try:
self.handle.sendline( "cd " + self.home )
- self.handle.expect( "ONOS\$" )
- main.log.info(
- self.name +
- ": Checking out git branch: " +
- branch +
- "..." )
+ self.handle.expect( self.home + "\$" )
+ main.log.info( self.name +
+ ": Checking out git branch/ref: " + branch + "..." )
cmd = "git checkout " + branch
self.handle.sendline( cmd )
self.handle.expect( cmd )
i = self.handle.expect(
- [
- 'fatal',
- 'Username\sfor\s(.*):\s',
- 'Already\son\s\'',
- 'Switched\sto\sbranch\s\'' +
- str( branch ),
- pexpect.TIMEOUT,
- 'error: Your local changes to the following files\
- would be overwritten by checkout:',
- 'error: you need to resolve your current index first' ],
+ [ 'fatal',
+ 'Username for (.*): ',
+ 'Already on \'',
+ 'Switched to branch \'' + str( branch ),
+ pexpect.TIMEOUT,
+ 'error: Your local changes to the following files' +
+ 'would be overwritten by checkout:',
+ 'error: you need to resolve your current index first',
+ "You are in 'detached HEAD' state.",
+ "HEAD is now at " ],
timeout=60 )
-
if i == 0:
main.log.error(
self.name +
@@ -380,55 +411,66 @@
": Git checkout asking for username." +
" Please configure your local git repository to be able " +
"to access your remote repository passwordlessly" )
+ # TODO add support for authenticating
return main.ERROR
elif i == 2:
main.log.info(
self.name +
- ": Git Checkout %s : Already on this branch" %
- branch )
- self.handle.expect( "ONOS\$" )
+ ": Git Checkout %s : Already on this branch" % branch )
+ self.handle.expect( self.home + "\$" )
# main.log.info( "DEBUG: after checkout cmd = "+
# self.handle.before )
return main.TRUE
elif i == 3:
main.log.info(
self.name +
- ": Git checkout %s - Switched to this branch" %
- branch )
- self.handle.expect( "ONOS\$" )
+ ": Git checkout %s - Switched to this branch" % branch )
+ self.handle.expect( self.home + "\$" )
# main.log.info( "DEBUG: after checkout cmd = "+
# self.handle.before )
return main.TRUE
elif i == 4:
main.log.error( self.name + ": Git Checkout- TIMEOUT" )
main.log.error(
- self.name + " Response was: " + str(
- self.handle.before ) )
+ self.name + " Response was: " + str( self.handle.before ) )
return main.ERROR
elif i == 5:
self.handle.expect( "Aborting" )
main.log.error(
self.name +
": Git checkout error: \n" +
- "Your local changes to the following\
- files would be overwritten by checkout:" +
- str(
- self.handle.before ) )
- self.handle.expect( "ONOS\$" )
+ "Your local changes to the following files would" +
+ " be overwritten by checkout:" +
+ str( self.handle.before ) )
+ self.handle.expect( self.home + "\$" )
return main.ERROR
elif i == 6:
- main.log.error( self.name +
- ": Git checkout error: \n" +
- "You need to resolve your\
- current index first:" +
- str( self.handle.before ) )
- self.handle.expect( "ONOS\$" )
+ main.log.error(
+ self.name +
+ ": Git checkout error: \n" +
+ "You need to resolve your current index first:" +
+ str( self.handle.before ) )
+ self.handle.expect( self.home + "\$" )
return main.ERROR
+ elif i == 7:
+ main.log.info(
+ self.name +
+ ": Git checkout " + str( branch ) +
+ " - You are in 'detached HEAD' state. HEAD is now at " +
+ str( branch ) )
+ self.handle.expect( self.home + "\$" )
+ return main.TRUE
+ elif i == 8: # Already in detached HEAD on the specified commit
+ main.log.info(
+ self.name +
+ ": Git Checkout %s : Already on commit" % branch )
+ self.handle.expect( self.home + "\$" )
+ return main.TRUE
else:
main.log.error(
self.name +
- ": Git Checkout - Unexpected response,\
- check for pull errors" )
+ ": Git Checkout - Unexpected response, " +
+ "check for pull errors" )
main.log.error( self.name + ": " + self.handle.before )
return main.ERROR
@@ -437,10 +479,8 @@
main.log.error( self.name + ": " + self.handle.before )
main.cleanup()
main.exit()
- except:
- main.log.info( self.name + ":" * 60 )
- main.log.error( traceback.print_exc() )
- main.log.info( ":" * 80 )
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
main.cleanup()
main.exit()
@@ -462,8 +502,8 @@
def getVersion( self, report=False ):
"""
- Writes the COMMIT number to the report to be parsed\
- by Jenkins data collecter.
+ Writes the COMMIT number to the report to be parsed
+ by Jenkins data collector.
"""
try:
self.handle.sendline( "" )
@@ -471,8 +511,8 @@
self.handle.sendline(
"cd " +
self.home +
- "; git log -1 --pretty=fuller --decorate=short | grep -A 6\
- \"commit\" --color=never" )
+ "; git log -1 --pretty=fuller --decorate=short | grep -A 6 " +
+ " \"commit\" --color=never" )
# NOTE: for some reason there are backspaces inserted in this
# phrase when run from Jenkins on some tests
self.handle.expect( "never" )
@@ -485,13 +525,18 @@
for line in lines:
print line
if report:
+ main.log.wiki( "<blockquote>" )
for line in lines[ 2:-1 ]:
# Bracket replacement is for Wiki-compliant
# formatting. '<' or '>' are interpreted
# as xml specific tags that cause errors
line = line.replace( "<", "[" )
line = line.replace( ">", "]" )
- main.log.report( "\t" + line )
+ #main.log.wiki( "\t" + line )
+ main.log.wiki( line + "<br /> " )
+ main.log.summary( line )
+ main.log.wiki( "</blockquote>" )
+ main.log.summary("\n")
return lines[ 2 ]
except pexpect.EOF:
main.log.error( self.name + ": EOF exception found" )
@@ -503,15 +548,13 @@
main.log.error( self.name + ": " + self.handle.before )
main.cleanup()
main.exit()
- except:
- main.log.info( self.name + ":" * 60 )
- main.log.error( traceback.print_exc() )
- main.log.info( ":" * 80 )
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
main.cleanup()
main.exit()
def createCellFile( self, benchIp, fileName, mnIpAddrs,
- extraFeatureString, *onosIpAddrs ):
+ appString, *onosIpAddrs ):
"""
Creates a cell file based on arguments
Required:
@@ -535,12 +578,11 @@
# Create the cell file in the directory for writing ( w+ )
cellFile = open( tempDirectory + fileName, 'w+' )
- # Feature string is hardcoded environment variables
+ # App string is hardcoded environment variables
# That you may wish to use by default on startup.
- # Note that you may not want certain features listed
+ # Note that you may not want certain apps listed
# on here.
- coreFeatureString = "export ONOS_FEATURES=webconsole,onos-api," +\
- "onos-cli,onos-openflow," + extraFeatureString
+ appString = "export ONOS_APPS=" + appString
mnString = "export OCN="
onosString = "export OC"
tempCount = 1
@@ -569,7 +611,7 @@
tempCount = tempCount + 1
cellFile.write( mnString + "\"" + mnIpAddrs + "\"" + "\n" )
- cellFile.write( coreFeatureString + "\n" )
+ cellFile.write( appString + "\n" )
cellFile.close()
# We use os.system to send the command to TestON cluster
@@ -588,10 +630,8 @@
main.log.error( self.name + ": " + self.handle.before )
main.cleanup()
main.exit()
- except:
- main.log.info( self.name + ":::::::::" )
- main.log.error( traceback.print_exc() )
- main.log.info( ":::::::" )
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
main.cleanup()
main.exit()
@@ -609,12 +649,12 @@
# Expect the cellname in the ONOSCELL variable.
# Note that this variable name is subject to change
# and that this driver will have to change accordingly
- self.handle.expect( "ONOS_CELL=" + str( cellname ) )
+ self.handle.expect(str(cellname))
handleBefore = self.handle.before
handleAfter = self.handle.after
# Get the rest of the handle
- self.handle.sendline( "" )
- self.handle.expect( "\$" )
+ self.handle.sendline("")
+ self.handle.expect("\$")
handleMore = self.handle.before
main.log.info( "Cell call returned: " + handleBefore +
@@ -627,10 +667,8 @@
main.log.error( self.name + ": " + self.handle.before )
main.cleanup()
main.exit()
- except:
- main.log.info( self.name + " ::::::" )
- main.log.error( traceback.print_exc() )
- main.log.info( self.name + " ::::::" )
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
main.cleanup()
main.exit()
@@ -657,15 +695,55 @@
handleAfter + handleMore )
return main.TRUE
- except pexpect.EOF:
- main.log.error( self.name + ": EOF exception found" )
+ except pexpect.ExceptionPexpect as e:
+ main.log.error( self.name + ": Pexpect exception found of type " +
+ str( type( e ) ) )
+ main.log.error ( e.get_trace() )
main.log.error( self.name + ": " + self.handle.before )
main.cleanup()
main.exit()
- except:
- main.log.info( self.name + " ::::::" )
- main.log.error( traceback.print_exc() )
- main.log.info( self.name + " ::::::" )
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
+ main.cleanup()
+ main.exit()
+
+ def onosCfgSet( self, ONOSIp, configName, configParam ):
+ """
+ Uses 'onos <node-ip> cfg set' to change a parameter value of an
+ application.
+
+ ex)
+ onos 10.0.0.1 cfg set org.onosproject.myapp appSetting 1
+
+ ONOSIp = '10.0.0.1'
+ configName = 'org.onosproject.myapp'
+ configParam = 'appSetting 1'
+
+ """
+ try:
+ cfgStr = ( "onos "+str(ONOSIp)+" cfg set "+
+ str(configName) + " " +
+ str(configParam)
+ )
+
+ self.handle.sendline( "" )
+ self.handle.expect( "\$" )
+ self.handle.sendline( cfgStr )
+ self.handle.expect( "\$" )
+
+ # TODO: Add meaningful assertion
+
+ return main.TRUE
+
+ except pexpect.ExceptionPexpect as e:
+ main.log.error( self.name + ": Pexpect exception found of type " +
+ str( type( e ) ) )
+ main.log.error ( e.get_trace() )
+ main.log.error( self.name + ": " + self.handle.before )
+ main.cleanup()
+ main.exit()
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
main.cleanup()
main.exit()
@@ -723,10 +801,8 @@
main.log.error( self.name + ": " + self.handle.before )
main.cleanup()
main.exit()
- except:
- main.log.info( self.name + " ::::::" )
- main.log.error( traceback.print_exc() )
- main.log.info( self.name + " ::::::" )
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
main.cleanup()
main.exit()
@@ -778,10 +854,8 @@
main.log.error( self.name + ": " + self.handle.before )
main.cleanup()
main.exit()
- except:
- main.log.info( self.name + " ::::::" )
- main.log.error( traceback.print_exc() )
- main.log.info( self.name + " ::::::" )
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
main.cleanup()
main.exit()
@@ -816,10 +890,8 @@
main.log.error( self.name + ": " + self.handle.before )
main.cleanup()
main.exit()
- except:
- main.log.info( self.name + " ::::::" )
- main.log.error( traceback.print_exc() )
- main.log.info( self.name + " ::::::" )
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
main.cleanup()
main.exit()
@@ -835,6 +907,7 @@
" stop" )
i = self.handle.expect( [
"stop/waiting",
+ "Could not resolve hostname",
"Unknown\sinstance",
pexpect.TIMEOUT ], timeout=60 )
@@ -842,9 +915,12 @@
main.log.info( "ONOS service stopped" )
return main.TRUE
elif i == 1:
- main.log.info( "Unknown ONOS instance specified: " +
+ main.log.info( "onosStop() Unknown ONOS instance specified: " +
str( nodeIp ) )
return main.FALSE
+ elif i == 2:
+ main.log.warn( "ONOS wasn't running" )
+ return main.TRUE
else:
main.log.error( "ONOS service failed to stop" )
return main.FALSE
@@ -854,10 +930,8 @@
main.log.error( self.name + ": " + self.handle.before )
main.cleanup()
main.exit()
- except:
- main.log.info( self.name + " ::::::" )
- main.log.error( traceback.print_exc() )
- main.log.info( self.name + " ::::::" )
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
main.cleanup()
main.exit()
@@ -869,7 +943,7 @@
"""
try:
self.handle.sendline( "" )
- self.handle.expect( "\$" )
+ self.handle.expect( "\$", timeout=60 )
self.handle.sendline( "onos-uninstall " + str( nodeIp ) )
self.handle.expect( "\$" )
@@ -878,15 +952,16 @@
# onos-uninstall command does not return any text
return main.TRUE
+ except pexpect.TIMEOUT:
+ main.log.exception( self.name + ": Timeout in onosUninstall" )
+ return main.FALSE
except pexpect.EOF:
main.log.error( self.name + ": EOF exception found" )
main.log.error( self.name + ": " + self.handle.before )
main.cleanup()
main.exit()
- except:
- main.log.info( self.name + " ::::::" )
- main.log.error( traceback.print_exc() )
- main.log.info( self.name + " ::::::" )
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
main.cleanup()
main.exit()
@@ -916,10 +991,8 @@
main.log.error( self.name + ": " + self.handle.before )
main.cleanup()
main.exit()
- except:
- main.log.info( self.name + " ::::::" )
- main.log.error( traceback.print_exc() )
- main.log.info( self.name + " ::::::" )
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
main.cleanup()
main.exit()
@@ -954,7 +1027,7 @@
" not configured" )
return main.FALSE
else:
- main.log.info( "ONOS instasnce was not killed" )
+ main.log.info( "ONOS instance was not killed" )
return main.FALSE
except pexpect.EOF:
@@ -962,10 +1035,8 @@
main.log.error( self.name + ": " + self.handle.before )
main.cleanup()
main.exit()
- except:
- main.log.info( self.name + " ::::::" )
- main.log.error( traceback.print_exc() )
- main.log.info( self.name + " ::::::" )
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
main.cleanup()
main.exit()
@@ -990,8 +1061,8 @@
timeout=120 )
if i == 1:
return main.FALSE
- self.handle.sendline( "" )
- self.handle.expect( "\$" )
+ #self.handle.sendline( "" )
+ #self.handle.expect( "\$" )
return main.TRUE
except pexpect.EOF:
@@ -999,10 +1070,8 @@
main.log.error( self.name + ": " + self.handle.before )
main.cleanup()
main.exit()
- except:
- main.log.info( self.name + " ::::::" )
- main.log.error( traceback.print_exc() )
- main.log.info( self.name + " ::::::" )
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
main.cleanup()
main.exit()
@@ -1038,26 +1107,23 @@
main.log.error( self.name + ": " + self.handle.before )
main.cleanup()
main.exit()
- except:
- main.log.info( self.name + " ::::::" )
- main.log.error( traceback.print_exc() )
- main.log.info( self.name + " ::::::" )
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
main.cleanup()
main.exit()
- def isup( self, node="", onosWaitStartTimeout=120 ):
+ def isup(self, node = "", timeout = 120):
"""
Run's onos-wait-for-start which only returns once ONOS is at run
- level 100( ready for use )
+ level 100(ready for use)
Returns: main.TRUE if ONOS is running and main.FALSE on timeout
"""
try:
- self.handle.sendline( "onos-wait-for-start " + node )
- self.handle.expect( "onos-wait-for-start" )
+ self.handle.sendline("onos-wait-for-start " + node )
+ self.handle.expect("onos-wait-for-start")
# NOTE: this timeout is arbitrary"
- i = self.handle.expect( [ "\$", pexpect.TIMEOUT ],
- onosWaitStartTimeout )
+ i = self.handle.expect(["\$", pexpect.TIMEOUT], timeout)
if i == 0:
main.log.info( self.name + ": " + node + " is up" )
return main.TRUE
@@ -1073,10 +1139,8 @@
main.log.error( self.name + ": " + self.handle.before )
main.cleanup()
main.exit()
- except:
- main.log.info( self.name + " ::::::" )
- main.log.error( traceback.print_exc() )
- main.log.info( self.name + " ::::::" )
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
main.cleanup()
main.exit()
@@ -1137,58 +1201,31 @@
main.log.error( self.name + ": " + self.handle.before )
main.cleanup()
main.exit()
- except:
- main.log.info( self.name + " ::::::" )
- main.log.error( traceback.print_exc() )
- main.log.info( self.name + " ::::::" )
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
main.cleanup()
main.exit()
def getTopology( self, topologyOutput ):
"""
- parses the onos:topology output
- Returns: a topology dict populated by the key values found in
- the cli command.
+ Definition:
+ Loads a json topology output
+ Return:
+ topology = current ONOS topology
"""
+ import json
try:
- # call the cli to get the topology summary
- # cmdstr = "onos:topology"
- # cliResult = self.onosCli( ip, cmdstr )
- # print "cli_result = ", cliResult
-
- # Parse the output
- topology = {}
- # for line in cliResult.split( "\n" ):
- for line in topologyOutput.splitlines():
- if not line.startswith( "time=" ):
- continue
- # else
- # print line
- for var in line.split( "," ):
- # print "'"+var+"'"
- # print "'"+var.strip()+"'"
- key, value = var.strip().split( "=" )
- topology[ key ] = value
- # print "topology = ", topology
- # devices = topology.get( 'devices', False )
- # print "devices = ", devices
- # links = topology.get( 'links', False )
- # print "links = ", links
- # SCCs = topology.get( 'SCC(s)', False )
- # print "SCCs = ", SCCs
- # paths = topology.get( 'paths', False )
- # print "paths = ", paths
-
+ # either onos:topology or 'topology' will work in CLI
+ topology = json.loads(topologyOutput)
+ print topology
return topology
except pexpect.EOF:
main.log.error( self.name + ": EOF exception found" )
main.log.error( self.name + ": " + self.handle.before )
main.cleanup()
main.exit()
- except:
- main.log.info( self.name + " ::::::" )
- main.log.error( traceback.print_exc() )
- main.log.info( self.name + " ::::::" )
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
main.cleanup()
main.exit()
@@ -1199,21 +1236,21 @@
numolink,
logLevel="info" ):
"""
- Checks the number of swithes & links that ONOS sees against the
+ Checks the number of switches & links that ONOS sees against the
supplied values. By default this will report to main.log, but the
- log level can be specifid.
+ log level can be specific.
Params: ip = ip used for the onos cli
numoswitch = expected number of switches
- numlink = expected number of links
+ numolink = expected number of links
logLevel = level to log to.
Currently accepts 'info', 'warn' and 'report'
logLevel can
- Returns: main.TRUE if the number of switchs and links are correct,
- main.FALSE if the numer of switches and links is incorrect,
+ Returns: main.TRUE if the number of switches and links are correct,
+ main.FALSE if the number of switches and links is incorrect,
and main.ERROR otherwise
"""
try:
@@ -1222,27 +1259,27 @@
return main.ERROR
output = ""
# Is the number of switches is what we expected
- devices = topology.get( 'devices', False )
- links = topology.get( 'links', False )
+ devices = topology.get( 'deviceCount', False )
+ links = topology.get( 'linkCount', False )
if not devices or not links:
return main.ERROR
switchCheck = ( int( devices ) == int( numoswitch ) )
# Is the number of links is what we expected
linkCheck = ( int( links ) == int( numolink ) )
- if ( switchCheck and linkCheck ):
+ if switchCheck and linkCheck:
# We expected the correct numbers
output = output + "The number of links and switches match "\
+ "what was expected"
result = main.TRUE
else:
output = output + \
- "The number of links and switches does not match\
- what was expected"
+ "The number of links and switches does not match " + \
+ "what was expected"
result = main.FALSE
- output = output + "\n ONOS sees %i devices (%i expected)\
- and %i links (%i expected)" %\
- ( int( devices ), int( numoswitch ),
- int( links ), int( numolink ) )
+ output = output + "\n ONOS sees %i devices" % int( devices )
+ output = output + " (%i expected) " % int( numoswitch )
+ output = output + "and %i links " % int( links )
+ output = output + "(%i expected)" % int( numolink )
if logLevel == "report":
main.log.report( output )
elif logLevel == "warn":
@@ -1255,10 +1292,8 @@
main.log.error( self.name + ": " + self.handle.before )
main.cleanup()
main.exit()
- except:
- main.log.info( self.name + " ::::::" )
- main.log.error( traceback.print_exc() )
- main.log.info( self.name + " ::::::" )
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
main.cleanup()
main.exit()
@@ -1271,31 +1306,41 @@
* interface: interface to capture
* dir: directory/filename to store pcap
"""
- self.handle.sendline( "" )
- self.handle.expect( "\$" )
+ try:
+ self.handle.sendline( "" )
+ self.handle.expect( "\$" )
- self.handle.sendline( "tshark -i " + str( interface ) +
- " -t e -w " + str( dirFile ) + " &" )
- self.handle.sendline( "\r" )
- self.handle.expect( "Capturing on" )
- self.handle.sendline( "\r" )
- self.handle.expect( "\$" )
+ self.handle.sendline( "tshark -i " + str( interface ) +
+ " -t e -w " + str( dirFile ) + " &" )
+ self.handle.sendline( "\r" )
+ self.handle.expect( "Capturing on" )
+ self.handle.sendline( "\r" )
+ self.handle.expect( "\$" )
- main.log.info( "Tshark started capturing files on " +
- str( interface ) + " and saving to directory: " +
- str( dirFile ) )
+ main.log.info( "Tshark started capturing files on " +
+ str( interface ) + " and saving to directory: " +
+ str( dirFile ) )
+ except pexpect.EOF:
+ main.log.error( self.name + ": EOF exception found" )
+ main.log.error( self.name + ": " + self.handle.before )
+ main.cleanup()
+ main.exit()
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
+ main.cleanup()
+ main.exit()
def runOnosTopoCfg( self, instanceName, jsonFile ):
"""
On ONOS bench, run this command:
- ./~/ONOS/tools/test/bin/onos-topo-cfg $OC1 filename
+ {ONOS_HOME}/tools/test/bin/onos-topo-cfg $OC1 filename
which starts the rest and copies
the json file to the onos instance
"""
try:
self.handle.sendline( "" )
self.handle.expect( "\$" )
- self.handle.sendline( "cd ~/ONOS/tools/test/bin" )
+ self.handle.sendline( "cd " + self.home + "/tools/test/bin" )
self.handle.expect( "/bin$" )
cmd = "./onos-topo-cfg " + instanceName + " " + jsonFile
print "cmd = ", cmd
@@ -1304,48 +1349,82 @@
self.handle.sendline( "cd ~" )
self.handle.expect( "\$" )
return main.TRUE
- except:
- return main.FALSE
+ except pexpect.EOF:
+ main.log.error( self.name + ": EOF exception found" )
+ main.log.error( self.name + ": " + self.handle.before )
+ main.cleanup()
+ main.exit()
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
+ main.cleanup()
+ main.exit()
- def tsharkGrep( self, grep, directory, interface='eth0' ):
+ def tsharkGrep( self, grep, directory, interface='eth0', grepOptions='' ):
"""
Required:
* grep string
* directory to store results
Optional:
* interface - default: eth0
+ * grepOptions - options for grep
Description:
Uses tshark command to grep specific group of packets
and stores the results to specified directory.
The timestamp is hardcoded to be in epoch
"""
- self.handle.sendline( "" )
- self.handle.expect( "\$" )
- self.handle.sendline( "" )
- self.handle.sendline(
- "tshark -i " +
- str( interface ) +
- " -t e | grep --line-buffered \"" +
- str(grep) +
- "\" >" +
- directory +
- " &" )
- self.handle.sendline( "\r" )
- self.handle.expect( "Capturing on" )
- self.handle.sendline( "\r" )
- self.handle.expect( "\$" )
+ try:
+ self.handle.sendline( "" )
+ self.handle.expect( "\$" )
+ self.handle.sendline( "" )
+ if grepOptions:
+ grepStr = "grep "+str(grepOptions)
+ else:
+ grepStr = "grep"
+
+ self.handle.sendline(
+ "tshark -i " +
+ str( interface ) +
+ " -t e | " +
+ grepStr + " --line-buffered \"" +
+ str(grep) +
+ "\" >" +
+ directory +
+ " &" )
+ self.handle.sendline( "\r" )
+ self.handle.expect( "Capturing on" )
+ self.handle.sendline( "\r" )
+ self.handle.expect( "\$" )
+ except pexpect.EOF:
+ main.log.error( self.name + ": EOF exception found" )
+ main.log.error( self.name + ": " + self.handle.before )
+ main.cleanup()
+ main.exit()
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
+ main.cleanup()
+ main.exit()
def tsharkStop( self ):
"""
Removes wireshark files from /tmp and kills all tshark processes
"""
# Remove all pcap from previous captures
- self.execute( cmd="sudo rm /tmp/wireshark*" )
- self.handle.sendline( "" )
- self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\" |" +
- " grep -v grep | awk '{print $2}'`" )
- self.handle.sendline( "" )
- main.log.info( "Tshark stopped" )
+ try:
+ self.execute( cmd="sudo rm /tmp/wireshark*" )
+ self.handle.sendline( "" )
+ self.handle.sendline( "sudo kill -9 `ps -ef | grep \"tshark -i\"" +
+ " | grep -v grep | awk '{print $2}'`" )
+ self.handle.sendline( "" )
+ main.log.info( "Tshark stopped" )
+ except pexpect.EOF:
+ main.log.error( self.name + ": EOF exception found" )
+ main.log.error( self.name + ": " + self.handle.before )
+ main.cleanup()
+ main.exit()
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
+ main.cleanup()
+ main.exit()
def ptpd( self, args ):
"""
@@ -1380,15 +1459,13 @@
main.log.error( self.name + ": " + self.handle.before )
main.cleanup()
main.exit()
- except:
- main.log.info( self.name + " ::::::" )
- main.log.error( traceback.print_exc() )
- main.log.info( self.name + " ::::::" )
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
main.cleanup()
main.exit()
def cpLogsToDir( self, logToCopy,
- destDir, copyFileName="" ):
+ destDir, copyFileName="" ):
"""
Copies logs to a desired directory.
Current implementation of ONOS deletes its karaf
@@ -1420,13 +1497,9 @@
destDir += "/"
if copyFileName:
- self.handle.sendline(
- "cp " +
- str( logToCopy ) +
- " " +
- str( destDir ) +
- str( copyFileName ) +
- localtime )
+ self.handle.sendline( "cp " + str( logToCopy ) + " " +
+ str( destDir ) + str( copyFileName ) +
+ localtime )
self.handle.expect( "cp" )
self.handle.expect( "\$" )
else:
@@ -1441,11 +1514,8 @@
main.log.error( "Copying files failed" )
main.log.error( self.name + ": EOF exception found" )
main.log.error( self.name + ": " + self.handle.before )
- except:
- main.log.error( "Copying files failed" )
- main.log.info( self.name + " ::::::" )
- main.log.error( traceback.print_exc() )
- main.log.info( self.name + " ::::::" )
+ except Exception:
+ main.log.exception( "Copying files failed" )
def checkLogs( self, onosIp ):
"""
@@ -1463,11 +1533,10 @@
main.log.error( "Lost ssh connection" )
main.log.error( self.name + ": EOF exception found" )
main.log.error( self.name + ": " + self.handle.before )
- except:
- main.log.error( "Some error in check_logs:" )
- main.log.info( self.name + " ::::::" )
- main.log.error( traceback.print_exc() )
- main.log.info( self.name + " ::::::" )
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
+ main.cleanup()
+ main.exit()
def onosStatus( self, node="" ):
"""
@@ -1488,8 +1557,6 @@
return main.TRUE
elif i == 1:
main.log.info( "ONOS is stopped" )
- return main.FALSE
- else:
main.log.error( "ONOS service failed to check the status" )
main.cleanup()
main.exit()
@@ -1498,9 +1565,503 @@
main.log.error( self.name + ": " + self.handle.before )
main.cleanup()
main.exit()
- except:
- main.log.info( self.name + " ::::::" )
- main.log.error( traceback.print_exc() )
- main.log.info( self.name + " ::::::" )
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
main.cleanup()
main.exit()
+
+ def setIpTables( self, ip, port='', action='add', packet_type='',
+ direction='INPUT', rule='DROP', states=True ):
+ """
+ Description:
+ add or remove iptables rule to DROP (default) packets from
+ specific IP and PORT
+ Usage:
+ * specify action ('add' or 'remove')
+ when removing, pass in the same argument as you would add. It will
+ delete that specific rule.
+ * specify the ip to block
+ * specify the destination port to block (defaults to all ports)
+ * optional packet type to block (default tcp)
+ * optional iptables rule (default DROP)
+ * optional direction to block (default 'INPUT')
+ * States boolean toggles adding all supported tcp states to the
+ firewall rule
+ Returns:
+ main.TRUE on success or
+ main.FALSE if given invalid input or
+ main.ERROR if there is an error in response from iptables
+ WARNING:
+ * This function uses root privilege iptables command which may result
+ in unwanted network errors. USE WITH CAUTION
+ """
+ import time
+
+ # NOTE*********
+ # The strict checking methods of this driver function is intentional
+ # to discourage any misuse or error of iptables, which can cause
+ # severe network errors
+ # *************
+
+ # NOTE: Sleep needed to give some time for rule to be added and
+ # registered to the instance. If you are calling this function
+ # multiple times this sleep will prevent any errors.
+ # DO NOT REMOVE
+ # time.sleep( 5 )
+ try:
+ # input validation
+ action_type = action.lower()
+ rule = rule.upper()
+ direction = direction.upper()
+ if action_type != 'add' and action_type != 'remove':
+ main.log.error( "Invalid action type. Use 'add' or "
+ "'remove' table rule" )
+ if rule != 'DROP' and rule != 'ACCEPT' and rule != 'LOG':
+ # NOTE Currently only supports rules DROP, ACCEPT, and LOG
+ main.log.error( "Invalid rule. Valid rules are 'DROP' or "
+ "'ACCEPT' or 'LOG' only." )
+ if direction != 'INPUT' and direction != 'OUTPUT':
+ # NOTE currently only supports rules INPUT and OUPTUT
+ main.log.error( "Invalid rule. Valid directions are"
+ " 'OUTPUT' or 'INPUT'" )
+ return main.FALSE
+ return main.FALSE
+ return main.FALSE
+ if action_type == 'add':
+ # -A is the 'append' action of iptables
+ actionFlag = '-A'
+ elif action_type == 'remove':
+ # -D is the 'delete' rule of iptables
+ actionFlag = '-D'
+ self.handle.sendline( "" )
+ self.handle.expect( "\$" )
+ cmd = "sudo iptables " + actionFlag + " " +\
+ direction +\
+ " -s " + str( ip )
+ # " -p " + str( packet_type ) +\
+ if packet_type:
+ cmd += " -p " + str( packet_type )
+ if port:
+ cmd += " --dport " + str( port )
+ if states:
+ cmd += " -m state --state="
+ #FIXME- Allow user to configure which states to block
+ cmd += "INVALID,ESTABLISHED,NEW,RELATED,UNTRACKED"
+ cmd += " -j " + str( rule )
+
+ self.handle.sendline( cmd )
+ self.handle.expect( "\$" )
+ main.log.warn( self.handle.before )
+
+ info_string = "On " + str( self.name )
+ info_string += " " + str( action_type )
+ info_string += " iptable rule [ "
+ info_string += " IP: " + str( ip )
+ info_string += " Port: " + str( port )
+ info_string += " Rule: " + str( rule )
+ info_string += " Direction: " + str( direction ) + " ]"
+ main.log.info( info_string )
+ return main.TRUE
+ except pexpect.TIMEOUT:
+ main.log.exception( self.name + ": Timeout exception in "
+ "setIpTables function" )
+ return main.ERROR
+ except pexpect.EOF:
+ main.log.error( self.name + ": EOF exception found" )
+ main.log.error( self.name + ": " + self.handle.before )
+ main.cleanup()
+ main.exit()
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
+ main.cleanup()
+ main.exit()
+
+ def detailed_status(self, log_filename):
+ """
+ This method is used by STS to check the status of the controller
+ Reports RUNNING, STARTING, STOPPED, FROZEN, ERROR (and reason)
+ """
+ import re
+ try:
+ self.handle.sendline( "" )
+ self.handle.expect( "\$" )
+ self.handle.sendline( "cd " + self.home )
+ self.handle.expect( "\$" )
+ self.handle.sendline( "service onos status" )
+ self.handle.expect( "\$" )
+ response = self.handle.before
+ if re.search( "onos start/running", response ):
+ # onos start/running, process 10457
+ return 'RUNNING'
+ # FIXME: Implement this case
+ # elif re.search( pattern, response ):
+ # return 'STARTING'
+ elif re.search( "onos stop/", response ):
+ # onos stop/waiting
+ # FIXME handle this differently?: onos stop/pre-stop
+ return 'STOPPED'
+ # FIXME: Implement this case
+ # elif re.search( pattern, response ):
+ # return 'FROZEN'
+ else:
+ main.log.warn( self.name +
+ " WARNING: status received unknown response" )
+ main.log.warn( response )
+ return 'ERROR', "Unknown response: %s" % response
+ except pexpect.TIMEOUT:
+ main.log.exception( self.name + ": Timeout exception in "
+ "setIpTables function" )
+ return 'ERROR', "Pexpect Timeout"
+ except pexpect.EOF:
+ main.log.error( self.name + ": EOF exception found" )
+ main.log.error( self.name + ": " + self.handle.before )
+ main.cleanup()
+ main.exit()
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
+ main.cleanup()
+ main.exit()
+
+ def createLinkGraphFile( self, benchIp, ONOSIpList, deviceCount):
+ '''
+ Create/formats the LinkGraph.cfg file based on arguments
+ -only creates a linear topology and connects islands
+ -evenly distributes devices
+ -must be called by ONOSbench
+
+ ONOSIpList - list of all of the node IPs to be used
+
+ deviceCount - number of switches to be assigned
+ '''
+ main.log.step("Creating link graph configuration file." )
+ linkGraphPath = self.home + "/tools/package/etc/linkGraph.cfg"
+ tempFile = "/tmp/linkGraph.cfg"
+
+ linkGraph = open(tempFile, 'w+')
+ linkGraph.write("# NullLinkProvider topology description (config file).\n")
+ linkGraph.write("# The NodeId is only added if the destination is another node's device.\n")
+ linkGraph.write("# Bugs: Comments cannot be appended to a line to be read.\n")
+
+ clusterCount = len(ONOSIpList)
+
+ if type(deviceCount) is int or type(deviceCount) is str:
+ deviceCount = int(deviceCount)
+ switchList = [0]*(clusterCount+1)
+ baselineSwitchCount = deviceCount/clusterCount
+
+ for node in range(1, clusterCount + 1):
+ switchList[node] = baselineSwitchCount
+
+ for node in range(1, (deviceCount%clusterCount)+1):
+ switchList[node] += 1
+
+ if type(deviceCount) is list:
+ main.log.info("Using provided device distribution")
+ switchList = [0]
+ for i in deviceCount:
+ switchList.append(int(i))
+
+ tempList = ['0']
+ tempList.extend(ONOSIpList)
+ ONOSIpList = tempList
+
+ myPort = 6
+ lastSwitch = 0
+ for node in range(1, clusterCount+1):
+ if switchList[node] == 0:
+ continue
+
+ linkGraph.write("graph " + ONOSIpList[node] + " {\n")
+
+ if node > 1:
+ #connect to last device on previous node
+ line = ("\t0:5 -> " + str(lastSwitch) + ":6:" + lastIp + "\n") #ONOSIpList[node-1]
+ linkGraph.write(line)
+
+ lastSwitch = 0
+ for switch in range (0, switchList[node]-1):
+ line = ""
+ line = ("\t" + str(switch) + ":" + str(myPort))
+ line += " -- "
+ line += (str(switch+1) + ":" + str(myPort-1) + "\n")
+ linkGraph.write(line)
+ lastSwitch = switch+1
+ lastIp = ONOSIpList[node]
+
+ #lastSwitch += 1
+ if node < (clusterCount):
+ #connect to first device on the next node
+ line = ("\t" + str(lastSwitch) + ":6 -> 0:5:" + ONOSIpList[node+1] + "\n")
+ linkGraph.write(line)
+
+ linkGraph.write("}\n")
+ linkGraph.close()
+
+ #SCP
+ os.system( "scp " + tempFile + " admin@" + benchIp + ":" + linkGraphPath)
+ main.log.info("linkGraph.cfg creation complete")
+
+ def configNullDev( self, ONOSIpList, deviceCount, numPorts=10):
+
+ '''
+ ONOSIpList = list of Ip addresses of nodes switches will be devided amongst
+ deviceCount = number of switches to distribute, or list of values to use as custom distribution
+ numPorts = number of ports per device. Defaults to 10 both in this function and in ONOS. Optional arg
+ '''
+
+ main.log.step("Configuring Null Device Provider" )
+ clusterCount = len(ONOSIpList)
+
+ try:
+
+ if type(deviceCount) is int or type(deviceCount) is str:
+ main.log.step("Creating device distribution")
+ deviceCount = int(deviceCount)
+ switchList = [0]*(clusterCount+1)
+ baselineSwitchCount = deviceCount/clusterCount
+
+ for node in range(1, clusterCount + 1):
+ switchList[node] = baselineSwitchCount
+
+ for node in range(1, (deviceCount%clusterCount)+1):
+ switchList[node] += 1
+
+ if type(deviceCount) is list:
+ main.log.info("Using provided device distribution")
+
+ if len(deviceCount) == clusterCount:
+ switchList = ['0']
+ switchList.extend(deviceCount)
+
+ if len(deviceCount) == (clusterCount + 1):
+ if deviceCount[0] == '0' or deviceCount[0] == 0:
+ switchList = deviceCount
+
+ assert len(switchList) == (clusterCount + 1)
+
+ except AssertionError:
+ main.log.error( "Bad device/Ip list match")
+ except TypeError:
+ main.log.exception( self.name + ": Object not as expected" )
+ return None
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
+ main.cleanup()
+ main.exit()
+
+
+ ONOSIp = [0]
+ ONOSIp.extend(ONOSIpList)
+
+ devicesString = "devConfigs = "
+ for node in range(1, len(ONOSIp)):
+ devicesString += (ONOSIp[node] + ":" + str(switchList[node] ))
+ if node < clusterCount:
+ devicesString += (",")
+
+ try:
+ self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider devConfigs " + devicesString )
+ self.handle.expect(":~")
+ self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.device.impl.NullDeviceProvider numPorts " + str(numPorts) )
+ self.handle.expect(":~")
+
+ for i in range(10):
+ self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.device.impl.NullDeviceProvider")
+ self.handle.expect(":~")
+ verification = self.handle.before
+ if (" value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification:
+ break
+ else:
+ time.sleep(1)
+
+ assert ("value=" + str(numPorts)) in verification and (" value=" + devicesString) in verification
+
+ except AssertionError:
+ main.log.error("Incorrect Config settings: " + verification)
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
+ main.cleanup()
+ main.exit()
+
+ def configNullLink( self,fileName="/opt/onos/apache-karaf-3.0.3/etc/linkGraph.cfg", eventRate=0):
+ '''
+ fileName default is currently the same as the default on ONOS, specify alternate file if
+ you want to use a different topology file than linkGraph.cfg
+ '''
+
+
+ try:
+ self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider eventRate " + str(eventRate))
+ self.handle.expect(":~")
+ self.handle.sendline("onos $OC1 cfg set org.onosproject.provider.nil.link.impl.NullLinkProvider cfgFile " + fileName )
+ self.handle.expect(":~")
+
+ for i in range(10):
+ self.handle.sendline("onos $OC1 cfg get org.onosproject.provider.nil.link.impl.NullLinkProvider")
+ self.handle.expect(":~")
+ verification = self.handle.before
+ if (" value=" + str(eventRate)) in verification and (" value=" + fileName) in verification:
+ break
+ else:
+ time.sleep(1)
+
+ assert ("value=" + str(eventRate)) in verification and (" value=" + fileName) in verification
+
+ except pexpect.EOF:
+ main.log.error( self.name + ": EOF exception found" )
+ main.log.error( self.name + ": " + self.handle.before )
+ main.cleanup()
+ main.exit()
+ except AssertionError:
+ main.log.info("Settings did not post to ONOS")
+ main.log.error(varification)
+ except Exception:
+ main.log.exception( self.name + ": Uncaught exception!" )
+ main.log.error(varification)
+ main.cleanup()
+ main.exit()
+
+
+ def getOnosIpFromEnv(self):
+
+ import string
+
+ # returns a list of ip addresses for the onos nodes, will work with up to 7 nodes + OCN and OCI
+ # returns in format [ 'x', OC1 ip, OC2 i... ect. ... , ONN ip ]
+
+ self.handle.sendline("env| grep OC")
+ self.handle.expect(":~")
+ rawOutput = self.handle.before
+ print rawOutput
+ print "-----------------------------"
+ print repr(rawOutput)
+ mpa = dict.fromkeys(range(32))
+ translated = rawOutput.translate(mpa)
+ print translated
+
+
+ # create list with only the lines that have the needed IPs
+ unparsedIps = []
+
+ # remove preceeding or trailing lines
+ for line in rawOutput:
+ if "OC" in line and "=" in line:
+ unparsedIps.append(str(line))
+
+ # determine cluster size
+ clusterCount = 0
+ for line in unparsedIps:
+ line = str(line)
+ print line
+ temp = line.replace("OC","")
+ print("line index " + str(line.index("=")))
+ OCindex = temp[0]
+ for i in range(0, 7):
+ if OCindex == str(i) and i > clusterCount:
+ clusterCount == i
+ print(clusterCount)
+ # create list to hold ips such that OC1 is at list[1] and OCN and OCI are at the end (in that order)
+ ONOSIps = ["x"] * (clusterCount + 3)
+
+ # populate list
+ for line in unparsedIps:
+ main.log.info(line)##########
+ temp = str(line.replace("OC",""))
+ main.log.info(str(list(temp)))
+ OCindex = temp[0]
+ main.log.info(OCindex)############
+ if OCindex == "N":
+ ONOSIps[ clusterCount + 1 ] = temp.replace("N=","")
+
+ if OCindex == "I":
+ ONOSIps[ clusterCount + 2 ] = temp.replace("I=","")
+
+ else:
+ ONOSIps[ int(OCindex) ] = temp.replace((OCindex + "=") ,"")
+
+ # validate
+ for x in ONOSIps:
+ if ONOSIps.index(x) != 0 and x == "x":
+ main.log.error("ENV READ FAILURE, MISSING DATA: \n\n" + str(ONOSIps) + "\n\n")
+
+ return ONOSIps
+
+
+ def onosErrorLog(self, nodeIp):
+
+ cmd = "onos-ssh " + nodeIp + " cat /opt/onos/log/karaf.log | grep WARN"
+ self.handle.sendline(cmd)
+ self.handle.expect(":~")
+ before = (self.handle.before).splitlines()
+
+ warnings = []
+
+ for line in before:
+ if "WARN" in line and "grep" not in line:
+ warnings.append(line)
+ main.warnings[main.warnings[0]+1] = line
+ main.warnings[0] += 1
+ if main.warnings[0] >= 10:
+ main.warnings[0] = 0
+
+ cmd = "onos-ssh " + nodeIp + " cat /opt/onos/log/karaf.log | grep ERROR"
+ self.handle.sendline(cmd)
+ self.handle.expect(":~")
+ before = (self.handle.before).splitlines()
+
+ errors = []
+
+ for line in before:
+ if "ERROR" in line and "grep" not in line:
+ errors.append(line)
+ main.errors[main.errors[0]+1] = line
+ main.errors[0] += 1
+ if main.errors[0] >= 10:
+ main.errors[0] = 0
+
+ cmd = "onos-ssh " + nodeIp + " cat /opt/onos/log/karaf.log | grep Exept"
+ self.handle.sendline(cmd)
+ self.handle.expect(":~")
+ before = (self.handle.before).splitlines()
+
+ exceptions = []
+
+ for line in before:
+ if "Except" in line and "grep" not in line:
+ exceptions.append(line)
+ main.exceptions[main.errors[0]+1] = line
+ main.exceptions[0] += 1
+ if main.exceptions[0] >= 10:
+ main.exceptions[0] = 0
+
+
+
+ ################################################################
+
+ msg1 = "WARNINGS: \n"
+ for i in main.warnings:
+ if type(i) is not int:
+ msg1 += ( i + "\n")
+
+ msg2 = "ERRORS: \n"
+ for i in main.errors:
+ if type(i) is not int:
+ msg2 += ( i + "\n")
+
+ msg3 = "EXCEPTIONS: \n"
+ for i in main.exceptions:
+ if type(i) is not int:
+ msg3 += ( i + "\n")
+
+ main.log.info("===============================================================\n")
+ main.log.info( "Warnings: " + str(len(warnings)))
+ main.log.info( "Errors: " + str(len(errors)))
+ main.log.info( "Exceptions: " + str(len(exceptions)))
+ if len(warnings) > 0:
+ main.log.info(msg1)
+ if len(errors) > 0:
+ main.log.info(msg2)
+ if len(exceptions) > 0:
+ main.log.info(msg3)
+ main.log.info("===============================================================\n")
+