[ONOS-7408] Refactor HA suite to be able to run with trellis
- Better support for dual homed hosts
- Support parsing more types of flows from OVS of1.3 tables
- More specific error handling in Mininet driver
- Only check attachment points if that mapping is provided
- Minor refactoring of link up/down argument names for consistency
- Use list of hosts/switches in mn instead of hard coded ranges
- Add .params.fabric for testing with fabric
- Add .params.intents for testing with intents, classic/default version
of the tests
- Add support for setting karaf log levels after startup
- Fix malformed command in cell file if no OCN is supplied
- Add back CFG for the ECFlowRuleStore now that it is the default impl
- Check Network config after connecting mininet
TODO:
- Set log levels in ONOS service files so we can set logging during startup
- Make sure we process all treatments in flows. eg drop and
clear_treatment
- Does the topology come up the same each time?
- same port numbers, etc...
- Jenkinsfiles
- use .params.fabric for HA fabric tests
Notes:
- Uses Topology and config from the SegmentRouting tests
Change-Id: I08f08ba1d3d18f710f63a45b28ac3a2868a1a5cf
diff --git a/TestON/drivers/common/cli/emulator/mininetclidriver.py b/TestON/drivers/common/cli/emulator/mininetclidriver.py
index 1da21b9..e11cb22 100644
--- a/TestON/drivers/common/cli/emulator/mininetclidriver.py
+++ b/TestON/drivers/common/cli/emulator/mininetclidriver.py
@@ -205,7 +205,8 @@
'Exception',
'\*\*\*',
pexpect.EOF,
- pexpect.TIMEOUT ],
+ pexpect.TIMEOUT,
+ "No such file or directory"],
timeout )
if i == 0:
main.log.info( self.name + ": Mininet built\nTime Took : " + str( time.time() - startTime ) )
@@ -234,6 +235,9 @@
self.name +
": Something took too long... " )
return main.FALSE
+ elif i == 5:
+ main.log.error( self.name + ": " + self.handle.before + self.handle.after )
+ return main.FALSE
# Why did we hit this part?
main.log.error( "startNet did not return correctly" )
return main.FASLE
@@ -285,8 +289,8 @@
numHostsPerSw = fanout
totalNumHosts = numSwitches * numHostsPerSw
numLinks = totalNumHosts + ( numSwitches - 1 )
- print "num_switches for %s(%d,%d) = %d and links=%d" %\
- ( topoType, depth, fanout, numSwitches, numLinks )
+ main.log.debug( "num_switches for %s(%d,%d) = %d and links=%d" %
+ ( topoType, depth, fanout, numSwitches, numLinks ) )
topoDict = { "num_switches": int( numSwitches ),
"num_corelinks": int( numLinks ) }
return topoDict
@@ -1650,7 +1654,9 @@
self.handle.expect( "mininet>" )
response = self.handle.before
main.log.info( response )
-
+ if "not in network" in response:
+ main.log.error( self.name + ": Could not find one of the endpoints of the link" )
+ return main.FALSE
return main.TRUE
except pexpect.TIMEOUT:
main.log.exception( self.name + ": Command timed out" )
@@ -1807,7 +1813,12 @@
prompt="mininet>",
timeout=10 )
if response:
- return response
+ if "no bridge named" in response:
+ main.log.error( self.name + ": Error in getSwController: " +
+ self.handle.before )
+ return main.FALSE
+ else:
+ return response
else:
return main.FALSE
except pexpect.EOF:
@@ -1936,6 +1947,9 @@
for cmd in commandList:
try:
self.execute( cmd=cmd, prompt="mininet>", timeout=5 )
+ if "no bridge named" in self.handle.before:
+ main.log.error( self.name + ": Error in assignSwController: " +
+ self.handle.before )
except pexpect.TIMEOUT:
main.log.error( self.name + ": pexpect.TIMEOUT found" )
return main.FALSE
@@ -2581,7 +2595,8 @@
sel = sel.split( "," )
# the priority is stuck in the selecter so put it back
# in the flow
- parsedFlow.append( sel.pop( 0 ) )
+ if 'priority' in sel[0]:
+ parsedFlow.append( sel.pop( 0 ) )
# parse selector
criteria = []
for item in sel:
@@ -2600,8 +2615,12 @@
# parse treatment
action = []
for item in treat:
- field = item.split( ":" )
- action.append( { field[ 0 ]: field[ 1 ] } )
+ if ":" in item:
+ field = item.split( ":" )
+ action.append( { field[ 0 ]: field[ 1 ] } )
+ else:
+ main.log.warn( "Do not know how to process this treatment:{}, ignoring.".format(
+ item ) )
# create the treatment field and add the actions
treatment = { "treatment": { "action": sorted( action ) } }
# parse the rest of the flow
@@ -2961,7 +2980,9 @@
main.log.exception( self.name + ": Uncaught exception!" )
main.cleanAndExit()
- def getHosts( self, verbose=False, updateTimeout=1000, hostClass=[ "Host", "DhcpClient", "Dhcp6Client", "DhcpServer", "Dhcp6Server", "DhcpRelay" ], getInterfaces=True ):
+ def getHosts( self, verbose=False, updateTimeout=1000,
+ hostClass=[ "Host", "DhcpClient", "Dhcp6Client", "DhcpServer", "Dhcp6Server", "DhcpRelay" ],
+ getInterfaces=True ):
"""
Read hosts from Mininet.
Optional:
@@ -2983,8 +3004,9 @@
if not isinstance( hostClass, types.ListType ):
hostClass = [ str( hostClass ) ]
classRE = "(" + "|".join([c for c in hostClass]) + ")"
- hostRE = r"" + classRE + "\s(?P<name>[^:]+)\:((\s(?P<ifname>[^:]+)\:" +\
- "(?P<ip>[^\s]+))|(\s)\spid=(?P<pid>[^>]+))"
+ ifaceRE = r"(?P<ifname>[^:]+)\:(?P<ip>[^\s,]+),?"
+ ifacesRE = r"(?P<ifaces>[^:]+\:[^\s]+)"
+ hostRE = r"" + classRE + "\s(?P<name>[^:]+)\:(" + ifacesRE + "*\spid=(?P<pid>[^>]+))"
# update mn port info
self.update( updateTimeout )
# Get mininet dump
@@ -3282,6 +3304,9 @@
onosPort2 ) == int( port2 ):
firstDir = main.TRUE
else:
+ # The right switches, but wrong ports, could be
+ # another link between these devices, or onos
+ # discovered the links incorrectly
main.log.warn(
'The port numbers do not match for ' +
str( link ) +
@@ -3289,7 +3314,9 @@
'link %s/%s -> %s/%s' %
( node1, port1, node2, port2 ) +
' ONOS has the values %s/%s -> %s/%s' %
- ( onosNode1, onosPort1, onosNode2, onosPort2 ) )
+ ( onosNode1, onosPort1, onosNode2, onosPort2 ) +
+ '. This could be another link between these devices' +
+ ' or a incorrectly discoved link' )
# check onos link from node2 to node1
elif ( str( onosNode1 ) == str( node2 ) and
@@ -3298,6 +3325,9 @@
and int( onosPort2 ) == int( port1 ) ):
secondDir = main.TRUE
else:
+ # The right switches, but wrong ports, could be
+ # another link between these devices, or onos
+ # discovered the links incorrectly
main.log.warn(
'The port numbers do not match for ' +
str( link ) +
@@ -3305,7 +3335,9 @@
'link %s/%s -> %s/%s' %
( node1, port1, node2, port2 ) +
' ONOS has the values %s/%s -> %s/%s' %
- ( onosNode2, onosPort2, onosNode1, onosPort1 ) )
+ ( onosNode2, onosPort2, onosNode1, onosPort1 ) +
+ '. This could be another link between these devices' +
+ ' or a incorrectly discoved link' )
else: # this is not the link you're looking for
pass
if not firstDir:
diff --git a/TestON/drivers/common/cli/onosdriver.py b/TestON/drivers/common/cli/onosdriver.py
index 8324677..37feab8 100755
--- a/TestON/drivers/common/cli/onosdriver.py
+++ b/TestON/drivers/common/cli/onosdriver.py
@@ -795,7 +795,8 @@
tempCount = tempCount + 1
cellFile.write( "export OCI=$OC1\n" )
- cellFile.write( mnString + "\"" + str(mnIpAddrs) + "\"\n" )
+ if mnString:
+ cellFile.write( mnString + "\"" + str( mnIpAddrs ) + "\"\n" )
cellFile.write( appString + "\n" )
cellFile.write( onosGroup + "\n" )
cellFile.write( onosUser + "\n" )
@@ -836,20 +837,19 @@
# Note that this variable name is subject to change
# and that this driver will have to change accordingly
self.handle.expect( str( cellname ) )
+ response = self.handle.before + self.handle.after
i = self.handle.expect( [ "No such cell",
- self.prompt,
- pexpect.TIMEOUT ], timeout=10 )
+ "command not found",
+ self.prompt ], timeout=10 )
+ response += self.handle.before + self.handle.after
if i == 0:
- main.log.error( self.name + ": No such cell. Response: " + str( self.handle.before ) )
+ main.log.error( self.name + ": No such cell. Response: " + str( response ) )
main.cleanAndExit()
elif i == 1:
- main.log.info( self.name + ": Successfully set cell: " + str( self.handle.before ) )
+ main.log.error( self.name + ": Error setting cell. Response: " + str( response ) )
+ main.cleanAndExit()
elif i == 2:
- main.log.error( self.name + ": Set cell timed out. Response: " + str( self.handle.before ) )
- main.cleanAndExit()
- else:
- main.log.error( self.name + ": Unexpected response: " + str( self.handle.before ) )
- main.cleanAndExit()
+ main.log.info( self.name + ": Successfully set cell: " + str( response ) )
return main.TRUE
except pexpect.TIMEOUT:
main.log.error( self.name + ": TIMEOUT exception found" )