Updating drivers
Changes Include:
* Modifying some log levels
* Remove some IDE injected code
* Fix for some disconnect bug which resulted in a loop of disconnect calls
* Add json support for Leaders in onosclidriver
* Add json support for pendingMap in onosclidriver
* Add json support for partitions in onosclidriver
* Add json support for nodes in onosclidriver
* In git pull function, add option to fast forward only and set as default
* Add more expects in git pull, mostly for when pulling results in a merge
* Add another expect for onosStop function
diff --git a/TestON/drivers/common/cli/emulator/mininetclidriver.py b/TestON/drivers/common/cli/emulator/mininetclidriver.py
index dc9de05..a6436ca 100644
--- a/TestON/drivers/common/cli/emulator/mininetclidriver.py
+++ b/TestON/drivers/common/cli/emulator/mininetclidriver.py
@@ -326,7 +326,7 @@
command = args[ "SRC" ] + " ping " + \
args[ "TARGET" ] + " -c 1 -i 1 -W 8"
try:
- main.log.warn( "Sending: " + command )
+ main.log.info( "Sending: " + command )
self.handle.sendline( command )
i = self.handle.expect( [ command, pexpect.TIMEOUT ] )
if i == 1:
diff --git a/TestON/drivers/common/cli/emulator/remotemininetdriver.py b/TestON/drivers/common/cli/emulator/remotemininetdriver.py
index 8e445a9..e451335 100644
--- a/TestON/drivers/common/cli/emulator/remotemininetdriver.py
+++ b/TestON/drivers/common/cli/emulator/remotemininetdriver.py
@@ -299,7 +299,7 @@
self.handle.sendline( "" )
i = self.handle.expect( [ 'No\ssuch\device', 'listening\son',
pexpect.TIMEOUT, "\$" ], timeout=10 )
- main.log.warn( self.handle.before + self.handle.after )
+ main.log.info( self.handle.before + self.handle.after )
if i == 0:
main.log.error( self.name + ": tcpdump - No such device exists.\
tcpdump attempted on: " + intf )
@@ -591,7 +591,6 @@
if actionType == 'remove':
# -D is the 'delete' rule of iptables
actionRemove = '-D'
- # noinspection PyBroadException
try:
self.handle.sendline( "" )
# Delete a specific rule specified into the function
diff --git a/TestON/drivers/common/cli/onosclidriver.py b/TestON/drivers/common/cli/onosclidriver.py
index 7146211..be5e425 100644
--- a/TestON/drivers/common/cli/onosclidriver.py
+++ b/TestON/drivers/common/cli/onosclidriver.py
@@ -84,19 +84,23 @@
Called when Test is complete to disconnect the ONOS handle.
"""
response = main.TRUE
- # noinspection PyBroadException
try:
- self.logout()
- self.handle.sendline( "" )
- self.handle.expect( "\$" )
- self.handle.sendline( "exit" )
- self.handle.expect( "closed" )
+ if self.handle:
+ i = self.logout()
+ if i == main.TRUE:
+ self.handle.sendline( "" )
+ self.handle.expect( "\$" )
+ self.handle.sendline( "exit" )
+ self.handle.expect( "closed" )
except TypeError:
main.log.exception( self.name + ": Object not as expected" )
response = main.FALSE
except pexpect.EOF:
main.log.error( self.name + ": EOF exception found" )
main.log.error( self.name + ": " + self.handle.before )
+ except ValueError:
+ main.log.exception( "Exception in discconect of " + self.name )
+ response = main.TRUE
except Exception:
main.log.exception( self.name + ": Connection failed to the host" )
response = main.FALSE
@@ -105,27 +109,36 @@
def logout( self ):
"""
Sends 'logout' command to ONOS cli
+ Returns main.TRUE if exited CLI and
+ main.FALSE on timeout (not guranteed you are disconnected)
+ None on TypeError
+ Exits test on unknown error or pexpect exits unexpectedly
"""
try:
- self.handle.sendline( "" )
- i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ],
- timeout=10 )
- if i == 0: # In ONOS CLI
- self.handle.sendline( "logout" )
- self.handle.expect( "\$" )
- elif i == 1: # not in CLI
+ if self.handle:
+ self.handle.sendline( "" )
+ i = self.handle.expect( [ "onos>", "\$", pexpect.TIMEOUT ],
+ timeout=10 )
+ if i == 0: # In ONOS CLI
+ self.handle.sendline( "logout" )
+ self.handle.expect( "\$" )
+ return main.TRUE
+ elif i == 1: # not in CLI
+ return main.TRUE
+ elif i == 3: # Timeout
+ return main.FALSE
+ else:
return main.TRUE
- elif i == 3: # Timeout
- return main.FALSE
except TypeError:
main.log.exception( self.name + ": Object not as expected" )
return None
except pexpect.EOF:
main.log.error( self.name + ": eof exception found" )
- main.log.error( self.name + ": " +
- self.handle.before )
+ main.log.error( self.name + ": " + self.handle.before )
main.cleanup()
main.exit()
+ except ValueError:
+ main.log.error( self.name + "ValueError exception in logout method" )
except Exception:
main.log.exception( self.name + ": Uncaught exception!" )
main.cleanup()
@@ -349,7 +362,6 @@
Optional:
* tcpPort
"""
- # noinspection PyBroadException
try:
cmdStr = "add-node " + str( nodeId ) + " " +\
str( ONOSIp ) + " " + str( tcpPort )
@@ -402,16 +414,24 @@
main.cleanup()
main.exit()
- def nodes( self ):
+ def nodes( self, jsonFormat=True):
"""
List the nodes currently visible
Issues command: 'nodes'
- Returns: entire handle of list of nodes
+ Optional argument:
+ * jsonFormat - boolean indicating if you want output in json
"""
try:
- cmdStr = "nodes"
- handle = self.sendline( cmdStr )
- return handle
+ if jsonFormat:
+ cmdStr = "nodes -j"
+ output = self.sendline( cmdStr )
+ ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
+ parsedOutput = ansiEscape.sub( '', output )
+ return parsedOutput
+ else:
+ cmdStr = "nodes"
+ output = self.sendline( cmdStr )
+ return output
except TypeError:
main.log.exception( self.name + ": Object not as expected" )
return None
@@ -938,6 +958,7 @@
handle = self.sendline( cmdStr )
if re.search( "Error", handle ):
main.log.error( "Error in adding Host intent" )
+ main.log.debug( "Response from ONOS was: " + repr( handle ) )
return None
else:
main.log.info( "Host intent installed between " +
@@ -947,6 +968,8 @@
return match.group()[3:-1]
else:
main.log.error( "Error, intent ID not found" )
+ main.log.debug( "Response from ONOS was: " +
+ repr( handle ) )
return None
except TypeError:
main.log.exception( self.name + ": Object not as expected" )
@@ -1299,10 +1322,10 @@
purge=False, sync=False ):
"""
Remove intent for specified application id and intent id
- Optional args:-
+ Optional args:-
-s or --sync: Waits for the removal before returning
- -p or --purge: Purge the intent from the store after removal
-
+ -p or --purge: Purge the intent from the store after removal
+
Returns:
main.False on error and
cli output otherwise
@@ -1472,7 +1495,7 @@
else:
cmdStr = "flows"
handle = self.sendline( cmdStr )
- if re.search( "Error\sexecuting\scommand:", handle ):
+ if re.search( "Error:", handle ):
main.log.error( self.name + ".flows() response: " +
str( handle ) )
return handle
@@ -2171,15 +2194,31 @@
main.cleanup()
main.exit()
- def leaders( self ):
+ def leaders( self, jsonFormat=True ):
"""
Returns the output of the leaders command.
+ Optional argument:
+ * jsonFormat - boolean indicating if you want output in json
"""
# FIXME: add json output
+ # Sample JSON
+ # {
+ # "electedTime": "13m ago",
+ # "epoch": 4,
+ # "leader": "10.128.30.17",
+ # "topic": "intent-partition-3"
+ # },
try:
- output = self.sendline( "onos:leaders" )
- main.log.warn( output )
- return output
+ if jsonFormat:
+ cmdStr = "onos:leaders -j"
+ output = self.sendline( cmdStr )
+ ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
+ cleanedOutput = ansiEscape.sub( '', output )
+ return cleanedOutput
+ else:
+ cmdStr = "onos:leaders"
+ output = self.sendline( cmdStr )
+ return output
except TypeError:
main.log.exception( self.name + ": Object not as expected" )
return None
@@ -2193,15 +2232,21 @@
main.cleanup()
main.exit()
- def pendingMap( self ):
+ def pendingMap( self, jsonFormat=True ):
"""
Returns the output of the intent Pending map.
"""
- # FIXME: add json output
try:
- output = self.sendline( "onos:intents -p" )
- main.log.warn( output )
- return output
+ if jsonFormat:
+ cmdStr = "onos:intents -p -j"
+ output = self.sendline( cmdStr )
+ ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
+ cleanedOutput = ansiEscape.sub( '', output )
+ return cleanedOutput
+ else:
+ cmdStr = "onos:intents -p"
+ output = self.sendline( cmdStr )
+ return output
except TypeError:
main.log.exception( self.name + ": Object not as expected" )
return None
@@ -2215,15 +2260,32 @@
main.cleanup()
main.exit()
- def partitions( self ):
+ def partitions( self, jsonFormat=True ):
"""
Returns the output of the raft partitions command for ONOS.
"""
- # FIXME: add json output
+ # Sample JSON
+ # {
+ # "leader": "tcp://10.128.30.11:7238",
+ # "members": [
+ # "tcp://10.128.30.11:7238",
+ # "tcp://10.128.30.17:7238",
+ # "tcp://10.128.30.13:7238",
+ # ],
+ # "name": "p1",
+ # "term": 3
+ # },
try:
- output = self.sendline( "partitions" )
- main.log.warn( output )
- return output
+ if jsonFormat:
+ cmdStr = "onos:partitions -j"
+ output = self.sendline( cmdStr )
+ ansiEscape = re.compile( r'\r\r\n\x1b[^m]*m' )
+ cleanedOutput = ansiEscape.sub( '', output )
+ return cleanedOutput
+ else:
+ cmdStr = "onos:partitions"
+ output = self.sendline( cmdStr )
+ return output
except TypeError:
main.log.exception( self.name + ": Object not as expected" )
return None
diff --git a/TestON/drivers/common/cli/onosdriver.py b/TestON/drivers/common/cli/onosdriver.py
index 05044c6..1c7d329 100644
--- a/TestON/drivers/common/cli/onosdriver.py
+++ b/TestON/drivers/common/cli/onosdriver.py
@@ -81,13 +81,17 @@
"""
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 ValueError:
+ main.log.exception( "Exception in discconect of " + self.name )
+ response = main.TRUE
except Exception:
main.log.exception( self.name + ": Connection failed to the host" )
response = main.FALSE
@@ -220,10 +224,14 @@
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,11 +247,12 @@
# self.stop()
self.handle.sendline( "cd " + self.home )
self.handle.expect( self.home + "\$" )
- if comp1 == "":
- self.handle.sendline( "git pull" )
- else:
- self.handle.sendline( "git pull " + comp1 )
-
+ cmd = "git pull"
+ if comp1 != "":
+ cmd += ' ' + comp1
+ if fastForward:
+ cmd += ' ' + " --ff-only"
+ self.handle.sendline( cmd )
i = self.handle.expect(
[
'fatal',
@@ -254,6 +263,9 @@
'You\sare\snot\scurrently\son\sa\sbranch',
'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
@@ -261,7 +273,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(
@@ -303,6 +319,29 @@
"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(
@@ -348,9 +387,9 @@
self.handle.expect( cmd )
i = self.handle.expect(
[ 'fatal',
- 'Username\sfor\s(.*):\s',
- 'Already\son\s\'',
- 'Switched\sto\sbranch\s\'' + str( branch ),
+ 'Username for (.*): ',
+ 'Already on \'',
+ 'Switched to branch \'' + str( branch ),
pexpect.TIMEOUT,
'error: Your local changes to the following files' +
'would be overwritten by checkout:',
@@ -805,6 +844,7 @@
" stop" )
i = self.handle.expect( [
"stop/waiting",
+ "Could not resolve hostname",
"Unknown\sinstance",
pexpect.TIMEOUT ], timeout=60 )
@@ -815,6 +855,9 @@
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