blob: c3104a5a62727bf5e79f7c4f1a9062d7f9e50238 [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="",
Jeremy Songsterff553672016-05-12 17:06:23 -070025 sw2="",
26 setVlan="" ):
kelvin-onlabd48a68c2015-07-13 16:01:36 -070027 """
Jeremy Songster1f39bf02016-01-20 17:17:25 -080028 Installs a Host Intent
29
kelvin-onlab58dc39e2015-08-06 08:11:09 -070030 Description:
Jeremy Songster1f39bf02016-01-20 17:17:25 -080031 Install a host intent using
32 add-host-intent
33
kelvin-onlab58dc39e2015-08-06 08:11:09 -070034 Steps:
Jeremy Songster1f39bf02016-01-20 17:17:25 -080035 - Fetch host data if not given
36 - Add host intent
37 - Ingress device is the first sender host
38 - Egress devices are the recipient devices
39 - Ports if defined in senders or recipients
40 - MAC address ethSrc loaded from Ingress device
41 - Check intent state with retry
kelvin-onlab58dc39e2015-08-06 08:11:09 -070042 Required:
43 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
Jeremy Songster1f39bf02016-01-20 17:17:25 -080044 host1 - Dictionary for host1
45 { "name":"h8", "id":"of:0000000000000005/8" }
46 host2 - Dictionary for host2
47 { "name":"h16", "id":"of:0000000000000006/8" }
kelvin-onlab58dc39e2015-08-06 08:11:09 -070048 Optional:
49 onosNode - ONOS node to install the intents in main.CLIs[ ]
50 0 by default so that it will always use the first
51 ONOS node
kelvin-onlab58dc39e2015-08-06 08:11:09 -070052 ethType - Ethernet type eg. IPV4, IPV6
kelvin-onlab58dc39e2015-08-06 08:11:09 -070053 bandwidth - Bandwidth capacity
54 lambdaAlloc - Allocate lambda, defaults to False
55 ipProto - IP protocol
Jeremy Songster1f39bf02016-01-20 17:17:25 -080056 tcp - TCP ports in the same order as the hosts in hostNames
57 """
58
59 assert main, "There is no main variable"
60 assert host1, "You must specify host1"
61 assert host2, "You must specify host2"
62
63 global itemName # The name of this run. Used for logs.
64 itemName = name
65 onosNode = int( onosNode )
66
67 main.log.info( itemName + ": Adding single point to multi point intents" )
Jeremyd9e4eb12016-04-13 12:09:06 -070068 try:
69 if not host1.get( "id" ):
70 main.log.warn( "ID not given for host1 {0}. Loading from main.hostData".format( host1.get( "name" ) ) )
71 main.log.debug( main.hostsData.get( host1.get( "name" ) ) )
72 host1[ "id" ] = main.hostsData.get( host1.get( "name" ) ).get( "id" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -080073
Jeremyd9e4eb12016-04-13 12:09:06 -070074 if not host2.get( "id" ):
75 main.log.warn( "ID not given for host2 {0}. Loading from main.hostData".format( host2.get( "name" ) ) )
76 host2[ "id" ] = main.hostsData.get( host2.get( "name" ) ).get( "id" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -080077
Jeremyd9e4eb12016-04-13 12:09:06 -070078 # Adding point intent
Jeremy Songster832f9e92016-05-05 14:30:49 -070079 vlanId = host1.get( "vlan" )
Jeremyd9e4eb12016-04-13 12:09:06 -070080 intentId = main.CLIs[ onosNode ].addHostIntent( hostIdOne=host1.get( "id" ),
Jeremy Songster832f9e92016-05-05 14:30:49 -070081 hostIdTwo=host2.get( "id" ),
Jeremy Songsterff553672016-05-12 17:06:23 -070082 vlanId=vlanId,
83 setVlan=setVlan )
Jeremyd9e4eb12016-04-13 12:09:06 -070084 except (KeyError, TypeError):
85 errorMsg = "There was a problem loading the hosts data."
86 if intentId:
87 errorMsg += " There was a problem installing host to host intent."
88 main.log.error( errorMsg )
89 return main.FALSE
Jeremy Songster1f39bf02016-01-20 17:17:25 -080090
91 # Check intents state
92 if utilities.retry( f=checkIntentState, retValue=main.FALSE,
93 args=( main, [ intentId ] ), sleep=main.checkIntentSleep ):
94 return intentId
95 else:
Jeremy2f190ca2016-01-29 15:23:57 -080096 main.log.error( "Host Intent did not install correctly" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -080097 return main.FALSE
98
99def testHostIntent( main,
100 name,
101 intentId,
102 host1,
103 host2,
104 onosNode=0,
105 sw1="s5",
106 sw2="s2",
107 expectedLink=0):
108 """
109 Test a Host Intent
110
111 Description:
112 Test a host intent of given ID between given hosts
113
114 Steps:
115 - Fetch host data if not given
116 - Check Intent State
117 - Check Flow State
118 - Check Connectivity
119 - Check Lack of Connectivity Between Hosts not in the Intent
120 - Reroute
121 - Take Expected Link Down
122 - Check Intent State
123 - Check Flow State
124 - Check Topology
125 - Check Connectivity
126 - Bring Expected Link Up
127 - Check Intent State
128 - Check Flow State
129 - Check Topology
130 - Check Connectivity
131 - Remove Topology
132
133 Required:
134 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
135 intentId - intent ID to be tested ( and removed )
136 host1 - Dictionary for host1
137 { "name":"h8", "id":"of:0000000000000005/8" }
138 host2 - Dictionary for host2
139 { "name":"h16", "id":"of:0000000000000006/8" }
140 Optional:
141 onosNode - ONOS node to install the intents in main.CLIs[ ]
142 0 by default so that it will always use the first
143 ONOS node
144 sw1 - First switch to bring down & up for rerouting purpose
145 sw2 - Second switch to bring down & up for rerouting purpose
146 expectedLink - Expected link when the switches are down, it should
147 be two links lower than the links before the two
148 switches are down
149
150 """
151
152 # Parameter Validity Check
153 assert main, "There is no main variable"
154 assert host1, "You must specify host1"
155 assert host2, "You must specify host2"
156
157 global itemName
158 itemName = name
159 tempHostsData = {}
160 onosNode = int( onosNode )
161
Jeremy2f190ca2016-01-29 15:23:57 -0800162 main.log.info( itemName + ": Testing Host Intent" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800163
Jeremyd9e4eb12016-04-13 12:09:06 -0700164 try:
165 if not host1.get( "id" ):
166 main.log.warn( "Id not given for host1 {0}. Loading from main.hostData".format( host1.get( "name" ) ) )
167 host1[ "id" ] = main.hostsData.get( host1.get( "name" ) ).get( "location" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800168
Jeremyd9e4eb12016-04-13 12:09:06 -0700169 if not host2.get( "id" ):
170 main.log.warn( "Id not given for host2 {0}. Loading from main.hostData".format( host2.get( "name" ) ) )
171 host2[ "id" ] = main.hostsData.get( host2.get( "name" ) ).get( "location" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800172
Jeremyd9e4eb12016-04-13 12:09:06 -0700173 senderNames = [ host1.get( "name" ), host2.get( "name" ) ]
174 recipientNames = [ host1.get( "name" ), host2.get( "name" ) ]
Jeremy Songster832f9e92016-05-05 14:30:49 -0700175 vlanId = host1.get( "vlan" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800176
Jeremyd9e4eb12016-04-13 12:09:06 -0700177 testResult = main.TRUE
178 except (KeyError, TypeError):
179 main.log.error( "There was a problem loading the hosts data." )
180 return main.FALSE
181
182 main.log.info( itemName + ": Testing Host to Host intents" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800183
184 # Check intent state
185 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, [ intentId ] ), sleep=main.checkIntentSleep ):
186 main.assertReturnString += 'Initial Intent State Passed\n'
187 else:
188 main.assertReturnString += 'Initial Intent State Failed\n'
189 testResult = main.FALSE
190
191 # Check flows count in each node
Jeremy03dab012016-04-11 08:59:17 -0700192 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 -0800193 main.assertReturnString += 'Initial Flow State Passed\n'
194 else:
195 main.assertReturnString += 'Intial Flow State Failed\n'
196 testResult = main.FALSE
197
198 # Check Connectivity
Jeremy Songster832f9e92016-05-05 14:30:49 -0700199 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId ) ):
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800200 main.assertReturnString += 'Initial Ping Passed\n'
201 else:
202 main.assertReturnString += 'Initial Ping Failed\n'
203 testResult = main.FALSE
204
205 # Test rerouting if these variables exist
206 if sw1 and sw2 and expectedLink:
207 # Take link down
208 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "down" ) ):
209 main.assertReturnString += 'Link Down Passed\n'
210 else:
211 main.assertReturnString += 'Link Down Failed\n'
212 testResult = main.FALSE
213
214 # Check intent state
215 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, [ intentId ] ), sleep=main.checkIntentSleep ):
216 main.assertReturnString += 'Link Down Intent State Passed\n'
217 else:
218 main.assertReturnString += 'Link Down Intent State Failed\n'
219 testResult = main.FALSE
220
221 # Check flows count in each node
Jeremy03dab012016-04-11 08:59:17 -0700222 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 -0800223 main.assertReturnString += 'Link Down Flow State Passed\n'
224 else:
225 main.assertReturnString += 'Link Down Flow State Failed\n'
226 testResult = main.FALSE
227
228 # Check OnosTopology
229 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, expectedLink ) ):
230 main.assertReturnString += 'Link Down Topology State Passed\n'
231 else:
232 main.assertReturnString += 'Link Down Topology State Failed\n'
233 testResult = main.FALSE
234
235 # Check Connection
Jeremy Songster832f9e92016-05-05 14:30:49 -0700236 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId ) ):
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800237 main.assertReturnString += 'Link Down Pingall Passed\n'
238 else:
239 main.assertReturnString += 'Link Down Pingall Failed\n'
240 testResult = main.FALSE
241
242 # Bring link up
243 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "up" ) ):
244 main.assertReturnString += 'Link Up Passed\n'
245 else:
246 main.assertReturnString += 'Link Up Failed\n'
247 testResult = main.FALSE
248
249 # Wait for reroute
250 time.sleep( main.rerouteSleep )
251
252 # Check Intents
253 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, [ intentId ] ), sleep=main.checkIntentSleep ):
254 main.assertReturnString += 'Link Up Intent State Passed\n'
255 else:
256 main.assertReturnString += 'Link Up Intent State Failed\n'
257 testResult = main.FALSE
258
259 # Check flows count in each node
Jeremy03dab012016-04-11 08:59:17 -0700260 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 -0800261 main.assertReturnString += 'Link Up Flow State Passed\n'
262 else:
263 main.assertReturnString += 'Link Up Flow State Failed\n'
264 testResult = main.FALSE
265
266 # Check OnosTopology
267 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, main.numLinks ) ):
268 main.assertReturnString += 'Link Up Topology State Passed\n'
269 else:
270 main.assertReturnString += 'Link Up Topology State Failed\n'
271 testResult = main.FALSE
272
273 # Check Connection
Jeremy Songster832f9e92016-05-05 14:30:49 -0700274 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId ) ):
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800275 main.assertReturnString += 'Link Up Pingall Passed\n'
276 else:
277 main.assertReturnString += 'Link Up Pingall Failed\n'
278 testResult = main.FALSE
279
280 # Remove all intents
281 if utilities.retry( f=removeAllIntents, retValue=main.FALSE, args=( main, [ intentId ] ) ):
282 main.assertReturnString += 'Remove Intents Passed'
283 else:
284 main.assertReturnString += 'Remove Intents Failed'
285 testResult = main.FALSE
286
287 return testResult
288
289def installPointIntent( main,
290 name,
291 senders,
292 recipients,
293 onosNode=0,
294 ethType="",
295 bandwidth="",
296 lambdaAlloc=False,
297 ipProto="",
298 ipSrc="",
299 ipDst="",
300 tcpSrc="",
Jeremy Songsterff553672016-05-12 17:06:23 -0700301 tcpDst="",
302 setVlan=""):
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800303 """
304 Installs a Single to Single Point Intent
305
306 Description:
307 Install a single to single point intent
308
309 Steps:
310 - Fetch host data if not given
311 - Add point intent
312 - Ingress device is the first sender device
313 - Egress device is the first recipient device
314 - Ports if defined in senders or recipients
315 - MAC address ethSrc loaded from Ingress device
316 - Check intent state with retry
317 Required:
318 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
319 senders - List of host dictionaries i.e.
320 [ { "name":"h8", "device":"of:0000000000000005/8","mac":"00:00:00:00:00:08" } ]
321 recipients - List of host dictionaries i.e.
322 [ { "name":"h16", "device":"of:0000000000000006/8", "mac":"00:00:00:00:00:10" } ]
323 Optional:
324 onosNode - ONOS node to install the intents in main.CLIs[ ]
325 0 by default so that it will always use the first
326 ONOS node
327 ethType - Ethernet type eg. IPV4, IPV6
328 bandwidth - Bandwidth capacity
329 lambdaAlloc - Allocate lambda, defaults to False
330 ipProto - IP protocol
331 tcp - TCP ports in the same order as the hosts in hostNames
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700332 sw1 - First switch to bring down & up for rerouting purpose
333 sw2 - Second switch to bring down & up for rerouting purpose
334 expectedLink - Expected link when the switches are down, it should
335 be two links lower than the links before the two
336 switches are down
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700337 """
338
339 assert main, "There is no main variable"
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800340 assert senders, "You must specify a sender"
341 assert recipients, "You must specify a recipient"
342 # Assert devices or main.hostsData, "You must specify devices"
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700343
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800344 global itemName # The name of this run. Used for logs.
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700345 itemName = name
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700346 onosNode = int( onosNode )
347
Jeremy6f000c62016-02-25 17:02:28 -0800348 main.log.info( itemName + ": Adding point to point intents" )
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700349
Jeremyd9e4eb12016-04-13 12:09:06 -0700350 try:
351 for sender in senders:
352 if not sender.get( "device" ):
353 main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
354 sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800355
Jeremyd9e4eb12016-04-13 12:09:06 -0700356 for recipient in recipients:
357 if not recipient.get( "device" ):
358 main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
359 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800360
361
Jeremyd9e4eb12016-04-13 12:09:06 -0700362 ingressDevice = senders[ 0 ].get( "device" )
363 egressDevice = recipients[ 0 ].get( "device" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800364
Jeremyd9e4eb12016-04-13 12:09:06 -0700365 portIngress = senders[ 0 ].get( "port", "" )
366 portEgress = recipients[ 0 ].get( "port", "" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800367
Jeremyd9e4eb12016-04-13 12:09:06 -0700368 dstMac = recipients[ 0 ].get( "mac" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800369
Jeremyd9e4eb12016-04-13 12:09:06 -0700370 ipSrc = senders[ 0 ].get( "ip" )
371 ipDst = recipients[ 0 ].get( "ip" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800372
Jeremy Songster832f9e92016-05-05 14:30:49 -0700373 vlanId = senders[ 0 ].get( "vlan" )
374
Jeremyd9e4eb12016-04-13 12:09:06 -0700375 # Adding point intent
376 intentId = main.CLIs[ onosNode ].addPointIntent(
377 ingressDevice=ingressDevice,
378 egressDevice=egressDevice,
379 portIngress=portIngress,
380 portEgress=portEgress,
381 ethType=ethType,
382 ethDst=dstMac,
383 bandwidth=bandwidth,
384 lambdaAlloc=lambdaAlloc,
385 ipProto=ipProto,
386 ipSrc=ipSrc,
387 ipDst=ipDst,
388 tcpSrc=tcpSrc,
Jeremy Songster832f9e92016-05-05 14:30:49 -0700389 tcpDst=tcpDst,
Jeremy Songsterff553672016-05-12 17:06:23 -0700390 vlanId=vlanId,
391 setVlan=setVlan )
Jeremyd9e4eb12016-04-13 12:09:06 -0700392 except (KeyError, TypeError):
393 errorMsg = "There was a problem loading the hosts data."
394 if intentId:
395 errorMsg += " There was a problem installing Point to Point intent."
396 main.log.error( errorMsg )
397 return main.FALSE
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700398
399 # Check intents state
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800400 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, [ intentId ] ), sleep=main.checkIntentSleep ):
401 return intentId
acsmarsd4862d12015-10-06 17:57:34 -0700402 else:
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800403 main.log.error( "Point Intent did not install correctly" )
404 return main.FALSE
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700405
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700406def pointIntentTcp( main,
407 name,
408 host1,
409 host2,
410 onosNode=0,
411 deviceId1="",
412 deviceId2="",
413 port1="",
414 port2="",
415 ethType="",
416 mac1="",
417 mac2="",
418 bandwidth="",
419 lambdaAlloc=False,
420 ipProto="",
421 ip1="",
422 ip2="",
423 tcp1="",
424 tcp2="",
425 sw1="",
426 sw2="",
427 expectedLink=0 ):
428
429 """
430 Description:
431 Verify add-point-intent only for TCP
432 Steps:
433 - Get device ids | ports
434 - Add point intents
435 - Check intents
436 - Verify flows
437 - Ping hosts
438 - Reroute
439 - Link down
440 - Verify flows
441 - Check topology
442 - Ping hosts
443 - Link up
444 - Verify flows
445 - Check topology
446 - Ping hosts
447 - Remove intents
448 Required:
449 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
450 host1 - Name of first host
451 host2 - Name of second host
452 Optional:
453 onosNode - ONOS node to install the intents in main.CLIs[ ]
454 0 by default so that it will always use the first
455 ONOS node
456 deviceId1 - ONOS device id of the first switch, the same as the
457 location of the first host eg. of:0000000000000001/1,
458 located at device 1 port 1
459 deviceId2 - ONOS device id of the second switch
460 port1 - The port number where the first host is attached
461 port2 - The port number where the second host is attached
462 ethType - Ethernet type eg. IPV4, IPV6
463 mac1 - Mac address of first host
464 mac2 - Mac address of the second host
465 bandwidth - Bandwidth capacity
466 lambdaAlloc - Allocate lambda, defaults to False
467 ipProto - IP protocol
468 ip1 - IP address of first host
469 ip2 - IP address of second host
470 tcp1 - TCP port of first host
471 tcp2 - TCP port of second host
472 sw1 - First switch to bring down & up for rerouting purpose
473 sw2 - Second switch to bring down & up for rerouting purpose
474 expectedLink - Expected link when the switches are down, it should
475 be two links lower than the links before the two
476 switches are down
477 """
478
479 assert main, "There is no main variable"
480 assert name, "variable name is empty"
481 assert host1 and host2, "You must specify hosts"
482
483 global itemName
484 itemName = name
485 host1 = host1
486 host2 = host2
487 hostNames = [ host1, host2 ]
488 intentsId = []
489
490 iperfResult = main.TRUE
491 intentResult = main.TRUE
492 removeIntentResult = main.TRUE
493 flowResult = main.TRUE
494 topoResult = main.TRUE
495 linkDownResult = main.TRUE
496 linkUpResult = main.TRUE
497 onosNode = int( onosNode )
498
499 # Adding bidirectional point intents
500 main.log.info( itemName + ": Adding point intents" )
501 intent1 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
502 egressDevice=deviceId2,
503 portIngress=port1,
504 portEgress=port2,
505 ethType=ethType,
506 ethSrc=mac1,
507 ethDst=mac2,
508 bandwidth=bandwidth,
509 lambdaAlloc=lambdaAlloc,
510 ipProto=ipProto,
511 ipSrc=ip1,
512 ipDst=ip2,
513 tcpSrc=tcp1,
514 tcpDst="" )
515
516 intent2 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
517 egressDevice=deviceId1,
518 portIngress=port2,
519 portEgress=port1,
520 ethType=ethType,
521 ethSrc=mac2,
522 ethDst=mac1,
523 bandwidth=bandwidth,
524 lambdaAlloc=lambdaAlloc,
525 ipProto=ipProto,
526 ipSrc=ip2,
527 ipDst=ip1,
528 tcpSrc=tcp2,
529 tcpDst="" )
530
531 intent3 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
532 egressDevice=deviceId2,
533 portIngress=port1,
534 portEgress=port2,
535 ethType=ethType,
536 ethSrc=mac1,
537 ethDst=mac2,
538 bandwidth=bandwidth,
539 lambdaAlloc=lambdaAlloc,
540 ipProto=ipProto,
541 ipSrc=ip1,
542 ipDst=ip2,
543 tcpSrc="",
544 tcpDst=tcp2 )
545
546 intent4 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
547 egressDevice=deviceId1,
548 portIngress=port2,
549 portEgress=port1,
550 ethType=ethType,
551 ethSrc=mac2,
552 ethDst=mac1,
553 bandwidth=bandwidth,
554 lambdaAlloc=lambdaAlloc,
555 ipProto=ipProto,
556 ipSrc=ip2,
557 ipDst=ip1,
558 tcpSrc="",
559 tcpDst=tcp1 )
560 intentsId.append( intent1 )
561 intentsId.append( intent2 )
562 intentsId.append( intent3 )
563 intentsId.append( intent4 )
564
565 # Check intents state
566 time.sleep( main.checkIntentSleep )
567 intentResult = checkIntentState( main, intentsId )
568 # Check flows count in each node
569 checkFlowsCount( main )
570
571 # Check intents state again if first check fails...
572 if not intentResult:
573 intentResult = checkIntentState( main, intentsId )
574
575 # Check flows count in each node
576 checkFlowsCount( main )
577
578 # Verify flows
579 checkFlowsState( main )
580
581 # Run iperf to both host
acsmarsd4862d12015-10-06 17:57:34 -0700582 iperfTemp = main.Mininet1.iperftcp( host1,host2,10 )
583 iperfResult = iperfResult and iperfTemp
584 if iperfTemp:
585 main.assertReturnString += 'Initial Iperf Passed\n'
586 else:
587 main.assertReturnString += 'Initial Iperf Failed\n'
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700588
589 # Test rerouting if these variables exist
590 if sw1 and sw2 and expectedLink:
591 # link down
592 linkDownResult = link( main, sw1, sw2, "down" )
acsmarsd4862d12015-10-06 17:57:34 -0700593
594 if linkDownResult:
595 main.assertReturnString += 'Link Down Passed\n'
596 else:
597 main.assertReturnString += 'Link Down Failed\n'
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700598
599 # Check flows count in each node
600 checkFlowsCount( main )
601 # Verify flows
602 checkFlowsState( main )
603
604 # Check OnosTopology
605 topoResult = checkTopology( main, expectedLink )
acsmarsd4862d12015-10-06 17:57:34 -0700606 if topoResult:
607 main.assertReturnString += 'Link Down Topology State Passed\n'
608 else:
609 main.assertReturnString += 'Link Down Topology State Failed\n'
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700610
611 # Run iperf to both host
acsmarsd4862d12015-10-06 17:57:34 -0700612 iperfTemp = main.Mininet1.iperftcp( host1,host2,10 )
613 iperfResult = iperfResult and iperfTemp
614 if iperfTemp:
615 main.assertReturnString += 'Link Down Iperf Passed\n'
616 else:
617 main.assertReturnString += 'Link Down Iperf Failed\n'
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700618
acsmarsd4862d12015-10-06 17:57:34 -0700619 # Check intent state
620 intentTemp = checkIntentState( main, intentsId )
621 intentResult = intentResult and intentTemp
622 if intentTemp:
623 main.assertReturnString += 'Link Down Intent State Passed\n'
624 else:
625 main.assertReturnString += 'Link Down Intent State Failed\n'
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700626
627 # Checks ONOS state in link down
628 if linkDownResult and topoResult and iperfResult and intentResult:
629 main.log.info( itemName + ": Successfully brought link down" )
630 else:
631 main.log.error( itemName + ": Failed to bring link down" )
632
633 # link up
634 linkUpResult = link( main, sw1, sw2, "up" )
acsmarsd4862d12015-10-06 17:57:34 -0700635 if linkUpTemp:
636 main.assertReturnString += 'Link Up Passed\n'
637 else:
638 main.assertReturnString += 'Link Up Failed\n'
639
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700640 time.sleep( main.rerouteSleep )
641
642 # Check flows count in each node
643 checkFlowsCount( main )
644 # Verify flows
645 checkFlowsState( main )
646
647 # Check OnosTopology
648 topoResult = checkTopology( main, main.numLinks )
649
acsmarsd4862d12015-10-06 17:57:34 -0700650 if topoResult:
651 main.assertReturnString += 'Link Up Topology State Passed\n'
652 else:
653 main.assertReturnString += 'Link Up Topology State Failed\n'
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700654
acsmarsd4862d12015-10-06 17:57:34 -0700655 # Run iperf to both host
656 iperfTemp = main.Mininet1.iperftcp( host1,host2,10 )
657 iperfResult = iperfResult and iperfTemp
658 if iperfTemp:
659 main.assertReturnString += 'Link Up Iperf Passed\n'
660 else:
661 main.assertReturnString += 'Link Up Iperf Failed\n'
662
663 # Check intent state
664 intentTemp = checkIntentState( main, intentsId )
665 intentResult = intentResult and intentTemp
666 if intentTemp:
667 main.assertReturnString += 'Link Down Intent State Passed\n'
668 else:
669 main.assertReturnString += 'Link Down Intent State Failed\n'
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700670
671 # Checks ONOS state in link up
672 if linkUpResult and topoResult and iperfResult and intentResult:
673 main.log.info( itemName + ": Successfully brought link back up" )
674 else:
675 main.log.error( itemName + ": Failed to bring link back up" )
676
677 # Remove all intents
678 removeIntentResult = removeAllIntents( main, intentsId )
acsmarsd4862d12015-10-06 17:57:34 -0700679 if removeIntentResult:
680 main.assertReturnString += 'Remove Intents Passed'
681 else:
682 main.assertReturnString += 'Remove Intents Failed'
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700683
684 stepResult = iperfResult and linkDownResult and linkUpResult \
685 and intentResult and removeIntentResult
686
687 return stepResult
688
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800689def installSingleToMultiIntent( main,
690 name,
691 senders,
692 recipients,
693 onosNode=0,
694 ethType="",
695 bandwidth="",
696 lambdaAlloc=False,
697 ipProto="",
698 ipAddresses="",
699 tcp="",
700 sw1="",
Jeremy Songsterff553672016-05-12 17:06:23 -0700701 sw2="",
702 setVlan=""):
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700703 """
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800704 Installs a Single to Multi Point Intent
705
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700706 Description:
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800707 Install a single to multi point intent using
708 add-single-to-multi-intent
709
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700710 Steps:
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800711 - Fetch host data if not given
712 - Add single to multi intent
713 - Ingress device is the first sender host
714 - Egress devices are the recipient devices
715 - Ports if defined in senders or recipients
716 - MAC address ethSrc loaded from Ingress device
717 - Check intent state with retry
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700718 Required:
719 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800720 senders - List of host dictionaries i.e.
721 { "name":"h8", "device":"of:0000000000000005/8","mac":"00:00:00:00:00:08" }
722 recipients - List of host dictionaries i.e.
723 { "name":"h16", "device":"of:0000000000000006/8", "mac":"00:00:00:00:00:10" }
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700724 Optional:
725 onosNode - ONOS node to install the intents in main.CLIs[ ]
726 0 by default so that it will always use the first
727 ONOS node
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700728 ethType - Ethernet type eg. IPV4, IPV6
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700729 bandwidth - Bandwidth capacity
730 lambdaAlloc - Allocate lambda, defaults to False
731 ipProto - IP protocol
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700732 tcp - TCP ports in the same order as the hosts in hostNames
733 sw1 - First switch to bring down & up for rerouting purpose
734 sw2 - Second switch to bring down & up for rerouting purpose
735 expectedLink - Expected link when the switches are down, it should
736 be two links lower than the links before the two
737 switches are down
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700738 """
739
740 assert main, "There is no main variable"
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800741 assert senders, "You must specify a sender"
742 assert recipients, "You must specify a recipient"
743 # Assert devices or main.hostsData, "You must specify devices"
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700744
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800745 global itemName # The name of this run. Used for logs.
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700746 itemName = name
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700747 onosNode = int( onosNode )
748
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700749 main.log.info( itemName + ": Adding single point to multi point intents" )
750
Jeremyd9e4eb12016-04-13 12:09:06 -0700751 try:
752 for sender in senders:
753 if not sender.get( "device" ):
754 main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
755 sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700756
Jeremyd9e4eb12016-04-13 12:09:06 -0700757 for recipient in recipients:
758 if not recipient.get( "device" ):
759 main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
760 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700761
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700762
Jeremyd9e4eb12016-04-13 12:09:06 -0700763 ingressDevice = senders[ 0 ].get( "device" )
764 egressDeviceList = [ x.get( "device" ) for x in recipients if x.get( "device" ) ]
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800765
Jeremyd9e4eb12016-04-13 12:09:06 -0700766 portIngress = senders[ 0 ].get( "port", "" )
767 portEgressList = [ x.get( "port" ) for x in recipients if x.get( "port" ) ]
768 if not portEgressList:
769 portEgressList = None
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800770
Jeremyd9e4eb12016-04-13 12:09:06 -0700771 srcMac = senders[ 0 ].get( "mac" )
Jeremy Songster832f9e92016-05-05 14:30:49 -0700772 vlanId = senders[ 0 ].get( "vlan" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800773
Jeremyd9e4eb12016-04-13 12:09:06 -0700774 # Adding point intent
775 intentId = main.CLIs[ onosNode ].addSinglepointToMultipointIntent(
776 ingressDevice=ingressDevice,
777 egressDeviceList=egressDeviceList,
778 portIngress=portIngress,
779 portEgressList=portEgressList,
780 ethType=ethType,
781 ethSrc=srcMac,
782 bandwidth=bandwidth,
783 lambdaAlloc=lambdaAlloc,
784 ipProto=ipProto,
785 ipSrc="",
786 ipDst="",
787 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -0700788 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -0700789 vlanId=vlanId,
790 setVlan=setVlan )
Jeremyd9e4eb12016-04-13 12:09:06 -0700791 except (KeyError, TypeError):
792 errorMsg = "There was a problem loading the hosts data."
793 if intentId:
794 errorMsg += " There was a problem installing Singlepoint to Multipoint intent."
795 main.log.error( errorMsg )
796 return main.FALSE
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700797
798 # Check intents state
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800799 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, [ intentId ] ), sleep=main.checkIntentSleep ):
800 return intentId
acsmarsd4862d12015-10-06 17:57:34 -0700801 else:
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800802 main.log.error( "Single to Multi Intent did not install correctly" )
803 return main.FALSE
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700804
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800805def installMultiToSingleIntent( main,
806 name,
807 senders,
808 recipients,
809 onosNode=0,
810 ethType="",
811 bandwidth="",
812 lambdaAlloc=False,
813 ipProto="",
814 ipAddresses="",
815 tcp="",
816 sw1="",
Jeremy Songsterff553672016-05-12 17:06:23 -0700817 sw2="",
818 setVlan=""):
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700819 """
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800820 Installs a Multi to Single Point Intent
821
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700822 Description:
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800823 Install a multi to single point intent using
824 add-multi-to-single-intent
825
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700826 Steps:
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800827 - Fetch host data if not given
828 - Add multi to single intent
829 - Ingress devices are the senders devices
830 - Egress device is the first recipient host
831 - Ports if defined in senders or recipients
832 - MAC address ethSrc loaded from Ingress device
833 - Check intent state with retry
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700834 Required:
835 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800836 senders - List of host dictionaries i.e.
837 [ { "name":"h8", "device":"of:0000000000000005/8","mac":"00:00:00:00:00:08" } ]
838 recipients - List of host dictionaries i.e.
839 [ { "name":"h16", "device":"of:0000000000000006/8", "mac":"00:00:00:00:00:10" } ]
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700840 Optional:
841 onosNode - ONOS node to install the intents in main.CLIs[ ]
842 0 by default so that it will always use the first
843 ONOS node
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700844 ethType - Ethernet type eg. IPV4, IPV6
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700845 bandwidth - Bandwidth capacity
846 lambdaAlloc - Allocate lambda, defaults to False
847 ipProto - IP protocol
kelvin-onlab58dc39e2015-08-06 08:11:09 -0700848 tcp - TCP ports in the same order as the hosts in hostNames
849 sw1 - First switch to bring down & up for rerouting purpose
850 sw2 - Second switch to bring down & up for rerouting purpose
851 expectedLink - Expected link when the switches are down, it should
852 be two links lower than the links before the two
853 switches are down
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700854 """
855
856 assert main, "There is no main variable"
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800857 assert senders, "You must specify a sender"
858 assert recipients, "You must specify a recipient"
859 # Assert devices or main.hostsData, "You must specify devices"
860
861 global itemName # The name of this run. Used for logs.
862 itemName = name
863 onosNode = int( onosNode )
864
865 main.log.info( itemName + ": Adding mutli to single point intents" )
866
Jeremyd9e4eb12016-04-13 12:09:06 -0700867 try:
868 for sender in senders:
869 if not sender.get( "device" ):
870 main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
871 sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800872
Jeremyd9e4eb12016-04-13 12:09:06 -0700873 for recipient in recipients:
874 if not recipient.get( "device" ):
875 main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
876 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800877
Jeremyd9e4eb12016-04-13 12:09:06 -0700878 ingressDeviceList = [ x.get( "device" ) for x in senders if x.get( "device" ) ]
879 egressDevice = recipients[ 0 ].get( "device" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800880
Jeremyd9e4eb12016-04-13 12:09:06 -0700881 portIngressList = [ x.get( "port" ) for x in senders if x.get( "port" ) ]
882 portEgress = recipients[ 0 ].get( "port", "" )
883 if not portIngressList:
884 portIngressList = None
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800885
Jeremyd9e4eb12016-04-13 12:09:06 -0700886 dstMac = recipients[ 0 ].get( "mac" )
Jeremy Songster832f9e92016-05-05 14:30:49 -0700887 vlanId = senders[ 0 ].get( "vlan" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800888
Jeremyd9e4eb12016-04-13 12:09:06 -0700889 # Adding point intent
890 intentId = main.CLIs[ onosNode ].addMultipointToSinglepointIntent(
891 ingressDeviceList=ingressDeviceList,
892 egressDevice=egressDevice,
893 portIngressList=portIngressList,
894 portEgress=portEgress,
895 ethType=ethType,
896 ethDst=dstMac,
897 bandwidth=bandwidth,
898 lambdaAlloc=lambdaAlloc,
899 ipProto=ipProto,
900 ipSrc="",
901 ipDst="",
902 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -0700903 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -0700904 vlanId=vlanId,
905 setVlan=setVlan )
Jeremyd9e4eb12016-04-13 12:09:06 -0700906 except (KeyError, TypeError):
907 errorMsg = "There was a problem loading the hosts data."
908 if intentId:
909 errorMsg += " There was a problem installing Multipoint to Singlepoint intent."
910 main.log.error( errorMsg )
911 return main.FALSE
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800912
913 # Check intents state
914 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, [ intentId ] ), sleep=main.checkIntentSleep ):
915 return intentId
916 else:
917 main.log.error( "Multi to Single Intent did not install correctly" )
918 return main.FALSE
919
920def testPointIntent( main,
Jeremye0cb5eb2016-01-27 17:39:09 -0800921 name,
922 intentId,
923 senders,
924 recipients,
925 badSenders={},
926 badRecipients={},
927 onosNode=0,
928 ethType="",
929 bandwidth="",
930 lambdaAlloc=False,
931 ipProto="",
932 ipAddresses="",
933 tcp="",
934 sw1="s5",
935 sw2="s2",
Jeremy Songstere405d3d2016-05-17 11:18:57 -0700936 expectedLink=0,
937 useTCP=False):
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800938 """
939 Test a Point Intent
940
941 Description:
942 Test a point intent
943
944 Steps:
945 - Fetch host data if not given
946 - Check Intent State
947 - Check Flow State
948 - Check Connectivity
949 - Check Lack of Connectivity Between Hosts not in the Intent
950 - Reroute
951 - Take Expected Link Down
952 - Check Intent State
953 - Check Flow State
954 - Check Topology
955 - Check Connectivity
956 - Bring Expected Link Up
957 - Check Intent State
958 - Check Flow State
959 - Check Topology
960 - Check Connectivity
961 - Remove Topology
962
963 Required:
964 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
965
966 senders - List of host dictionaries i.e.
967 { "name":"h8", "device":"of:0000000000000005/8","mac":"00:00:00:00:00:08" }
968 recipients - List of host dictionaries i.e.
969 { "name":"h16", "device":"of:0000000000000006/8", "mac":"00:00:00:00:00:10" }
970 Optional:
971 onosNode - ONOS node to install the intents in main.CLIs[ ]
972 0 by default so that it will always use the first
973 ONOS node
974 ethType - Ethernet type eg. IPV4, IPV6
975 bandwidth - Bandwidth capacity
976 lambdaAlloc - Allocate lambda, defaults to False
977 ipProto - IP protocol
978 tcp - TCP ports in the same order as the hosts in hostNames
979 sw1 - First switch to bring down & up for rerouting purpose
980 sw2 - Second switch to bring down & up for rerouting purpose
981 expectedLink - Expected link when the switches are down, it should
982 be two links lower than the links before the two
983 switches are down
984
985 """
986
987 # Parameter Validity Check
988 assert main, "There is no main variable"
989 assert senders, "You must specify a sender"
990 assert recipients, "You must specify a recipient"
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700991
992 global itemName
993 itemName = name
994 tempHostsData = {}
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700995 onosNode = int( onosNode )
996
Jeremy Songster1f39bf02016-01-20 17:17:25 -0800997 main.log.info( itemName + ": Testing Point Intent" )
kelvin-onlabd48a68c2015-07-13 16:01:36 -0700998
Jeremyd9e4eb12016-04-13 12:09:06 -0700999 try:
1000 # Names for scapy
1001 senderNames = [ x.get( "name" ) for x in senders ]
1002 recipientNames = [ x.get( "name" ) for x in recipients ]
1003 badSenderNames = [ x.get( "name" ) for x in badSenders ]
1004 badRecipientNames = [ x.get( "name" ) for x in badRecipients ]
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001005
Jeremyd9e4eb12016-04-13 12:09:06 -07001006 for sender in senders:
1007 if not sender.get( "device" ):
1008 main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
1009 sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001010
Jeremyd9e4eb12016-04-13 12:09:06 -07001011 for recipient in recipients:
1012 if not recipient.get( "device" ):
1013 main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
1014 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
Jeremy Songster832f9e92016-05-05 14:30:49 -07001015 vlanId = senders[ 0 ].get( "vlan" )
Jeremyd9e4eb12016-04-13 12:09:06 -07001016 except (KeyError, TypeError):
1017 main.log.error( "There was a problem loading the hosts data." )
1018 return main.FALSE
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001019
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001020 testResult = main.TRUE
1021 main.log.info( itemName + ": Adding single point to multi point intents" )
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001022
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001023 # Check intent state
1024 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, [ intentId ] ), sleep=main.checkIntentSleep ):
1025 main.assertReturnString += 'Initial Intent State Passed\n'
acsmarsd4862d12015-10-06 17:57:34 -07001026 else:
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001027 main.assertReturnString += 'Initial Intent State Failed\n'
1028 testResult = main.FALSE
1029
1030 # Check flows count in each node
Jeremy03dab012016-04-11 08:59:17 -07001031 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 -08001032 main.assertReturnString += 'Initial Flow State Passed\n'
1033 else:
1034 main.assertReturnString += 'Intial Flow State Failed\n'
1035 testResult = main.FALSE
1036
1037 # Check Connectivity
Jeremy Songstere405d3d2016-05-17 11:18:57 -07001038 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId, useTCP ), attempts=3, sleep=5 ):
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001039 main.assertReturnString += 'Initial Ping Passed\n'
1040 else:
1041 main.assertReturnString += 'Initial Ping Failed\n'
1042 testResult = main.FALSE
1043
1044 # Check connections that shouldn't work
1045 if badSenderNames:
1046 main.log.info( "Checking that packets from incorrect sender do not go through" )
1047 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, badSenderNames, recipientNames ), kwargs={ "expectFailure":True } ):
1048 main.assertReturnString += 'Bad Sender Ping Passed\n'
1049 else:
1050 main.assertReturnString += 'Bad Sender Ping Failed\n'
1051 testResult = main.FALSE
1052
1053 if badRecipientNames:
1054 main.log.info( "Checking that packets to incorrect recipients do not go through" )
1055 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, badRecipientNames ), kwargs={ "expectFailure":True } ):
1056 main.assertReturnString += 'Bad Recipient Ping Passed\n'
1057 else:
1058 main.assertReturnString += 'Bad Recipient Ping Failed\n'
1059 testResult = main.FALSE
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001060
1061 # Test rerouting if these variables exist
1062 if sw1 and sw2 and expectedLink:
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001063 # Take link down
1064 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "down" ) ):
acsmarsd4862d12015-10-06 17:57:34 -07001065 main.assertReturnString += 'Link Down Passed\n'
1066 else:
1067 main.assertReturnString += 'Link Down Failed\n'
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001068 testResult = main.FALSE
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001069
acsmarsd4862d12015-10-06 17:57:34 -07001070 # Check intent state
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001071 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, [ intentId ] ), sleep=main.checkIntentSleep ):
acsmarsd4862d12015-10-06 17:57:34 -07001072 main.assertReturnString += 'Link Down Intent State Passed\n'
1073 else:
1074 main.assertReturnString += 'Link Down Intent State Failed\n'
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001075 testResult = main.FALSE
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001076
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001077 # Check flows count in each node
Jeremy03dab012016-04-11 08:59:17 -07001078 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 -08001079 main.assertReturnString += 'Link Down Flow State Passed\n'
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001080 else:
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001081 main.assertReturnString += 'Link Down Flow State Failed\n'
1082 testResult = main.FALSE
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001083
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001084 # Check OnosTopology
1085 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, expectedLink ) ):
1086 main.assertReturnString += 'Link Down Topology State Passed\n'
1087 else:
1088 main.assertReturnString += 'Link Down Topology State Failed\n'
1089 testResult = main.FALSE
1090
1091 # Check Connection
Jeremy Songstere405d3d2016-05-17 11:18:57 -07001092 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId, useTCP ) ):
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001093 main.assertReturnString += 'Link Down Pingall Passed\n'
1094 else:
1095 main.assertReturnString += 'Link Down Pingall Failed\n'
1096 testResult = main.FALSE
1097
1098 # Bring link up
1099 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "up" ) ):
acsmarsd4862d12015-10-06 17:57:34 -07001100 main.assertReturnString += 'Link Up Passed\n'
1101 else:
1102 main.assertReturnString += 'Link Up Failed\n'
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001103 testResult = main.FALSE
acsmarsd4862d12015-10-06 17:57:34 -07001104
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001105 # Wait for reroute
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001106 time.sleep( main.rerouteSleep )
1107
acsmarsd4862d12015-10-06 17:57:34 -07001108 # Check Intents
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001109 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, [ intentId ] ), sleep=main.checkIntentSleep ):
acsmarsd4862d12015-10-06 17:57:34 -07001110 main.assertReturnString += 'Link Up Intent State Passed\n'
1111 else:
1112 main.assertReturnString += 'Link Up Intent State Failed\n'
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001113 testResult = main.FALSE
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001114
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001115 # Check flows count in each node
Jeremy03dab012016-04-11 08:59:17 -07001116 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 -08001117 main.assertReturnString += 'Link Up Flow State Passed\n'
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001118 else:
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001119 main.assertReturnString += 'Link Up Flow State Failed\n'
1120 testResult = main.FALSE
1121
1122 # Check OnosTopology
1123 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, main.numLinks ) ):
1124 main.assertReturnString += 'Link Up Topology State Passed\n'
1125 else:
1126 main.assertReturnString += 'Link Up Topology State Failed\n'
1127 testResult = main.FALSE
1128
1129 # Check Connection
Jeremy Songstere405d3d2016-05-17 11:18:57 -07001130 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId, useTCP ) ):
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001131 main.assertReturnString += 'Link Up Scapy Packet Received Passed\n'
1132 else:
1133 main.assertReturnString += 'Link Up Scapy Packet Recieved Failed\n'
1134 testResult = main.FALSE
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001135
1136 # Remove all intents
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001137 if utilities.retry( f=removeAllIntents, retValue=main.FALSE, args=( main, [ intentId ] ) ):
acsmarsd4862d12015-10-06 17:57:34 -07001138 main.assertReturnString += 'Remove Intents Passed'
1139 else:
1140 main.assertReturnString += 'Remove Intents Failed'
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001141 testResult = main.FALSE
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001142
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001143 return testResult
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001144
Jeremye0cb5eb2016-01-27 17:39:09 -08001145def testEndPointFail( main,
1146 name,
1147 intentId,
1148 senders,
1149 recipients,
1150 isolatedSenders,
1151 isolatedRecipients,
1152 onosNode=0,
1153 ethType="",
1154 bandwidth="",
1155 lambdaAlloc=False,
1156 ipProto="",
1157 ipAddresses="",
1158 tcp="",
1159 sw1="",
1160 sw2="",
1161 sw3="",
1162 sw4="",
1163 sw5="",
1164 expectedLink1=0,
1165 expectedLink2=0 ):
1166 """
1167 Test Single to Multipoint Topology for Endpoint failures
1168 """
1169
1170 # Parameter Validity Check
1171 assert main, "There is no main variable"
1172 assert senders, "You must specify a sender"
1173 assert recipients, "You must specify a recipient"
1174
1175 global itemName
1176 itemName = name
1177 tempHostsData = {}
1178 onosNode = int( onosNode )
1179
1180 main.log.info( itemName + ": Testing Point Intent" )
1181
Jeremyd9e4eb12016-04-13 12:09:06 -07001182 try:
1183 # Names for scapy
1184 senderNames = [ x.get( "name" ) for x in senders ]
1185 recipientNames = [ x.get( "name" ) for x in recipients ]
1186 isolatedSenderNames = [ x.get( "name" ) for x in isolatedSenders ]
1187 isolatedRecipientNames = [ x.get( "name" ) for x in isolatedRecipients ]
1188 connectedSenderNames = [x.get("name") for x in senders if x.get("name") not in isolatedSenderNames]
1189 connectedRecipientNames = [x.get("name") for x in recipients if x.get("name") not in isolatedRecipientNames]
Jeremye0cb5eb2016-01-27 17:39:09 -08001190
Jeremyd9e4eb12016-04-13 12:09:06 -07001191 for sender in senders:
1192 if not sender.get( "device" ):
1193 main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
1194 sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )
Jeremye0cb5eb2016-01-27 17:39:09 -08001195
Jeremyd9e4eb12016-04-13 12:09:06 -07001196 for recipient in recipients:
1197 if not recipient.get( "device" ):
1198 main.log.warn( "Device not given for recipient {0}. Loading from\
1199 main.hostData".format( recipient.get( "name" ) ) )
1200 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
1201 except (KeyError, TypeError):
1202 main.log.error( "There was a problem loading the hosts data." )
1203 return main.FALSE
Jeremye0cb5eb2016-01-27 17:39:09 -08001204
1205 testResult = main.TRUE
1206 main.log.info( itemName + ": Adding multi point to single point intents" )
1207
1208 # Check intent state
1209 if utilities.retry( f=checkIntentState, retValue=main.FALSE,
1210 args=( main, [ intentId ] ), sleep=main.checkIntentSleep ):
1211 main.assertReturnString += 'Initial Intent State Passed\n'
1212 else:
1213 main.assertReturnString += 'Initial Intent State Failed\n'
1214 testResult = main.FALSE
1215
1216 # Check flows count in each node
1217 if utilities.retry( f=checkFlowsCount, retValue=main.FALSE,
1218 args=[ main ] ) and utilities.retry( f=checkFlowsState,
1219 retValue=main.FALSE,
1220 args=[ main ] ):
1221 main.assertReturnString += 'Initial Flow State Passed\n'
1222 else:
1223 main.assertReturnString += 'Intial Flow State Failed\n'
1224 testResult = main.FALSE
1225
1226 # Check Connectivity
1227 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE,
1228 args=( main, senderNames, recipientNames ) ):
1229 main.assertReturnString += 'Initial Connectivity Check Passed\n'
1230 else:
1231 main.assertReturnString += 'Initial Connectivity Check Failed\n'
1232 testResult = main.FALSE
1233
1234 # Take two links down
1235 # Take first link down
1236 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "down" ) ):
1237 main.assertReturnString += 'Link Down Passed\n'
1238 else:
1239 main.assertReturnString += 'Link Down Failed\n'
1240 testResult = main.FALSE
1241
1242 # Take second link down
1243 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw3, sw4, "down" ) ):
1244 main.assertReturnString += 'Link Down Passed\n'
1245 else:
1246 main.assertReturnString += 'Link Down Failed\n'
1247 testResult = main.FALSE
1248
1249 # Check intent state
1250 if utilities.retry( f=checkIntentState, retValue=main.FALSE,
1251 args=( main, [ intentId ] ), sleep=main.checkIntentSleep ):
1252 main.assertReturnString += 'Link Down Intent State Passed\n'
1253 else:
1254 main.assertReturnString += 'Link Down Intent State Failed\n'
1255 testResult = main.FALSE
1256
1257 # Check flows count in each node
1258 if utilities.retry( f=checkFlowsCount, retValue=main.FALSE,
1259 args=[ main ] ) and utilities.retry( f=checkFlowsState,
1260 retValue=main.FALSE, args=[ main ] ):
1261 main.assertReturnString += 'Link Down Flow State Passed\n'
1262 else:
1263 main.assertReturnString += 'Link Down Flow State Failed\n'
1264 testResult = main.FALSE
1265
1266 # Check OnosTopology
1267 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, expectedLink1 ) ):
1268 main.assertReturnString += 'Link Down Topology State Passed\n'
1269 else:
1270 main.assertReturnString += 'Link Down Topology State Failed\n'
1271 testResult = main.FALSE
1272
1273 # Check Connection
1274 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE,
1275 args=( main, senderNames, recipientNames ) ):
1276 main.assertReturnString += 'Link Down Connectivity Check Passed\n'
1277 else:
1278 main.assertReturnString += 'Link Down Connectivity Check Failed\n'
1279 testResult = main.FALSE
1280
1281 # Take a third link down to isolate one node
1282 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw3, sw5, "down" ) ):
1283 main.assertReturnString += 'Isolation link Down Passed\n'
1284 else:
1285 main.assertReturnString += 'Isolation link Down Failed\n'
1286 testResult = main.FALSE
1287
1288 # Check intent state
1289 if utilities.retry( f=checkIntentState, retValue=main.FALSE,
1290 args=( main, [ intentId ] ), sleep=main.checkIntentSleep ):
1291 main.assertReturnString += 'Isolation link Down Intent State Passed\n'
1292 else:
1293 main.assertReturnString += 'Isolation link Down Intent State Failed\n'
1294 testResult = main.FALSE
1295
1296 # Check flows count in each node
1297 if utilities.retry( f=checkFlowsCount, retValue=main.FALSE,
1298 args=[ main ] ) and utilities.retry( f=checkFlowsState,
1299 retValue=main.FALSE, args=[ main ] ):
1300 main.assertReturnString += 'Isolation link Down Flow State Passed\n'
1301 else:
1302 main.assertReturnString += 'Isolation link Down Flow State Failed\n'
1303 testResult = main.FALSE
1304
1305 # Check OnosTopology
1306 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, expectedLink2 ) ):
1307 main.assertReturnString += 'Isolation link Down Topology State Passed\n'
1308 else:
1309 main.assertReturnString += 'Isolation link Down Topology State Failed\n'
1310 testResult = main.FALSE
1311
1312 # Check Connectivity
1313 # First check connectivity of any isolated senders to recipients
1314 if isolatedSenderNames:
Jeremy Songstere405d3d2016-05-17 11:18:57 -07001315 if scapyCheckConnection( main, isolatedSenderNames, recipientNames, None, None, None, None, main.TRUE ):
Jeremye0cb5eb2016-01-27 17:39:09 -08001316 main.assertReturnString += 'Isolation link Down Connectivity Check Passed\n'
1317 else:
1318 main.assertReturnString += 'Isolation link Down Connectivity Check Failed\n'
1319 testResult = main.FALSE
1320
1321 # Next check connectivity of senders to any isolated recipients
1322 if isolatedRecipientNames:
Jeremy Songstere405d3d2016-05-17 11:18:57 -07001323 if scapyCheckConnection( main, senderNames, isolatedRecipientNames, None, None, None, None, main.TRUE ):
Jeremye0cb5eb2016-01-27 17:39:09 -08001324 main.assertReturnString += 'Isolation link Down Connectivity Check Passed\n'
1325 else:
1326 main.assertReturnString += 'Isolation link Down Connectivity Check Failed\n'
1327 testResult = main.FALSE
1328
1329 # Next check connectivity of connected senders and recipients
1330 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE,
1331 args=( main, connectedSenderNames , connectedRecipientNames ) ):
1332 main.assertReturnString += 'Isolation link Down Connectivity Check Passed\n'
1333 else:
1334 main.assertReturnString += 'Isolation link Down Connectivity Check Failed\n'
1335 testResult = main.FALSE
1336
1337 # Bring the links back up
1338 # Bring first link up
1339 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "up" ) ):
1340 main.assertReturnString += 'Link Up Passed\n'
1341 else:
1342 main.assertReturnString += 'Link Up Failed\n'
1343 testResult = main.FALSE
1344
1345 # Bring second link up
1346 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw3, sw5, "up" ) ):
1347 main.assertReturnString += 'Link Up Passed\n'
1348 else:
1349 main.assertReturnString += 'Link Up Failed\n'
1350 testResult = main.FALSE
1351
1352 # Bring third link up
1353 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw3, sw4, "up" ) ):
1354 main.assertReturnString += 'Link Up Passed\n'
1355 else:
1356 main.assertReturnString += 'Link Up Failed\n'
1357 testResult = main.FALSE
1358
1359 # Wait for reroute
1360 time.sleep( main.rerouteSleep )
1361
1362 # Check Intents
1363 if utilities.retry( f=checkIntentState, retValue=main.FALSE,
1364 args=( main, [ intentId ] ), sleep=main.checkIntentSleep ):
1365 main.assertReturnString += 'Link Up Intent State Passed\n'
1366 else:
1367 main.assertReturnString += 'Link Up Intent State Failed\n'
1368 testResult = main.FALSE
1369
1370 # Check flows count in each node
1371 if utilities.retry( f=checkFlowsCount, retValue=main.FALSE,
1372 args=[ main ] ) and utilities.retry( f=checkFlowsState,
1373 retValue=main.FALSE, args=[ main ] ):
1374 main.assertReturnString += 'Link Up Flow State Passed\n'
1375 else:
1376 main.assertReturnString += 'Link Up Flow State Failed\n'
1377 testResult = main.FALSE
1378
1379 # Check OnosTopology
1380 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, main.numLinks ) ):
1381 main.assertReturnString += 'Link Up Topology State Passed\n'
1382 else:
1383 main.assertReturnString += 'Link Up Topology State Failed\n'
1384 testResult = main.FALSE
1385
1386 # Check Connection
1387 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE,
1388 args=( main, senderNames, recipientNames ) ):
1389 main.assertReturnString += 'Link Up Scapy Packet Received Passed\n'
1390 else:
1391 main.assertReturnString += 'Link Up Scapy Packet Recieved Failed\n'
1392 testResult = main.FALSE
1393
1394 # Remove all intents
1395 if utilities.retry( f=removeAllIntents, retValue=main.FALSE, args=( main, [ intentId ] ) ):
1396 main.assertReturnString += 'Remove Intents Passed'
1397 else:
1398 main.assertReturnString += 'Remove Intents Failed'
1399 testResult = main.FALSE
1400
1401 return testResult
1402
1403
kelvin-onlab58dc39e2015-08-06 08:11:09 -07001404def pingallHosts( main, hostList ):
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001405 """
1406 Ping all host in the hosts list variable
1407 """
Jon Halla5cb3412015-08-18 14:08:22 -07001408 main.log.info( "Pinging: " + str( hostList ) )
1409 return main.Mininet1.pingallHosts( hostList )
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001410
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001411def fwdPingall( main ):
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001412 """
1413 Use fwd app and pingall to discover all the hosts
1414 """
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001415 activateResult = main.TRUE
1416 appCheck = main.TRUE
1417 getDataResult = main.TRUE
1418 main.log.info( "Activating reactive forwarding app " )
1419 activateResult = main.CLIs[ 0 ].activateApp( "org.onosproject.fwd" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001420
1421 # Wait for forward app activation to propagate
kelvin-onlab0ad05d12015-07-23 14:21:15 -07001422 time.sleep( main.fwdSleep )
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001423
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001424 # Check that forwarding is enabled on all nodes
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001425 for i in range( main.numCtrls ):
1426 appCheck = appCheck and main.CLIs[ i ].appToIDCheck()
1427 if appCheck != main.TRUE:
1428 main.log.warn( main.CLIs[ i ].apps() )
1429 main.log.warn( main.CLIs[ i ].appIDs() )
1430
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001431 # Send pingall in mininet
1432 main.log.info( "Run Pingall" )
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001433 pingResult = main.Mininet1.pingall( timeout = 600 )
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001434
1435 main.log.info( "Deactivating reactive forwarding app " )
1436 deactivateResult = main.CLIs[ 0 ].deactivateApp( "org.onosproject.fwd" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001437 if activateResult and deactivateResult:
1438 main.log.info( "Successfully used fwd app to discover hosts" )
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001439 getDataResult = main.TRUE
1440 else:
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001441 main.log.info( "Failed to use fwd app to discover hosts" )
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001442 getDataResult = main.FALSE
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001443 return getDataResult
1444
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001445def confirmHostDiscovery( main ):
1446 """
1447 Confirms that all ONOS nodes have discovered all scapy hosts
1448 """
1449 import collections
1450 scapyHostCount = len( main.scapyHosts )
1451 hosts = main.topo.getAllHosts( main ) # Get host data from each ONOS node
1452 hostFails = [] # Reset for each failed attempt
1453
1454 # Check for matching hosts on each node
1455 scapyHostIPs = [ x.hostIp for x in main.scapyHosts if x.hostIp != "0.0.0.0" ]
1456 for controller in range( main.numCtrls ):
1457 controllerStr = str( controller + 1 ) # ONOS node number
1458 # Compare Hosts
1459 # Load hosts data for controller node
Jeremyd9e4eb12016-04-13 12:09:06 -07001460 try:
1461 if hosts[ controller ]:
1462 main.log.info( "Hosts discovered" )
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001463 else:
Jeremyd9e4eb12016-04-13 12:09:06 -07001464 main.log.error( "Problem discovering hosts" )
1465 if hosts[ controller ] and "Error" not in hosts[ controller ]:
1466 try:
1467 hostData = json.loads( hosts[ controller ] )
1468 except ( TypeError, ValueError ):
1469 main.log.error( "Could not load json:" + str( hosts[ controller ] ) )
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001470 hostFails.append( controllerStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001471 else:
1472 onosHostIPs = [ x.get( "ipAddresses" )[ 0 ]
1473 for x in hostData
1474 if len( x.get( "ipAddresses" ) ) > 0 ]
1475 if not set( collections.Counter( scapyHostIPs ) ).issubset( set ( collections.Counter( onosHostIPs ) ) ):
1476 main.log.warn( "Controller {0} only sees nodes with {1} IPs. It should see all of the following: {2}".format( controllerStr, onosHostIPs, scapyHostIPs ) )
1477 hostFails.append( controllerStr )
1478 else:
1479 main.log.error( "Hosts returned nothing or an error." )
1480 hostFails.append( controllerStr )
1481 except IndexError:
1482 main.log.error( "Hosts returned nothing, Failed to discover hosts." )
1483 return main.FALSE
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001484
1485 if hostFails:
1486 main.log.error( "List of failed ONOS Nodes:" + ', '.join(map(str, hostFails )) )
1487 return main.FALSE
1488 else:
1489 return main.TRUE
1490
1491def sendDiscoveryArp( main, hosts=None ):
1492 """
1493 Sends Discovery ARP packets from each host provided
1494 Defaults to each host in main.scapyHosts
1495 """
1496 # Send an arp ping from each host
1497 if not hosts:
1498 hosts = main.scapyHosts
1499 for host in hosts:
1500 pkt = 'Ether( src="{0}")/ARP( psrc="{1}")'.format( host.hostMac ,host.hostIp )
1501 # Send from the VLAN interface if there is one so ONOS discovers the VLAN correctly
1502 iface = None
1503 for interface in host.getIfList():
1504 if '.' in interface:
1505 main.log.debug( "Detected VLAN interface {0}. Sending ARP packet from {0}".format( interface ) )
1506 iface = interface
1507 break
1508 host.sendPacket( packet=pkt, iface=iface )
1509 main.log.info( "Sending ARP packet from {0}".format( host.name ) )
1510
1511def populateHostData( main ):
1512 """
1513 Populates hostsData
1514 """
1515 import json
1516 try:
1517 hostsJson = json.loads( main.CLIs[ 0 ].hosts() )
1518 hosts = main.Mininet1.getHosts().keys()
1519 # TODO: Make better use of new getHosts function
1520 for host in hosts:
1521 main.hostsData[ host ] = {}
1522 main.hostsData[ host ][ 'mac' ] = \
1523 main.Mininet1.getMacAddress( host ).upper()
1524 for hostj in hostsJson:
1525 if main.hostsData[ host ][ 'mac' ] == hostj[ 'mac' ]:
1526 main.hostsData[ host ][ 'id' ] = hostj[ 'id' ]
1527 main.hostsData[ host ][ 'vlan' ] = hostj[ 'vlan' ]
1528 main.hostsData[ host ][ 'location' ] = \
1529 hostj[ 'location' ][ 'elementId' ] + '/' + \
1530 hostj[ 'location' ][ 'port' ]
1531 main.hostsData[ host ][ 'ipAddresses' ] = hostj[ 'ipAddresses' ]
1532 return main.TRUE
Jeremyd9e4eb12016-04-13 12:09:06 -07001533 except ValueError:
1534 main.log.error( "ValueError while populating hostsData" )
1535 return main.FALSE
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001536 except KeyError:
1537 main.log.error( "KeyError while populating hostsData")
1538 return main.FALSE
Jeremyd9e4eb12016-04-13 12:09:06 -07001539 except IndexError:
1540 main.log.error( "IndexError while populating hostsData" )
1541 return main.FALSE
1542 except TypeError:
1543 main.log.error( "TypeError while populating hostsData" )
1544 return main.FALSE
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001545
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001546def checkTopology( main, expectedLink ):
1547 statusResult = main.TRUE
1548 # Check onos topology
1549 main.log.info( itemName + ": Checking ONOS topology " )
1550
1551 for i in range( main.numCtrls ):
1552 topologyResult = main.CLIs[ i ].topology()
You Wang24139872016-05-03 11:48:47 -07001553 statusResult = main.CLIs[ i ].checkStatus( topologyResult,
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001554 main.numSwitch,
1555 expectedLink )\
1556 and statusResult
1557 if not statusResult:
1558 main.log.error( itemName + ": Topology mismatch" )
1559 else:
1560 main.log.info( itemName + ": Topology match" )
1561 return statusResult
1562
1563def checkIntentState( main, intentsId ):
1564 """
1565 This function will check intent state to make sure all the intents
1566 are in INSTALLED state
1567 """
1568
1569 intentResult = main.TRUE
1570 results = []
1571
1572 main.log.info( itemName + ": Checking intents state" )
1573 # First check of intents
1574 for i in range( main.numCtrls ):
1575 tempResult = main.CLIs[ i ].checkIntentState( intentsId=intentsId )
1576 results.append( tempResult )
1577
1578 expectedState = [ 'INSTALLED', 'INSTALLING' ]
1579
1580 if all( result == main.TRUE for result in results ):
1581 main.log.info( itemName + ": Intents are installed correctly" )
1582 else:
1583 # Wait for at least 5 second before checking the intents again
acsmarsb9a92692015-10-08 16:43:01 -07001584 main.log.error( "Intents are not installed correctly. Waiting 5 sec" )
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001585 time.sleep( 5 )
1586 results = []
1587 # Second check of intents since some of the intents may be in
1588 # INSTALLING state, they should be in INSTALLED at this time
1589 for i in range( main.numCtrls ):
Jeremy2f190ca2016-01-29 15:23:57 -08001590 tempResult = main.CLIs[ i ].checkIntentState( intentsId=intentsId )
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001591 results.append( tempResult )
1592 if all( result == main.TRUE for result in results ):
1593 main.log.info( itemName + ": Intents are installed correctly" )
acsmarsb9a92692015-10-08 16:43:01 -07001594 intentResult = main.TRUE
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001595 else:
1596 main.log.error( itemName + ": Intents are NOT installed correctly" )
1597 intentResult = main.FALSE
1598
1599 return intentResult
1600
1601def checkFlowsState( main ):
1602
1603 main.log.info( itemName + ": Check flows state" )
Jeremy Songsterff553672016-05-12 17:06:23 -07001604 checkFlowsResult = main.CLIs[ 0 ].checkFlowsState( isPENDING=False )
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001605 return checkFlowsResult
1606
1607def link( main, sw1, sw2, option):
1608
1609 # link down
1610 main.log.info( itemName + ": Bring link " + option + "between " +
1611 sw1 + " and " + sw2 )
1612 linkResult = main.Mininet1.link( end1=sw1, end2=sw2, option=option )
1613 return linkResult
1614
Jeremy Songstere405d3d2016-05-17 11:18:57 -07001615def scapyCheckConnection( main, senders, recipients, vlanId=None, useTCP=False, packet=None, packetFilter=None, expectFailure=False ):
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001616 """
1617 Checks the connectivity between all given sender hosts and all given recipient hosts
1618 Packet may be specified. Defaults to Ether/IP packet
1619 Packet Filter may be specified. Defaults to Ether/IP from current sender MAC
1620 Todo: Optional packet and packet filter attributes for sender and recipients
1621 Expect Failure when the sender and recipient are not supposed to have connectivity
1622 Timeout of 1 second, returns main.TRUE if the filter is not triggered and kills the filter
1623
1624 """
1625 connectionsFunctional = main.TRUE
1626
1627 if not packetFilter:
1628 packetFilter = 'ether host {}'
Jeremy Songstere405d3d2016-05-17 11:18:57 -07001629 if useTCP:
1630 packetFilter += ' ip proto \\tcp tcp port {}'.format(main.params[ 'SDNIP' ][ 'dstPort' ])
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001631 if expectFailure:
1632 timeout = 1
1633 else:
1634 timeout = 10
1635
1636 for sender in senders:
1637 try:
1638 senderComp = getattr( main, sender )
1639 except AttributeError:
1640 main.log.error( "main has no attribute {}".format( sender ) )
1641 connectionsFunctional = main.FALSE
1642 continue
1643
1644 for recipient in recipients:
1645 # Do not send packets to self since recipient CLI will already be busy
1646 if recipient == sender:
1647 continue
1648 try:
1649 recipientComp = getattr( main, recipient )
1650 except AttributeError:
1651 main.log.error( "main has no attribute {}".format( recipient ) )
1652 connectionsFunctional = main.FALSE
1653 continue
1654
Jeremy Songster832f9e92016-05-05 14:30:49 -07001655 if vlanId:
1656 recipientComp.startFilter( pktFilter = ( "vlan {}".format( vlanId ) + " && " + packetFilter.format( senderComp.hostMac ) ) )
1657 else:
1658 recipientComp.startFilter( pktFilter = packetFilter.format( senderComp.hostMac ) )
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001659
1660 if not packet:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001661 if vlanId:
1662 pkt = 'Ether( src="{0}", dst="{2}" )/Dot1Q(vlan={4})/IP( src="{1}", dst="{3}" )'.format(
1663 senderComp.hostMac,
1664 senderComp.hostIp,
1665 recipientComp.hostMac,
1666 recipientComp.hostIp,
1667 vlanId )
1668 else:
1669 pkt = 'Ether( src="{0}", dst="{2}" )/IP( src="{1}", dst="{3}" )'.format(
1670 senderComp.hostMac,
1671 senderComp.hostIp,
1672 recipientComp.hostMac,
1673 recipientComp.hostIp )
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001674 else:
1675 pkt = packet
Jeremy Songster832f9e92016-05-05 14:30:49 -07001676 if vlanId:
1677 senderComp.sendPacket( iface=( "{0}-eth0.{1}".format( sender, vlanId ) ), packet = pkt )
1678 else:
1679 senderComp.sendPacket( packet = pkt )
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001680
1681 if recipientComp.checkFilter( timeout ):
1682 if expectFailure:
1683 main.log.error( "Packet from {0} successfully received by {1} when it should not have been".format( sender , recipient ) )
1684 connectionsFunctional = main.FALSE
1685 else:
1686 main.log.info( "Packet from {0} successfully received by {1}".format( sender , recipient ) )
1687 else:
1688 recipientComp.killFilter()
1689 if expectFailure:
1690 main.log.info( "As expected, packet from {0} was not received by {1}".format( sender , recipient ) )
1691 else:
1692 main.log.error( "Packet from {0} was not received by {1}".format( sender , recipient ) )
1693 connectionsFunctional = main.FALSE
1694
1695 return connectionsFunctional
1696
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001697def removeAllIntents( main, intentsId ):
1698 """
1699 Remove all intents in the intentsId
1700 """
1701
kelvin-onlab5c706ff2015-07-20 10:56:52 -07001702 onosSummary = []
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001703 removeIntentResult = main.TRUE
1704 # Remove intents
1705 for intent in intentsId:
1706 main.CLIs[ 0 ].removeIntent( intentId=intent, purge=True )
1707
acsmarscfa52272015-08-06 15:21:45 -07001708 time.sleep( main.removeIntentSleep )
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001709
kelvin-onlab5c706ff2015-07-20 10:56:52 -07001710 # If there is remianing intents then remove intents should fail
1711 for i in range( main.numCtrls ):
1712 onosSummary.append( json.loads( main.CLIs[ i ].summary() ) )
1713
1714 for summary in onosSummary:
1715 if summary.get( 'intents' ) != 0:
1716 main.log.warn( itemName + ": There are " +
1717 str( summary.get( 'intents' ) ) +
1718 " intents remaining in node " +
1719 str( summary.get( 'node' ) ) +
1720 ", failed to remove all the intents " )
1721 removeIntentResult = main.FALSE
1722
1723 if removeIntentResult:
1724 main.log.info( itemName + ": There are no more intents remaining, " +
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001725 "successfully removed all the intents." )
kelvin-onlab5c706ff2015-07-20 10:56:52 -07001726
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001727 return removeIntentResult
1728
1729def checkFlowsCount( main ):
1730 """
1731 Check flows count in each node
1732 """
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001733 flowsCount = []
1734 main.log.info( itemName + ": Checking flows count in each ONOS node" )
1735 for i in range( main.numCtrls ):
1736 summaryResult = main.CLIs[ i ].summary()
1737 if not summaryResult:
1738 main.log.error( itemName + ": There is something wrong with " +
1739 "summary command" )
1740 return main.FALSE
1741 else:
1742 summaryJson = json.loads( summaryResult )
1743 flowsCount.append( summaryJson.get( 'flows' ) )
1744
1745 if flowsCount:
1746 if all( flows==flowsCount[ 0 ] for flows in flowsCount ):
1747 main.log.info( itemName + ": There are " + str( flowsCount[ 0 ] ) +
1748 " flows in all ONOS node" )
1749 else:
1750 for i in range( main.numCtrls ):
1751 main.log.debug( itemName + ": ONOS node " + str( i ) + " has " +
kelvin-onlab6dea6e62015-07-23 13:07:26 -07001752 str( flowsCount[ i ] ) + " flows" )
kelvin-onlabd48a68c2015-07-13 16:01:36 -07001753 else:
1754 main.log.error( "Checking flows count failed, check summary command" )
1755 return main.FALSE
1756
1757 return main.TRUE
1758
kelvin-onlab58dc39e2015-08-06 08:11:09 -07001759def checkLeaderChange( leaders1, leaders2 ):
acsmarse6b410f2015-07-17 14:39:34 -07001760 """
1761 Checks for a change in intent partition leadership.
1762
1763 Takes the output of leaders -c in json string format before and after
1764 a potential change as input
1765
1766 Returns main.TRUE if no mismatches are detected
1767 Returns main.FALSE if there is a mismatch or on error loading the input
1768 """
1769 try:
1770 leaders1 = json.loads( leaders1 )
1771 leaders2 = json.loads( leaders2 )
1772 except ( AttributeError, TypeError):
1773 main.log.exception( self.name + ": Object not as expected" )
1774 return main.FALSE
1775 except Exception:
1776 main.log.exception( self.name + ": Uncaught exception!" )
1777 main.cleanup()
1778 main.exit()
1779 main.log.info( "Checking Intent Paritions for Change in Leadership" )
1780 mismatch = False
1781 for dict1 in leaders1:
1782 if "intent" in dict1.get( "topic", [] ):
1783 for dict2 in leaders2:
1784 if dict1.get( "topic", 0 ) == dict2.get( "topic", 0 ) and \
1785 dict1.get( "leader", 0 ) != dict2.get( "leader", 0 ):
1786 mismatch = True
1787 main.log.error( "{0} changed leader from {1} to {2}".\
1788 format( dict1.get( "topic", "no-topic" ),\
1789 dict1.get( "leader", "no-leader" ),\
1790 dict2.get( "leader", "no-leader" ) ) )
1791 if mismatch:
1792 return main.FALSE
1793 else:
1794 return main.TRUE
kelvin-onlab016dce22015-08-10 09:54:11 -07001795
1796def report( main ):
1797 """
Jeremy Songster1f39bf02016-01-20 17:17:25 -08001798 Report errors/warnings/exceptions
kelvin-onlab016dce22015-08-10 09:54:11 -07001799 """
kelvin-onlab016dce22015-08-10 09:54:11 -07001800 main.ONOSbench.logReport( main.ONOSip[ 0 ],
1801 [ "INFO",
1802 "FOLLOWER",
1803 "WARN",
1804 "flow",
1805 "ERROR",
1806 "Except" ],
1807 "s" )
1808
1809 main.log.info( "ERROR report: \n" )
1810 for i in range( main.numCtrls ):
1811 main.ONOSbench.logReport( main.ONOSip[ i ],
1812 [ "ERROR" ],
1813 "d" )
1814
1815 main.log.info( "EXCEPTIONS report: \n" )
1816 for i in range( main.numCtrls ):
1817 main.ONOSbench.logReport( main.ONOSip[ i ],
1818 [ "Except" ],
1819 "d" )
1820
1821 main.log.info( "WARNING report: \n" )
1822 for i in range( main.numCtrls ):
1823 main.ONOSbench.logReport( main.ONOSip[ i ],
1824 [ "WARN" ],
1825 "d" )