blob: 56a29a9ebf6a7306eaf9e983f9e79cf261077f08 [file] [log] [blame]
Devin Lim142b5342017-07-20 15:22:39 -07001"""
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002Copyright 2016 Open Networking Foundation ( ONF )
Devin Lim142b5342017-07-20 15:22:39 -07003
4Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
5the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
6or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
7
8 TestON is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 2 of the License, or
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070011 ( at your option ) any later version.
Devin Lim142b5342017-07-20 15:22:39 -070012
13 TestON is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with TestON. If not, see <http://www.gnu.org/licenses/>.
20"""
Devin Lim58046fa2017-07-05 16:55:00 -070021import time
22import re
23import imp
24import json
You Wang5da39c82018-04-26 22:55:08 -070025from core import utilities
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070026
27
Devin Lim58046fa2017-07-05 16:55:00 -070028class Topology:
29
30 def __init__( self ):
31 self.default = ''
Devin Lim142b5342017-07-20 15:22:39 -070032
Devin Lim58046fa2017-07-05 16:55:00 -070033 """
34 These functions can be used for topology comparisons
35 """
Devin Lim142b5342017-07-20 15:22:39 -070036 def getAll( self, function, needRetry=False, kwargs={}, inJson=False ):
Devin Lim58046fa2017-07-05 16:55:00 -070037 """
Devin Lim142b5342017-07-20 15:22:39 -070038 Description:
39 get all devices/links/hosts/ports of the onosCli
40 Required:
41 * function - name of the function
42 * needRetry - it will retry if this is true.
43 * kwargs - kwargs of the function
44 * inJson - True if want it in Json form
45 Returns:
46 Returns the list of the result.
Devin Lim58046fa2017-07-05 16:55:00 -070047 """
Devin Lim142b5342017-07-20 15:22:39 -070048 returnList = []
Devin Lim58046fa2017-07-05 16:55:00 -070049 threads = []
Jon Hallca319892017-06-15 15:25:22 -070050 for ctrl in main.Cluster.active():
Devin Lim142b5342017-07-20 15:22:39 -070051 func = getattr( ctrl.CLI, function )
52 t = main.Thread( target=utilities.retry if needRetry else func,
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070053 name=function + "-" + str( ctrl ),
Devin Lim142b5342017-07-20 15:22:39 -070054 args=[ func, [ None ] ] if needRetry else [],
Devin Lim58046fa2017-07-05 16:55:00 -070055 kwargs=kwargs )
56 threads.append( t )
57 t.start()
58
59 for t in threads:
60 t.join()
61 if inJson:
62 try:
Devin Lim142b5342017-07-20 15:22:39 -070063 returnList.append( json.loads( t.result ) )
Devin Lim58046fa2017-07-05 16:55:00 -070064 except ( ValueError, TypeError ):
65 main.log.exception( "Error parsing hosts results" )
66 main.log.error( repr( t.result ) )
Devin Lim142b5342017-07-20 15:22:39 -070067 returnList.append( None )
Devin Lim58046fa2017-07-05 16:55:00 -070068 else:
Devin Lim142b5342017-07-20 15:22:39 -070069 returnList.append( t.result )
70 return returnList
Devin Lim58046fa2017-07-05 16:55:00 -070071
72 def compareDevicePort( self, Mininet, controller, mnSwitches, devices, ports ):
Devin Lim142b5342017-07-20 15:22:39 -070073 """
74 Description:
75 compares the devices and port of the onos to the mininet.
76 Required:
77 * Mininet - mininet driver to use
78 * controller - controller position of the devices
79 * mnSwitches - switches of mininet
80 * devices - devices of the onos
81 * ports - ports of the onos
82 Returns:
83 Returns main.TRUE if the results are matching else
84 Returns main.FALSE
85 """
Devin Lim58046fa2017-07-05 16:55:00 -070086 if devices[ controller ] and ports[ controller ] and \
87 "Error" not in devices[ controller ] and \
88 "Error" not in ports[ controller ]:
89 try:
90 currentDevicesResult = Mininet.compareSwitches(
91 mnSwitches,
92 json.loads( devices[ controller ] ),
93 json.loads( ports[ controller ] ) )
Jon Hallca319892017-06-15 15:25:22 -070094 except ( TypeError, ValueError ):
Devin Lim58046fa2017-07-05 16:55:00 -070095 main.log.error(
Jon Hallca319892017-06-15 15:25:22 -070096 "Could not load json: {0} or {1}".format( str( devices[ controller ] ),
97 str( ports[ controller ] ) ) )
Devin Lim58046fa2017-07-05 16:55:00 -070098 currentDevicesResult = main.FALSE
99 else:
100 currentDevicesResult = main.FALSE
101 return currentDevicesResult
102
103 def compareBase( self, compareElem, controller, compareF, compareArg ):
Devin Lim142b5342017-07-20 15:22:39 -0700104 """
105 Description:
106 compares the links/hosts of the onos to the mininet.
107 Required:
108 * compareElem - list of links/hosts of the onos
109 * controller - controller position of the devices
110 * compareF - function of the mininet that will compare the
111 results
112 * compareArg - arg of the compareF.
113 Returns:
114 Returns main.TRUE if the results are matching else
115 Returns main.FALSE
116 """
Devin Lim58046fa2017-07-05 16:55:00 -0700117 if compareElem[ controller ] and "Error" not in compareElem[ controller ]:
118 try:
119 if isinstance( compareArg, list ):
120 compareArg.append( json.loads( compareElem[ controller ] ) )
121 else:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700122 compareArg = [ compareArg, json.loads( compareElem[ controller ] ) ]
Devin Lim58046fa2017-07-05 16:55:00 -0700123
124 currentCompareResult = compareF( *compareArg )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700125 except( TypeError, ValueError ):
Devin Lim58046fa2017-07-05 16:55:00 -0700126 main.log.error(
127 "Could not load json: {0} or {1}".format( str( compareElem[ controller ] ) ) )
128 currentCompareResult = main.FALSE
129 else:
130 currentCompareResult = main.FALSE
131
132 return currentCompareResult
133
Devin Lim0c972b72018-02-08 14:53:59 -0800134 def compareTopos( self, Mininet, attempts=1, includeCaseDesc=True ):
Devin Lim142b5342017-07-20 15:22:39 -0700135 """
136 Description:
137 compares the links and hosts and switches of the onos to the mininet.
138 Required:
139 * Mininet - Mininet driver to use.
140 * attempts - number of attempts to compare in case
141 the result is different after a certain time.
142 Returns:
143 Returns main.TRUE if the results are matching else
144 Returns main.FALSE
145 """
Devin Lim0c972b72018-02-08 14:53:59 -0800146 if includeCaseDesc:
147 main.case( "Compare ONOS Topology view to Mininet topology" )
148 main.caseExplanation = "Compare topology elements between Mininet" +\
149 " and ONOS"
Devin Lim58046fa2017-07-05 16:55:00 -0700150 main.log.info( "Gathering topology information from Mininet" )
151 devicesResults = main.FALSE # Overall Boolean for device correctness
152 linksResults = main.FALSE # Overall Boolean for link correctness
153 hostsResults = main.FALSE # Overall Boolean for host correctness
154 deviceFails = [] # Nodes where devices are incorrect
155 linkFails = [] # Nodes where links are incorrect
156 hostFails = [] # Nodes where hosts are incorrect
157
158 mnSwitches = Mininet.getSwitches()
159 mnLinks = Mininet.getLinks()
160 mnHosts = Mininet.getHosts()
161
162 main.step( "Comparing Mininet topology to ONOS topology" )
163
164 while ( attempts >= 0 ) and\
165 ( not devicesResults or not linksResults or not hostsResults ):
166 main.log.info( "Sleeping {} seconds".format( 2 ) )
167 time.sleep( 2 )
168 if not devicesResults:
Devin Lim142b5342017-07-20 15:22:39 -0700169 devices = self.getAll( "devices", False )
170 ports = self.getAll( "ports", False )
Devin Lim58046fa2017-07-05 16:55:00 -0700171 devicesResults = main.TRUE
172 deviceFails = [] # Reset for each failed attempt
173 if not linksResults:
Devin Lim142b5342017-07-20 15:22:39 -0700174 links = self.getAll( "links", False )
Devin Lim58046fa2017-07-05 16:55:00 -0700175 linksResults = main.TRUE
176 linkFails = [] # Reset for each failed attempt
177 if not hostsResults:
Devin Lim142b5342017-07-20 15:22:39 -0700178 hosts = self.getAll( "hosts", False )
Devin Lim58046fa2017-07-05 16:55:00 -0700179 hostsResults = main.TRUE
180 hostFails = [] # Reset for each failed attempt
181
182 # Check for matching topology on each node
Devin Lim142b5342017-07-20 15:22:39 -0700183 for controller in main.Cluster.getRunningPos():
Devin Lim58046fa2017-07-05 16:55:00 -0700184 controllerStr = str( controller + 1 ) # ONOS node number
185 # Compare Devices
186 currentDevicesResult = self.compareDevicePort( Mininet, controller,
Jon Hallca319892017-06-15 15:25:22 -0700187 mnSwitches,
188 devices, ports )
Devin Lim58046fa2017-07-05 16:55:00 -0700189 if not currentDevicesResult:
190 deviceFails.append( controllerStr )
191 devicesResults = devicesResults and currentDevicesResult
192 # Compare Links
193 currentLinksResult = self.compareBase( links, controller,
Jon Hallca319892017-06-15 15:25:22 -0700194 Mininet.compareLinks,
195 [ mnSwitches, mnLinks ] )
Devin Lim58046fa2017-07-05 16:55:00 -0700196 if not currentLinksResult:
197 linkFails.append( controllerStr )
198 linksResults = linksResults and currentLinksResult
199 # Compare Hosts
200 currentHostsResult = self.compareBase( hosts, controller,
201 Mininet.compareHosts,
202 mnHosts )
203 if not currentHostsResult:
204 hostFails.append( controllerStr )
205 hostsResults = hostsResults and currentHostsResult
206 # Decrement Attempts Remaining
207 attempts -= 1
208
209 utilities.assert_equals( expect=[],
210 actual=deviceFails,
211 onpass="ONOS correctly discovered all devices",
212 onfail="ONOS incorrectly discovered devices on nodes: " +
213 str( deviceFails ) )
214 utilities.assert_equals( expect=[],
215 actual=linkFails,
216 onpass="ONOS correctly discovered all links",
217 onfail="ONOS incorrectly discovered links on nodes: " +
218 str( linkFails ) )
219 utilities.assert_equals( expect=[],
220 actual=hostFails,
221 onpass="ONOS correctly discovered all hosts",
222 onfail="ONOS incorrectly discovered hosts on nodes: " +
223 str( hostFails ) )
224 topoResults = hostsResults and linksResults and devicesResults
225 utilities.assert_equals( expect=main.TRUE,
226 actual=topoResults,
227 onpass="ONOS correctly discovered the topology",
228 onfail="ONOS incorrectly discovered the topology" )
Devin Lim142b5342017-07-20 15:22:39 -0700229 return topoResults
You Wang5da39c82018-04-26 22:55:08 -0700230
You Wang0fa76e72018-05-18 11:33:25 -0700231 def ping( self, srcList, dstList, ipv6=False, expect=True, wait=1, acceptableFailed=0, collectT3=True, t3Simple=False ):
You Wang5da39c82018-04-26 22:55:08 -0700232 """
233 Description:
234 Ping from every host in srcList to every host in dstList and
235 verify if ping results are as expected.
236 Pings are executed in parallel from host components
237 Options:
238 src: a list of source host names, e.g. [ "h1", "h2" ]
239 dst: a list of destination host names, e.g. [ "h3", "h4" ]
240 expect: expect ping result to pass if True, otherwise fail
241 acceptableFailed: maximum number of failed pings acceptable for
242 each src-dst host pair
243 collectT3: save t3-troubleshoot output for src and dst host that failed to ping
You Wang0fa76e72018-05-18 11:33:25 -0700244 t3Simple: use t3-troubleshoot-simple command when collecting t3 output
You Wang5da39c82018-04-26 22:55:08 -0700245 Returns:
246 main.TRUE if all ping results are expected, otherwise main.FALSE
247 """
248 main.log.info( "Pinging from {} to {}, expected result is {}".format( srcList, dstList,
249 "pass" if expect else "fail" ) )
250 # Verify host component has been created
251 srcIpList = {}
252 for src in srcList:
253 if not hasattr( main, src ):
254 main.log.info( "Creating component for host {}".format( src ) )
255 main.Network.createHostComponent( src )
256 hostHandle = getattr( main, src )
You Wang0fc21702018-11-02 17:49:18 -0700257 if hasattr( main, 'Mininet1' ):
258 main.log.info( "Starting CLI on host {}".format( src ) )
259 hostHandle.startHostCli()
260 else:
261 hostHandle.connectInband()
Siddesha2938fe2021-04-06 02:46:06 +0000262 hostHandle = getattr( main, src )
263 srcIpList[ src ] = main.Network.getIPAddress( src, proto='IPV6' if ipv6 else 'IPV4', iface=hostHandle.interfaces[0].get("name") )
You Wang5da39c82018-04-26 22:55:08 -0700264 unexpectedPings = []
265 for dst in dstList:
Jon Hallc03ade92021-09-13 17:19:10 -0700266 if not hasattr( main, dst ):
267 main.log.info( "Creating component for host {}".format( dst ) )
268 main.Network.createHostComponent( dst )
269 hostHandle = getattr( main, dst )
270 if hasattr( main, 'Mininet1' ):
271 main.log.info( "Starting CLI on host {}".format( dst ) )
272 hostHandle.startHostCli()
273 else:
274 hostHandle.connectInband()
Siddesha2938fe2021-04-06 02:46:06 +0000275 hostHandle = getattr( main, dst )
276 dstIp = main.Network.getIPAddress( dst, proto='IPV6' if ipv6 else 'IPV4', iface=hostHandle.interfaces[0].get("name") )
You Wang5da39c82018-04-26 22:55:08 -0700277 # Start pings from src hosts in parallel
278 pool = []
279 for src in srcList:
280 srcIp = srcIpList[ src ]
You Wangbe98fb12018-05-24 16:15:17 -0700281 if not srcIp or not dstIp:
282 if expect:
283 unexpectedPings.append( [ src, dst, "no IP" ] )
You Wang5da39c82018-04-26 22:55:08 -0700284 continue
You Wangbe98fb12018-05-24 16:15:17 -0700285 if srcIp == dstIp:
You Wang5da39c82018-04-26 22:55:08 -0700286 continue
287 hostHandle = getattr( main, src )
288 thread = main.Thread( target=utilities.retry,
289 name="{}-{}".format( srcIp, dstIp ),
290 args=[ hostHandle.pingHostSetAlternative, [ main.FALSE ] ],
You Wangc564c6f2018-05-01 15:24:57 -0700291 kwargs={ "args": ( [ dstIp ], wait, ipv6 ),
You Wang5da39c82018-04-26 22:55:08 -0700292 "attempts": acceptableFailed + 1,
293 "sleep": 1 } )
294 pool.append( thread )
295 thread.start()
296 # Wait for threads to finish and check ping result
297 for thread in pool:
298 thread.join( 10 )
299 srcIp, dstIp = thread.name.split( "-" )
300 if expect and not thread.result or not expect and thread.result:
301 unexpectedPings.append( [ srcIp, dstIp, "fail" if expect else "pass" ] )
You Wang85747762018-05-11 15:51:50 -0700302 main.log.info( "Unexpected pings: {}".format( unexpectedPings ) )
You Wang5da39c82018-04-26 22:55:08 -0700303 if collectT3:
304 for unexpectedPing in unexpectedPings:
305 if unexpectedPing[ 2 ] == "no IP":
306 continue
307 srcIp = unexpectedPing[ 0 ]
308 dstIp = unexpectedPing[ 1 ]
309 main.log.debug( "Collecting t3 with source {} and destination {}".format( srcIp, dstIp ) )
You Wang54b1d672018-06-11 16:44:13 -0700310 cmdList = main.Cluster.active( 0 ).CLI.composeT3Command( srcIp, dstIp, ipv6, True, t3Simple )
311 if not cmdList:
312 main.log.warn( "Failed to compose T3 command with source {} and destination {}".format( srcIp, dstIp ) )
313 continue
314 for i in range( 0, len( cmdList ) ):
315 cmd = cmdList[ i ]
316 main.log.debug( "t3 command: {}".format( cmd ) )
You Wang5da39c82018-04-26 22:55:08 -0700317 main.ONOSbench.dumpONOSCmd( main.Cluster.active( 0 ).ipAddress, cmd, main.logdir,
You Wang54b1d672018-06-11 16:44:13 -0700318 "t3-CASE{}-{}-{}-route{}-".format( main.CurrentTestCaseNumber, srcIp, dstIp, i ),
Jon Hall06fd0df2021-01-25 15:50:06 -0800319 timeout=10,
320 cliPort=main.Cluster.active(0).CLI.karafPort )
You Wang5da39c82018-04-26 22:55:08 -0700321 return main.FALSE if unexpectedPings else main.TRUE
You Wangc564c6f2018-05-01 15:24:57 -0700322
323 def sendScapyPackets( self, sender, receiver, pktFilter, pkt, sIface=None, dIface=None, expect=True, acceptableFailed=0, collectT3=True, t3Command="" ):
324 """
325 Description:
You Wang2cb70172018-07-25 16:44:13 -0700326 Send Scapy packets from sender to receiver and verify if result is as expected and retry if neccessary
You Wangc564c6f2018-05-01 15:24:57 -0700327 If collectT3 is True and t3Command is specified, collect t3-troubleshoot output on unexpected scapy results
You Wangc564c6f2018-05-01 15:24:57 -0700328 Options:
329 sender: the component of the host that is sending packets
330 receiver: the component of the host that is receiving packets
331 pktFilter: packet filter used by receiver
332 pkt: keyword that is expected to be conrained in the received packets
333 expect: expect receiver to receive the packet if True, otherwise not receiving the packet
334 acceptableFailed: maximum number of unexpected scapy results acceptable
335 collectT3: save t3-troubleshoot output for unexpected scapy results
336 Returns:
337 main.TRUE if scapy result is expected, otherwise main.FALSE
You Wang2cb70172018-07-25 16:44:13 -0700338 Note: It is assumed that Scapy is already started on the destination host
You Wangc564c6f2018-05-01 15:24:57 -0700339 """
340 main.log.info( "Sending scapy packets from {} to {}, expected result is {}".format( sender.name, receiver.name,
341 "pass" if expect else "fail" ) )
You Wang2cb70172018-07-25 16:44:13 -0700342 scapyResult = utilities.retry( self.sendScapyPacketsHelper,
You Wangc564c6f2018-05-01 15:24:57 -0700343 main.FALSE,
344 args=( sender, receiver, pktFilter, pkt,
345 sIface, dIface, expect ),
346 attempts=acceptableFailed + 1,
347 sleep=1 )
348 if not scapyResult and collectT3 and t3Command:
349 main.log.debug( "Collecting t3 with source {} and destination {}".format( sender.name, receiver.name ) )
350 main.log.debug( "t3 command: {}".format( t3Command ) )
351 main.ONOSbench.dumpONOSCmd( main.Cluster.active( 0 ).ipAddress, t3Command, main.logdir,
Jon Hall06fd0df2021-01-25 15:50:06 -0800352 "t3-CASE{}-{}-{}-".format( main.CurrentTestCaseNumber, sender.name, receiver.name ),
353 cliPort=main.Cluster.active(0).CLI.karafPort )
You Wangc564c6f2018-05-01 15:24:57 -0700354 return scapyResult
355
You Wang2cb70172018-07-25 16:44:13 -0700356 def sendScapyPacketsHelper( self, sender, receiver, pktFilter, pkt, sIface=None, dIface=None, expect=True ):
You Wangc564c6f2018-05-01 15:24:57 -0700357 """
358 Description:
359 Send Scapy packets from sender to receiver and verify if result is as expected
360 Options:
361 sender: the component of the host that is sending packets
362 receiver: the component of the host that is receiving packets
363 pktFilter: packet filter used by receiver
364 pkt: keyword that is expected to be conrained in the received packets
365 expect: expect receiver to receive the packet if True, otherwise not receiving the packet
366 Returns:
367 main.TRUE if scapy result is expected, otherwise main.FALSE
368 """
You Wang3a5f74c2018-08-03 14:58:15 -0700369 started = receiver.startFilter( ifaceName=dIface, pktFilter=pktFilter )
370 if not started:
371 main.log.error("Failed to start Scapy packet filter")
372 return main.FALSE
You Wangc564c6f2018-05-01 15:24:57 -0700373 sender.sendPacket( iface=sIface )
374 finished = receiver.checkFilter()
375 packet = ""
376 if finished:
You Wang548db382020-08-12 09:17:13 -0700377 packets = receiver.readPackets( detailed=True )
You Wangc564c6f2018-05-01 15:24:57 -0700378 for packet in packets.splitlines():
379 main.log.debug( packet )
380 else:
381 kill = receiver.killFilter()
382 main.log.debug( kill )
383 sender.handle.sendline( "" )
384 sender.handle.expect( sender.scapyPrompt )
385 main.log.debug( sender.handle.before )
386 packetCaptured = True if pkt in packet else False
387 return main.TRUE if packetCaptured == expect else main.FALSE
You Wang2cb70172018-07-25 16:44:13 -0700388
389 def pingAndCapture( self, srcHost, dstIp, dstHost, dstIntf, ipv6=False, expect=True, acceptableFailed=0, collectT3=True, t3Simple=False ):
390 """
391 Description:
392 Ping from src host to dst IP and capture packets at dst Host using Scapy and retry if neccessary
393 If collectT3 is True, collect t3-troubleshoot output on unexpected scapy results
394 Options:
395 srcHost: name of the source host
396 dstIp: destination IP of the ping packets
397 dstHost: host that runs Scapy to capture the packets
398 dstIntf: name of the interface on the destination host
399 ipv6: ping with IPv6 if True; Otherwise IPv4
400 expect: use True if the ping is expected to be captured at destination;
401 Otherwise False
402 acceptableFailed: maximum number of failed pings acceptable
403 collectT3: save t3-troubleshoot output for src and dst host that failed to ping
404 t3Simple: use t3-troubleshoot-simple command when collecting t3 output
405 Returns:
406 main.TRUE if packet capturing result is expected, otherwise main.FALSE
407 Note: It is assumed that Scapy is already started on the destination host
408 """
409 main.log.info( "Pinging from {} to {}, expected {} capture the packet at {}".format( srcHost, dstIp,
410 "to" if expect else "not to", dstHost ) )
411 # Verify host component has been created
412 if not hasattr( main, srcHost ):
413 main.log.info( "Creating component for host {}".format( srcHost ) )
414 main.Network.createHostComponent( srcHost )
415 srcHandle = getattr( main, srcHost )
416 main.log.info( "Starting CLI on host {}".format( srcHost ) )
417 srcHandle.startHostCli()
418 trafficResult = utilities.retry( self.pingAndCaptureHelper,
419 main.FALSE,
420 args=( srcHost, dstIp, dstHost, dstIntf, ipv6, expect ),
421 attempts=acceptableFailed + 1,
422 sleep=1 )
423 if not trafficResult and collectT3:
424 srcIp = main.Network.getIPAddress( srcHost, proto='IPV6' if ipv6 else 'IPV4' )
425 main.log.debug( "Collecting t3 with source {} and destination {}".format( srcIp, dstIp ) )
426 cmdList = main.Cluster.active( 0 ).CLI.composeT3Command( srcIp, dstIp, ipv6, True, t3Simple )
427 if not cmdList:
428 main.log.warn( "Failed to compose T3 command with source {} and destination {}".format( srcIp, dstIp ) )
429 for i in range( 0, len( cmdList ) ):
430 cmd = cmdList[ i ]
431 main.log.debug( "t3 command: {}".format( cmd ) )
432 main.ONOSbench.dumpONOSCmd( main.Cluster.active( 0 ).ipAddress, cmd, main.logdir,
433 "t3-CASE{}-{}-{}-route{}-".format( main.CurrentTestCaseNumber, srcIp, dstIp, i ),
Jon Hall06fd0df2021-01-25 15:50:06 -0800434 timeout=10,
435 cliPort=main.Cluster.active(0).CLI.karafPort )
You Wang2cb70172018-07-25 16:44:13 -0700436 return trafficResult
437
438 def pingAndCaptureHelper( self, srcHost, dstIp, dstHost, dstIntf, ipv6=False, expect=True ):
439 """
440 Description:
441 Ping from src host to dst IP and capture packets at dst Host using Scapy
442 Options:
443 srcHost: name of the source host
444 dstIp: destination IP of the ping packets
445 dstHost: host that runs Scapy to capture the packets
446 dstIntf: name of the interface on the destination host
447 ipv6: ping with IPv6 if True; Otherwise IPv4
448 expect: use True if the ping is expected to be captured at destination;
449 Otherwise False
450 Returns:
451 main.TRUE if packet capturing result is expected, otherwise main.FALSE
452 """
453 packetCaptured = True
454 srcHandle = getattr( main, srcHost )
455 dstHandle = getattr( main, dstHost )
You Wangaec6a092018-08-06 15:36:31 -0700456 pktFilter = "ip6 host {}".format( dstIp ) if ipv6 else "ip host {}".format( dstIp )
457 started = dstHandle.startFilter( ifaceName=dstIntf, pktFilter=pktFilter )
You Wang3a5f74c2018-08-03 14:58:15 -0700458 if not started:
459 main.log.error("Failed to start Scapy packet filter")
460 return main.FALSE
You Wang2cb70172018-07-25 16:44:13 -0700461 srcHandle.pingHostSetAlternative( [ dstIp ], IPv6=ipv6 )
462 finished = dstHandle.checkFilter()
463 packet = ""
464 if finished:
You Wang548db382020-08-12 09:17:13 -0700465 packets = receiver.readPackets( detailed=True )
You Wang2cb70172018-07-25 16:44:13 -0700466 for packet in packets.splitlines():
467 main.log.debug( packet )
468 else:
469 kill = dstHandle.killFilter()
470 main.log.debug( kill )
471 packetCaptured = True if "dst={}".format( dstIp ) in packet else False
472 return main.TRUE if packetCaptured == expect else main.FALSE