blob: 900abd5b27ee7033c914c8cee5086e5b832cbe6a [file] [log] [blame]
kelvin-onlab44147802015-07-27 17:57:31 -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
kelvin-onlab0e684682015-08-11 18:51:41 -07009import types
kelvin-onlab44147802015-07-27 17:57:31 -070010
11def __init__( self ):
12 self.default = ''
13
Jeremy2f190ca2016-01-29 15:23:57 -080014def installHostIntent( main,
15 name,
16 host1,
17 host2,
18 onosNode=0,
19 ethType="",
20 bandwidth="",
21 lambdaAlloc=False,
22 ipProto="",
23 ipAddresses="",
24 tcp="",
25 sw1="",
26 sw2=""):
kelvin-onlab44147802015-07-27 17:57:31 -070027 """
Jeremy2f190ca2016-01-29 15:23:57 -080028 Installs a Host Intent
29
30 Description:
31 Install a host intent using
32 add-host-intent
33
34 Steps:
35 - 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
42 Required:
43 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
44 host1 - Dictionary for host1
45 { "name":"h8", "id":"of:0000000000000005/8" }
46 host2 - Dictionary for host2
47 { "name":"h16", "id":"of:0000000000000006/8" }
48 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
52 ethType - Ethernet type eg. IPV4, IPV6
53 bandwidth - Bandwidth capacity
54 lambdaAlloc - Allocate lambda, defaults to False
55 ipProto - IP protocol
56 tcp - TCP ports in the same order as the hosts in hostNames
kelvin-onlab44147802015-07-27 17:57:31 -070057 """
58
kelvin-onlab44147802015-07-27 17:57:31 -070059 assert main, "There is no main variable"
Jeremy2f190ca2016-01-29 15:23:57 -080060 assert host1, "You must specify host1"
61 assert host2, "You must specify host2"
kelvin-onlab44147802015-07-27 17:57:31 -070062
Jeremy2f190ca2016-01-29 15:23:57 -080063 global itemName # The name of this run. Used for logs.
kelvin-onlab44147802015-07-27 17:57:31 -070064 itemName = name
kelvin-onlab44147802015-07-27 17:57:31 -070065 onosNode = int( onosNode )
66
Jeremy2f190ca2016-01-29 15:23:57 -080067 main.log.info( itemName + ": Adding single point to multi point intents" )
kelvin-onlab44147802015-07-27 17:57:31 -070068
Jeremy2f190ca2016-01-29 15:23:57 -080069 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" )
kelvin-onlab44147802015-07-27 17:57:31 -070073
Jeremy2f190ca2016-01-29 15:23:57 -080074 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" )
kelvin-onlab44147802015-07-27 17:57:31 -070077
78 # Adding host intents
79 main.log.info( itemName + ": Adding host intents" )
80
Jeremy2f190ca2016-01-29 15:23:57 -080081 intent1 = main.CLIs[ onosNode ].addHostIntent( hostIdOne=host1.get( "id" ),
82 hostIdTwo=host2.get( "id" ) )
kelvin-onlab44147802015-07-27 17:57:31 -070083
kelvin-onlab0e684682015-08-11 18:51:41 -070084 # Get all intents ID in the system, time delay right after intents are added
85 time.sleep( main.addIntentSleep )
kelvin-onlab44147802015-07-27 17:57:31 -070086 intentsId = main.CLIs[ 0 ].getIntentsId()
kelvin-onlab44147802015-07-27 17:57:31 -070087
Jeremy2f190ca2016-01-29 15:23:57 -080088 if utilities.retry ( f=checkIntentState, retValue=main.FALSE,
89 args = (main, intentsId ), sleep=main.checkIntentSleep ):
90 return intentsId
91 else:
92 main.log.error( "Host Intent did not install correctly" )
93 return main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -070094
Jeremy2f190ca2016-01-29 15:23:57 -080095def 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
kelvin-onlab44147802015-07-27 17:57:31 -0700106
Jeremy2f190ca2016-01-29 15:23:57 -0800107 Description:
108 Test a host intent of given ID between given hosts
kelvin-onlab44147802015-07-27 17:57:31 -0700109
Jeremy2f190ca2016-01-29 15:23:57 -0800110 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
kelvin-onlab44147802015-07-27 17:57:31 -0700128
Jeremy2f190ca2016-01-29 15:23:57 -0800129 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
kelvin-onlab44147802015-07-27 17:57:31 -0700145
146 """
kelvin-onlab44147802015-07-27 17:57:31 -0700147
Jeremy2f190ca2016-01-29 15:23:57 -0800148 # Parameter Validity Check
kelvin-onlab44147802015-07-27 17:57:31 -0700149 assert main, "There is no main variable"
Jeremy2f190ca2016-01-29 15:23:57 -0800150 assert host1, "You must specify host1"
151 assert host2, "You must specify host2"
kelvin-onlab44147802015-07-27 17:57:31 -0700152
153 global itemName
154 itemName = name
Jeremy2f190ca2016-01-29 15:23:57 -0800155 tempHostsData = {}
kelvin-onlab44147802015-07-27 17:57:31 -0700156 onosNode = int( onosNode )
157
Jeremy2f190ca2016-01-29 15:23:57 -0800158 main.log.info( itemName + ": Testing Host Intent" )
kelvin-onlab44147802015-07-27 17:57:31 -0700159
Jeremy2f190ca2016-01-29 15:23:57 -0800160 if not host1.get( "id" ):
161 main.log.warn( "Id not given for host1 {0}. Loading from main.hostData".format( host1.get( "name" ) ) )
162 host1[ "id" ] = main.hostsData.get( host1.get( "name" ) ).get( "location" )
kelvin-onlab0e684682015-08-11 18:51:41 -0700163
Jeremy2f190ca2016-01-29 15:23:57 -0800164 if not host2.get( "id" ):
165 main.log.warn( "Id not given for host2 {0}. Loading from main.hostData".format( host2.get( "name" ) ) )
166 host2[ "id" ] = main.hostsData.get( host2.get( "name" ) ).get( "location" )
kelvin-onlab44147802015-07-27 17:57:31 -0700167
Jeremy2f190ca2016-01-29 15:23:57 -0800168 senderNames = [ host1.get( "name" ), host2.get( "name" ) ]
169 recipientNames = [ host1.get( "name" ), host2.get( "name" ) ]
kelvin-onlab44147802015-07-27 17:57:31 -0700170
Jeremy2f190ca2016-01-29 15:23:57 -0800171 testResult = main.TRUE
172 main.log.info( itemName + ": Adding single point to multi point intents" )
173
174 # Check intent state
175 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
176 main.assertReturnString += 'Initial Intent State Passed\n'
177 else:
178 main.assertReturnString += 'Initial Intent State Failed\n'
179 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700180
181 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800182 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 ):
Jeremy2f190ca2016-01-29 15:23:57 -0800183 main.assertReturnString += 'Initial Flow State Passed\n'
184 else:
185 main.assertReturnString += 'Intial Flow State Failed\n'
186 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700187
Jeremy2f190ca2016-01-29 15:23:57 -0800188 # Check Connectivity
189 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames ) ):
190 main.assertReturnString += 'Initial Ping Passed\n'
191 else:
192 main.assertReturnString += 'Initial Ping Failed\n'
193 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700194
195 # Test rerouting if these variables exist
196 if sw1 and sw2 and expectedLink:
Jeremy2f190ca2016-01-29 15:23:57 -0800197 # Take link down
198 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "down" ) ):
199 main.assertReturnString += 'Link Down Passed\n'
200 else:
201 main.assertReturnString += 'Link Down Failed\n'
202 testResult = main.FALSE
203
204 # Check intent state
205 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
206 main.assertReturnString += 'Link Down Intent State Passed\n'
207 else:
208 main.assertReturnString += 'Link Down Intent State Failed\n'
209 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700210
211 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800212 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 ):
Jeremy2f190ca2016-01-29 15:23:57 -0800213 main.assertReturnString += 'Link Down Flow State Passed\n'
214 else:
215 main.assertReturnString += 'Link Down Flow State Failed\n'
216 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700217
218 # Check OnosTopology
Jeremybc6a0aa2016-02-05 14:10:08 -0800219 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, expectedLink ), sleep=10 ):
Jeremy2f190ca2016-01-29 15:23:57 -0800220 main.assertReturnString += 'Link Down Topology State Passed\n'
kelvin-onlab44147802015-07-27 17:57:31 -0700221 else:
Jeremy2f190ca2016-01-29 15:23:57 -0800222 main.assertReturnString += 'Link Down Topology State Failed\n'
223 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700224
Jeremy2f190ca2016-01-29 15:23:57 -0800225 # Check Connection
226 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames ) ):
227 main.assertReturnString += 'Link Down Pingall Passed\n'
228 else:
229 main.assertReturnString += 'Link Down Pingall Failed\n'
230 testResult = main.FALSE
231
232 # Bring link up
233 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "up" ) ):
234 main.assertReturnString += 'Link Up Passed\n'
235 else:
236 main.assertReturnString += 'Link Up Failed\n'
237 testResult = main.FALSE
238
239 # Wait for reroute
kelvin-onlab44147802015-07-27 17:57:31 -0700240 time.sleep( main.rerouteSleep )
241
Jeremy2f190ca2016-01-29 15:23:57 -0800242 # Check Intents
243 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
244 main.assertReturnString += 'Link Up Intent State Passed\n'
245 else:
246 main.assertReturnString += 'Link Up Intent State Failed\n'
247 testResult = main.FALSE
248
kelvin-onlab44147802015-07-27 17:57:31 -0700249 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800250 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 ):
Jeremy2f190ca2016-01-29 15:23:57 -0800251 main.assertReturnString += 'Link Up Flow State Passed\n'
252 else:
253 main.assertReturnString += 'Link Up Flow State Failed\n'
254 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700255
256 # Check OnosTopology
Jeremy2f190ca2016-01-29 15:23:57 -0800257 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, main.numLinks ) ):
258 main.assertReturnString += 'Link Up Topology State Passed\n'
kelvin-onlab44147802015-07-27 17:57:31 -0700259 else:
Jeremy2f190ca2016-01-29 15:23:57 -0800260 main.assertReturnString += 'Link Up Topology State Failed\n'
261 testResult = main.FALSE
262
263 # Check Connection
264 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames ) ):
265 main.assertReturnString += 'Link Up Pingall Passed\n'
266 else:
267 main.assertReturnString += 'Link Up Pingall Failed\n'
268 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700269
270 # Remove all intents
Jeremy2f190ca2016-01-29 15:23:57 -0800271 if utilities.retry( f=removeAllIntents, retValue=main.FALSE, args=( main, ) ):
272 main.assertReturnString += 'Remove Intents Passed'
273 else:
274 main.assertReturnString += 'Remove Intents Failed'
275 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700276
Jeremy2f190ca2016-01-29 15:23:57 -0800277 return testResult
kelvin-onlab44147802015-07-27 17:57:31 -0700278
Jeremy2f190ca2016-01-29 15:23:57 -0800279def installPointIntent( main,
280 name,
281 senders,
282 recipients,
283 onosNode=0,
284 ethType="",
285 bandwidth="",
286 lambdaAlloc=False,
287 ipProto="",
288 ipSrc="",
289 ipDst="",
290 tcpSrc="",
291 tcpDst=""):
292 """
293 Installs a Single to Single Point Intent
294
295 Description:
296 Install a single to single point intent
297
298 Steps:
299 - Fetch host data if not given
300 - Add point intent
301 - Ingress device is the first sender device
302 - Egress device is the first recipient device
303 - Ports if defined in senders or recipients
304 - MAC address ethSrc loaded from Ingress device
305 - Check intent state with retry
306 Required:
307 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
308 senders - List of host dictionaries i.e.
309 [ { "name":"h8", "device":"of:0000000000000005/8","mac":"00:00:00:00:00:08" } ]
310 recipients - List of host dictionaries i.e.
311 [ { "name":"h16", "device":"of:0000000000000006/8", "mac":"00:00:00:00:00:10" } ]
312 Optional:
313 onosNode - ONOS node to install the intents in main.CLIs[ ]
314 0 by default so that it will always use the first
315 ONOS node
316 ethType - Ethernet type eg. IPV4, IPV6
317 bandwidth - Bandwidth capacity
318 lambdaAlloc - Allocate lambda, defaults to False
319 ipProto - IP protocol
320 tcp - TCP ports in the same order as the hosts in hostNames
321 sw1 - First switch to bring down & up for rerouting purpose
322 sw2 - Second switch to bring down & up for rerouting purpose
323 expectedLink - Expected link when the switches are down, it should
324 be two links lower than the links before the two
325 switches are down
326 """
327
328 assert main, "There is no main variable"
329 assert senders, "You must specify a sender"
330 assert recipients, "You must specify a recipient"
331 # Assert devices or main.hostsData, "You must specify devices"
332
333 global itemName # The name of this run. Used for logs.
334 itemName = name
335 onosNode = int( onosNode )
336
337 main.log.info( itemName + ": Adding single to single point intents" )
338
339 for sender in senders:
340 if not sender.get( "device" ):
341 main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
342 sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )
343
344 for recipient in recipients:
345 if not recipient.get( "device" ):
346 main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
347 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
348
349
350 ingressDevice = senders[ 0 ].get( "device" )
351 egressDevice = recipients[ 0 ].get( "device" )
352
353 portIngress = senders[ 0 ].get( "port", "" )
354 portEgress = recipients[ 0 ].get( "port", "" )
355 main.log.debug( ingressDevice )
356 main.log.debug( egressDevice )
357
358 srcMac = senders[ 0 ].get( "mac" )
359 dstMac = recipients[ 0 ].get( "mac" )
360
361 ipSrc = senders[ 0 ].get( "ip" )
362 ipDst = recipients[ 0 ].get( "ip" )
363
364 intent1 = main.CLIs[ onosNode ].addPointIntent(
365 ingressDevice=ingressDevice,
366 egressDevice=egressDevice,
367 ingressPort=portIngress,
368 egressPort=portEgress,
369 ethType=ethType,
370 ethSrc=srcMac,
371 ethDst=dstMac,
372 bandwidth=bandwidth,
373 lambdaAlloc=lambdaAlloc,
374 ipProto=ipProto,
375 ipSrc=ipSrc,
376 ipDst=ipDst,
377 tcpSrc=tcpSrc,
378 tcpDst=tcpDst )
379
380 time.sleep( main.addIntentSleep )
381 intentsId = main.CLIs[ 0 ].getIntentsId()
382
383 if utilities.retry ( f=checkIntentState, retValue=main.FALSE,
384 args = (main, intentsId ), sleep=main.checkIntentSleep ):
385 return intentsId
386 else:
387 main.log.error( "Single to Single point intent did not install correctly" )
388 return main.FALSE
389
390 # Check intents state
391 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentsId ), sleep=main.checkIntentSleep ):
392 return intentsId
393 else:
394 main.log.error( "Point Intent did not install correctly" )
395 return main.FALSE
396
397def testPointIntent( main,
398 name,
399 intentId,
400 senders,
401 recipients,
402 badSenders={},
403 badRecipients={},
404 onosNode=0,
405 ethType="",
406 bandwidth="",
407 lambdaAlloc=False,
408 ipProto="",
409 ipAddresses="",
410 tcp="",
411 sw1="s5",
412 sw2="s2",
413 expectedLink=0):
414 """
415 Test a Point Intent
416
417 Description:
418 Test a point intent
419
420 Steps:
421 - Fetch host data if not given
422 - Check Intent State
423 - Check Flow State
424 - Check Connectivity
425 - Check Lack of Connectivity Between Hosts not in the Intent
426 - Reroute
427 - Take Expected Link Down
428 - Check Intent State
429 - Check Flow State
430 - Check Topology
431 - Check Connectivity
432 - Bring Expected Link Up
433 - Check Intent State
434 - Check Flow State
435 - Check Topology
436 - Check Connectivity
437 - Remove Topology
438
439 Required:
440 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
441
442 senders - List of host dictionaries i.e.
443 { "name":"h8", "device":"of:0000000000000005/8","mac":"00:00:00:00:00:08" }
444 recipients - List of host dictionaries i.e.
445 { "name":"h16", "device":"of:0000000000000006/8", "mac":"00:00:00:00:00:10" }
446 Optional:
447 onosNode - ONOS node to install the intents in main.CLIs[ ]
448 0 by default so that it will always use the first
449 ONOS node
450 ethType - Ethernet type eg. IPV4, IPV6
451 bandwidth - Bandwidth capacity
452 lambdaAlloc - Allocate lambda, defaults to False
453 ipProto - IP protocol
454 tcp - TCP ports in the same order as the hosts in hostNames
455 sw1 - First switch to bring down & up for rerouting purpose
456 sw2 - Second switch to bring down & up for rerouting purpose
457 expectedLink - Expected link when the switches are down, it should
458 be two links lower than the links before the two
459 switches are down
460
461 """
462
463 # Parameter Validity Check
464 assert main, "There is no main variable"
465 assert senders, "You must specify a sender"
466 assert recipients, "You must specify a recipient"
467
468 global itemName
469 itemName = name
470 tempHostsData = {}
471 onosNode = int( onosNode )
472
473 main.log.info( itemName + ": Testing Point Intent" )
474
475 # Names for scapy
476 senderNames = [ x.get( "name" ) for x in senders ]
477 recipientNames = [ x.get( "name" ) for x in recipients ]
478 badSenderNames = [ x.get( "name" ) for x in badSenders ]
479 badRecipientNames = [ x.get( "name" ) for x in badRecipients ]
480
481 for sender in senders:
482 if not sender.get( "device" ):
483 main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
484 sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )
485
486 for recipient in recipients:
487 if not recipient.get( "device" ):
488 main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
489 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
490
491 testResult = main.TRUE
492 main.log.info( itemName + ": Testing point intents" )
493
494 # Check intent state
495 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
496 main.assertReturnString += 'Initial Intent State Passed\n'
497 else:
498 main.assertReturnString += 'Initial Intent State Failed\n'
499 testResult = main.FALSE
500
501 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800502 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 ):
Jeremy2f190ca2016-01-29 15:23:57 -0800503 main.assertReturnString += 'Initial Flow State Passed\n'
504 else:
505 main.assertReturnString += 'Intial Flow State Failed\n'
506 testResult = main.FALSE
507
508 # Check Connectivity
509 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames ) ):
510 main.assertReturnString += 'Initial Ping Passed\n'
511 else:
512 main.assertReturnString += 'Initial Ping Failed\n'
513 testResult = main.FALSE
514
515 # Check connections that shouldn't work
516 if badSenderNames:
517 main.log.info( "Checking that packets from incorrect sender do not go through" )
518 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, badSenderNames, recipientNames ), kwargs={ "expectFailure":True } ):
519 main.assertReturnString += 'Bad Sender Ping Passed\n'
520 else:
521 main.assertReturnString += 'Bad Sender Ping Failed\n'
522 testResult = main.FALSE
523
524 if badRecipientNames:
525 main.log.info( "Checking that packets to incorrect recipients do not go through" )
526 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, badRecipientNames ), kwargs={ "expectFailure":True } ):
527 main.assertReturnString += 'Bad Recipient Ping Passed\n'
528 else:
529 main.assertReturnString += 'Bad Recipient Ping Failed\n'
530 testResult = main.FALSE
531
532 # Test rerouting if these variables exist
533 if sw1 and sw2 and expectedLink:
534 # Take link down
535 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "down" ) ):
536 main.assertReturnString += 'Link Down Passed\n'
537 else:
538 main.assertReturnString += 'Link Down Failed\n'
539 testResult = main.FALSE
540
541 # Check intent state
542 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
543 main.assertReturnString += 'Link Down Intent State Passed\n'
544 else:
545 main.assertReturnString += 'Link Down Intent State Failed\n'
546 testResult = main.FALSE
547
548 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800549 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 ):
Jeremy2f190ca2016-01-29 15:23:57 -0800550 main.assertReturnString += 'Link Down Flow State Passed\n'
551 else:
552 main.assertReturnString += 'Link Down Flow State Failed\n'
553 testResult = main.FALSE
554
555 # Check OnosTopology
Jeremybc6a0aa2016-02-05 14:10:08 -0800556 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, expectedLink ), sleep=10 ):
Jeremy2f190ca2016-01-29 15:23:57 -0800557 main.assertReturnString += 'Link Down Topology State Passed\n'
558 else:
559 main.assertReturnString += 'Link Down Topology State Failed\n'
560 testResult = main.FALSE
561
562 # Check Connection
563 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames ) ):
564 main.assertReturnString += 'Link Down Pingall Passed\n'
565 else:
566 main.assertReturnString += 'Link Down Pingall Failed\n'
567 testResult = main.FALSE
568
569 # Bring link up
570 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "up" ) ):
571 main.assertReturnString += 'Link Up Passed\n'
572 else:
573 main.assertReturnString += 'Link Up Failed\n'
574 testResult = main.FALSE
575
576 # Wait for reroute
577 time.sleep( main.rerouteSleep )
578
579 # Check Intents
580 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
581 main.assertReturnString += 'Link Up Intent State Passed\n'
582 else:
583 main.assertReturnString += 'Link Up Intent State Failed\n'
584 testResult = main.FALSE
585
586 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800587 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 ):
Jeremy2f190ca2016-01-29 15:23:57 -0800588 main.assertReturnString += 'Link Up Flow State Passed\n'
589 else:
590 main.assertReturnString += 'Link Up Flow State Failed\n'
591 testResult = main.FALSE
592
593 # Check OnosTopology
594 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, main.numLinks ) ):
595 main.assertReturnString += 'Link Up Topology State Passed\n'
596 else:
597 main.assertReturnString += 'Link Up Topology State Failed\n'
598 testResult = main.FALSE
599
600 # Check Connection
601 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames ) ):
602 main.assertReturnString += 'Link Up Scapy Packet Received Passed\n'
603 else:
604 main.assertReturnString += 'Link Up Scapy Packet Recieved Failed\n'
605 testResult = main.FALSE
606
607 # Remove all intents
608 if utilities.retry( f=removeAllIntents, retValue=main.FALSE, args=( main, ) ):
609 main.assertReturnString += 'Remove Intents Passed'
610 else:
611 main.assertReturnString += 'Remove Intents Failed'
612 testResult = main.FALSE
613
614 return testResult
kelvin-onlab44147802015-07-27 17:57:31 -0700615
kelvin-onlab0e684682015-08-11 18:51:41 -0700616def pointIntentTcp( main,
617 name,
618 host1,
619 host2,
620 onosNode=0,
621 deviceId1="",
622 deviceId2="",
623 port1="",
624 port2="",
625 ethType="",
626 mac1="",
627 mac2="",
628 bandwidth="",
629 lambdaAlloc=False,
630 ipProto="",
631 ip1="",
632 ip2="",
633 tcp1="",
634 tcp2="",
635 sw1="",
636 sw2="",
637 expectedLink=0 ):
638
639 """
640 Description:
641 Verify add-point-intent only for TCP
642 Steps:
643 - Get device ids | ports
644 - Add point intents
645 - Check intents
646 - Verify flows
647 - Ping hosts
648 - Reroute
649 - Link down
650 - Verify flows
651 - Check topology
652 - Ping hosts
653 - Link up
654 - Verify flows
655 - Check topology
656 - Ping hosts
657 - Remove intents
658 Required:
659 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
660 host1 - Name of first host
661 host2 - Name of second host
662 Optional:
663 onosNode - ONOS node to install the intents in main.CLIs[ ]
664 0 by default so that it will always use the first
665 ONOS node
666 deviceId1 - ONOS device id of the first switch, the same as the
667 location of the first host eg. of:0000000000000001/1,
668 located at device 1 port 1
669 deviceId2 - ONOS device id of the second switch
670 port1 - The port number where the first host is attached
671 port2 - The port number where the second host is attached
672 ethType - Ethernet type eg. IPV4, IPV6
673 mac1 - Mac address of first host
674 mac2 - Mac address of the second host
675 bandwidth - Bandwidth capacity
676 lambdaAlloc - Allocate lambda, defaults to False
677 ipProto - IP protocol
678 ip1 - IP address of first host
679 ip2 - IP address of second host
680 tcp1 - TCP port of first host
681 tcp2 - TCP port of second host
682 sw1 - First switch to bring down & up for rerouting purpose
683 sw2 - Second switch to bring down & up for rerouting purpose
684 expectedLink - Expected link when the switches are down, it should
685 be two links lower than the links before the two
686 switches are down
687 """
688
689 assert main, "There is no main variable"
690 assert name, "variable name is empty"
691 assert host1 and host2, "You must specify hosts"
692
693 global itemName
694 itemName = name
695 host1 = host1
696 host2 = host2
697 hostNames = [ host1, host2 ]
698 intentsId = []
699
700 iperfResult = main.TRUE
701 intentResult = main.TRUE
702 removeIntentResult = main.TRUE
703 flowResult = main.TRUE
704 topoResult = main.TRUE
705 linkDownResult = main.TRUE
706 linkUpResult = main.TRUE
707 onosNode = int( onosNode )
708
709 # Adding bidirectional point intents
710 main.log.info( itemName + ": Adding point intents" )
711 intent1 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
712 egressDevice=deviceId2,
713 ingressPort=port1,
714 egressPort=port2,
715 ethType=ethType,
716 ethSrc=mac1,
717 ethDst=mac2,
718 bandwidth=bandwidth,
719 lambdaAlloc=lambdaAlloc,
720 ipProto=ipProto,
721 ipSrc=ip1,
722 ipDst=ip2,
723 tcpSrc=tcp1,
724 tcpDst="" )
725
726 intent2 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
727 egressDevice=deviceId1,
728 ingressPort=port2,
729 egressPort=port1,
730 ethType=ethType,
731 ethSrc=mac2,
732 ethDst=mac1,
733 bandwidth=bandwidth,
734 lambdaAlloc=lambdaAlloc,
735 ipProto=ipProto,
736 ipSrc=ip2,
737 ipDst=ip1,
738 tcpSrc=tcp2,
739 tcpDst="" )
740
741 intent3 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
742 egressDevice=deviceId2,
743 ingressPort=port1,
744 egressPort=port2,
745 ethType=ethType,
746 ethSrc=mac1,
747 ethDst=mac2,
748 bandwidth=bandwidth,
749 lambdaAlloc=lambdaAlloc,
750 ipProto=ipProto,
751 ipSrc=ip1,
752 ipDst=ip2,
753 tcpSrc="",
754 tcpDst=tcp2 )
755
756 intent4 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
757 egressDevice=deviceId1,
758 ingressPort=port2,
759 egressPort=port1,
760 ethType=ethType,
761 ethSrc=mac2,
762 ethDst=mac1,
763 bandwidth=bandwidth,
764 lambdaAlloc=lambdaAlloc,
765 ipProto=ipProto,
766 ipSrc=ip2,
767 ipDst=ip1,
768 tcpSrc="",
769 tcpDst=tcp1 )
770
771 # Get all intents ID in the system, time delay right after intents are added
772 time.sleep( main.addIntentSleep )
773 intentsId = main.CLIs[ 0 ].getIntentsId()
774 # Check intents state
775 time.sleep( main.checkIntentSleep )
776 intentResult = checkIntentState( main, intentsId )
777 # Check flows count in each node
778 checkFlowsCount( main )
779
780 # Check intents state again if first check fails...
781 if not intentResult:
782 intentResult = checkIntentState( main, intentsId )
783
784 # Check flows count in each node
785 checkFlowsCount( main )
786
787 # Verify flows
788 checkFlowsState( main )
789
790 # Run iperf to both host
791 iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
792 host2, 10 )
793
794 # Test rerouting if these variables exist
795 if sw1 and sw2 and expectedLink:
796 # link down
797 linkDownResult = link( main, sw1, sw2, "down" )
798 intentResult = intentResult and checkIntentState( main, intentsId )
799
800 # Check flows count in each node
801 checkFlowsCount( main )
802 # Verify flows
803 checkFlowsState( main )
804
805 # Check OnosTopology
806 topoResult = checkTopology( main, expectedLink )
807
808 # Run iperf to both host
809 iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
810 host2, 10 )
811
812 intentResult = checkIntentState( main, intentsId )
813
814 # Checks ONOS state in link down
815 if linkDownResult and topoResult and iperfResult and intentResult:
816 main.log.info( itemName + ": Successfully brought link down" )
817 else:
818 main.log.error( itemName + ": Failed to bring link down" )
819
820 # link up
821 linkUpResult = link( main, sw1, sw2, "up" )
822 time.sleep( main.rerouteSleep )
823
824 # Check flows count in each node
825 checkFlowsCount( main )
826 # Verify flows
827 checkFlowsState( main )
828
829 # Check OnosTopology
830 topoResult = checkTopology( main, main.numLinks )
831
832 # Run iperf to both host
833 iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
834 host2, 10 )
835
836 intentResult = checkIntentState( main, intentsId )
837
838 # Checks ONOS state in link up
839 if linkUpResult and topoResult and iperfResult and intentResult:
840 main.log.info( itemName + ": Successfully brought link back up" )
841 else:
842 main.log.error( itemName + ": Failed to bring link back up" )
843
844 # Remove all intents
845 removeIntentResult = removeAllIntents( main )
846
847 stepResult = iperfResult and linkDownResult and linkUpResult \
848 and intentResult and removeIntentResult
849
850 return stepResult
851
kelvin-onlab44147802015-07-27 17:57:31 -0700852def singleToMultiIntent( main,
853 name,
854 hostNames,
855 onosNode=0,
856 devices="",
857 ports=None,
858 ethType="",
859 macs=None,
860 bandwidth="",
861 lambdaAlloc=False,
862 ipProto="",
863 ipAddresses="",
864 tcp="",
865 sw1="",
866 sw2="",
867 expectedLink=0 ):
868 """
869 Verify Single to Multi Point intents
870 NOTE:If main.hostsData is not defined, variables data should be passed
871 in the same order index wise. All devices in the list should have the
872 same format, either all the devices have its port or it doesn't.
873 eg. hostName = [ 'h1', 'h2' ,.. ]
874 devices = [ 'of:0000000000000001', 'of:0000000000000002', ...]
875 ports = [ '1', '1', ..]
876 ...
877 Description:
878 Verify add-single-to-multi-intent iterates through the list of given
879 host | devices and add intents
880 Steps:
881 - Get device ids | ports
882 - Add single to multi point intents
883 - Check intents
884 - Verify flows
885 - Ping hosts
886 - Reroute
887 - Link down
888 - Verify flows
889 - Check topology
890 - Ping hosts
891 - Link up
892 - Verify flows
893 - Check topology
894 - Ping hosts
895 - Remove intents
896 Required:
897 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
898 hostNames - List of host names
899 Optional:
900 onosNode - ONOS node to install the intents in main.CLIs[ ]
901 0 by default so that it will always use the first
902 ONOS node
903 devices - List of device ids in the same order as the hosts
904 in hostNames
905 ports - List of port numbers in the same order as the device in
906 devices
907 ethType - Ethernet type eg. IPV4, IPV6
908 macs - List of hosts mac address in the same order as the hosts in
909 hostNames
910 bandwidth - Bandwidth capacity
911 lambdaAlloc - Allocate lambda, defaults to False
912 ipProto - IP protocol
913 ipAddresses - IP addresses of host in the same order as the hosts in
914 hostNames
915 tcp - TCP ports in the same order as the hosts in hostNames
916 sw1 - First switch to bring down & up for rerouting purpose
917 sw2 - Second switch to bring down & up for rerouting purpose
918 expectedLink - Expected link when the switches are down, it should
919 be two links lower than the links before the two
920 switches are down
921 """
922
923 assert main, "There is no main variable"
924 assert hostNames, "You must specify hosts"
925 assert devices or main.hostsData, "You must specify devices"
926
927 global itemName
928 itemName = name
929 tempHostsData = {}
930 intentsId = []
931 onosNode = int( onosNode )
932
933 macsDict = {}
934 ipDict = {}
935 if hostNames and devices:
936 if len( hostNames ) != len( devices ):
937 main.log.debug( "hosts and devices does not have the same length" )
938 #print "len hostNames = ", len( hostNames )
939 #print "len devices = ", len( devices )
940 return main.FALSE
941 if ports:
942 if len( ports ) != len( devices ):
943 main.log.error( "Ports and devices does " +
944 "not have the same length" )
945 #print "len devices = ", len( devices )
946 #print "len ports = ", len( ports )
947 return main.FALSE
948 else:
949 main.log.info( "Device Ports are not specified" )
950 if macs:
951 for i in range( len( devices ) ):
952 macsDict[ devices[ i ] ] = macs[ i ]
953
954 elif hostNames and not devices and main.hostsData:
955 devices = []
956 main.log.info( "singleToMultiIntent function is using main.hostsData" )
957 for host in hostNames:
958 devices.append( main.hostsData.get( host ).get( 'location' ) )
959 macsDict[ main.hostsData.get( host ).get( 'location' ) ] = \
960 main.hostsData.get( host ).get( 'mac' )
961 ipDict[ main.hostsData.get( host ).get( 'location' ) ] = \
962 main.hostsData.get( host ).get( 'ipAddresses' )
963 #print main.hostsData
964
965 #print 'host names = ', hostNames
966 #print 'devices = ', devices
967 #print "macsDict = ", macsDict
968
969 pingResult = main.TRUE
970 intentResult = main.TRUE
971 removeIntentResult = main.TRUE
972 flowResult = main.TRUE
973 topoResult = main.TRUE
974 linkDownResult = main.TRUE
975 linkUpResult = main.TRUE
976
977 devicesCopy = copy.copy( devices )
978 if ports:
979 portsCopy = copy.copy( ports )
980 main.log.info( itemName + ": Adding single point to multi point intents" )
981
982 # Check flows count in each node
983 checkFlowsCount( main )
984
985 # Adding bidirectional point intents
986 for i in range( len( devices ) ):
987 ingressDevice = devicesCopy[ i ]
988 egressDeviceList = copy.copy( devicesCopy )
989 egressDeviceList.remove( ingressDevice )
990 if ports:
991 portIngress = portsCopy[ i ]
992 portEgressList = copy.copy( portsCopy )
993 del portEgressList[ i ]
994 else:
995 portIngress = ""
996 portEgressList = None
997 if not macsDict:
998 srcMac = ""
999 else:
1000 srcMac = macsDict[ ingressDevice ]
1001 if srcMac == None:
1002 main.log.debug( "There is no MAC in device - " + ingressDevice )
1003 srcMac = ""
1004
1005 intentsId.append(
1006 main.CLIs[ onosNode ].addSinglepointToMultipointIntent(
1007 ingressDevice=ingressDevice,
1008 egressDeviceList=egressDeviceList,
1009 portIngress=portIngress,
1010 portEgressList=portEgressList,
1011 ethType=ethType,
1012 ethSrc=srcMac,
1013 bandwidth=bandwidth,
1014 lambdaAlloc=lambdaAlloc,
1015 ipProto=ipProto,
1016 ipSrc="",
1017 ipDst="",
1018 tcpSrc="",
1019 tcpDst="" ) )
1020
1021 # Wait some time for the flow to go through when using multi instance
1022 pingResult = pingallHosts( main, hostNames )
1023
1024 # Check intents state
1025 time.sleep( main.checkIntentSleep )
1026 intentResult = checkIntentState( main, intentsId )
1027
1028 # Check intents state again if first check fails...
1029 if not intentResult:
1030 intentResult = checkIntentState( main, intentsId )
1031
1032 # Check flows count in each node
1033 checkFlowsCount( main )
1034 # Verify flows
1035 checkFlowsState( main )
1036
1037 pingResult = pingResult and pingallHosts( main, hostNames )
1038
1039 # Test rerouting if these variables exist
1040 if sw1 and sw2 and expectedLink:
1041 # link down
1042 linkDownResult = link( main, sw1, sw2, "down" )
1043 intentResult = intentResult and checkIntentState( main, intentsId )
1044
1045 # Check flows count in each node
1046 checkFlowsCount( main )
1047 # Verify flows
1048 checkFlowsState( main )
1049
1050 # Check OnosTopology
1051 topoResult = checkTopology( main, expectedLink )
1052
1053 # Ping hosts
1054 pingResult = pingResult and pingallHosts( main, hostNames )
1055
1056 intentResult = checkIntentState( main, intentsId )
1057
1058 # Checks ONOS state in link down
1059 if linkDownResult and topoResult and pingResult and intentResult:
1060 main.log.info( itemName + ": Successfully brought link down" )
1061 else:
1062 main.log.error( itemName + ": Failed to bring link down" )
1063
1064 # link up
1065 linkUpResult = link( main, sw1, sw2, "up" )
1066 time.sleep( main.rerouteSleep )
1067
1068 # Check flows count in each node
1069 checkFlowsCount( main )
1070 # Verify flows
1071 checkFlowsState( main )
1072
1073 # Check OnosTopology
1074 topoResult = checkTopology( main, main.numLinks )
1075
1076 # Ping hosts
1077 pingResult = pingResult and pingallHosts( main, hostNames )
1078
1079 intentResult = checkIntentState( main, intentsId )
1080
1081 # Checks ONOS state in link up
1082 if linkUpResult and topoResult and pingResult and intentResult:
1083 main.log.info( itemName + ": Successfully brought link back up" )
1084 else:
1085 main.log.error( itemName + ": Failed to bring link back up" )
1086
1087 # Remove all intents
1088 removeIntentResult = removeAllIntents( main, intentsId )
1089
1090 stepResult = pingResult and linkDownResult and linkUpResult \
1091 and intentResult and removeIntentResult
1092
1093 return stepResult
1094
1095def multiToSingleIntent( main,
1096 name,
1097 hostNames,
1098 onosNode=0,
1099 devices="",
1100 ports=None,
1101 ethType="",
1102 macs=None,
1103 bandwidth="",
1104 lambdaAlloc=False,
1105 ipProto="",
1106 ipAddresses="",
1107 tcp="",
1108 sw1="",
1109 sw2="",
1110 expectedLink=0 ):
1111 """
1112 Verify Single to Multi Point intents
1113 NOTE:If main.hostsData is not defined, variables data should be passed in the
1114 same order index wise. All devices in the list should have the same
1115 format, either all the devices have its port or it doesn't.
1116 eg. hostName = [ 'h1', 'h2' ,.. ]
1117 devices = [ 'of:0000000000000001', 'of:0000000000000002', ...]
1118 ports = [ '1', '1', ..]
1119 ...
1120 Description:
1121 Verify add-multi-to-single-intent
1122 Steps:
1123 - Get device ids | ports
1124 - Add multi to single point intents
1125 - Check intents
1126 - Verify flows
1127 - Ping hosts
1128 - Reroute
1129 - Link down
1130 - Verify flows
1131 - Check topology
1132 - Ping hosts
1133 - Link up
1134 - Verify flows
1135 - Check topology
1136 - Ping hosts
1137 - Remove intents
1138 Required:
1139 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
1140 hostNames - List of host names
1141 Optional:
1142 onosNode - ONOS node to install the intents in main.CLIs[ ]
1143 0 by default so that it will always use the first
1144 ONOS node
1145 devices - List of device ids in the same order as the hosts
1146 in hostNames
1147 ports - List of port numbers in the same order as the device in
1148 devices
1149 ethType - Ethernet type eg. IPV4, IPV6
1150 macs - List of hosts mac address in the same order as the hosts in
1151 hostNames
1152 bandwidth - Bandwidth capacity
1153 lambdaAlloc - Allocate lambda, defaults to False
1154 ipProto - IP protocol
1155 ipAddresses - IP addresses of host in the same order as the hosts in
1156 hostNames
1157 tcp - TCP ports in the same order as the hosts in hostNames
1158 sw1 - First switch to bring down & up for rerouting purpose
1159 sw2 - Second switch to bring down & up for rerouting purpose
1160 expectedLink - Expected link when the switches are down, it should
1161 be two links lower than the links before the two
1162 switches are down
1163 """
1164
1165 assert main, "There is no main variable"
1166 assert hostNames, "You must specify hosts"
1167 assert devices or main.hostsData, "You must specify devices"
1168
1169 global itemName
1170 itemName = name
1171 tempHostsData = {}
1172 intentsId = []
1173 onosNode = int( onosNode )
1174
1175 macsDict = {}
1176 ipDict = {}
1177 if hostNames and devices:
1178 if len( hostNames ) != len( devices ):
1179 main.log.debug( "hosts and devices does not have the same length" )
1180 #print "len hostNames = ", len( hostNames )
1181 #print "len devices = ", len( devices )
1182 return main.FALSE
1183 if ports:
1184 if len( ports ) != len( devices ):
1185 main.log.error( "Ports and devices does " +
1186 "not have the same length" )
1187 #print "len devices = ", len( devices )
1188 #print "len ports = ", len( ports )
1189 return main.FALSE
1190 else:
1191 main.log.info( "Device Ports are not specified" )
1192 if macs:
1193 for i in range( len( devices ) ):
1194 macsDict[ devices[ i ] ] = macs[ i ]
1195 elif hostNames and not devices and main.hostsData:
1196 devices = []
1197 main.log.info( "multiToSingleIntent function is using main.hostsData" )
1198 for host in hostNames:
1199 devices.append( main.hostsData.get( host ).get( 'location' ) )
1200 macsDict[ main.hostsData.get( host ).get( 'location' ) ] = \
1201 main.hostsData.get( host ).get( 'mac' )
1202 ipDict[ main.hostsData.get( host ).get( 'location' ) ] = \
1203 main.hostsData.get( host ).get( 'ipAddresses' )
1204 #print main.hostsData
1205
1206 #print 'host names = ', hostNames
1207 #print 'devices = ', devices
1208 #print "macsDict = ", macsDict
1209
1210 pingResult = main.TRUE
1211 intentResult = main.TRUE
1212 removeIntentResult = main.TRUE
1213 flowResult = main.TRUE
1214 topoResult = main.TRUE
1215 linkDownResult = main.TRUE
1216 linkUpResult = main.TRUE
1217
1218 devicesCopy = copy.copy( devices )
1219 if ports:
1220 portsCopy = copy.copy( ports )
1221 main.log.info( itemName + ": Adding multi point to single point intents" )
1222
1223 # Check flows count in each node
1224 checkFlowsCount( main )
1225
1226 # Adding bidirectional point intents
1227 for i in range( len( devices ) ):
1228 egressDevice = devicesCopy[ i ]
1229 ingressDeviceList = copy.copy( devicesCopy )
1230 ingressDeviceList.remove( egressDevice )
1231 if ports:
1232 portEgress = portsCopy[ i ]
1233 portIngressList = copy.copy( portsCopy )
1234 del portIngressList[ i ]
1235 else:
1236 portEgress = ""
1237 portIngressList = None
1238 if not macsDict:
1239 dstMac = ""
1240 else:
1241 dstMac = macsDict[ egressDevice ]
1242 if dstMac == None:
1243 main.log.debug( "There is no MAC in device - " + egressDevice )
1244 dstMac = ""
1245
1246 intentsId.append(
1247 main.CLIs[ onosNode ].addMultipointToSinglepointIntent(
1248 ingressDeviceList=ingressDeviceList,
1249 egressDevice=egressDevice,
1250 portIngressList=portIngressList,
1251 portEgress=portEgress,
1252 ethType=ethType,
1253 ethDst=dstMac,
1254 bandwidth=bandwidth,
1255 lambdaAlloc=lambdaAlloc,
1256 ipProto=ipProto,
1257 ipSrc="",
1258 ipDst="",
1259 tcpSrc="",
1260 tcpDst="" ) )
1261
1262 pingResult = pingallHosts( main, hostNames )
1263
1264 # Check intents state
1265 time.sleep( main.checkIntentSleep )
1266 intentResult = checkIntentState( main, intentsId )
1267
1268 # Check intents state again if first check fails...
1269 if not intentResult:
1270 intentResult = checkIntentState( main, intentsId )
1271
1272 # Check flows count in each node
1273 checkFlowsCount( main )
1274 # Verify flows
1275 checkFlowsState( main )
1276
1277 # Ping hosts
1278 pingResult = pingResult and pingallHosts( main, hostNames )
1279 # Ping hosts again...
1280 pingResult = pingResult and pingallHosts( main, hostNames )
1281
1282 # Test rerouting if these variables exist
1283 if sw1 and sw2 and expectedLink:
1284 # link down
1285 linkDownResult = link( main, sw1, sw2, "down" )
1286 intentResult = intentResult and checkIntentState( main, intentsId )
1287
1288 # Check flows count in each node
1289 checkFlowsCount( main )
1290 # Verify flows
1291 checkFlowsState( main )
1292
1293 # Check OnosTopology
1294 topoResult = checkTopology( main, expectedLink )
1295
1296 # Ping hosts
1297 pingResult = pingResult and pingallHosts( main, hostNames )
1298
1299 intentResult = checkIntentState( main, intentsId )
1300
1301 # Checks ONOS state in link down
1302 if linkDownResult and topoResult and pingResult and intentResult:
1303 main.log.info( itemName + ": Successfully brought link down" )
1304 else:
1305 main.log.error( itemName + ": Failed to bring link down" )
1306
1307 # link up
1308 linkUpResult = link( main, sw1, sw2, "up" )
1309 time.sleep( main.rerouteSleep )
1310
1311 # Check flows count in each node
1312 checkFlowsCount( main )
1313 # Verify flows
1314 checkFlowsState( main )
1315
1316 # Check OnosTopology
1317 topoResult = checkTopology( main, main.numLinks )
1318
1319 # Ping hosts
1320 pingResult = pingResult and pingallHosts( main, hostNames )
1321
1322 intentResult = checkIntentState( main, intentsId )
1323
1324 # Checks ONOS state in link up
1325 if linkUpResult and topoResult and pingResult and intentResult:
1326 main.log.info( itemName + ": Successfully brought link back up" )
1327 else:
1328 main.log.error( itemName + ": Failed to bring link back up" )
1329
1330 # Remove all intents
1331 removeIntentResult = removeAllIntents( main, intentsId )
1332
1333 stepResult = pingResult and linkDownResult and linkUpResult \
1334 and intentResult and removeIntentResult
1335
1336 return stepResult
1337
kelvin-onlab0e684682015-08-11 18:51:41 -07001338def pingallHosts( main, hostList ):
kelvin-onlab44147802015-07-27 17:57:31 -07001339 # Ping all host in the hosts list variable
1340 print "Pinging : ", hostList
1341 pingResult = main.TRUE
kelvin-onlab0e684682015-08-11 18:51:41 -07001342 pingResult = main.Mininet1.pingallHosts( hostList )
kelvin-onlab44147802015-07-27 17:57:31 -07001343 return pingResult
1344
kelvin-onlab0e684682015-08-11 18:51:41 -07001345def getHostsData( main, hostList ):
kelvin-onlab44147802015-07-27 17:57:31 -07001346 """
1347 Use fwd app and pingall to discover all the hosts
1348 """
1349
1350 activateResult = main.TRUE
1351 appCheck = main.TRUE
1352 getDataResult = main.TRUE
1353 main.log.info( "Activating reactive forwarding app " )
1354 activateResult = main.CLIs[ 0 ].activateApp( "org.onosproject.fwd" )
1355 if not activateResult:
1356 main.log.error( "Something went wrong installing fwd app" )
1357 time.sleep( main.fwdSleep )
kelvin-onlab0e684682015-08-11 18:51:41 -07001358 if isinstance( hostList[ 0 ], types.StringType ):
1359 main.Mininet1.pingallHosts( hostList )
1360 elif isinstance( hostList[ 0 ], types.ListType ):
1361 for i in xrange( len( hostList ) ):
1362 main.Mininet1.pingallHosts( hostList[ i ] )
1363
kelvin-onlab44147802015-07-27 17:57:31 -07001364 hostsJson = json.loads( main.CLIs[ 0 ].hosts() )
1365 hosts = main.Mininet1.getHosts().keys()
1366 # TODO: Make better use of new getHosts function
1367 for host in hosts:
1368 main.hostsData[ host ] = {}
1369 main.hostsData[ host ][ 'mac' ] = \
1370 main.Mininet1.getMacAddress( host ).upper()
1371 for hostj in hostsJson:
1372 if main.hostsData[ host ][ 'mac' ] == hostj[ 'mac' ]:
1373 main.hostsData[ host ][ 'id' ] = hostj[ 'id' ]
1374 main.hostsData[ host ][ 'vlan' ] = hostj[ 'vlan' ]
1375 main.hostsData[ host ][ 'location' ] = \
1376 hostj[ 'location' ][ 'elementId' ] + '/' + \
1377 hostj[ 'location' ][ 'port' ]
1378 main.hostsData[ host ][ 'ipAddresses' ] = hostj[ 'ipAddresses' ]
1379
1380 main.log.info( "Deactivating reactive forwarding app " )
1381 deactivateResult = main.CLIs[ 0 ].deactivateApp( "org.onosproject.fwd" )
1382 if activateResult and deactivateResult and main.hostsData:
1383 main.log.info( "Successfully used fwd app to discover hosts " )
1384 getDataResult = main.TRUE
1385 else:
1386 main.log.info( "Failed to use fwd app to discover hosts " )
1387 getDataResult = main.FALSE
1388
1389 print main.hostsData
1390
1391 return getDataResult
1392
1393def checkTopology( main, expectedLink ):
1394 statusResult = main.TRUE
1395 # Check onos topology
1396 main.log.info( itemName + ": Checking ONOS topology " )
1397
1398 for i in range( main.numCtrls ):
1399 topologyResult = main.CLIs[ i ].topology()
1400 statusResult = main.ONOSbench.checkStatus( topologyResult,
1401 main.numSwitch,
1402 expectedLink )\
1403 and statusResult
1404 if not statusResult:
1405 main.log.error( itemName + ": Topology mismatch" )
1406 else:
1407 main.log.info( itemName + ": Topology match" )
1408 return statusResult
1409
1410def checkIntentState( main, intentsId ):
1411 """
1412 This function will check intent state to make sure all the intents
1413 are in INSTALLED state
1414 """
1415
1416 intentResult = main.TRUE
1417 results = []
1418
1419 main.log.info( itemName + ": Checking intents state" )
1420 # First check of intents
1421 for i in range( main.numCtrls ):
1422 tempResult = main.CLIs[ i ].checkIntentState( intentsId=intentsId )
1423 results.append( tempResult )
1424
1425 expectedState = [ 'INSTALLED', 'INSTALLING' ]
1426
1427 if all( result == main.TRUE for result in results ):
1428 main.log.info( itemName + ": Intents are installed correctly" )
1429 else:
1430 # Wait for at least 5 second before checking the intents again
Jeremy2f190ca2016-01-29 15:23:57 -08001431 main.log.error( "Intents are not installed correctly. Waiting 5 sec" )
kelvin-onlab44147802015-07-27 17:57:31 -07001432 time.sleep( 5 )
1433 results = []
1434 # Second check of intents since some of the intents may be in
1435 # INSTALLING state, they should be in INSTALLED at this time
1436 for i in range( main.numCtrls ):
Jeremy2f190ca2016-01-29 15:23:57 -08001437 tempResult = main.CLIs[ i ].checkIntentState( intentsId=intentsId )
kelvin-onlab44147802015-07-27 17:57:31 -07001438 results.append( tempResult )
1439 if all( result == main.TRUE for result in results ):
1440 main.log.info( itemName + ": Intents are installed correctly" )
Jeremy2f190ca2016-01-29 15:23:57 -08001441 intentResult = main.TRUE
kelvin-onlab44147802015-07-27 17:57:31 -07001442 else:
1443 main.log.error( itemName + ": Intents are NOT installed correctly" )
1444 intentResult = main.FALSE
1445
1446 return intentResult
1447
1448def checkFlowsState( main ):
1449
1450 main.log.info( itemName + ": Check flows state" )
1451 checkFlowsResult = main.CLIs[ 0 ].checkFlowsState()
1452 return checkFlowsResult
1453
1454def link( main, sw1, sw2, option):
1455
1456 # link down
1457 main.log.info( itemName + ": Bring link " + option + "between " +
1458 sw1 + " and " + sw2 )
1459 linkResult = main.Mininet1.link( end1=sw1, end2=sw2, option=option )
1460 return linkResult
1461
1462def removeAllIntents( main ):
1463 """
1464 Remove all intents in the intentsId
1465 """
1466
1467 onosSummary = []
1468 removeIntentResult = main.TRUE
1469 # Remove intents
1470 removeIntentResult = main.CLIs[ 0 ].removeAllIntents( )
1471
1472 if removeIntentResult:
1473 main.log.info( itemName + ": There are no more intents remaining, " +
1474 "successfully removed all the intents." )
1475
1476 return removeIntentResult
1477
1478def checkFlowsCount( main ):
1479 """
1480 Check flows count in each node
1481 """
1482
1483 flowsCount = []
1484 main.log.info( itemName + ": Checking flows count in each ONOS node" )
1485 for i in range( main.numCtrls ):
1486 flowsCount.append( len( json.loads( main.CLIs[ i ].flows() ) ) )
1487
1488 if flowsCount:
1489 if all( flows==flowsCount[ 0 ] for flows in flowsCount ):
1490 main.log.info( itemName + ": There are " + str( flowsCount[ 0 ] ) +
1491 " flows in all ONOS node" )
1492 else:
1493 for i in range( main.numCtrls ):
1494 main.log.debug( itemName + ": ONOS node " + str( i + 1 ) +
Jeremy2f190ca2016-01-29 15:23:57 -08001495 " has " + str( flowsCount[ i ] ) + " flows" )
kelvin-onlab44147802015-07-27 17:57:31 -07001496 else:
1497 main.log.error( "Checking flows count failed, check summary command" )
1498 return main.FALSE
1499
1500 return main.TRUE
1501
Jeremy2f190ca2016-01-29 15:23:57 -08001502def sendDiscoveryArp( main, hosts=None ):
1503 """
1504 Sends Discovery ARP packets from each host provided
1505 Defaults to each host in main.scapyHosts
1506 """
1507 # Send an arp ping from each host
1508 if not hosts:
1509 hosts = main.scapyHosts
1510 for host in hosts:
1511 pkt = 'Ether( src="{0}")/ARP( psrc="{1}")'.format( host.hostMac ,host.hostIp )
1512 # Send from the VLAN interface if there is one so ONOS discovers the VLAN correctly
1513 iface = None
1514 for interface in host.getIfList():
1515 if '.' in interface:
1516 main.log.debug( "Detected VLAN interface {0}. Sending ARP packet from {0}".format( interface ) )
1517 iface = interface
1518 break
1519 host.sendPacket( packet=pkt, iface=iface )
1520 main.log.info( "Sending ARP packet from {0}".format( host.name ) )
1521
1522def confirmHostDiscovery( main ):
1523 """
1524 Confirms that all ONOS nodes have discovered all scapy hosts
1525 """
1526 import collections
1527 scapyHostCount = len( main.scapyHosts )
1528 hosts = main.topo.getAllHosts( main ) # Get host data from each ONOS node
1529 hostFails = [] # Reset for each failed attempt
1530
1531 # Check for matching hosts on each node
1532 scapyHostIPs = [ x.hostIp for x in main.scapyHosts if x.hostIp != "0.0.0.0" ]
1533 for controller in range( main.numCtrls ):
1534 controllerStr = str( controller + 1 ) # ONOS node number
1535 # Compare Hosts
1536 # Load hosts data for controller node
1537 if hosts[ controller ] and "Error" not in hosts[ controller ]:
1538 try:
1539 hostData = json.loads( hosts[ controller ] )
1540 except ( TypeError, ValueError ):
1541 main.log.error( "Could not load json:" + str( hosts[ controller ] ) )
1542 hostFails.append( controllerStr )
1543 else:
1544 onosHostIPs = [ x.get( "ipAddresses" )[ 0 ]
1545 for x in hostData
1546 if len( x.get( "ipAddresses" ) ) > 0 ]
1547 if not set( collections.Counter( scapyHostIPs ) ).issubset( set ( collections.Counter( onosHostIPs ) ) ):
1548 main.log.warn( "Controller {0} only sees nodes with {1} IPs. It should see all of the following: {2}".format( controllerStr, onosHostIPs, scapyHostIPs ) )
1549 hostFails.append( controllerStr )
1550 else:
1551 main.log.error( "Hosts returned nothing or an error." )
1552 hostFails.append( controllerStr )
1553
1554 if hostFails:
1555 main.log.error( "List of failed ONOS Nodes:" + ', '.join(map(str, hostFails )) )
1556 return main.FALSE
1557 else:
1558 return main.TRUE
1559
1560def populateHostData( main ):
1561 """
1562 Populates hostsData
1563 """
1564 import json
1565 try:
1566 hostsJson = json.loads( main.CLIs[ 0 ].hosts() )
1567 hosts = main.Mininet1.getHosts().keys()
1568 # TODO: Make better use of new getHosts function
1569 for host in hosts:
1570 main.hostsData[ host ] = {}
1571 main.hostsData[ host ][ 'mac' ] = \
1572 main.Mininet1.getMacAddress( host ).upper()
1573 for hostj in hostsJson:
1574 if main.hostsData[ host ][ 'mac' ] == hostj[ 'mac' ]:
1575 main.hostsData[ host ][ 'id' ] = hostj[ 'id' ]
1576 main.hostsData[ host ][ 'vlan' ] = hostj[ 'vlan' ]
1577 main.hostsData[ host ][ 'location' ] = \
1578 hostj[ 'location' ][ 'elementId' ] + '/' + \
1579 hostj[ 'location' ][ 'port' ]
1580 main.hostsData[ host ][ 'ipAddresses' ] = hostj[ 'ipAddresses' ]
1581 return main.TRUE
1582 except KeyError:
1583 main.log.error( "KeyError while populating hostsData")
1584 return main.FALSE
1585
1586def scapyCheckConnection( main, senders, recipients, packet=None, packetFilter=None, expectFailure=False ):
1587 """
1588 Checks the connectivity between all given sender hosts and all given recipient hosts
1589 Packet may be specified. Defaults to Ether/IP packet
1590 Packet Filter may be specified. Defaults to Ether/IP from current sender MAC
1591 Todo: Optional packet and packet filter attributes for sender and recipients
1592 Expect Failure when the sender and recipient are not supposed to have connectivity
1593 Timeout of 1 second, returns main.TRUE if the filter is not triggered and kills the filter
1594
1595 """
1596 connectionsFunctional = main.TRUE
1597
1598 if not packetFilter:
1599 packetFilter = 'ether host {}'
1600
1601 if expectFailure:
1602 timeout = 1
1603 else:
1604 timeout = 10
1605
1606 for sender in senders:
1607 try:
1608 senderComp = getattr( main, sender )
1609 except AttributeError:
1610 main.log.error( "main has no attribute {}".format( sender ) )
1611 connectionsFunctional = main.FALSE
1612 continue
1613
1614 for recipient in recipients:
1615 # Do not send packets to self since recipient CLI will already be busy
1616 if recipient == sender:
1617 continue
1618 try:
1619 recipientComp = getattr( main, recipient )
1620 except AttributeError:
1621 main.log.error( "main has no attribute {}".format( recipient ) )
1622 connectionsFunctional = main.FALSE
1623 continue
1624
1625 recipientComp.startFilter( pktFilter = packetFilter.format( senderComp.hostMac ) )
1626
1627 if not packet:
1628 pkt = 'Ether( src="{0}", dst="{2}" )/IP( src="{1}", dst="{3}" )'.format(
1629 senderComp.hostMac,
1630 senderComp.hostIp,
1631 recipientComp.hostMac,
1632 recipientComp.hostIp )
1633 else:
1634 pkt = packet
1635 senderComp.sendPacket( packet = pkt )
1636
1637 if recipientComp.checkFilter( timeout ):
1638 if expectFailure:
1639 main.log.error( "Packet from {0} successfully received by {1} when it should not have been".format( sender , recipient ) )
1640 connectionsFunctional = main.FALSE
1641 else:
1642 main.log.info( "Packet from {0} successfully received by {1}".format( sender , recipient ) )
1643 else:
1644 recipientComp.killFilter()
1645 if expectFailure:
1646 main.log.info( "As expected, packet from {0} was not received by {1}".format( sender , recipient ) )
1647 else:
1648 main.log.error( "Packet from {0} was not received by {1}".format( sender , recipient ) )
1649 connectionsFunctional = main.FALSE
1650
1651 return connectionsFunctional
1652
Jeremye1ea0602016-02-08 16:35:05 -08001653def checkLeaderChange( leaders1, leaders2 ):
1654 """
1655 Checks for a change in intent partition leadership.
1656
1657 Takes the output of leaders -c in json string format before and after
1658 a potential change as input
1659
1660 Returns main.TRUE if no mismatches are detected
1661 Returns main.FALSE if there is a mismatch or on error loading the input
1662 """
1663 try:
1664 leaders1 = json.loads( leaders1 )
1665 leaders2 = json.loads( leaders2 )
1666 except ( AttributeError, TypeError):
1667 main.log.exception( self.name + ": Object not as expected" )
1668 return main.FALSE
1669 except Exception:
1670 main.log.exception( self.name + ": Uncaught exception!" )
1671 main.cleanup()
1672 main.exit()
1673 main.log.info( "Checking Intent Paritions for Change in Leadership" )
1674 mismatch = False
1675 for dict1 in leaders1:
1676 if "intent" in dict1.get( "topic", [] ):
1677 for dict2 in leaders2:
1678 if dict1.get( "topic", 0 ) == dict2.get( "topic", 0 ) and \
1679 dict1.get( "leader", 0 ) != dict2.get( "leader", 0 ):
1680 mismatch = True
1681 main.log.error( "{0} changed leader from {1} to {2}".\
1682 format( dict1.get( "topic", "no-topic" ),\
1683 dict1.get( "leader", "no-leader" ),\
1684 dict2.get( "leader", "no-leader" ) ) )
1685 if mismatch:
1686 return main.FALSE
1687 else:
1688 return main.TRUE
1689
1690
Jeremy2f190ca2016-01-29 15:23:57 -08001691def report( main ):
1692 """
1693 Report errors/warnings/exceptions
1694 """
1695 main.ONOSbench.logReport( main.ONOSip[ 0 ],
1696 [ "INFO",
1697 "FOLLOWER",
1698 "WARN",
1699 "flow",
1700 "ERROR",
1701 "Except" ],
1702 "s" )
1703
1704 main.log.info( "ERROR report: \n" )
1705 for i in range( main.numCtrls ):
1706 main.ONOSbench.logReport( main.ONOSip[ i ],
1707 [ "ERROR" ],
1708 "d" )
1709
1710 main.log.info( "EXCEPTIONS report: \n" )
1711 for i in range( main.numCtrls ):
1712 main.ONOSbench.logReport( main.ONOSip[ i ],
1713 [ "Except" ],
1714 "d" )
1715
1716 main.log.info( "WARNING report: \n" )
1717 for i in range( main.numCtrls ):
1718 main.ONOSbench.logReport( main.ONOSip[ i ],
1719 [ "WARN" ],
1720 "d" )