blob: 88a0cad6e183ffe50cde977b2b0840f122e5b993 [file] [log] [blame]
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001"""
2 Wrapper functions for FuncIntent
3 This functions include Onosclidriver and Mininetclidriver driver functions
4 Author: kelvin@onlab.us
5"""
6import time
7import copy
8import json
9
10def __init__( self ):
11 self.default = ''
12
Jeremy Songster1f39bf02016-01-20 17:17:25 -080013def installHostIntent( main,
Jeremy2f190ca2016-01-29 15:23:57 -080014 name,
15 host1,
16 host2,
17 onosNode=0,
18 ethType="",
19 bandwidth="",
20 lambdaAlloc=False,
21 ipProto="",
22 ipAddresses="",
23 tcp="",
24 sw1="",
25 sw2=""):
kelvin-onlabd48a68c2015-07-13 16:01:36 -070026 """
Jeremy Songster1f39bf02016-01-20 17:17:25 -080027 Installs a Host Intent
28
kelvin-onlab58dc39e2015-08-06 08:11:09 -070029 Description:
Jeremy Songster1f39bf02016-01-20 17:17:25 -080030 Install a host intent using
31 add-host-intent
32
kelvin-onlab58dc39e2015-08-06 08:11:09 -070033 Steps:
Jeremy Songster1f39bf02016-01-20 17:17:25 -080034 - Fetch host data if not given
35 - Add host intent
36 - Ingress device is the first sender host
37 - Egress devices are the recipient devices
38 - Ports if defined in senders or recipients
39 - MAC address ethSrc loaded from Ingress device
40 - Check intent state with retry
kelvin-onlab58dc39e2015-08-06 08:11:09 -070041 Required:
42 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
Jeremy Songster1f39bf02016-01-20 17:17:25 -080043 host1 - Dictionary for host1
44 { "name":"h8", "id":"of:0000000000000005/8" }
45 host2 - Dictionary for host2
46 { "name":"h16", "id":"of:0000000000000006/8" }
kelvin-onlab58dc39e2015-08-06 08:11:09 -070047 Optional:
48 onosNode - ONOS node to install the intents in main.CLIs[ ]
49 0 by default so that it will always use the first
50 ONOS node
kelvin-onlab58dc39e2015-08-06 08:11:09 -070051 ethType - Ethernet type eg. IPV4, IPV6
kelvin-onlab58dc39e2015-08-06 08:11:09 -070052 bandwidth - Bandwidth capacity
53 lambdaAlloc - Allocate lambda, defaults to False
54 ipProto - IP protocol
Jeremy Songster1f39bf02016-01-20 17:17:25 -080055 tcp - TCP ports in the same order as the hosts in hostNames
56 """
57
58 assert main, "There is no main variable"
59 assert host1, "You must specify host1"
60 assert host2, "You must specify host2"
61
62 global itemName # The name of this run. Used for logs.
63 itemName = name
64 onosNode = int( onosNode )
65
66 main.log.info( itemName + ": Adding single point to multi point intents" )
Jeremyd9e4eb12016-04-13 12:09:06 -070067 try:
68 if not host1.get( "id" ):
69 main.log.warn( "ID not given for host1 {0}. Loading from main.hostData".format( host1.get( "name" ) ) )
70 main.log.debug( main.hostsData.get( host1.get( "name" ) ) )
71 host1[ "id" ] = main.hostsData.get( host1.get( "name" ) ).get( "id" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -080072
Jeremyd9e4eb12016-04-13 12:09:06 -070073 if not host2.get( "id" ):
74 main.log.warn( "ID not given for host2 {0}. Loading from main.hostData".format( host2.get( "name" ) ) )
75 host2[ "id" ] = main.hostsData.get( host2.get( "name" ) ).get( "id" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -080076
Jeremyd9e4eb12016-04-13 12:09:06 -070077 # Adding point intent
78 intentId = main.CLIs[ onosNode ].addHostIntent( hostIdOne=host1.get( "id" ),
79 hostIdTwo=host2.get( "id" ) )
80 except (KeyError, TypeError):
81 errorMsg = "There was a problem loading the hosts data."
82 if intentId:
83 errorMsg += " There was a problem installing host to host intent."
84 main.log.error( errorMsg )
85 return main.FALSE
Jeremy Songster1f39bf02016-01-20 17:17:25 -080086
87 # Check intents state
88 if utilities.retry( f=checkIntentState, retValue=main.FALSE,
89 args=( main, [ intentId ] ), sleep=main.checkIntentSleep ):
90 return intentId
91 else:
Jeremy2f190ca2016-01-29 15:23:57 -080092 main.log.error( "Host Intent did not install correctly" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -080093 return main.FALSE
94
95def testHostIntent( main,
96 name,
97 intentId,
98 host1,
99 host2,
100 onosNode=0,
101 sw1="s5",
102 sw2="s2",
103 expectedLink=0):
104 """
105 Test a Host Intent
106
107 Description:
108 Test a host intent of given ID between given hosts
109
110 Steps:
111 - Fetch host data if not given
112 - Check Intent State
113 - Check Flow State
114 - Check Connectivity
115 - Check Lack of Connectivity Between Hosts not in the Intent
116 - Reroute
117 - Take Expected Link Down
118 - Check Intent State
119 - Check Flow State
120 - Check Topology
121 - Check Connectivity
122 - Bring Expected Link Up
123 - Check Intent State
124 - Check Flow State
125 - Check Topology
126 - Check Connectivity
127 - Remove Topology
128
129 Required:
130 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
131 intentId - intent ID to be tested ( and removed )
132 host1 - Dictionary for host1
133 { "name":"h8", "id":"of:0000000000000005/8" }
134 host2 - Dictionary for host2
135 { "name":"h16", "id":"of:0000000000000006/8" }
136 Optional:
137 onosNode - ONOS node to install the intents in main.CLIs[ ]
138 0 by default so that it will always use the first
139 ONOS node
140 sw1 - First switch to bring down & up for rerouting purpose
141 sw2 - Second switch to bring down & up for rerouting purpose
142 expectedLink - Expected link when the switches are down, it should
143 be two links lower than the links before the two
144 switches are down
145
146 """
147
148 # Parameter Validity Check
149 assert main, "There is no main variable"
150 assert host1, "You must specify host1"
151 assert host2, "You must specify host2"
152
153 global itemName
154 itemName = name
155 tempHostsData = {}
156 onosNode = int( onosNode )
157
Jeremy2f190ca2016-01-29 15:23:57 -0800158 main.log.info( itemName + ": Testing Host Intent" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800159
Jeremyd9e4eb12016-04-13 12:09:06 -0700160 try:
161 if not host1.get( "id" ):
162 main.log.warn( "Id not given for host1 {0}. Loading from main.hostData".format( host1.get( "name" ) ) )
163 host1[ "id" ] = main.hostsData.get( host1.get( "name" ) ).get( "location" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800164
Jeremyd9e4eb12016-04-13 12:09:06 -0700165 if not host2.get( "id" ):
166 main.log.warn( "Id not given for host2 {0}. Loading from main.hostData".format( host2.get( "name" ) ) )
167 host2[ "id" ] = main.hostsData.get( host2.get( "name" ) ).get( "location" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800168
Jeremyd9e4eb12016-04-13 12:09:06 -0700169 senderNames = [ host1.get( "name" ), host2.get( "name" ) ]
170 recipientNames = [ host1.get( "name" ), host2.get( "name" ) ]
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800171
Jeremyd9e4eb12016-04-13 12:09:06 -0700172 testResult = main.TRUE
173 except (KeyError, TypeError):
174 main.log.error( "There was a problem loading the hosts data." )
175 return main.FALSE
176
177 main.log.info( itemName + ": Testing Host to Host intents" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800178
179 # Check intent state
180 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, [ intentId ] ), sleep=main.checkIntentSleep ):
181 main.assertReturnString += 'Initial Intent State Passed\n'
182 else:
183 main.assertReturnString += 'Initial Intent State Failed\n'
184 testResult = main.FALSE
185
186 # Check flows count in each node
Jeremy03dab012016-04-11 08:59:17 -0700187 if utilities.retry( f=checkFlowsCount, retValue=main.FALSE, args=[ main ], sleep=20, attempts=3 ) and utilities.retry( f=checkFlowsState, retValue=main.FALSE, args=[ main ], sleep=20, attempts=3 ):
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800188 main.assertReturnString += 'Initial Flow State Passed\n'
189 else:
190 main.assertReturnString += 'Intial Flow State Failed\n'
191 testResult = main.FALSE
192
193 # Check Connectivity
194 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames ) ):
195 main.assertReturnString += 'Initial Ping Passed\n'
196 else:
197 main.assertReturnString += 'Initial Ping Failed\n'
198 testResult = main.FALSE
199
200 # Test rerouting if these variables exist
201 if sw1 and sw2 and expectedLink:
202 # Take link down
203 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "down" ) ):
204 main.assertReturnString += 'Link Down Passed\n'
205 else:
206 main.assertReturnString += 'Link Down Failed\n'
207 testResult = main.FALSE
208
209 # Check intent state
210 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, [ intentId ] ), sleep=main.checkIntentSleep ):
211 main.assertReturnString += 'Link Down Intent State Passed\n'
212 else:
213 main.assertReturnString += 'Link Down Intent State Failed\n'
214 testResult = main.FALSE
215
216 # Check flows count in each node
Jeremy03dab012016-04-11 08:59:17 -0700217 if utilities.retry( f=checkFlowsCount, retValue=main.FALSE, args=[ main ], sleep=20, attempts=3 ) and utilities.retry( f=checkFlowsState, retValue=main.FALSE, args=[ main ], sleep=20, attempts=3 ):
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800218 main.assertReturnString += 'Link Down Flow State Passed\n'
219 else:
220 main.assertReturnString += 'Link Down Flow State Failed\n'
221 testResult = main.FALSE
222
223 # Check OnosTopology
224 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, expectedLink ) ):
225 main.assertReturnString += 'Link Down Topology State Passed\n'
226 else:
227 main.assertReturnString += 'Link Down Topology State Failed\n'
228 testResult = main.FALSE
229
230 # Check Connection
231 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames ) ):
232 main.assertReturnString += 'Link Down Pingall Passed\n'
233 else:
234 main.assertReturnString += 'Link Down Pingall Failed\n'
235 testResult = main.FALSE
236
237 # Bring link up
238 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "up" ) ):
239 main.assertReturnString += 'Link Up Passed\n'
240 else:
241 main.assertReturnString += 'Link Up Failed\n'
242 testResult = main.FALSE
243
244 # Wait for reroute
245 time.sleep( main.rerouteSleep )
246
247 # Check Intents
248 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, [ intentId ] ), sleep=main.checkIntentSleep ):
249 main.assertReturnString += 'Link Up Intent State Passed\n'
250 else:
251 main.assertReturnString += 'Link Up Intent State Failed\n'
252 testResult = main.FALSE
253
254 # Check flows count in each node
Jeremy03dab012016-04-11 08:59:17 -0700255 if utilities.retry( f=checkFlowsCount, retValue=main.FALSE, args=[ main ], sleep=20, attempts=3 ) and utilities.retry( f=checkFlowsState, retValue=main.FALSE, args=[ main ], sleep=20, attempts=3 ):
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800256 main.assertReturnString += 'Link Up Flow State Passed\n'
257 else:
258 main.assertReturnString += 'Link Up Flow State Failed\n'
259 testResult = main.FALSE
260
261 # Check OnosTopology
262 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, main.numLinks ) ):
263 main.assertReturnString += 'Link Up Topology State Passed\n'
264 else:
265 main.assertReturnString += 'Link Up Topology State Failed\n'
266 testResult = main.FALSE
267
268 # Check Connection
269 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames ) ):
270 main.assertReturnString += 'Link Up Pingall Passed\n'
271 else:
272 main.assertReturnString += 'Link Up Pingall Failed\n'
273 testResult = main.FALSE
274
275 # Remove all intents
276 if utilities.retry( f=removeAllIntents, retValue=main.FALSE, args=( main, [ intentId ] ) ):
277 main.assertReturnString += 'Remove Intents Passed'
278 else:
279 main.assertReturnString += 'Remove Intents Failed'
280 testResult = main.FALSE
281
282 return testResult
283
284def installPointIntent( main,
285 name,
286 senders,
287 recipients,
288 onosNode=0,
289 ethType="",
290 bandwidth="",
291 lambdaAlloc=False,
292 ipProto="",
293 ipSrc="",
294 ipDst="",
295 tcpSrc="",
296 tcpDst=""):
297 """
298 Installs a Single to Single Point Intent
299
300 Description:
301 Install a single to single point intent
302
303 Steps:
304 - Fetch host data if not given
305 - Add point intent
306 - Ingress device is the first sender device
307 - Egress device is the first recipient device
308 - Ports if defined in senders or recipients
309 - MAC address ethSrc loaded from Ingress device
310 - Check intent state with retry
311 Required:
312 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
313 senders - List of host dictionaries i.e.
314 [ { "name":"h8", "device":"of:0000000000000005/8","mac":"00:00:00:00:00:08" } ]
315 recipients - List of host dictionaries i.e.
316 [ { "name":"h16", "device":"of:0000000000000006/8", "mac":"00:00:00:00:00:10" } ]
317 Optional:
318 onosNode - ONOS node to install the intents in main.CLIs[ ]
319 0 by default so that it will always use the first
320 ONOS node
321 ethType - Ethernet type eg. IPV4, IPV6
322 bandwidth - Bandwidth capacity
323 lambdaAlloc - Allocate lambda, defaults to False
324 ipProto - IP protocol
325 tcp - TCP ports in the same order as the hosts in hostNames
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700326 sw1 - First switch to bring down & up for rerouting purpose
327 sw2 - Second switch to bring down & up for rerouting purpose
328 expectedLink - Expected link when the switches are down, it should
329 be two links lower than the links before the two
330 switches are down
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700331 """
332
333 assert main, "There is no main variable"
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800334 assert senders, "You must specify a sender"
335 assert recipients, "You must specify a recipient"
336 # Assert devices or main.hostsData, "You must specify devices"
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700337
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800338 global itemName # The name of this run. Used for logs.
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700339 itemName = name
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700340 onosNode = int( onosNode )
341
Jeremy6f000c62016-02-25 17:02:28 -0800342 main.log.info( itemName + ": Adding point to point intents" )
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700343
Jeremyd9e4eb12016-04-13 12:09:06 -0700344 try:
345 for sender in senders:
346 if not sender.get( "device" ):
347 main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
348 sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800349
Jeremyd9e4eb12016-04-13 12:09:06 -0700350 for recipient in recipients:
351 if not recipient.get( "device" ):
352 main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
353 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800354
355
Jeremyd9e4eb12016-04-13 12:09:06 -0700356 ingressDevice = senders[ 0 ].get( "device" )
357 egressDevice = recipients[ 0 ].get( "device" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800358
Jeremyd9e4eb12016-04-13 12:09:06 -0700359 portIngress = senders[ 0 ].get( "port", "" )
360 portEgress = recipients[ 0 ].get( "port", "" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800361
Jeremyd9e4eb12016-04-13 12:09:06 -0700362 dstMac = recipients[ 0 ].get( "mac" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800363
Jeremyd9e4eb12016-04-13 12:09:06 -0700364 ipSrc = senders[ 0 ].get( "ip" )
365 ipDst = recipients[ 0 ].get( "ip" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800366
Jeremyd9e4eb12016-04-13 12:09:06 -0700367 # Adding point intent
368 intentId = main.CLIs[ onosNode ].addPointIntent(
369 ingressDevice=ingressDevice,
370 egressDevice=egressDevice,
371 portIngress=portIngress,
372 portEgress=portEgress,
373 ethType=ethType,
374 ethDst=dstMac,
375 bandwidth=bandwidth,
376 lambdaAlloc=lambdaAlloc,
377 ipProto=ipProto,
378 ipSrc=ipSrc,
379 ipDst=ipDst,
380 tcpSrc=tcpSrc,
381 tcpDst=tcpDst )
382 except (KeyError, TypeError):
383 errorMsg = "There was a problem loading the hosts data."
384 if intentId:
385 errorMsg += " There was a problem installing Point to Point intent."
386 main.log.error( errorMsg )
387 return main.FALSE
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700388
389 # Check intents state
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800390 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, [ intentId ] ), sleep=main.checkIntentSleep ):
391 return intentId
acsmarsd4862d12015-10-06 17:57:34 -0700392 else:
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800393 main.log.error( "Point Intent did not install correctly" )
394 return main.FALSE
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700395
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700396def pointIntentTcp( main,
397 name,
398 host1,
399 host2,
400 onosNode=0,
401 deviceId1="",
402 deviceId2="",
403 port1="",
404 port2="",
405 ethType="",
406 mac1="",
407 mac2="",
408 bandwidth="",
409 lambdaAlloc=False,
410 ipProto="",
411 ip1="",
412 ip2="",
413 tcp1="",
414 tcp2="",
415 sw1="",
416 sw2="",
417 expectedLink=0 ):
418
419 """
420 Description:
421 Verify add-point-intent only for TCP
422 Steps:
423 - Get device ids | ports
424 - Add point intents
425 - Check intents
426 - Verify flows
427 - Ping hosts
428 - Reroute
429 - Link down
430 - Verify flows
431 - Check topology
432 - Ping hosts
433 - Link up
434 - Verify flows
435 - Check topology
436 - Ping hosts
437 - Remove intents
438 Required:
439 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
440 host1 - Name of first host
441 host2 - Name of second host
442 Optional:
443 onosNode - ONOS node to install the intents in main.CLIs[ ]
444 0 by default so that it will always use the first
445 ONOS node
446 deviceId1 - ONOS device id of the first switch, the same as the
447 location of the first host eg. of:0000000000000001/1,
448 located at device 1 port 1
449 deviceId2 - ONOS device id of the second switch
450 port1 - The port number where the first host is attached
451 port2 - The port number where the second host is attached
452 ethType - Ethernet type eg. IPV4, IPV6
453 mac1 - Mac address of first host
454 mac2 - Mac address of the second host
455 bandwidth - Bandwidth capacity
456 lambdaAlloc - Allocate lambda, defaults to False
457 ipProto - IP protocol
458 ip1 - IP address of first host
459 ip2 - IP address of second host
460 tcp1 - TCP port of first host
461 tcp2 - TCP port of second host
462 sw1 - First switch to bring down & up for rerouting purpose
463 sw2 - Second switch to bring down & up for rerouting purpose
464 expectedLink - Expected link when the switches are down, it should
465 be two links lower than the links before the two
466 switches are down
467 """
468
469 assert main, "There is no main variable"
470 assert name, "variable name is empty"
471 assert host1 and host2, "You must specify hosts"
472
473 global itemName
474 itemName = name
475 host1 = host1
476 host2 = host2
477 hostNames = [ host1, host2 ]
478 intentsId = []
479
480 iperfResult = main.TRUE
481 intentResult = main.TRUE
482 removeIntentResult = main.TRUE
483 flowResult = main.TRUE
484 topoResult = main.TRUE
485 linkDownResult = main.TRUE
486 linkUpResult = main.TRUE
487 onosNode = int( onosNode )
488
489 # Adding bidirectional point intents
490 main.log.info( itemName + ": Adding point intents" )
491 intent1 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
492 egressDevice=deviceId2,
493 portIngress=port1,
494 portEgress=port2,
495 ethType=ethType,
496 ethSrc=mac1,
497 ethDst=mac2,
498 bandwidth=bandwidth,
499 lambdaAlloc=lambdaAlloc,
500 ipProto=ipProto,
501 ipSrc=ip1,
502 ipDst=ip2,
503 tcpSrc=tcp1,
504 tcpDst="" )
505
506 intent2 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
507 egressDevice=deviceId1,
508 portIngress=port2,
509 portEgress=port1,
510 ethType=ethType,
511 ethSrc=mac2,
512 ethDst=mac1,
513 bandwidth=bandwidth,
514 lambdaAlloc=lambdaAlloc,
515 ipProto=ipProto,
516 ipSrc=ip2,
517 ipDst=ip1,
518 tcpSrc=tcp2,
519 tcpDst="" )
520
521 intent3 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
522 egressDevice=deviceId2,
523 portIngress=port1,
524 portEgress=port2,
525 ethType=ethType,
526 ethSrc=mac1,
527 ethDst=mac2,
528 bandwidth=bandwidth,
529 lambdaAlloc=lambdaAlloc,
530 ipProto=ipProto,
531 ipSrc=ip1,
532 ipDst=ip2,
533 tcpSrc="",
534 tcpDst=tcp2 )
535
536 intent4 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
537 egressDevice=deviceId1,
538 portIngress=port2,
539 portEgress=port1,
540 ethType=ethType,
541 ethSrc=mac2,
542 ethDst=mac1,
543 bandwidth=bandwidth,
544 lambdaAlloc=lambdaAlloc,
545 ipProto=ipProto,
546 ipSrc=ip2,
547 ipDst=ip1,
548 tcpSrc="",
549 tcpDst=tcp1 )
550 intentsId.append( intent1 )
551 intentsId.append( intent2 )
552 intentsId.append( intent3 )
553 intentsId.append( intent4 )
554
555 # Check intents state
556 time.sleep( main.checkIntentSleep )
557 intentResult = checkIntentState( main, intentsId )
558 # Check flows count in each node
559 checkFlowsCount( main )
560
561 # Check intents state again if first check fails...
562 if not intentResult:
563 intentResult = checkIntentState( main, intentsId )
564
565 # Check flows count in each node
566 checkFlowsCount( main )
567
568 # Verify flows
569 checkFlowsState( main )
570
571 # Run iperf to both host
acsmarsd4862d12015-10-06 17:57:34 -0700572 iperfTemp = main.Mininet1.iperftcp( host1,host2,10 )
573 iperfResult = iperfResult and iperfTemp
574 if iperfTemp:
575 main.assertReturnString += 'Initial Iperf Passed\n'
576 else:
577 main.assertReturnString += 'Initial Iperf Failed\n'
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700578
579 # Test rerouting if these variables exist
580 if sw1 and sw2 and expectedLink:
581 # link down
582 linkDownResult = link( main, sw1, sw2, "down" )
acsmarsd4862d12015-10-06 17:57:34 -0700583
584 if linkDownResult:
585 main.assertReturnString += 'Link Down Passed\n'
586 else:
587 main.assertReturnString += 'Link Down Failed\n'
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700588
589 # Check flows count in each node
590 checkFlowsCount( main )
591 # Verify flows
592 checkFlowsState( main )
593
594 # Check OnosTopology
595 topoResult = checkTopology( main, expectedLink )
acsmarsd4862d12015-10-06 17:57:34 -0700596 if topoResult:
597 main.assertReturnString += 'Link Down Topology State Passed\n'
598 else:
599 main.assertReturnString += 'Link Down Topology State Failed\n'
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700600
601 # Run iperf to both host
acsmarsd4862d12015-10-06 17:57:34 -0700602 iperfTemp = main.Mininet1.iperftcp( host1,host2,10 )
603 iperfResult = iperfResult and iperfTemp
604 if iperfTemp:
605 main.assertReturnString += 'Link Down Iperf Passed\n'
606 else:
607 main.assertReturnString += 'Link Down Iperf Failed\n'
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700608
acsmarsd4862d12015-10-06 17:57:34 -0700609 # Check intent state
610 intentTemp = checkIntentState( main, intentsId )
611 intentResult = intentResult and intentTemp
612 if intentTemp:
613 main.assertReturnString += 'Link Down Intent State Passed\n'
614 else:
615 main.assertReturnString += 'Link Down Intent State Failed\n'
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700616
617 # Checks ONOS state in link down
618 if linkDownResult and topoResult and iperfResult and intentResult:
619 main.log.info( itemName + ": Successfully brought link down" )
620 else:
621 main.log.error( itemName + ": Failed to bring link down" )
622
623 # link up
624 linkUpResult = link( main, sw1, sw2, "up" )
acsmarsd4862d12015-10-06 17:57:34 -0700625 if linkUpTemp:
626 main.assertReturnString += 'Link Up Passed\n'
627 else:
628 main.assertReturnString += 'Link Up Failed\n'
629
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700630 time.sleep( main.rerouteSleep )
631
632 # Check flows count in each node
633 checkFlowsCount( main )
634 # Verify flows
635 checkFlowsState( main )
636
637 # Check OnosTopology
638 topoResult = checkTopology( main, main.numLinks )
639
acsmarsd4862d12015-10-06 17:57:34 -0700640 if topoResult:
641 main.assertReturnString += 'Link Up Topology State Passed\n'
642 else:
643 main.assertReturnString += 'Link Up Topology State Failed\n'
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700644
acsmarsd4862d12015-10-06 17:57:34 -0700645 # Run iperf to both host
646 iperfTemp = main.Mininet1.iperftcp( host1,host2,10 )
647 iperfResult = iperfResult and iperfTemp
648 if iperfTemp:
649 main.assertReturnString += 'Link Up Iperf Passed\n'
650 else:
651 main.assertReturnString += 'Link Up Iperf Failed\n'
652
653 # Check intent state
654 intentTemp = checkIntentState( main, intentsId )
655 intentResult = intentResult and intentTemp
656 if intentTemp:
657 main.assertReturnString += 'Link Down Intent State Passed\n'
658 else:
659 main.assertReturnString += 'Link Down Intent State Failed\n'
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700660
661 # Checks ONOS state in link up
662 if linkUpResult and topoResult and iperfResult and intentResult:
663 main.log.info( itemName + ": Successfully brought link back up" )
664 else:
665 main.log.error( itemName + ": Failed to bring link back up" )
666
667 # Remove all intents
668 removeIntentResult = removeAllIntents( main, intentsId )
acsmarsd4862d12015-10-06 17:57:34 -0700669 if removeIntentResult:
670 main.assertReturnString += 'Remove Intents Passed'
671 else:
672 main.assertReturnString += 'Remove Intents Failed'
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700673
674 stepResult = iperfResult and linkDownResult and linkUpResult \
675 and intentResult and removeIntentResult
676
677 return stepResult
678
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800679def installSingleToMultiIntent( main,
680 name,
681 senders,
682 recipients,
683 onosNode=0,
684 ethType="",
685 bandwidth="",
686 lambdaAlloc=False,
687 ipProto="",
688 ipAddresses="",
689 tcp="",
690 sw1="",
691 sw2=""):
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700692 """
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800693 Installs a Single to Multi Point Intent
694
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700695 Description:
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800696 Install a single to multi point intent using
697 add-single-to-multi-intent
698
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700699 Steps:
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800700 - Fetch host data if not given
701 - Add single to multi intent
702 - Ingress device is the first sender host
703 - Egress devices are the recipient devices
704 - Ports if defined in senders or recipients
705 - MAC address ethSrc loaded from Ingress device
706 - Check intent state with retry
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700707 Required:
708 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800709 senders - List of host dictionaries i.e.
710 { "name":"h8", "device":"of:0000000000000005/8","mac":"00:00:00:00:00:08" }
711 recipients - List of host dictionaries i.e.
712 { "name":"h16", "device":"of:0000000000000006/8", "mac":"00:00:00:00:00:10" }
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700713 Optional:
714 onosNode - ONOS node to install the intents in main.CLIs[ ]
715 0 by default so that it will always use the first
716 ONOS node
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700717 ethType - Ethernet type eg. IPV4, IPV6
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700718 bandwidth - Bandwidth capacity
719 lambdaAlloc - Allocate lambda, defaults to False
720 ipProto - IP protocol
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700721 tcp - TCP ports in the same order as the hosts in hostNames
722 sw1 - First switch to bring down & up for rerouting purpose
723 sw2 - Second switch to bring down & up for rerouting purpose
724 expectedLink - Expected link when the switches are down, it should
725 be two links lower than the links before the two
726 switches are down
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700727 """
728
729 assert main, "There is no main variable"
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800730 assert senders, "You must specify a sender"
731 assert recipients, "You must specify a recipient"
732 # Assert devices or main.hostsData, "You must specify devices"
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700733
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800734 global itemName # The name of this run. Used for logs.
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700735 itemName = name
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700736 onosNode = int( onosNode )
737
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700738 main.log.info( itemName + ": Adding single point to multi point intents" )
739
Jeremyd9e4eb12016-04-13 12:09:06 -0700740 try:
741 for sender in senders:
742 if not sender.get( "device" ):
743 main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
744 sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700745
Jeremyd9e4eb12016-04-13 12:09:06 -0700746 for recipient in recipients:
747 if not recipient.get( "device" ):
748 main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
749 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700750
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700751
Jeremyd9e4eb12016-04-13 12:09:06 -0700752 ingressDevice = senders[ 0 ].get( "device" )
753 egressDeviceList = [ x.get( "device" ) for x in recipients if x.get( "device" ) ]
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800754
Jeremyd9e4eb12016-04-13 12:09:06 -0700755 portIngress = senders[ 0 ].get( "port", "" )
756 portEgressList = [ x.get( "port" ) for x in recipients if x.get( "port" ) ]
757 if not portEgressList:
758 portEgressList = None
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800759
Jeremyd9e4eb12016-04-13 12:09:06 -0700760 srcMac = senders[ 0 ].get( "mac" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800761
Jeremyd9e4eb12016-04-13 12:09:06 -0700762 # Adding point intent
763 intentId = main.CLIs[ onosNode ].addSinglepointToMultipointIntent(
764 ingressDevice=ingressDevice,
765 egressDeviceList=egressDeviceList,
766 portIngress=portIngress,
767 portEgressList=portEgressList,
768 ethType=ethType,
769 ethSrc=srcMac,
770 bandwidth=bandwidth,
771 lambdaAlloc=lambdaAlloc,
772 ipProto=ipProto,
773 ipSrc="",
774 ipDst="",
775 tcpSrc="",
776 tcpDst="" )
777 except (KeyError, TypeError):
778 errorMsg = "There was a problem loading the hosts data."
779 if intentId:
780 errorMsg += " There was a problem installing Singlepoint to Multipoint intent."
781 main.log.error( errorMsg )
782 return main.FALSE
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700783
784 # Check intents state
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800785 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, [ intentId ] ), sleep=main.checkIntentSleep ):
786 return intentId
acsmarsd4862d12015-10-06 17:57:34 -0700787 else:
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800788 main.log.error( "Single to Multi Intent did not install correctly" )
789 return main.FALSE
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700790
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800791def installMultiToSingleIntent( main,
792 name,
793 senders,
794 recipients,
795 onosNode=0,
796 ethType="",
797 bandwidth="",
798 lambdaAlloc=False,
799 ipProto="",
800 ipAddresses="",
801 tcp="",
802 sw1="",
803 sw2=""):
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700804 """
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800805 Installs a Multi to Single Point Intent
806
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700807 Description:
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800808 Install a multi to single point intent using
809 add-multi-to-single-intent
810
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700811 Steps:
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800812 - Fetch host data if not given
813 - Add multi to single intent
814 - Ingress devices are the senders devices
815 - Egress device is the first recipient host
816 - Ports if defined in senders or recipients
817 - MAC address ethSrc loaded from Ingress device
818 - Check intent state with retry
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700819 Required:
820 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800821 senders - List of host dictionaries i.e.
822 [ { "name":"h8", "device":"of:0000000000000005/8","mac":"00:00:00:00:00:08" } ]
823 recipients - List of host dictionaries i.e.
824 [ { "name":"h16", "device":"of:0000000000000006/8", "mac":"00:00:00:00:00:10" } ]
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700825 Optional:
826 onosNode - ONOS node to install the intents in main.CLIs[ ]
827 0 by default so that it will always use the first
828 ONOS node
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700829 ethType - Ethernet type eg. IPV4, IPV6
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700830 bandwidth - Bandwidth capacity
831 lambdaAlloc - Allocate lambda, defaults to False
832 ipProto - IP protocol
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700833 tcp - TCP ports in the same order as the hosts in hostNames
834 sw1 - First switch to bring down & up for rerouting purpose
835 sw2 - Second switch to bring down & up for rerouting purpose
836 expectedLink - Expected link when the switches are down, it should
837 be two links lower than the links before the two
838 switches are down
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700839 """
840
841 assert main, "There is no main variable"
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800842 assert senders, "You must specify a sender"
843 assert recipients, "You must specify a recipient"
844 # Assert devices or main.hostsData, "You must specify devices"
845
846 global itemName # The name of this run. Used for logs.
847 itemName = name
848 onosNode = int( onosNode )
849
850 main.log.info( itemName + ": Adding mutli to single point intents" )
851
Jeremyd9e4eb12016-04-13 12:09:06 -0700852 try:
853 for sender in senders:
854 if not sender.get( "device" ):
855 main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
856 sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800857
Jeremyd9e4eb12016-04-13 12:09:06 -0700858 for recipient in recipients:
859 if not recipient.get( "device" ):
860 main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
861 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800862
Jeremyd9e4eb12016-04-13 12:09:06 -0700863 ingressDeviceList = [ x.get( "device" ) for x in senders if x.get( "device" ) ]
864 egressDevice = recipients[ 0 ].get( "device" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800865
Jeremyd9e4eb12016-04-13 12:09:06 -0700866 portIngressList = [ x.get( "port" ) for x in senders if x.get( "port" ) ]
867 portEgress = recipients[ 0 ].get( "port", "" )
868 if not portIngressList:
869 portIngressList = None
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800870
Jeremyd9e4eb12016-04-13 12:09:06 -0700871 dstMac = recipients[ 0 ].get( "mac" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800872
Jeremyd9e4eb12016-04-13 12:09:06 -0700873 # Adding point intent
874 intentId = main.CLIs[ onosNode ].addMultipointToSinglepointIntent(
875 ingressDeviceList=ingressDeviceList,
876 egressDevice=egressDevice,
877 portIngressList=portIngressList,
878 portEgress=portEgress,
879 ethType=ethType,
880 ethDst=dstMac,
881 bandwidth=bandwidth,
882 lambdaAlloc=lambdaAlloc,
883 ipProto=ipProto,
884 ipSrc="",
885 ipDst="",
886 tcpSrc="",
887 tcpDst="" )
888 except (KeyError, TypeError):
889 errorMsg = "There was a problem loading the hosts data."
890 if intentId:
891 errorMsg += " There was a problem installing Multipoint to Singlepoint intent."
892 main.log.error( errorMsg )
893 return main.FALSE
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800894
895 # Check intents state
896 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, [ intentId ] ), sleep=main.checkIntentSleep ):
897 return intentId
898 else:
899 main.log.error( "Multi to Single Intent did not install correctly" )
900 return main.FALSE
901
902def testPointIntent( main,
Jeremye0cb5eb2016-01-27 17:39:09 -0800903 name,
904 intentId,
905 senders,
906 recipients,
907 badSenders={},
908 badRecipients={},
909 onosNode=0,
910 ethType="",
911 bandwidth="",
912 lambdaAlloc=False,
913 ipProto="",
914 ipAddresses="",
915 tcp="",
916 sw1="s5",
917 sw2="s2",
918 expectedLink=0):
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800919 """
920 Test a Point Intent
921
922 Description:
923 Test a point intent
924
925 Steps:
926 - Fetch host data if not given
927 - Check Intent State
928 - Check Flow State
929 - Check Connectivity
930 - Check Lack of Connectivity Between Hosts not in the Intent
931 - Reroute
932 - Take Expected Link Down
933 - Check Intent State
934 - Check Flow State
935 - Check Topology
936 - Check Connectivity
937 - Bring Expected Link Up
938 - Check Intent State
939 - Check Flow State
940 - Check Topology
941 - Check Connectivity
942 - Remove Topology
943
944 Required:
945 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
946
947 senders - List of host dictionaries i.e.
948 { "name":"h8", "device":"of:0000000000000005/8","mac":"00:00:00:00:00:08" }
949 recipients - List of host dictionaries i.e.
950 { "name":"h16", "device":"of:0000000000000006/8", "mac":"00:00:00:00:00:10" }
951 Optional:
952 onosNode - ONOS node to install the intents in main.CLIs[ ]
953 0 by default so that it will always use the first
954 ONOS node
955 ethType - Ethernet type eg. IPV4, IPV6
956 bandwidth - Bandwidth capacity
957 lambdaAlloc - Allocate lambda, defaults to False
958 ipProto - IP protocol
959 tcp - TCP ports in the same order as the hosts in hostNames
960 sw1 - First switch to bring down & up for rerouting purpose
961 sw2 - Second switch to bring down & up for rerouting purpose
962 expectedLink - Expected link when the switches are down, it should
963 be two links lower than the links before the two
964 switches are down
965
966 """
967
968 # Parameter Validity Check
969 assert main, "There is no main variable"
970 assert senders, "You must specify a sender"
971 assert recipients, "You must specify a recipient"
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700972
973 global itemName
974 itemName = name
975 tempHostsData = {}
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700976 onosNode = int( onosNode )
977
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800978 main.log.info( itemName + ": Testing Point Intent" )
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700979
Jeremyd9e4eb12016-04-13 12:09:06 -0700980 try:
981 # Names for scapy
982 senderNames = [ x.get( "name" ) for x in senders ]
983 recipientNames = [ x.get( "name" ) for x in recipients ]
984 badSenderNames = [ x.get( "name" ) for x in badSenders ]
985 badRecipientNames = [ x.get( "name" ) for x in badRecipients ]
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700986
Jeremyd9e4eb12016-04-13 12:09:06 -0700987 for sender in senders:
988 if not sender.get( "device" ):
989 main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
990 sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700991
Jeremyd9e4eb12016-04-13 12:09:06 -0700992 for recipient in recipients:
993 if not recipient.get( "device" ):
994 main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
995 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
996 except (KeyError, TypeError):
997 main.log.error( "There was a problem loading the hosts data." )
998 return main.FALSE
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700999
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001000 testResult = main.TRUE
1001 main.log.info( itemName + ": Adding single point to multi point intents" )
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001002
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001003 # Check intent state
1004 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, [ intentId ] ), sleep=main.checkIntentSleep ):
1005 main.assertReturnString += 'Initial Intent State Passed\n'
acsmarsd4862d12015-10-06 17:57:34 -07001006 else:
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001007 main.assertReturnString += 'Initial Intent State Failed\n'
1008 testResult = main.FALSE
1009
1010 # Check flows count in each node
Jeremy03dab012016-04-11 08:59:17 -07001011 if utilities.retry( f=checkFlowsCount, retValue=main.FALSE, args=[ main ], sleep=20, attempts=3 ) and utilities.retry( f=checkFlowsState, retValue=main.FALSE, args=[ main ], sleep=20, attempts=3 ):
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001012 main.assertReturnString += 'Initial Flow State Passed\n'
1013 else:
1014 main.assertReturnString += 'Intial Flow State Failed\n'
1015 testResult = main.FALSE
1016
1017 # Check Connectivity
Jeremy Songster5c3fdb42016-04-27 12:19:27 -07001018 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames ), attempts=3, sleep=5 ):
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001019 main.assertReturnString += 'Initial Ping Passed\n'
1020 else:
1021 main.assertReturnString += 'Initial Ping Failed\n'
1022 testResult = main.FALSE
1023
1024 # Check connections that shouldn't work
1025 if badSenderNames:
1026 main.log.info( "Checking that packets from incorrect sender do not go through" )
1027 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, badSenderNames, recipientNames ), kwargs={ "expectFailure":True } ):
1028 main.assertReturnString += 'Bad Sender Ping Passed\n'
1029 else:
1030 main.assertReturnString += 'Bad Sender Ping Failed\n'
1031 testResult = main.FALSE
1032
1033 if badRecipientNames:
1034 main.log.info( "Checking that packets to incorrect recipients do not go through" )
1035 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, badRecipientNames ), kwargs={ "expectFailure":True } ):
1036 main.assertReturnString += 'Bad Recipient Ping Passed\n'
1037 else:
1038 main.assertReturnString += 'Bad Recipient Ping Failed\n'
1039 testResult = main.FALSE
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001040
1041 # Test rerouting if these variables exist
1042 if sw1 and sw2 and expectedLink:
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001043 # Take link down
1044 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "down" ) ):
acsmarsd4862d12015-10-06 17:57:34 -07001045 main.assertReturnString += 'Link Down Passed\n'
1046 else:
1047 main.assertReturnString += 'Link Down Failed\n'
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001048 testResult = main.FALSE
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001049
acsmarsd4862d12015-10-06 17:57:34 -07001050 # Check intent state
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001051 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, [ intentId ] ), sleep=main.checkIntentSleep ):
acsmarsd4862d12015-10-06 17:57:34 -07001052 main.assertReturnString += 'Link Down Intent State Passed\n'
1053 else:
1054 main.assertReturnString += 'Link Down Intent State Failed\n'
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001055 testResult = main.FALSE
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001056
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001057 # Check flows count in each node
Jeremy03dab012016-04-11 08:59:17 -07001058 if utilities.retry( f=checkFlowsCount, retValue=main.FALSE, args=[ main ], sleep=20, attempts=3 ) and utilities.retry( f=checkFlowsState, retValue=main.FALSE, args=[ main ], sleep=20, attempts=3 ):
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001059 main.assertReturnString += 'Link Down Flow State Passed\n'
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001060 else:
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001061 main.assertReturnString += 'Link Down Flow State Failed\n'
1062 testResult = main.FALSE
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001063
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001064 # Check OnosTopology
1065 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, expectedLink ) ):
1066 main.assertReturnString += 'Link Down Topology State Passed\n'
1067 else:
1068 main.assertReturnString += 'Link Down Topology State Failed\n'
1069 testResult = main.FALSE
1070
1071 # Check Connection
1072 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames ) ):
1073 main.assertReturnString += 'Link Down Pingall Passed\n'
1074 else:
1075 main.assertReturnString += 'Link Down Pingall Failed\n'
1076 testResult = main.FALSE
1077
1078 # Bring link up
1079 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "up" ) ):
acsmarsd4862d12015-10-06 17:57:34 -07001080 main.assertReturnString += 'Link Up Passed\n'
1081 else:
1082 main.assertReturnString += 'Link Up Failed\n'
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001083 testResult = main.FALSE
acsmarsd4862d12015-10-06 17:57:34 -07001084
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001085 # Wait for reroute
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001086 time.sleep( main.rerouteSleep )
1087
acsmarsd4862d12015-10-06 17:57:34 -07001088 # Check Intents
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001089 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, [ intentId ] ), sleep=main.checkIntentSleep ):
acsmarsd4862d12015-10-06 17:57:34 -07001090 main.assertReturnString += 'Link Up Intent State Passed\n'
1091 else:
1092 main.assertReturnString += 'Link Up Intent State Failed\n'
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001093 testResult = main.FALSE
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001094
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001095 # Check flows count in each node
Jeremy03dab012016-04-11 08:59:17 -07001096 if utilities.retry( f=checkFlowsCount, retValue=main.FALSE, args=[ main ], sleep=20, attempts=3 ) and utilities.retry( f=checkFlowsState, retValue=main.FALSE, args=[ main ], sleep=20, attempts=3 ):
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001097 main.assertReturnString += 'Link Up Flow State Passed\n'
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001098 else:
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001099 main.assertReturnString += 'Link Up Flow State Failed\n'
1100 testResult = main.FALSE
1101
1102 # Check OnosTopology
1103 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, main.numLinks ) ):
1104 main.assertReturnString += 'Link Up Topology State Passed\n'
1105 else:
1106 main.assertReturnString += 'Link Up Topology State Failed\n'
1107 testResult = main.FALSE
1108
1109 # Check Connection
1110 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames ) ):
1111 main.assertReturnString += 'Link Up Scapy Packet Received Passed\n'
1112 else:
1113 main.assertReturnString += 'Link Up Scapy Packet Recieved Failed\n'
1114 testResult = main.FALSE
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001115
1116 # Remove all intents
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001117 if utilities.retry( f=removeAllIntents, retValue=main.FALSE, args=( main, [ intentId ] ) ):
acsmarsd4862d12015-10-06 17:57:34 -07001118 main.assertReturnString += 'Remove Intents Passed'
1119 else:
1120 main.assertReturnString += 'Remove Intents Failed'
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001121 testResult = main.FALSE
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001122
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001123 return testResult
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001124
Jeremye0cb5eb2016-01-27 17:39:09 -08001125def testEndPointFail( main,
1126 name,
1127 intentId,
1128 senders,
1129 recipients,
1130 isolatedSenders,
1131 isolatedRecipients,
1132 onosNode=0,
1133 ethType="",
1134 bandwidth="",
1135 lambdaAlloc=False,
1136 ipProto="",
1137 ipAddresses="",
1138 tcp="",
1139 sw1="",
1140 sw2="",
1141 sw3="",
1142 sw4="",
1143 sw5="",
1144 expectedLink1=0,
1145 expectedLink2=0 ):
1146 """
1147 Test Single to Multipoint Topology for Endpoint failures
1148 """
1149
1150 # Parameter Validity Check
1151 assert main, "There is no main variable"
1152 assert senders, "You must specify a sender"
1153 assert recipients, "You must specify a recipient"
1154
1155 global itemName
1156 itemName = name
1157 tempHostsData = {}
1158 onosNode = int( onosNode )
1159
1160 main.log.info( itemName + ": Testing Point Intent" )
1161
Jeremyd9e4eb12016-04-13 12:09:06 -07001162 try:
1163 # Names for scapy
1164 senderNames = [ x.get( "name" ) for x in senders ]
1165 recipientNames = [ x.get( "name" ) for x in recipients ]
1166 isolatedSenderNames = [ x.get( "name" ) for x in isolatedSenders ]
1167 isolatedRecipientNames = [ x.get( "name" ) for x in isolatedRecipients ]
1168 connectedSenderNames = [x.get("name") for x in senders if x.get("name") not in isolatedSenderNames]
1169 connectedRecipientNames = [x.get("name") for x in recipients if x.get("name") not in isolatedRecipientNames]
Jeremye0cb5eb2016-01-27 17:39:09 -08001170
Jeremyd9e4eb12016-04-13 12:09:06 -07001171 for sender in senders:
1172 if not sender.get( "device" ):
1173 main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
1174 sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )
Jeremye0cb5eb2016-01-27 17:39:09 -08001175
Jeremyd9e4eb12016-04-13 12:09:06 -07001176 for recipient in recipients:
1177 if not recipient.get( "device" ):
1178 main.log.warn( "Device not given for recipient {0}. Loading from\
1179 main.hostData".format( recipient.get( "name" ) ) )
1180 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
1181 except (KeyError, TypeError):
1182 main.log.error( "There was a problem loading the hosts data." )
1183 return main.FALSE
Jeremye0cb5eb2016-01-27 17:39:09 -08001184
1185 testResult = main.TRUE
1186 main.log.info( itemName + ": Adding multi point to single point intents" )
1187
1188 # Check intent state
1189 if utilities.retry( f=checkIntentState, retValue=main.FALSE,
1190 args=( main, [ intentId ] ), sleep=main.checkIntentSleep ):
1191 main.assertReturnString += 'Initial Intent State Passed\n'
1192 else:
1193 main.assertReturnString += 'Initial Intent State Failed\n'
1194 testResult = main.FALSE
1195
1196 # Check flows count in each node
1197 if utilities.retry( f=checkFlowsCount, retValue=main.FALSE,
1198 args=[ main ] ) and utilities.retry( f=checkFlowsState,
1199 retValue=main.FALSE,
1200 args=[ main ] ):
1201 main.assertReturnString += 'Initial Flow State Passed\n'
1202 else:
1203 main.assertReturnString += 'Intial Flow State Failed\n'
1204 testResult = main.FALSE
1205
1206 # Check Connectivity
1207 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE,
1208 args=( main, senderNames, recipientNames ) ):
1209 main.assertReturnString += 'Initial Connectivity Check Passed\n'
1210 else:
1211 main.assertReturnString += 'Initial Connectivity Check Failed\n'
1212 testResult = main.FALSE
1213
1214 # Take two links down
1215 # Take first link down
1216 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "down" ) ):
1217 main.assertReturnString += 'Link Down Passed\n'
1218 else:
1219 main.assertReturnString += 'Link Down Failed\n'
1220 testResult = main.FALSE
1221
1222 # Take second link down
1223 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw3, sw4, "down" ) ):
1224 main.assertReturnString += 'Link Down Passed\n'
1225 else:
1226 main.assertReturnString += 'Link Down Failed\n'
1227 testResult = main.FALSE
1228
1229 # Check intent state
1230 if utilities.retry( f=checkIntentState, retValue=main.FALSE,
1231 args=( main, [ intentId ] ), sleep=main.checkIntentSleep ):
1232 main.assertReturnString += 'Link Down Intent State Passed\n'
1233 else:
1234 main.assertReturnString += 'Link Down Intent State Failed\n'
1235 testResult = main.FALSE
1236
1237 # Check flows count in each node
1238 if utilities.retry( f=checkFlowsCount, retValue=main.FALSE,
1239 args=[ main ] ) and utilities.retry( f=checkFlowsState,
1240 retValue=main.FALSE, args=[ main ] ):
1241 main.assertReturnString += 'Link Down Flow State Passed\n'
1242 else:
1243 main.assertReturnString += 'Link Down Flow State Failed\n'
1244 testResult = main.FALSE
1245
1246 # Check OnosTopology
1247 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, expectedLink1 ) ):
1248 main.assertReturnString += 'Link Down Topology State Passed\n'
1249 else:
1250 main.assertReturnString += 'Link Down Topology State Failed\n'
1251 testResult = main.FALSE
1252
1253 # Check Connection
1254 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE,
1255 args=( main, senderNames, recipientNames ) ):
1256 main.assertReturnString += 'Link Down Connectivity Check Passed\n'
1257 else:
1258 main.assertReturnString += 'Link Down Connectivity Check Failed\n'
1259 testResult = main.FALSE
1260
1261 # Take a third link down to isolate one node
1262 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw3, sw5, "down" ) ):
1263 main.assertReturnString += 'Isolation link Down Passed\n'
1264 else:
1265 main.assertReturnString += 'Isolation link Down Failed\n'
1266 testResult = main.FALSE
1267
1268 # Check intent state
1269 if utilities.retry( f=checkIntentState, retValue=main.FALSE,
1270 args=( main, [ intentId ] ), sleep=main.checkIntentSleep ):
1271 main.assertReturnString += 'Isolation link Down Intent State Passed\n'
1272 else:
1273 main.assertReturnString += 'Isolation link Down Intent State Failed\n'
1274 testResult = main.FALSE
1275
1276 # Check flows count in each node
1277 if utilities.retry( f=checkFlowsCount, retValue=main.FALSE,
1278 args=[ main ] ) and utilities.retry( f=checkFlowsState,
1279 retValue=main.FALSE, args=[ main ] ):
1280 main.assertReturnString += 'Isolation link Down Flow State Passed\n'
1281 else:
1282 main.assertReturnString += 'Isolation link Down Flow State Failed\n'
1283 testResult = main.FALSE
1284
1285 # Check OnosTopology
1286 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, expectedLink2 ) ):
1287 main.assertReturnString += 'Isolation link Down Topology State Passed\n'
1288 else:
1289 main.assertReturnString += 'Isolation link Down Topology State Failed\n'
1290 testResult = main.FALSE
1291
1292 # Check Connectivity
1293 # First check connectivity of any isolated senders to recipients
1294 if isolatedSenderNames:
1295 if scapyCheckConnection( main, isolatedSenderNames, recipientNames, None, None, main.TRUE ):
1296 main.assertReturnString += 'Isolation link Down Connectivity Check Passed\n'
1297 else:
1298 main.assertReturnString += 'Isolation link Down Connectivity Check Failed\n'
1299 testResult = main.FALSE
1300
1301 # Next check connectivity of senders to any isolated recipients
1302 if isolatedRecipientNames:
1303 if scapyCheckConnection( main, senderNames, isolatedRecipientNames, None, None, main.TRUE ):
1304 main.assertReturnString += 'Isolation link Down Connectivity Check Passed\n'
1305 else:
1306 main.assertReturnString += 'Isolation link Down Connectivity Check Failed\n'
1307 testResult = main.FALSE
1308
1309 # Next check connectivity of connected senders and recipients
1310 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE,
1311 args=( main, connectedSenderNames , connectedRecipientNames ) ):
1312 main.assertReturnString += 'Isolation link Down Connectivity Check Passed\n'
1313 else:
1314 main.assertReturnString += 'Isolation link Down Connectivity Check Failed\n'
1315 testResult = main.FALSE
1316
1317 # Bring the links back up
1318 # Bring first link up
1319 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "up" ) ):
1320 main.assertReturnString += 'Link Up Passed\n'
1321 else:
1322 main.assertReturnString += 'Link Up Failed\n'
1323 testResult = main.FALSE
1324
1325 # Bring second link up
1326 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw3, sw5, "up" ) ):
1327 main.assertReturnString += 'Link Up Passed\n'
1328 else:
1329 main.assertReturnString += 'Link Up Failed\n'
1330 testResult = main.FALSE
1331
1332 # Bring third link up
1333 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw3, sw4, "up" ) ):
1334 main.assertReturnString += 'Link Up Passed\n'
1335 else:
1336 main.assertReturnString += 'Link Up Failed\n'
1337 testResult = main.FALSE
1338
1339 # Wait for reroute
1340 time.sleep( main.rerouteSleep )
1341
1342 # Check Intents
1343 if utilities.retry( f=checkIntentState, retValue=main.FALSE,
1344 args=( main, [ intentId ] ), sleep=main.checkIntentSleep ):
1345 main.assertReturnString += 'Link Up Intent State Passed\n'
1346 else:
1347 main.assertReturnString += 'Link Up Intent State Failed\n'
1348 testResult = main.FALSE
1349
1350 # Check flows count in each node
1351 if utilities.retry( f=checkFlowsCount, retValue=main.FALSE,
1352 args=[ main ] ) and utilities.retry( f=checkFlowsState,
1353 retValue=main.FALSE, args=[ main ] ):
1354 main.assertReturnString += 'Link Up Flow State Passed\n'
1355 else:
1356 main.assertReturnString += 'Link Up Flow State Failed\n'
1357 testResult = main.FALSE
1358
1359 # Check OnosTopology
1360 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, main.numLinks ) ):
1361 main.assertReturnString += 'Link Up Topology State Passed\n'
1362 else:
1363 main.assertReturnString += 'Link Up Topology State Failed\n'
1364 testResult = main.FALSE
1365
1366 # Check Connection
1367 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE,
1368 args=( main, senderNames, recipientNames ) ):
1369 main.assertReturnString += 'Link Up Scapy Packet Received Passed\n'
1370 else:
1371 main.assertReturnString += 'Link Up Scapy Packet Recieved Failed\n'
1372 testResult = main.FALSE
1373
1374 # Remove all intents
1375 if utilities.retry( f=removeAllIntents, retValue=main.FALSE, args=( main, [ intentId ] ) ):
1376 main.assertReturnString += 'Remove Intents Passed'
1377 else:
1378 main.assertReturnString += 'Remove Intents Failed'
1379 testResult = main.FALSE
1380
1381 return testResult
1382
1383
kelvin-onlab58dc39e2015-08-06 08:11:09 -07001384def pingallHosts( main, hostList ):
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001385 """
1386 Ping all host in the hosts list variable
1387 """
Jon Halla5cb3412015-08-18 14:08:22 -07001388 main.log.info( "Pinging: " + str( hostList ) )
1389 return main.Mininet1.pingallHosts( hostList )
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001390
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001391def fwdPingall( main ):
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001392 """
1393 Use fwd app and pingall to discover all the hosts
1394 """
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001395 activateResult = main.TRUE
1396 appCheck = main.TRUE
1397 getDataResult = main.TRUE
1398 main.log.info( "Activating reactive forwarding app " )
1399 activateResult = main.CLIs[ 0 ].activateApp( "org.onosproject.fwd" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001400
1401 # Wait for forward app activation to propagate
kelvin-onlab0ad05d12015-07-23 14:21:15 -07001402 time.sleep( main.fwdSleep )
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001403
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001404 # Check that forwarding is enabled on all nodes
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001405 for i in range( main.numCtrls ):
1406 appCheck = appCheck and main.CLIs[ i ].appToIDCheck()
1407 if appCheck != main.TRUE:
1408 main.log.warn( main.CLIs[ i ].apps() )
1409 main.log.warn( main.CLIs[ i ].appIDs() )
1410
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001411 # Send pingall in mininet
1412 main.log.info( "Run Pingall" )
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001413 pingResult = main.Mininet1.pingall( timeout = 600 )
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001414
1415 main.log.info( "Deactivating reactive forwarding app " )
1416 deactivateResult = main.CLIs[ 0 ].deactivateApp( "org.onosproject.fwd" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001417 if activateResult and deactivateResult:
1418 main.log.info( "Successfully used fwd app to discover hosts" )
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001419 getDataResult = main.TRUE
1420 else:
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001421 main.log.info( "Failed to use fwd app to discover hosts" )
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001422 getDataResult = main.FALSE
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001423 return getDataResult
1424
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001425def confirmHostDiscovery( main ):
1426 """
1427 Confirms that all ONOS nodes have discovered all scapy hosts
1428 """
1429 import collections
1430 scapyHostCount = len( main.scapyHosts )
1431 hosts = main.topo.getAllHosts( main ) # Get host data from each ONOS node
1432 hostFails = [] # Reset for each failed attempt
1433
1434 # Check for matching hosts on each node
1435 scapyHostIPs = [ x.hostIp for x in main.scapyHosts if x.hostIp != "0.0.0.0" ]
1436 for controller in range( main.numCtrls ):
1437 controllerStr = str( controller + 1 ) # ONOS node number
1438 # Compare Hosts
1439 # Load hosts data for controller node
Jeremyd9e4eb12016-04-13 12:09:06 -07001440 try:
1441 if hosts[ controller ]:
1442 main.log.info( "Hosts discovered" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001443 else:
Jeremyd9e4eb12016-04-13 12:09:06 -07001444 main.log.error( "Problem discovering hosts" )
1445 if hosts[ controller ] and "Error" not in hosts[ controller ]:
1446 try:
1447 hostData = json.loads( hosts[ controller ] )
1448 except ( TypeError, ValueError ):
1449 main.log.error( "Could not load json:" + str( hosts[ controller ] ) )
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001450 hostFails.append( controllerStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001451 else:
1452 onosHostIPs = [ x.get( "ipAddresses" )[ 0 ]
1453 for x in hostData
1454 if len( x.get( "ipAddresses" ) ) > 0 ]
1455 if not set( collections.Counter( scapyHostIPs ) ).issubset( set ( collections.Counter( onosHostIPs ) ) ):
1456 main.log.warn( "Controller {0} only sees nodes with {1} IPs. It should see all of the following: {2}".format( controllerStr, onosHostIPs, scapyHostIPs ) )
1457 hostFails.append( controllerStr )
1458 else:
1459 main.log.error( "Hosts returned nothing or an error." )
1460 hostFails.append( controllerStr )
1461 except IndexError:
1462 main.log.error( "Hosts returned nothing, Failed to discover hosts." )
1463 return main.FALSE
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001464
1465 if hostFails:
1466 main.log.error( "List of failed ONOS Nodes:" + ', '.join(map(str, hostFails )) )
1467 return main.FALSE
1468 else:
1469 return main.TRUE
1470
1471def sendDiscoveryArp( main, hosts=None ):
1472 """
1473 Sends Discovery ARP packets from each host provided
1474 Defaults to each host in main.scapyHosts
1475 """
1476 # Send an arp ping from each host
1477 if not hosts:
1478 hosts = main.scapyHosts
1479 for host in hosts:
1480 pkt = 'Ether( src="{0}")/ARP( psrc="{1}")'.format( host.hostMac ,host.hostIp )
1481 # Send from the VLAN interface if there is one so ONOS discovers the VLAN correctly
1482 iface = None
1483 for interface in host.getIfList():
1484 if '.' in interface:
1485 main.log.debug( "Detected VLAN interface {0}. Sending ARP packet from {0}".format( interface ) )
1486 iface = interface
1487 break
1488 host.sendPacket( packet=pkt, iface=iface )
1489 main.log.info( "Sending ARP packet from {0}".format( host.name ) )
1490
1491def populateHostData( main ):
1492 """
1493 Populates hostsData
1494 """
1495 import json
1496 try:
1497 hostsJson = json.loads( main.CLIs[ 0 ].hosts() )
1498 hosts = main.Mininet1.getHosts().keys()
1499 # TODO: Make better use of new getHosts function
1500 for host in hosts:
1501 main.hostsData[ host ] = {}
1502 main.hostsData[ host ][ 'mac' ] = \
1503 main.Mininet1.getMacAddress( host ).upper()
1504 for hostj in hostsJson:
1505 if main.hostsData[ host ][ 'mac' ] == hostj[ 'mac' ]:
1506 main.hostsData[ host ][ 'id' ] = hostj[ 'id' ]
1507 main.hostsData[ host ][ 'vlan' ] = hostj[ 'vlan' ]
1508 main.hostsData[ host ][ 'location' ] = \
1509 hostj[ 'location' ][ 'elementId' ] + '/' + \
1510 hostj[ 'location' ][ 'port' ]
1511 main.hostsData[ host ][ 'ipAddresses' ] = hostj[ 'ipAddresses' ]
1512 return main.TRUE
Jeremyd9e4eb12016-04-13 12:09:06 -07001513 except ValueError:
1514 main.log.error( "ValueError while populating hostsData" )
1515 return main.FALSE
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001516 except KeyError:
1517 main.log.error( "KeyError while populating hostsData")
1518 return main.FALSE
Jeremyd9e4eb12016-04-13 12:09:06 -07001519 except IndexError:
1520 main.log.error( "IndexError while populating hostsData" )
1521 return main.FALSE
1522 except TypeError:
1523 main.log.error( "TypeError while populating hostsData" )
1524 return main.FALSE
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001525
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001526def checkTopology( main, expectedLink ):
1527 statusResult = main.TRUE
1528 # Check onos topology
1529 main.log.info( itemName + ": Checking ONOS topology " )
1530
1531 for i in range( main.numCtrls ):
1532 topologyResult = main.CLIs[ i ].topology()
You Wang24139872016-05-03 11:48:47 -07001533 statusResult = main.CLIs[ i ].checkStatus( topologyResult,
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001534 main.numSwitch,
1535 expectedLink )\
1536 and statusResult
1537 if not statusResult:
1538 main.log.error( itemName + ": Topology mismatch" )
1539 else:
1540 main.log.info( itemName + ": Topology match" )
1541 return statusResult
1542
1543def checkIntentState( main, intentsId ):
1544 """
1545 This function will check intent state to make sure all the intents
1546 are in INSTALLED state
1547 """
1548
1549 intentResult = main.TRUE
1550 results = []
1551
1552 main.log.info( itemName + ": Checking intents state" )
1553 # First check of intents
1554 for i in range( main.numCtrls ):
1555 tempResult = main.CLIs[ i ].checkIntentState( intentsId=intentsId )
1556 results.append( tempResult )
1557
1558 expectedState = [ 'INSTALLED', 'INSTALLING' ]
1559
1560 if all( result == main.TRUE for result in results ):
1561 main.log.info( itemName + ": Intents are installed correctly" )
1562 else:
1563 # Wait for at least 5 second before checking the intents again
acsmarsb9a92692015-10-08 16:43:01 -07001564 main.log.error( "Intents are not installed correctly. Waiting 5 sec" )
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001565 time.sleep( 5 )
1566 results = []
1567 # Second check of intents since some of the intents may be in
1568 # INSTALLING state, they should be in INSTALLED at this time
1569 for i in range( main.numCtrls ):
Jeremy2f190ca2016-01-29 15:23:57 -08001570 tempResult = main.CLIs[ i ].checkIntentState( intentsId=intentsId )
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001571 results.append( tempResult )
1572 if all( result == main.TRUE for result in results ):
1573 main.log.info( itemName + ": Intents are installed correctly" )
acsmarsb9a92692015-10-08 16:43:01 -07001574 intentResult = main.TRUE
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001575 else:
1576 main.log.error( itemName + ": Intents are NOT installed correctly" )
1577 intentResult = main.FALSE
1578
1579 return intentResult
1580
1581def checkFlowsState( main ):
1582
1583 main.log.info( itemName + ": Check flows state" )
1584 checkFlowsResult = main.CLIs[ 0 ].checkFlowsState()
1585 return checkFlowsResult
1586
1587def link( main, sw1, sw2, option):
1588
1589 # link down
1590 main.log.info( itemName + ": Bring link " + option + "between " +
1591 sw1 + " and " + sw2 )
1592 linkResult = main.Mininet1.link( end1=sw1, end2=sw2, option=option )
1593 return linkResult
1594
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001595def scapyCheckConnection( main, senders, recipients, packet=None, packetFilter=None, expectFailure=False ):
1596 """
1597 Checks the connectivity between all given sender hosts and all given recipient hosts
1598 Packet may be specified. Defaults to Ether/IP packet
1599 Packet Filter may be specified. Defaults to Ether/IP from current sender MAC
1600 Todo: Optional packet and packet filter attributes for sender and recipients
1601 Expect Failure when the sender and recipient are not supposed to have connectivity
1602 Timeout of 1 second, returns main.TRUE if the filter is not triggered and kills the filter
1603
1604 """
1605 connectionsFunctional = main.TRUE
1606
1607 if not packetFilter:
1608 packetFilter = 'ether host {}'
1609
1610 if expectFailure:
1611 timeout = 1
1612 else:
1613 timeout = 10
1614
1615 for sender in senders:
1616 try:
1617 senderComp = getattr( main, sender )
1618 except AttributeError:
1619 main.log.error( "main has no attribute {}".format( sender ) )
1620 connectionsFunctional = main.FALSE
1621 continue
1622
1623 for recipient in recipients:
1624 # Do not send packets to self since recipient CLI will already be busy
1625 if recipient == sender:
1626 continue
1627 try:
1628 recipientComp = getattr( main, recipient )
1629 except AttributeError:
1630 main.log.error( "main has no attribute {}".format( recipient ) )
1631 connectionsFunctional = main.FALSE
1632 continue
1633
1634 recipientComp.startFilter( pktFilter = packetFilter.format( senderComp.hostMac ) )
1635
1636 if not packet:
1637 pkt = 'Ether( src="{0}", dst="{2}" )/IP( src="{1}", dst="{3}" )'.format(
1638 senderComp.hostMac,
1639 senderComp.hostIp,
1640 recipientComp.hostMac,
1641 recipientComp.hostIp )
1642 else:
1643 pkt = packet
1644 senderComp.sendPacket( packet = pkt )
1645
1646 if recipientComp.checkFilter( timeout ):
1647 if expectFailure:
1648 main.log.error( "Packet from {0} successfully received by {1} when it should not have been".format( sender , recipient ) )
1649 connectionsFunctional = main.FALSE
1650 else:
1651 main.log.info( "Packet from {0} successfully received by {1}".format( sender , recipient ) )
1652 else:
1653 recipientComp.killFilter()
1654 if expectFailure:
1655 main.log.info( "As expected, packet from {0} was not received by {1}".format( sender , recipient ) )
1656 else:
1657 main.log.error( "Packet from {0} was not received by {1}".format( sender , recipient ) )
1658 connectionsFunctional = main.FALSE
1659
1660 return connectionsFunctional
1661
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001662def removeAllIntents( main, intentsId ):
1663 """
1664 Remove all intents in the intentsId
1665 """
1666
kelvin-onlab5c706ff2015-07-20 10:56:52 -07001667 onosSummary = []
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001668 removeIntentResult = main.TRUE
1669 # Remove intents
1670 for intent in intentsId:
1671 main.CLIs[ 0 ].removeIntent( intentId=intent, purge=True )
1672
acsmarscfa52272015-08-06 15:21:45 -07001673 time.sleep( main.removeIntentSleep )
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001674
kelvin-onlab5c706ff2015-07-20 10:56:52 -07001675 # If there is remianing intents then remove intents should fail
1676 for i in range( main.numCtrls ):
1677 onosSummary.append( json.loads( main.CLIs[ i ].summary() ) )
1678
1679 for summary in onosSummary:
1680 if summary.get( 'intents' ) != 0:
1681 main.log.warn( itemName + ": There are " +
1682 str( summary.get( 'intents' ) ) +
1683 " intents remaining in node " +
1684 str( summary.get( 'node' ) ) +
1685 ", failed to remove all the intents " )
1686 removeIntentResult = main.FALSE
1687
1688 if removeIntentResult:
1689 main.log.info( itemName + ": There are no more intents remaining, " +
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001690 "successfully removed all the intents." )
kelvin-onlab5c706ff2015-07-20 10:56:52 -07001691
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001692 return removeIntentResult
1693
1694def checkFlowsCount( main ):
1695 """
1696 Check flows count in each node
1697 """
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001698 flowsCount = []
1699 main.log.info( itemName + ": Checking flows count in each ONOS node" )
1700 for i in range( main.numCtrls ):
1701 summaryResult = main.CLIs[ i ].summary()
1702 if not summaryResult:
1703 main.log.error( itemName + ": There is something wrong with " +
1704 "summary command" )
1705 return main.FALSE
1706 else:
1707 summaryJson = json.loads( summaryResult )
1708 flowsCount.append( summaryJson.get( 'flows' ) )
1709
1710 if flowsCount:
1711 if all( flows==flowsCount[ 0 ] for flows in flowsCount ):
1712 main.log.info( itemName + ": There are " + str( flowsCount[ 0 ] ) +
1713 " flows in all ONOS node" )
1714 else:
1715 for i in range( main.numCtrls ):
1716 main.log.debug( itemName + ": ONOS node " + str( i ) + " has " +
kelvin-onlab6dea6e62015-07-23 13:07:26 -07001717 str( flowsCount[ i ] ) + " flows" )
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001718 else:
1719 main.log.error( "Checking flows count failed, check summary command" )
1720 return main.FALSE
1721
1722 return main.TRUE
1723
kelvin-onlab58dc39e2015-08-06 08:11:09 -07001724def checkLeaderChange( leaders1, leaders2 ):
acsmarse6b410f2015-07-17 14:39:34 -07001725 """
1726 Checks for a change in intent partition leadership.
1727
1728 Takes the output of leaders -c in json string format before and after
1729 a potential change as input
1730
1731 Returns main.TRUE if no mismatches are detected
1732 Returns main.FALSE if there is a mismatch or on error loading the input
1733 """
1734 try:
1735 leaders1 = json.loads( leaders1 )
1736 leaders2 = json.loads( leaders2 )
1737 except ( AttributeError, TypeError):
1738 main.log.exception( self.name + ": Object not as expected" )
1739 return main.FALSE
1740 except Exception:
1741 main.log.exception( self.name + ": Uncaught exception!" )
1742 main.cleanup()
1743 main.exit()
1744 main.log.info( "Checking Intent Paritions for Change in Leadership" )
1745 mismatch = False
1746 for dict1 in leaders1:
1747 if "intent" in dict1.get( "topic", [] ):
1748 for dict2 in leaders2:
1749 if dict1.get( "topic", 0 ) == dict2.get( "topic", 0 ) and \
1750 dict1.get( "leader", 0 ) != dict2.get( "leader", 0 ):
1751 mismatch = True
1752 main.log.error( "{0} changed leader from {1} to {2}".\
1753 format( dict1.get( "topic", "no-topic" ),\
1754 dict1.get( "leader", "no-leader" ),\
1755 dict2.get( "leader", "no-leader" ) ) )
1756 if mismatch:
1757 return main.FALSE
1758 else:
1759 return main.TRUE
kelvin-onlab016dce22015-08-10 09:54:11 -07001760
1761def report( main ):
1762 """
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001763 Report errors/warnings/exceptions
kelvin-onlab016dce22015-08-10 09:54:11 -07001764 """
kelvin-onlab016dce22015-08-10 09:54:11 -07001765 main.ONOSbench.logReport( main.ONOSip[ 0 ],
1766 [ "INFO",
1767 "FOLLOWER",
1768 "WARN",
1769 "flow",
1770 "ERROR",
1771 "Except" ],
1772 "s" )
1773
1774 main.log.info( "ERROR report: \n" )
1775 for i in range( main.numCtrls ):
1776 main.ONOSbench.logReport( main.ONOSip[ i ],
1777 [ "ERROR" ],
1778 "d" )
1779
1780 main.log.info( "EXCEPTIONS report: \n" )
1781 for i in range( main.numCtrls ):
1782 main.ONOSbench.logReport( main.ONOSip[ i ],
1783 [ "Except" ],
1784 "d" )
1785
1786 main.log.info( "WARNING report: \n" )
1787 for i in range( main.numCtrls ):
1788 main.ONOSbench.logReport( main.ONOSip[ i ],
1789 [ "WARN" ],
1790 "d" )