[ONOS-7635][ONOS-7636] Support for complex scenarios in SRRouting test
- New ping function to execute pings in parallel
- Collect t3 output on ping failures
- Allow expected ping failures
Change-Id: I4492a89bc4c0a581ff2e35bcc1896ddd5ea64a18
diff --git a/TestON/tests/dependencies/topology.py b/TestON/tests/dependencies/topology.py
index 04e6246..6527a83 100644
--- a/TestON/tests/dependencies/topology.py
+++ b/TestON/tests/dependencies/topology.py
@@ -22,6 +22,7 @@
import re
import imp
import json
+from core import utilities
class Topology:
@@ -226,3 +227,78 @@
onpass="ONOS correctly discovered the topology",
onfail="ONOS incorrectly discovered the topology" )
return topoResults
+
+ def ping( self, srcList, dstList, ipv6=False, expect=True, wait=1, acceptableFailed=0, collectT3=True ):
+ """
+ Description:
+ Ping from every host in srcList to every host in dstList and
+ verify if ping results are as expected.
+ Pings are executed in parallel from host components
+ Options:
+ src: a list of source host names, e.g. [ "h1", "h2" ]
+ dst: a list of destination host names, e.g. [ "h3", "h4" ]
+ expect: expect ping result to pass if True, otherwise fail
+ acceptableFailed: maximum number of failed pings acceptable for
+ each src-dst host pair
+ collectT3: save t3-troubleshoot output for src and dst host that failed to ping
+ Returns:
+ main.TRUE if all ping results are expected, otherwise main.FALSE
+ """
+ main.log.info( "Pinging from {} to {}, expected result is {}".format( srcList, dstList,
+ "pass" if expect else "fail" ) )
+ # Verify host component has been created
+ srcIpList = {}
+ for src in srcList:
+ if not hasattr( main, src ):
+ main.log.info( "Creating component for host {}".format( src ) )
+ main.Network.createHostComponent( src )
+ hostHandle = getattr( main, src )
+ main.log.info( "Starting CLI on host {}".format( src ) )
+ hostHandle.startHostCli()
+ srcIpList[ src ] = main.Network.getIPAddress( src, proto='IPV6' if ipv6 else 'IPV4' )
+
+ unexpectedPings = []
+ for dst in dstList:
+ dstIp = main.Network.getIPAddress( dst, proto='IPV6' if ipv6 else 'IPV4' )
+ # Start pings from src hosts in parallel
+ pool = []
+ for src in srcList:
+ srcIp = srcIpList[ src ]
+ if srcIp == dstIp:
+ continue
+ if expect and ( not srcIp or not dstIp ):
+ unexpectedPings.append( [ src, dst, "no IP" ] )
+ continue
+ hostHandle = getattr( main, src )
+ thread = main.Thread( target=utilities.retry,
+ name="{}-{}".format( srcIp, dstIp ),
+ args=[ hostHandle.pingHostSetAlternative, [ main.FALSE ] ],
+ kwargs={ "args":( [ dstIp ], wait, ipv6 ),
+ "attempts": acceptableFailed + 1,
+ "sleep": 1 } )
+ pool.append( thread )
+ thread.start()
+ # Wait for threads to finish and check ping result
+ for thread in pool:
+ thread.join( 10 )
+ srcIp, dstIp = thread.name.split( "-" )
+ if expect and not thread.result or not expect and thread.result:
+ unexpectedPings.append( [ srcIp, dstIp, "fail" if expect else "pass" ] )
+
+ utilities.assert_equals( expect=[],
+ actual=unexpectedPings,
+ onpass="Pings from {} to {} all as expected".format( srcList, dstList ),
+ onfail="Unexpected pings: {}".format( unexpectedPings ) )
+ if collectT3:
+ for unexpectedPing in unexpectedPings:
+ if unexpectedPing[ 2 ] == "no IP":
+ continue
+ srcIp = unexpectedPing[ 0 ]
+ dstIp = unexpectedPing[ 1 ]
+ main.log.debug( "Collecting t3 with source {} and destination {}".format( srcIp, dstIp ) )
+ cmd = main.Cluster.active( 0 ).CLI.composeT3Command( srcIp, dstIp, ipv6 )
+ main.log.debug( "t3 command: {}".format( cmd ) )
+ if cmd:
+ main.ONOSbench.dumpONOSCmd( main.Cluster.active( 0 ).ipAddress, cmd, main.logdir,
+ "t3-CASE{}-{}-{}-".format( main.CurrentTestCaseNumber, srcIp, dstIp ) )
+ return main.FALSE if unexpectedPings else main.TRUE