blob: 8a48a13297f283c9fe9532795940eec33ef20780 [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
Jeremydd9bda62016-04-18 12:02:32 -070069 try:
70 if not host1.get( "id" ):
71 main.log.warn( "ID not given for host1 {0}. Loading from main.hostData".format( host1.get( "name" ) ) )
72 main.log.debug( main.hostsData.get( host1.get( "name" ) ) )
73 host1[ "id" ] = main.hostsData.get( host1.get( "name" ) ).get( "id" )
kelvin-onlab44147802015-07-27 17:57:31 -070074
Jeremydd9bda62016-04-18 12:02:32 -070075 if not host2.get( "id" ):
76 main.log.warn( "ID not given for host2 {0}. Loading from main.hostData".format( host2.get( "name" ) ) )
77 host2[ "id" ] = main.hostsData.get( host2.get( "name" ) ).get( "id" )
kelvin-onlab44147802015-07-27 17:57:31 -070078
Jeremydd9bda62016-04-18 12:02:32 -070079 # Adding host intents
80 main.log.info( itemName + ": Adding host intents" )
kelvin-onlab44147802015-07-27 17:57:31 -070081
Jeremydd9bda62016-04-18 12:02:32 -070082 intent1 = main.CLIs[ onosNode ].addHostIntent( hostIdOne=host1.get( "id" ),
83 hostIdTwo=host2.get( "id" ) )
kelvin-onlab44147802015-07-27 17:57:31 -070084
Jeremydd9bda62016-04-18 12:02:32 -070085 # Get all intents ID in the system, time delay right after intents are added
86 time.sleep( main.addIntentSleep )
87 intentsId = main.CLIs[ 0 ].getIntentsId()
88 except (KeyError, TypeError):
89 errorMsg = "There was a problem loading the hosts data."
90 if intentsId:
91 errorMsg += " There was a problem installing host to host intent."
92 main.log.error( errorMsg )
93 return main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -070094
Jeremy2f190ca2016-01-29 15:23:57 -080095 if utilities.retry ( f=checkIntentState, retValue=main.FALSE,
96 args = (main, intentsId ), sleep=main.checkIntentSleep ):
97 return intentsId
98 else:
99 main.log.error( "Host Intent did not install correctly" )
100 return main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700101
Jeremy2f190ca2016-01-29 15:23:57 -0800102def testHostIntent( main,
103 name,
104 intentId,
105 host1,
106 host2,
107 onosNode=0,
108 sw1="s5",
109 sw2="s2",
110 expectedLink=0):
111 """
112 Test a Host Intent
kelvin-onlab44147802015-07-27 17:57:31 -0700113
Jeremy2f190ca2016-01-29 15:23:57 -0800114 Description:
115 Test a host intent of given ID between given hosts
kelvin-onlab44147802015-07-27 17:57:31 -0700116
Jeremy2f190ca2016-01-29 15:23:57 -0800117 Steps:
118 - Fetch host data if not given
119 - Check Intent State
120 - Check Flow State
121 - Check Connectivity
122 - Check Lack of Connectivity Between Hosts not in the Intent
123 - Reroute
124 - Take Expected Link Down
125 - Check Intent State
126 - Check Flow State
127 - Check Topology
128 - Check Connectivity
129 - Bring Expected Link Up
130 - Check Intent State
131 - Check Flow State
132 - Check Topology
133 - Check Connectivity
134 - Remove Topology
kelvin-onlab44147802015-07-27 17:57:31 -0700135
Jeremy2f190ca2016-01-29 15:23:57 -0800136 Required:
137 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
138 intentId - intent ID to be tested ( and removed )
139 host1 - Dictionary for host1
140 { "name":"h8", "id":"of:0000000000000005/8" }
141 host2 - Dictionary for host2
142 { "name":"h16", "id":"of:0000000000000006/8" }
143 Optional:
144 onosNode - ONOS node to install the intents in main.CLIs[ ]
145 0 by default so that it will always use the first
146 ONOS node
147 sw1 - First switch to bring down & up for rerouting purpose
148 sw2 - Second switch to bring down & up for rerouting purpose
149 expectedLink - Expected link when the switches are down, it should
150 be two links lower than the links before the two
151 switches are down
kelvin-onlab44147802015-07-27 17:57:31 -0700152
153 """
kelvin-onlab44147802015-07-27 17:57:31 -0700154
Jeremy2f190ca2016-01-29 15:23:57 -0800155 # Parameter Validity Check
kelvin-onlab44147802015-07-27 17:57:31 -0700156 assert main, "There is no main variable"
Jeremy2f190ca2016-01-29 15:23:57 -0800157 assert host1, "You must specify host1"
158 assert host2, "You must specify host2"
kelvin-onlab44147802015-07-27 17:57:31 -0700159
160 global itemName
161 itemName = name
Jeremy2f190ca2016-01-29 15:23:57 -0800162 tempHostsData = {}
kelvin-onlab44147802015-07-27 17:57:31 -0700163 onosNode = int( onosNode )
164
Jeremy2f190ca2016-01-29 15:23:57 -0800165 main.log.info( itemName + ": Testing Host Intent" )
kelvin-onlab44147802015-07-27 17:57:31 -0700166
Jeremydd9bda62016-04-18 12:02:32 -0700167 try:
168 if not host1.get( "id" ):
169 main.log.warn( "Id not given for host1 {0}. Loading from main.hostData".format( host1.get( "name" ) ) )
170 host1[ "id" ] = main.hostsData.get( host1.get( "name" ) ).get( "location" )
kelvin-onlab0e684682015-08-11 18:51:41 -0700171
Jeremydd9bda62016-04-18 12:02:32 -0700172 if not host2.get( "id" ):
173 main.log.warn( "Id not given for host2 {0}. Loading from main.hostData".format( host2.get( "name" ) ) )
174 host2[ "id" ] = main.hostsData.get( host2.get( "name" ) ).get( "location" )
kelvin-onlab44147802015-07-27 17:57:31 -0700175
Jeremydd9bda62016-04-18 12:02:32 -0700176 senderNames = [ host1.get( "name" ), host2.get( "name" ) ]
177 recipientNames = [ host1.get( "name" ), host2.get( "name" ) ]
178 except ( KeyError, TypeError ):
179 main.log.error( "There was a problem loading the hosts data." )
180 return main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700181
Jeremy2f190ca2016-01-29 15:23:57 -0800182 testResult = main.TRUE
183 main.log.info( itemName + ": Adding single point to multi point intents" )
184
185 # Check intent state
186 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
187 main.assertReturnString += 'Initial Intent State Passed\n'
188 else:
189 main.assertReturnString += 'Initial Intent State Failed\n'
190 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700191
192 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800193 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 -0800194 main.assertReturnString += 'Initial Flow State Passed\n'
195 else:
196 main.assertReturnString += 'Intial Flow State Failed\n'
197 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700198
Jeremy2f190ca2016-01-29 15:23:57 -0800199 # Check Connectivity
200 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames ) ):
201 main.assertReturnString += 'Initial Ping Passed\n'
202 else:
203 main.assertReturnString += 'Initial Ping Failed\n'
204 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700205
206 # Test rerouting if these variables exist
207 if sw1 and sw2 and expectedLink:
Jeremy2f190ca2016-01-29 15:23:57 -0800208 # Take link down
209 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "down" ) ):
210 main.assertReturnString += 'Link Down Passed\n'
211 else:
212 main.assertReturnString += 'Link Down Failed\n'
213 testResult = main.FALSE
214
215 # Check intent state
216 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
217 main.assertReturnString += 'Link Down Intent State Passed\n'
218 else:
219 main.assertReturnString += 'Link Down Intent State Failed\n'
220 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700221
222 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800223 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 -0800224 main.assertReturnString += 'Link Down Flow State Passed\n'
225 else:
226 main.assertReturnString += 'Link Down Flow State Failed\n'
227 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700228
229 # Check OnosTopology
Jeremybc6a0aa2016-02-05 14:10:08 -0800230 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, expectedLink ), sleep=10 ):
Jeremy2f190ca2016-01-29 15:23:57 -0800231 main.assertReturnString += 'Link Down Topology State Passed\n'
kelvin-onlab44147802015-07-27 17:57:31 -0700232 else:
Jeremy2f190ca2016-01-29 15:23:57 -0800233 main.assertReturnString += 'Link Down Topology State Failed\n'
234 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700235
Jeremy2f190ca2016-01-29 15:23:57 -0800236 # Check Connection
237 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames ) ):
238 main.assertReturnString += 'Link Down Pingall Passed\n'
239 else:
240 main.assertReturnString += 'Link Down Pingall Failed\n'
241 testResult = main.FALSE
242
243 # Bring link up
244 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "up" ) ):
245 main.assertReturnString += 'Link Up Passed\n'
246 else:
247 main.assertReturnString += 'Link Up Failed\n'
248 testResult = main.FALSE
249
250 # Wait for reroute
kelvin-onlab44147802015-07-27 17:57:31 -0700251 time.sleep( main.rerouteSleep )
252
Jeremy2f190ca2016-01-29 15:23:57 -0800253 # Check Intents
254 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
255 main.assertReturnString += 'Link Up Intent State Passed\n'
256 else:
257 main.assertReturnString += 'Link Up Intent State Failed\n'
258 testResult = main.FALSE
259
kelvin-onlab44147802015-07-27 17:57:31 -0700260 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800261 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 -0800262 main.assertReturnString += 'Link Up Flow State Passed\n'
263 else:
264 main.assertReturnString += 'Link Up Flow State Failed\n'
265 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700266
267 # Check OnosTopology
Jeremy2f190ca2016-01-29 15:23:57 -0800268 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, main.numLinks ) ):
269 main.assertReturnString += 'Link Up Topology State Passed\n'
kelvin-onlab44147802015-07-27 17:57:31 -0700270 else:
Jeremy2f190ca2016-01-29 15:23:57 -0800271 main.assertReturnString += 'Link Up Topology State Failed\n'
272 testResult = main.FALSE
273
274 # Check Connection
275 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames ) ):
276 main.assertReturnString += 'Link Up Pingall Passed\n'
277 else:
278 main.assertReturnString += 'Link Up Pingall Failed\n'
279 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700280
281 # Remove all intents
Jeremy2f190ca2016-01-29 15:23:57 -0800282 if utilities.retry( f=removeAllIntents, retValue=main.FALSE, args=( main, ) ):
283 main.assertReturnString += 'Remove Intents Passed'
284 else:
285 main.assertReturnString += 'Remove Intents Failed'
286 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700287
Jeremy2f190ca2016-01-29 15:23:57 -0800288 return testResult
kelvin-onlab44147802015-07-27 17:57:31 -0700289
Jeremy2f190ca2016-01-29 15:23:57 -0800290def installPointIntent( main,
291 name,
292 senders,
293 recipients,
294 onosNode=0,
295 ethType="",
296 bandwidth="",
297 lambdaAlloc=False,
298 ipProto="",
299 ipSrc="",
300 ipDst="",
301 tcpSrc="",
302 tcpDst=""):
303 """
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
332 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
337 """
338
339 assert main, "There is no main variable"
340 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"
343
344 global itemName # The name of this run. Used for logs.
345 itemName = name
346 onosNode = int( onosNode )
347
348 main.log.info( itemName + ": Adding single to single point intents" )
349
Jeremydd9bda62016-04-18 12:02:32 -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" )
Jeremy2f190ca2016-01-29 15:23:57 -0800355
Jeremydd9bda62016-04-18 12:02:32 -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" )
Jeremy2f190ca2016-01-29 15:23:57 -0800360
361
Jeremydd9bda62016-04-18 12:02:32 -0700362 ingressDevice = senders[ 0 ].get( "device" )
363 egressDevice = recipients[ 0 ].get( "device" )
Jeremy2f190ca2016-01-29 15:23:57 -0800364
Jeremydd9bda62016-04-18 12:02:32 -0700365 portIngress = senders[ 0 ].get( "port", "" )
366 portEgress = recipients[ 0 ].get( "port", "" )
367 main.log.debug( ingressDevice )
368 main.log.debug( egressDevice )
Jeremy2f190ca2016-01-29 15:23:57 -0800369
Jeremydd9bda62016-04-18 12:02:32 -0700370 srcMac = senders[ 0 ].get( "mac" )
371 dstMac = recipients[ 0 ].get( "mac" )
Jeremy2f190ca2016-01-29 15:23:57 -0800372
Jeremydd9bda62016-04-18 12:02:32 -0700373 ipSrc = senders[ 0 ].get( "ip" )
374 ipDst = recipients[ 0 ].get( "ip" )
Jeremy2f190ca2016-01-29 15:23:57 -0800375
Jeremydd9bda62016-04-18 12:02:32 -0700376 intent1 = main.CLIs[ onosNode ].addPointIntent(
377 ingressDevice=ingressDevice,
378 egressDevice=egressDevice,
379 ingressPort=portIngress,
380 egressPort=portEgress,
381 ethType=ethType,
382 ethSrc=srcMac,
383 ethDst=dstMac,
384 bandwidth=bandwidth,
385 lambdaAlloc=lambdaAlloc,
386 ipProto=ipProto,
387 ipSrc=ipSrc,
388 ipDst=ipDst,
389 tcpSrc=tcpSrc,
390 tcpDst=tcpDst )
Jeremy2f190ca2016-01-29 15:23:57 -0800391
Jeremydd9bda62016-04-18 12:02:32 -0700392 time.sleep( main.addIntentSleep )
393 intentsId = main.CLIs[ 0 ].getIntentsId()
394 except (KeyError, TypeError):
395 errorMsg = "There was a problem loading the hosts data."
396 if intentId:
397 errorMsg += " There was a problem installing Point to Point intent."
398 main.log.error( errorMsg )
399 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -0800400
Jeremydd9bda62016-04-18 12:02:32 -0700401 # Check intent state
Jeremy2f190ca2016-01-29 15:23:57 -0800402 if utilities.retry ( f=checkIntentState, retValue=main.FALSE,
403 args = (main, intentsId ), sleep=main.checkIntentSleep ):
404 return intentsId
405 else:
406 main.log.error( "Single to Single point intent did not install correctly" )
407 return main.FALSE
408
Jeremy2f190ca2016-01-29 15:23:57 -0800409def testPointIntent( main,
410 name,
411 intentId,
412 senders,
413 recipients,
414 badSenders={},
415 badRecipients={},
416 onosNode=0,
417 ethType="",
418 bandwidth="",
419 lambdaAlloc=False,
420 ipProto="",
421 ipAddresses="",
422 tcp="",
423 sw1="s5",
424 sw2="s2",
425 expectedLink=0):
426 """
427 Test a Point Intent
428
429 Description:
430 Test a point intent
431
432 Steps:
433 - Fetch host data if not given
434 - Check Intent State
435 - Check Flow State
436 - Check Connectivity
437 - Check Lack of Connectivity Between Hosts not in the Intent
438 - Reroute
439 - Take Expected Link Down
440 - Check Intent State
441 - Check Flow State
442 - Check Topology
443 - Check Connectivity
444 - Bring Expected Link Up
445 - Check Intent State
446 - Check Flow State
447 - Check Topology
448 - Check Connectivity
449 - Remove Topology
450
451 Required:
452 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
453
454 senders - List of host dictionaries i.e.
455 { "name":"h8", "device":"of:0000000000000005/8","mac":"00:00:00:00:00:08" }
456 recipients - List of host dictionaries i.e.
457 { "name":"h16", "device":"of:0000000000000006/8", "mac":"00:00:00:00:00:10" }
458 Optional:
459 onosNode - ONOS node to install the intents in main.CLIs[ ]
460 0 by default so that it will always use the first
461 ONOS node
462 ethType - Ethernet type eg. IPV4, IPV6
463 bandwidth - Bandwidth capacity
464 lambdaAlloc - Allocate lambda, defaults to False
465 ipProto - IP protocol
466 tcp - TCP ports in the same order as the hosts in hostNames
467 sw1 - First switch to bring down & up for rerouting purpose
468 sw2 - Second switch to bring down & up for rerouting purpose
469 expectedLink - Expected link when the switches are down, it should
470 be two links lower than the links before the two
471 switches are down
472
473 """
474
475 # Parameter Validity Check
476 assert main, "There is no main variable"
477 assert senders, "You must specify a sender"
478 assert recipients, "You must specify a recipient"
479
480 global itemName
481 itemName = name
482 tempHostsData = {}
483 onosNode = int( onosNode )
484
485 main.log.info( itemName + ": Testing Point Intent" )
486
Jeremydd9bda62016-04-18 12:02:32 -0700487 try:
488 # Names for scapy
489 senderNames = [ x.get( "name" ) for x in senders ]
490 recipientNames = [ x.get( "name" ) for x in recipients ]
491 badSenderNames = [ x.get( "name" ) for x in badSenders ]
492 badRecipientNames = [ x.get( "name" ) for x in badRecipients ]
Jeremy2f190ca2016-01-29 15:23:57 -0800493
Jeremydd9bda62016-04-18 12:02:32 -0700494 for sender in senders:
495 if not sender.get( "device" ):
496 main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
497 sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )
Jeremy2f190ca2016-01-29 15:23:57 -0800498
Jeremydd9bda62016-04-18 12:02:32 -0700499 for recipient in recipients:
500 if not recipient.get( "device" ):
501 main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
502 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
503 except (KeyError, TypeError):
504 main.log.error( "There was a problem loading the hosts data." )
505 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -0800506
507 testResult = main.TRUE
508 main.log.info( itemName + ": Testing point intents" )
509
510 # Check intent state
511 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
512 main.assertReturnString += 'Initial Intent State Passed\n'
513 else:
514 main.assertReturnString += 'Initial Intent State Failed\n'
515 testResult = main.FALSE
516
517 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800518 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 -0800519 main.assertReturnString += 'Initial Flow State Passed\n'
520 else:
521 main.assertReturnString += 'Intial Flow State Failed\n'
522 testResult = main.FALSE
523
524 # Check Connectivity
525 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames ) ):
526 main.assertReturnString += 'Initial Ping Passed\n'
527 else:
528 main.assertReturnString += 'Initial Ping Failed\n'
529 testResult = main.FALSE
530
531 # Check connections that shouldn't work
532 if badSenderNames:
533 main.log.info( "Checking that packets from incorrect sender do not go through" )
534 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, badSenderNames, recipientNames ), kwargs={ "expectFailure":True } ):
535 main.assertReturnString += 'Bad Sender Ping Passed\n'
536 else:
537 main.assertReturnString += 'Bad Sender Ping Failed\n'
538 testResult = main.FALSE
539
540 if badRecipientNames:
541 main.log.info( "Checking that packets to incorrect recipients do not go through" )
542 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, badRecipientNames ), kwargs={ "expectFailure":True } ):
543 main.assertReturnString += 'Bad Recipient Ping Passed\n'
544 else:
545 main.assertReturnString += 'Bad Recipient Ping Failed\n'
546 testResult = main.FALSE
547
548 # Test rerouting if these variables exist
549 if sw1 and sw2 and expectedLink:
550 # Take link down
551 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "down" ) ):
552 main.assertReturnString += 'Link Down Passed\n'
553 else:
554 main.assertReturnString += 'Link Down Failed\n'
555 testResult = main.FALSE
556
557 # Check intent state
558 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
559 main.assertReturnString += 'Link Down Intent State Passed\n'
560 else:
561 main.assertReturnString += 'Link Down Intent State Failed\n'
562 testResult = main.FALSE
563
564 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800565 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 -0800566 main.assertReturnString += 'Link Down Flow State Passed\n'
567 else:
568 main.assertReturnString += 'Link Down Flow State Failed\n'
569 testResult = main.FALSE
570
571 # Check OnosTopology
Jeremybc6a0aa2016-02-05 14:10:08 -0800572 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, expectedLink ), sleep=10 ):
Jeremy2f190ca2016-01-29 15:23:57 -0800573 main.assertReturnString += 'Link Down Topology State Passed\n'
574 else:
575 main.assertReturnString += 'Link Down Topology State Failed\n'
576 testResult = main.FALSE
577
578 # Check Connection
579 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames ) ):
580 main.assertReturnString += 'Link Down Pingall Passed\n'
581 else:
582 main.assertReturnString += 'Link Down Pingall Failed\n'
583 testResult = main.FALSE
584
585 # Bring link up
586 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "up" ) ):
587 main.assertReturnString += 'Link Up Passed\n'
588 else:
589 main.assertReturnString += 'Link Up Failed\n'
590 testResult = main.FALSE
591
592 # Wait for reroute
593 time.sleep( main.rerouteSleep )
594
595 # Check Intents
596 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
597 main.assertReturnString += 'Link Up Intent State Passed\n'
598 else:
599 main.assertReturnString += 'Link Up Intent State Failed\n'
600 testResult = main.FALSE
601
602 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800603 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 -0800604 main.assertReturnString += 'Link Up Flow State Passed\n'
605 else:
606 main.assertReturnString += 'Link Up Flow State Failed\n'
607 testResult = main.FALSE
608
609 # Check OnosTopology
610 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, main.numLinks ) ):
611 main.assertReturnString += 'Link Up Topology State Passed\n'
612 else:
613 main.assertReturnString += 'Link Up Topology State Failed\n'
614 testResult = main.FALSE
615
616 # Check Connection
617 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames ) ):
618 main.assertReturnString += 'Link Up Scapy Packet Received Passed\n'
619 else:
620 main.assertReturnString += 'Link Up Scapy Packet Recieved Failed\n'
621 testResult = main.FALSE
622
623 # Remove all intents
624 if utilities.retry( f=removeAllIntents, retValue=main.FALSE, args=( main, ) ):
625 main.assertReturnString += 'Remove Intents Passed'
626 else:
627 main.assertReturnString += 'Remove Intents Failed'
628 testResult = main.FALSE
629
630 return testResult
kelvin-onlab44147802015-07-27 17:57:31 -0700631
kelvin-onlab0e684682015-08-11 18:51:41 -0700632def pointIntentTcp( main,
633 name,
634 host1,
635 host2,
636 onosNode=0,
637 deviceId1="",
638 deviceId2="",
639 port1="",
640 port2="",
641 ethType="",
642 mac1="",
643 mac2="",
644 bandwidth="",
645 lambdaAlloc=False,
646 ipProto="",
647 ip1="",
648 ip2="",
649 tcp1="",
650 tcp2="",
651 sw1="",
652 sw2="",
653 expectedLink=0 ):
654
655 """
656 Description:
657 Verify add-point-intent only for TCP
658 Steps:
659 - Get device ids | ports
660 - Add point intents
661 - Check intents
662 - Verify flows
663 - Ping hosts
664 - Reroute
665 - Link down
666 - Verify flows
667 - Check topology
668 - Ping hosts
669 - Link up
670 - Verify flows
671 - Check topology
672 - Ping hosts
673 - Remove intents
674 Required:
675 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
676 host1 - Name of first host
677 host2 - Name of second host
678 Optional:
679 onosNode - ONOS node to install the intents in main.CLIs[ ]
680 0 by default so that it will always use the first
681 ONOS node
682 deviceId1 - ONOS device id of the first switch, the same as the
683 location of the first host eg. of:0000000000000001/1,
684 located at device 1 port 1
685 deviceId2 - ONOS device id of the second switch
686 port1 - The port number where the first host is attached
687 port2 - The port number where the second host is attached
688 ethType - Ethernet type eg. IPV4, IPV6
689 mac1 - Mac address of first host
690 mac2 - Mac address of the second host
691 bandwidth - Bandwidth capacity
692 lambdaAlloc - Allocate lambda, defaults to False
693 ipProto - IP protocol
694 ip1 - IP address of first host
695 ip2 - IP address of second host
696 tcp1 - TCP port of first host
697 tcp2 - TCP port of second host
698 sw1 - First switch to bring down & up for rerouting purpose
699 sw2 - Second switch to bring down & up for rerouting purpose
700 expectedLink - Expected link when the switches are down, it should
701 be two links lower than the links before the two
702 switches are down
703 """
704
705 assert main, "There is no main variable"
706 assert name, "variable name is empty"
707 assert host1 and host2, "You must specify hosts"
708
709 global itemName
710 itemName = name
711 host1 = host1
712 host2 = host2
713 hostNames = [ host1, host2 ]
714 intentsId = []
715
716 iperfResult = main.TRUE
717 intentResult = main.TRUE
718 removeIntentResult = main.TRUE
719 flowResult = main.TRUE
720 topoResult = main.TRUE
721 linkDownResult = main.TRUE
722 linkUpResult = main.TRUE
723 onosNode = int( onosNode )
724
725 # Adding bidirectional point intents
726 main.log.info( itemName + ": Adding point intents" )
727 intent1 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
728 egressDevice=deviceId2,
729 ingressPort=port1,
730 egressPort=port2,
731 ethType=ethType,
732 ethSrc=mac1,
733 ethDst=mac2,
734 bandwidth=bandwidth,
735 lambdaAlloc=lambdaAlloc,
736 ipProto=ipProto,
737 ipSrc=ip1,
738 ipDst=ip2,
739 tcpSrc=tcp1,
740 tcpDst="" )
741
742 intent2 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
743 egressDevice=deviceId1,
744 ingressPort=port2,
745 egressPort=port1,
746 ethType=ethType,
747 ethSrc=mac2,
748 ethDst=mac1,
749 bandwidth=bandwidth,
750 lambdaAlloc=lambdaAlloc,
751 ipProto=ipProto,
752 ipSrc=ip2,
753 ipDst=ip1,
754 tcpSrc=tcp2,
755 tcpDst="" )
756
757 intent3 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
758 egressDevice=deviceId2,
759 ingressPort=port1,
760 egressPort=port2,
761 ethType=ethType,
762 ethSrc=mac1,
763 ethDst=mac2,
764 bandwidth=bandwidth,
765 lambdaAlloc=lambdaAlloc,
766 ipProto=ipProto,
767 ipSrc=ip1,
768 ipDst=ip2,
769 tcpSrc="",
770 tcpDst=tcp2 )
771
772 intent4 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
773 egressDevice=deviceId1,
774 ingressPort=port2,
775 egressPort=port1,
776 ethType=ethType,
777 ethSrc=mac2,
778 ethDst=mac1,
779 bandwidth=bandwidth,
780 lambdaAlloc=lambdaAlloc,
781 ipProto=ipProto,
782 ipSrc=ip2,
783 ipDst=ip1,
784 tcpSrc="",
785 tcpDst=tcp1 )
786
787 # Get all intents ID in the system, time delay right after intents are added
788 time.sleep( main.addIntentSleep )
789 intentsId = main.CLIs[ 0 ].getIntentsId()
790 # Check intents state
791 time.sleep( main.checkIntentSleep )
792 intentResult = checkIntentState( main, intentsId )
793 # Check flows count in each node
794 checkFlowsCount( main )
795
796 # Check intents state again if first check fails...
797 if not intentResult:
798 intentResult = checkIntentState( main, intentsId )
799
800 # Check flows count in each node
801 checkFlowsCount( main )
802
803 # Verify flows
804 checkFlowsState( main )
805
806 # Run iperf to both host
807 iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
808 host2, 10 )
809
810 # Test rerouting if these variables exist
811 if sw1 and sw2 and expectedLink:
812 # link down
813 linkDownResult = link( main, sw1, sw2, "down" )
814 intentResult = intentResult and checkIntentState( main, intentsId )
815
816 # Check flows count in each node
817 checkFlowsCount( main )
818 # Verify flows
819 checkFlowsState( main )
820
821 # Check OnosTopology
822 topoResult = checkTopology( main, expectedLink )
823
824 # Run iperf to both host
825 iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
826 host2, 10 )
827
828 intentResult = checkIntentState( main, intentsId )
829
830 # Checks ONOS state in link down
831 if linkDownResult and topoResult and iperfResult and intentResult:
832 main.log.info( itemName + ": Successfully brought link down" )
833 else:
834 main.log.error( itemName + ": Failed to bring link down" )
835
836 # link up
837 linkUpResult = link( main, sw1, sw2, "up" )
838 time.sleep( main.rerouteSleep )
839
840 # Check flows count in each node
841 checkFlowsCount( main )
842 # Verify flows
843 checkFlowsState( main )
844
845 # Check OnosTopology
846 topoResult = checkTopology( main, main.numLinks )
847
848 # Run iperf to both host
849 iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
850 host2, 10 )
851
852 intentResult = checkIntentState( main, intentsId )
853
854 # Checks ONOS state in link up
855 if linkUpResult and topoResult and iperfResult and intentResult:
856 main.log.info( itemName + ": Successfully brought link back up" )
857 else:
858 main.log.error( itemName + ": Failed to bring link back up" )
859
860 # Remove all intents
861 removeIntentResult = removeAllIntents( main )
862
863 stepResult = iperfResult and linkDownResult and linkUpResult \
864 and intentResult and removeIntentResult
865
866 return stepResult
867
kelvin-onlab44147802015-07-27 17:57:31 -0700868def singleToMultiIntent( main,
869 name,
870 hostNames,
871 onosNode=0,
872 devices="",
873 ports=None,
874 ethType="",
875 macs=None,
876 bandwidth="",
877 lambdaAlloc=False,
878 ipProto="",
879 ipAddresses="",
880 tcp="",
881 sw1="",
882 sw2="",
883 expectedLink=0 ):
884 """
885 Verify Single to Multi Point intents
886 NOTE:If main.hostsData is not defined, variables data should be passed
887 in the same order index wise. All devices in the list should have the
888 same format, either all the devices have its port or it doesn't.
889 eg. hostName = [ 'h1', 'h2' ,.. ]
890 devices = [ 'of:0000000000000001', 'of:0000000000000002', ...]
891 ports = [ '1', '1', ..]
892 ...
893 Description:
894 Verify add-single-to-multi-intent iterates through the list of given
895 host | devices and add intents
896 Steps:
897 - Get device ids | ports
898 - Add single to multi point intents
899 - Check intents
900 - Verify flows
901 - Ping hosts
902 - Reroute
903 - Link down
904 - Verify flows
905 - Check topology
906 - Ping hosts
907 - Link up
908 - Verify flows
909 - Check topology
910 - Ping hosts
911 - Remove intents
912 Required:
913 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
914 hostNames - List of host names
915 Optional:
916 onosNode - ONOS node to install the intents in main.CLIs[ ]
917 0 by default so that it will always use the first
918 ONOS node
919 devices - List of device ids in the same order as the hosts
920 in hostNames
921 ports - List of port numbers in the same order as the device in
922 devices
923 ethType - Ethernet type eg. IPV4, IPV6
924 macs - List of hosts mac address in the same order as the hosts in
925 hostNames
926 bandwidth - Bandwidth capacity
927 lambdaAlloc - Allocate lambda, defaults to False
928 ipProto - IP protocol
929 ipAddresses - IP addresses of host in the same order as the hosts in
930 hostNames
931 tcp - TCP ports in the same order as the hosts in hostNames
932 sw1 - First switch to bring down & up for rerouting purpose
933 sw2 - Second switch to bring down & up for rerouting purpose
934 expectedLink - Expected link when the switches are down, it should
935 be two links lower than the links before the two
936 switches are down
937 """
938
939 assert main, "There is no main variable"
940 assert hostNames, "You must specify hosts"
941 assert devices or main.hostsData, "You must specify devices"
942
943 global itemName
944 itemName = name
945 tempHostsData = {}
946 intentsId = []
947 onosNode = int( onosNode )
948
949 macsDict = {}
950 ipDict = {}
951 if hostNames and devices:
952 if len( hostNames ) != len( devices ):
953 main.log.debug( "hosts and devices does not have the same length" )
954 #print "len hostNames = ", len( hostNames )
955 #print "len devices = ", len( devices )
956 return main.FALSE
957 if ports:
958 if len( ports ) != len( devices ):
959 main.log.error( "Ports and devices does " +
960 "not have the same length" )
961 #print "len devices = ", len( devices )
962 #print "len ports = ", len( ports )
963 return main.FALSE
964 else:
965 main.log.info( "Device Ports are not specified" )
966 if macs:
967 for i in range( len( devices ) ):
968 macsDict[ devices[ i ] ] = macs[ i ]
969
970 elif hostNames and not devices and main.hostsData:
971 devices = []
972 main.log.info( "singleToMultiIntent function is using main.hostsData" )
973 for host in hostNames:
974 devices.append( main.hostsData.get( host ).get( 'location' ) )
975 macsDict[ main.hostsData.get( host ).get( 'location' ) ] = \
976 main.hostsData.get( host ).get( 'mac' )
977 ipDict[ main.hostsData.get( host ).get( 'location' ) ] = \
978 main.hostsData.get( host ).get( 'ipAddresses' )
979 #print main.hostsData
980
981 #print 'host names = ', hostNames
982 #print 'devices = ', devices
983 #print "macsDict = ", macsDict
984
985 pingResult = main.TRUE
986 intentResult = main.TRUE
987 removeIntentResult = main.TRUE
988 flowResult = main.TRUE
989 topoResult = main.TRUE
990 linkDownResult = main.TRUE
991 linkUpResult = main.TRUE
992
993 devicesCopy = copy.copy( devices )
994 if ports:
995 portsCopy = copy.copy( ports )
996 main.log.info( itemName + ": Adding single point to multi point intents" )
997
998 # Check flows count in each node
999 checkFlowsCount( main )
1000
1001 # Adding bidirectional point intents
1002 for i in range( len( devices ) ):
1003 ingressDevice = devicesCopy[ i ]
1004 egressDeviceList = copy.copy( devicesCopy )
1005 egressDeviceList.remove( ingressDevice )
1006 if ports:
1007 portIngress = portsCopy[ i ]
1008 portEgressList = copy.copy( portsCopy )
1009 del portEgressList[ i ]
1010 else:
1011 portIngress = ""
1012 portEgressList = None
1013 if not macsDict:
1014 srcMac = ""
1015 else:
1016 srcMac = macsDict[ ingressDevice ]
1017 if srcMac == None:
1018 main.log.debug( "There is no MAC in device - " + ingressDevice )
1019 srcMac = ""
1020
1021 intentsId.append(
1022 main.CLIs[ onosNode ].addSinglepointToMultipointIntent(
1023 ingressDevice=ingressDevice,
1024 egressDeviceList=egressDeviceList,
1025 portIngress=portIngress,
1026 portEgressList=portEgressList,
1027 ethType=ethType,
1028 ethSrc=srcMac,
1029 bandwidth=bandwidth,
1030 lambdaAlloc=lambdaAlloc,
1031 ipProto=ipProto,
1032 ipSrc="",
1033 ipDst="",
1034 tcpSrc="",
1035 tcpDst="" ) )
1036
1037 # Wait some time for the flow to go through when using multi instance
1038 pingResult = pingallHosts( main, hostNames )
1039
1040 # Check intents state
1041 time.sleep( main.checkIntentSleep )
1042 intentResult = checkIntentState( main, intentsId )
1043
1044 # Check intents state again if first check fails...
1045 if not intentResult:
1046 intentResult = checkIntentState( main, intentsId )
1047
1048 # Check flows count in each node
1049 checkFlowsCount( main )
1050 # Verify flows
1051 checkFlowsState( main )
1052
1053 pingResult = pingResult and pingallHosts( main, hostNames )
1054
1055 # Test rerouting if these variables exist
1056 if sw1 and sw2 and expectedLink:
1057 # link down
1058 linkDownResult = link( main, sw1, sw2, "down" )
1059 intentResult = intentResult and checkIntentState( main, intentsId )
1060
1061 # Check flows count in each node
1062 checkFlowsCount( main )
1063 # Verify flows
1064 checkFlowsState( main )
1065
1066 # Check OnosTopology
1067 topoResult = checkTopology( main, expectedLink )
1068
1069 # Ping hosts
1070 pingResult = pingResult and pingallHosts( main, hostNames )
1071
1072 intentResult = checkIntentState( main, intentsId )
1073
1074 # Checks ONOS state in link down
1075 if linkDownResult and topoResult and pingResult and intentResult:
1076 main.log.info( itemName + ": Successfully brought link down" )
1077 else:
1078 main.log.error( itemName + ": Failed to bring link down" )
1079
1080 # link up
1081 linkUpResult = link( main, sw1, sw2, "up" )
1082 time.sleep( main.rerouteSleep )
1083
1084 # Check flows count in each node
1085 checkFlowsCount( main )
1086 # Verify flows
1087 checkFlowsState( main )
1088
1089 # Check OnosTopology
1090 topoResult = checkTopology( main, main.numLinks )
1091
1092 # Ping hosts
1093 pingResult = pingResult and pingallHosts( main, hostNames )
1094
1095 intentResult = checkIntentState( main, intentsId )
1096
1097 # Checks ONOS state in link up
1098 if linkUpResult and topoResult and pingResult and intentResult:
1099 main.log.info( itemName + ": Successfully brought link back up" )
1100 else:
1101 main.log.error( itemName + ": Failed to bring link back up" )
1102
1103 # Remove all intents
1104 removeIntentResult = removeAllIntents( main, intentsId )
1105
1106 stepResult = pingResult and linkDownResult and linkUpResult \
1107 and intentResult and removeIntentResult
1108
1109 return stepResult
1110
1111def multiToSingleIntent( main,
1112 name,
1113 hostNames,
1114 onosNode=0,
1115 devices="",
1116 ports=None,
1117 ethType="",
1118 macs=None,
1119 bandwidth="",
1120 lambdaAlloc=False,
1121 ipProto="",
1122 ipAddresses="",
1123 tcp="",
1124 sw1="",
1125 sw2="",
1126 expectedLink=0 ):
1127 """
1128 Verify Single to Multi Point intents
1129 NOTE:If main.hostsData is not defined, variables data should be passed in the
1130 same order index wise. All devices in the list should have the same
1131 format, either all the devices have its port or it doesn't.
1132 eg. hostName = [ 'h1', 'h2' ,.. ]
1133 devices = [ 'of:0000000000000001', 'of:0000000000000002', ...]
1134 ports = [ '1', '1', ..]
1135 ...
1136 Description:
1137 Verify add-multi-to-single-intent
1138 Steps:
1139 - Get device ids | ports
1140 - Add multi to single point intents
1141 - Check intents
1142 - Verify flows
1143 - Ping hosts
1144 - Reroute
1145 - Link down
1146 - Verify flows
1147 - Check topology
1148 - Ping hosts
1149 - Link up
1150 - Verify flows
1151 - Check topology
1152 - Ping hosts
1153 - Remove intents
1154 Required:
1155 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
1156 hostNames - List of host names
1157 Optional:
1158 onosNode - ONOS node to install the intents in main.CLIs[ ]
1159 0 by default so that it will always use the first
1160 ONOS node
1161 devices - List of device ids in the same order as the hosts
1162 in hostNames
1163 ports - List of port numbers in the same order as the device in
1164 devices
1165 ethType - Ethernet type eg. IPV4, IPV6
1166 macs - List of hosts mac address in the same order as the hosts in
1167 hostNames
1168 bandwidth - Bandwidth capacity
1169 lambdaAlloc - Allocate lambda, defaults to False
1170 ipProto - IP protocol
1171 ipAddresses - IP addresses of host in the same order as the hosts in
1172 hostNames
1173 tcp - TCP ports in the same order as the hosts in hostNames
1174 sw1 - First switch to bring down & up for rerouting purpose
1175 sw2 - Second switch to bring down & up for rerouting purpose
1176 expectedLink - Expected link when the switches are down, it should
1177 be two links lower than the links before the two
1178 switches are down
1179 """
1180
1181 assert main, "There is no main variable"
1182 assert hostNames, "You must specify hosts"
1183 assert devices or main.hostsData, "You must specify devices"
1184
1185 global itemName
1186 itemName = name
1187 tempHostsData = {}
1188 intentsId = []
1189 onosNode = int( onosNode )
1190
1191 macsDict = {}
1192 ipDict = {}
1193 if hostNames and devices:
1194 if len( hostNames ) != len( devices ):
1195 main.log.debug( "hosts and devices does not have the same length" )
1196 #print "len hostNames = ", len( hostNames )
1197 #print "len devices = ", len( devices )
1198 return main.FALSE
1199 if ports:
1200 if len( ports ) != len( devices ):
1201 main.log.error( "Ports and devices does " +
1202 "not have the same length" )
1203 #print "len devices = ", len( devices )
1204 #print "len ports = ", len( ports )
1205 return main.FALSE
1206 else:
1207 main.log.info( "Device Ports are not specified" )
1208 if macs:
1209 for i in range( len( devices ) ):
1210 macsDict[ devices[ i ] ] = macs[ i ]
1211 elif hostNames and not devices and main.hostsData:
1212 devices = []
1213 main.log.info( "multiToSingleIntent function is using main.hostsData" )
1214 for host in hostNames:
1215 devices.append( main.hostsData.get( host ).get( 'location' ) )
1216 macsDict[ main.hostsData.get( host ).get( 'location' ) ] = \
1217 main.hostsData.get( host ).get( 'mac' )
1218 ipDict[ main.hostsData.get( host ).get( 'location' ) ] = \
1219 main.hostsData.get( host ).get( 'ipAddresses' )
1220 #print main.hostsData
1221
1222 #print 'host names = ', hostNames
1223 #print 'devices = ', devices
1224 #print "macsDict = ", macsDict
1225
1226 pingResult = main.TRUE
1227 intentResult = main.TRUE
1228 removeIntentResult = main.TRUE
1229 flowResult = main.TRUE
1230 topoResult = main.TRUE
1231 linkDownResult = main.TRUE
1232 linkUpResult = main.TRUE
1233
1234 devicesCopy = copy.copy( devices )
1235 if ports:
1236 portsCopy = copy.copy( ports )
1237 main.log.info( itemName + ": Adding multi point to single point intents" )
1238
1239 # Check flows count in each node
1240 checkFlowsCount( main )
1241
1242 # Adding bidirectional point intents
1243 for i in range( len( devices ) ):
1244 egressDevice = devicesCopy[ i ]
1245 ingressDeviceList = copy.copy( devicesCopy )
1246 ingressDeviceList.remove( egressDevice )
1247 if ports:
1248 portEgress = portsCopy[ i ]
1249 portIngressList = copy.copy( portsCopy )
1250 del portIngressList[ i ]
1251 else:
1252 portEgress = ""
1253 portIngressList = None
1254 if not macsDict:
1255 dstMac = ""
1256 else:
1257 dstMac = macsDict[ egressDevice ]
1258 if dstMac == None:
1259 main.log.debug( "There is no MAC in device - " + egressDevice )
1260 dstMac = ""
1261
1262 intentsId.append(
1263 main.CLIs[ onosNode ].addMultipointToSinglepointIntent(
1264 ingressDeviceList=ingressDeviceList,
1265 egressDevice=egressDevice,
1266 portIngressList=portIngressList,
1267 portEgress=portEgress,
1268 ethType=ethType,
1269 ethDst=dstMac,
1270 bandwidth=bandwidth,
1271 lambdaAlloc=lambdaAlloc,
1272 ipProto=ipProto,
1273 ipSrc="",
1274 ipDst="",
1275 tcpSrc="",
1276 tcpDst="" ) )
1277
1278 pingResult = pingallHosts( main, hostNames )
1279
1280 # Check intents state
1281 time.sleep( main.checkIntentSleep )
1282 intentResult = checkIntentState( main, intentsId )
1283
1284 # Check intents state again if first check fails...
1285 if not intentResult:
1286 intentResult = checkIntentState( main, intentsId )
1287
1288 # Check flows count in each node
1289 checkFlowsCount( main )
1290 # Verify flows
1291 checkFlowsState( main )
1292
1293 # Ping hosts
1294 pingResult = pingResult and pingallHosts( main, hostNames )
1295 # Ping hosts again...
1296 pingResult = pingResult and pingallHosts( main, hostNames )
1297
1298 # Test rerouting if these variables exist
1299 if sw1 and sw2 and expectedLink:
1300 # link down
1301 linkDownResult = link( main, sw1, sw2, "down" )
1302 intentResult = intentResult and checkIntentState( main, intentsId )
1303
1304 # Check flows count in each node
1305 checkFlowsCount( main )
1306 # Verify flows
1307 checkFlowsState( main )
1308
1309 # Check OnosTopology
1310 topoResult = checkTopology( main, expectedLink )
1311
1312 # Ping hosts
1313 pingResult = pingResult and pingallHosts( main, hostNames )
1314
1315 intentResult = checkIntentState( main, intentsId )
1316
1317 # Checks ONOS state in link down
1318 if linkDownResult and topoResult and pingResult and intentResult:
1319 main.log.info( itemName + ": Successfully brought link down" )
1320 else:
1321 main.log.error( itemName + ": Failed to bring link down" )
1322
1323 # link up
1324 linkUpResult = link( main, sw1, sw2, "up" )
1325 time.sleep( main.rerouteSleep )
1326
1327 # Check flows count in each node
1328 checkFlowsCount( main )
1329 # Verify flows
1330 checkFlowsState( main )
1331
1332 # Check OnosTopology
1333 topoResult = checkTopology( main, main.numLinks )
1334
1335 # Ping hosts
1336 pingResult = pingResult and pingallHosts( main, hostNames )
1337
1338 intentResult = checkIntentState( main, intentsId )
1339
1340 # Checks ONOS state in link up
1341 if linkUpResult and topoResult and pingResult and intentResult:
1342 main.log.info( itemName + ": Successfully brought link back up" )
1343 else:
1344 main.log.error( itemName + ": Failed to bring link back up" )
1345
1346 # Remove all intents
1347 removeIntentResult = removeAllIntents( main, intentsId )
1348
1349 stepResult = pingResult and linkDownResult and linkUpResult \
1350 and intentResult and removeIntentResult
1351
1352 return stepResult
1353
kelvin-onlab0e684682015-08-11 18:51:41 -07001354def pingallHosts( main, hostList ):
kelvin-onlab44147802015-07-27 17:57:31 -07001355 # Ping all host in the hosts list variable
1356 print "Pinging : ", hostList
1357 pingResult = main.TRUE
kelvin-onlab0e684682015-08-11 18:51:41 -07001358 pingResult = main.Mininet1.pingallHosts( hostList )
kelvin-onlab44147802015-07-27 17:57:31 -07001359 return pingResult
1360
kelvin-onlab0e684682015-08-11 18:51:41 -07001361def getHostsData( main, hostList ):
kelvin-onlab44147802015-07-27 17:57:31 -07001362 """
1363 Use fwd app and pingall to discover all the hosts
1364 """
1365
1366 activateResult = main.TRUE
1367 appCheck = main.TRUE
1368 getDataResult = main.TRUE
1369 main.log.info( "Activating reactive forwarding app " )
1370 activateResult = main.CLIs[ 0 ].activateApp( "org.onosproject.fwd" )
1371 if not activateResult:
1372 main.log.error( "Something went wrong installing fwd app" )
1373 time.sleep( main.fwdSleep )
kelvin-onlab0e684682015-08-11 18:51:41 -07001374 if isinstance( hostList[ 0 ], types.StringType ):
1375 main.Mininet1.pingallHosts( hostList )
1376 elif isinstance( hostList[ 0 ], types.ListType ):
1377 for i in xrange( len( hostList ) ):
1378 main.Mininet1.pingallHosts( hostList[ i ] )
1379
kelvin-onlab44147802015-07-27 17:57:31 -07001380 hostsJson = json.loads( main.CLIs[ 0 ].hosts() )
1381 hosts = main.Mininet1.getHosts().keys()
1382 # TODO: Make better use of new getHosts function
1383 for host in hosts:
1384 main.hostsData[ host ] = {}
1385 main.hostsData[ host ][ 'mac' ] = \
1386 main.Mininet1.getMacAddress( host ).upper()
1387 for hostj in hostsJson:
1388 if main.hostsData[ host ][ 'mac' ] == hostj[ 'mac' ]:
1389 main.hostsData[ host ][ 'id' ] = hostj[ 'id' ]
1390 main.hostsData[ host ][ 'vlan' ] = hostj[ 'vlan' ]
1391 main.hostsData[ host ][ 'location' ] = \
1392 hostj[ 'location' ][ 'elementId' ] + '/' + \
1393 hostj[ 'location' ][ 'port' ]
1394 main.hostsData[ host ][ 'ipAddresses' ] = hostj[ 'ipAddresses' ]
1395
1396 main.log.info( "Deactivating reactive forwarding app " )
1397 deactivateResult = main.CLIs[ 0 ].deactivateApp( "org.onosproject.fwd" )
1398 if activateResult and deactivateResult and main.hostsData:
1399 main.log.info( "Successfully used fwd app to discover hosts " )
1400 getDataResult = main.TRUE
1401 else:
1402 main.log.info( "Failed to use fwd app to discover hosts " )
1403 getDataResult = main.FALSE
1404
1405 print main.hostsData
1406
1407 return getDataResult
1408
1409def checkTopology( main, expectedLink ):
1410 statusResult = main.TRUE
1411 # Check onos topology
1412 main.log.info( itemName + ": Checking ONOS topology " )
1413
1414 for i in range( main.numCtrls ):
1415 topologyResult = main.CLIs[ i ].topology()
1416 statusResult = main.ONOSbench.checkStatus( topologyResult,
1417 main.numSwitch,
1418 expectedLink )\
1419 and statusResult
1420 if not statusResult:
1421 main.log.error( itemName + ": Topology mismatch" )
1422 else:
1423 main.log.info( itemName + ": Topology match" )
1424 return statusResult
1425
1426def checkIntentState( main, intentsId ):
1427 """
1428 This function will check intent state to make sure all the intents
1429 are in INSTALLED state
1430 """
1431
1432 intentResult = main.TRUE
1433 results = []
1434
1435 main.log.info( itemName + ": Checking intents state" )
1436 # First check of intents
1437 for i in range( main.numCtrls ):
1438 tempResult = main.CLIs[ i ].checkIntentState( intentsId=intentsId )
1439 results.append( tempResult )
1440
1441 expectedState = [ 'INSTALLED', 'INSTALLING' ]
1442
1443 if all( result == main.TRUE for result in results ):
1444 main.log.info( itemName + ": Intents are installed correctly" )
1445 else:
1446 # Wait for at least 5 second before checking the intents again
Jeremy2f190ca2016-01-29 15:23:57 -08001447 main.log.error( "Intents are not installed correctly. Waiting 5 sec" )
kelvin-onlab44147802015-07-27 17:57:31 -07001448 time.sleep( 5 )
1449 results = []
1450 # Second check of intents since some of the intents may be in
1451 # INSTALLING state, they should be in INSTALLED at this time
1452 for i in range( main.numCtrls ):
Jeremy2f190ca2016-01-29 15:23:57 -08001453 tempResult = main.CLIs[ i ].checkIntentState( intentsId=intentsId )
kelvin-onlab44147802015-07-27 17:57:31 -07001454 results.append( tempResult )
1455 if all( result == main.TRUE for result in results ):
1456 main.log.info( itemName + ": Intents are installed correctly" )
Jeremy2f190ca2016-01-29 15:23:57 -08001457 intentResult = main.TRUE
kelvin-onlab44147802015-07-27 17:57:31 -07001458 else:
1459 main.log.error( itemName + ": Intents are NOT installed correctly" )
1460 intentResult = main.FALSE
1461
1462 return intentResult
1463
1464def checkFlowsState( main ):
1465
1466 main.log.info( itemName + ": Check flows state" )
1467 checkFlowsResult = main.CLIs[ 0 ].checkFlowsState()
1468 return checkFlowsResult
1469
1470def link( main, sw1, sw2, option):
1471
1472 # link down
1473 main.log.info( itemName + ": Bring link " + option + "between " +
1474 sw1 + " and " + sw2 )
1475 linkResult = main.Mininet1.link( end1=sw1, end2=sw2, option=option )
1476 return linkResult
1477
1478def removeAllIntents( main ):
1479 """
1480 Remove all intents in the intentsId
1481 """
1482
1483 onosSummary = []
1484 removeIntentResult = main.TRUE
1485 # Remove intents
1486 removeIntentResult = main.CLIs[ 0 ].removeAllIntents( )
1487
1488 if removeIntentResult:
1489 main.log.info( itemName + ": There are no more intents remaining, " +
1490 "successfully removed all the intents." )
1491
1492 return removeIntentResult
1493
1494def checkFlowsCount( main ):
1495 """
1496 Check flows count in each node
1497 """
1498
1499 flowsCount = []
1500 main.log.info( itemName + ": Checking flows count in each ONOS node" )
1501 for i in range( main.numCtrls ):
1502 flowsCount.append( len( json.loads( main.CLIs[ i ].flows() ) ) )
1503
1504 if flowsCount:
1505 if all( flows==flowsCount[ 0 ] for flows in flowsCount ):
1506 main.log.info( itemName + ": There are " + str( flowsCount[ 0 ] ) +
1507 " flows in all ONOS node" )
1508 else:
1509 for i in range( main.numCtrls ):
1510 main.log.debug( itemName + ": ONOS node " + str( i + 1 ) +
Jeremy2f190ca2016-01-29 15:23:57 -08001511 " has " + str( flowsCount[ i ] ) + " flows" )
kelvin-onlab44147802015-07-27 17:57:31 -07001512 else:
1513 main.log.error( "Checking flows count failed, check summary command" )
1514 return main.FALSE
1515
1516 return main.TRUE
1517
Jeremy2f190ca2016-01-29 15:23:57 -08001518def sendDiscoveryArp( main, hosts=None ):
1519 """
1520 Sends Discovery ARP packets from each host provided
1521 Defaults to each host in main.scapyHosts
1522 """
1523 # Send an arp ping from each host
1524 if not hosts:
1525 hosts = main.scapyHosts
1526 for host in hosts:
1527 pkt = 'Ether( src="{0}")/ARP( psrc="{1}")'.format( host.hostMac ,host.hostIp )
1528 # Send from the VLAN interface if there is one so ONOS discovers the VLAN correctly
1529 iface = None
1530 for interface in host.getIfList():
1531 if '.' in interface:
1532 main.log.debug( "Detected VLAN interface {0}. Sending ARP packet from {0}".format( interface ) )
1533 iface = interface
1534 break
1535 host.sendPacket( packet=pkt, iface=iface )
1536 main.log.info( "Sending ARP packet from {0}".format( host.name ) )
1537
1538def confirmHostDiscovery( main ):
1539 """
1540 Confirms that all ONOS nodes have discovered all scapy hosts
1541 """
1542 import collections
1543 scapyHostCount = len( main.scapyHosts )
1544 hosts = main.topo.getAllHosts( main ) # Get host data from each ONOS node
1545 hostFails = [] # Reset for each failed attempt
1546
1547 # Check for matching hosts on each node
1548 scapyHostIPs = [ x.hostIp for x in main.scapyHosts if x.hostIp != "0.0.0.0" ]
1549 for controller in range( main.numCtrls ):
1550 controllerStr = str( controller + 1 ) # ONOS node number
1551 # Compare Hosts
1552 # Load hosts data for controller node
Jeremydd9bda62016-04-18 12:02:32 -07001553 try:
1554 if hosts[ controller ]:
1555 main.log.info( "Hosts discovered" )
Jeremy2f190ca2016-01-29 15:23:57 -08001556 else:
Jeremydd9bda62016-04-18 12:02:32 -07001557 main.log.error( "Problem discovering hosts" )
1558 if hosts[ controller ] and "Error" not in hosts[ controller ]:
1559 try:
1560 hostData = json.loads( hosts[ controller ] )
1561 except ( TypeError, ValueError ):
1562 main.log.error( "Could not load json:" + str( hosts[ controller ] ) )
Jeremy2f190ca2016-01-29 15:23:57 -08001563 hostFails.append( controllerStr )
Jeremydd9bda62016-04-18 12:02:32 -07001564 else:
1565 onosHostIPs = [ x.get( "ipAddresses" )[ 0 ]
1566 for x in hostData
1567 if len( x.get( "ipAddresses" ) ) > 0 ]
1568 if not set( collections.Counter( scapyHostIPs ) ).issubset( set ( collections.Counter( onosHostIPs ) ) ):
1569 main.log.warn( "Controller {0} only sees nodes with {1} IPs. It should see all of the following: {2}".format( controllerStr, onosHostIPs, scapyHostIPs ) )
1570 hostFails.append( controllerStr )
1571 else:
1572 main.log.error( "Hosts returned nothing or an error." )
1573 hostFails.append( controllerStr )
1574 except IndexError:
1575 main.log.error( "Hosts returned nothing, Failed to discover hosts." )
1576 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -08001577
1578 if hostFails:
1579 main.log.error( "List of failed ONOS Nodes:" + ', '.join(map(str, hostFails )) )
1580 return main.FALSE
1581 else:
1582 return main.TRUE
1583
1584def populateHostData( main ):
1585 """
1586 Populates hostsData
1587 """
1588 import json
1589 try:
1590 hostsJson = json.loads( main.CLIs[ 0 ].hosts() )
1591 hosts = main.Mininet1.getHosts().keys()
1592 # TODO: Make better use of new getHosts function
1593 for host in hosts:
1594 main.hostsData[ host ] = {}
1595 main.hostsData[ host ][ 'mac' ] = \
1596 main.Mininet1.getMacAddress( host ).upper()
1597 for hostj in hostsJson:
1598 if main.hostsData[ host ][ 'mac' ] == hostj[ 'mac' ]:
1599 main.hostsData[ host ][ 'id' ] = hostj[ 'id' ]
1600 main.hostsData[ host ][ 'vlan' ] = hostj[ 'vlan' ]
1601 main.hostsData[ host ][ 'location' ] = \
1602 hostj[ 'location' ][ 'elementId' ] + '/' + \
1603 hostj[ 'location' ][ 'port' ]
1604 main.hostsData[ host ][ 'ipAddresses' ] = hostj[ 'ipAddresses' ]
1605 return main.TRUE
Jeremydd9bda62016-04-18 12:02:32 -07001606 except ValueError:
1607 main.log.error( "ValueError while populating hostsData" )
1608 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -08001609 except KeyError:
1610 main.log.error( "KeyError while populating hostsData")
1611 return main.FALSE
Jeremydd9bda62016-04-18 12:02:32 -07001612 except IndexError:
1613 main.log.error( "IndexError while populating hostsData" )
1614 return main.FALSE
1615 except TypeError:
1616 main.log.error( "TypeError while populating hostsData" )
1617 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -08001618
1619def scapyCheckConnection( main, senders, recipients, packet=None, packetFilter=None, expectFailure=False ):
1620 """
1621 Checks the connectivity between all given sender hosts and all given recipient hosts
1622 Packet may be specified. Defaults to Ether/IP packet
1623 Packet Filter may be specified. Defaults to Ether/IP from current sender MAC
1624 Todo: Optional packet and packet filter attributes for sender and recipients
1625 Expect Failure when the sender and recipient are not supposed to have connectivity
1626 Timeout of 1 second, returns main.TRUE if the filter is not triggered and kills the filter
1627
1628 """
1629 connectionsFunctional = main.TRUE
1630
1631 if not packetFilter:
1632 packetFilter = 'ether host {}'
1633
1634 if expectFailure:
1635 timeout = 1
1636 else:
1637 timeout = 10
1638
1639 for sender in senders:
1640 try:
1641 senderComp = getattr( main, sender )
1642 except AttributeError:
1643 main.log.error( "main has no attribute {}".format( sender ) )
1644 connectionsFunctional = main.FALSE
1645 continue
1646
1647 for recipient in recipients:
1648 # Do not send packets to self since recipient CLI will already be busy
1649 if recipient == sender:
1650 continue
1651 try:
1652 recipientComp = getattr( main, recipient )
1653 except AttributeError:
1654 main.log.error( "main has no attribute {}".format( recipient ) )
1655 connectionsFunctional = main.FALSE
1656 continue
1657
1658 recipientComp.startFilter( pktFilter = packetFilter.format( senderComp.hostMac ) )
1659
1660 if not packet:
1661 pkt = 'Ether( src="{0}", dst="{2}" )/IP( src="{1}", dst="{3}" )'.format(
1662 senderComp.hostMac,
1663 senderComp.hostIp,
1664 recipientComp.hostMac,
1665 recipientComp.hostIp )
1666 else:
1667 pkt = packet
1668 senderComp.sendPacket( packet = pkt )
1669
1670 if recipientComp.checkFilter( timeout ):
1671 if expectFailure:
1672 main.log.error( "Packet from {0} successfully received by {1} when it should not have been".format( sender , recipient ) )
1673 connectionsFunctional = main.FALSE
1674 else:
1675 main.log.info( "Packet from {0} successfully received by {1}".format( sender , recipient ) )
1676 else:
1677 recipientComp.killFilter()
1678 if expectFailure:
1679 main.log.info( "As expected, packet from {0} was not received by {1}".format( sender , recipient ) )
1680 else:
1681 main.log.error( "Packet from {0} was not received by {1}".format( sender , recipient ) )
1682 connectionsFunctional = main.FALSE
1683
1684 return connectionsFunctional
1685
Jeremye1ea0602016-02-08 16:35:05 -08001686def checkLeaderChange( leaders1, leaders2 ):
1687 """
1688 Checks for a change in intent partition leadership.
1689
1690 Takes the output of leaders -c in json string format before and after
1691 a potential change as input
1692
1693 Returns main.TRUE if no mismatches are detected
1694 Returns main.FALSE if there is a mismatch or on error loading the input
1695 """
1696 try:
1697 leaders1 = json.loads( leaders1 )
1698 leaders2 = json.loads( leaders2 )
1699 except ( AttributeError, TypeError):
1700 main.log.exception( self.name + ": Object not as expected" )
1701 return main.FALSE
1702 except Exception:
1703 main.log.exception( self.name + ": Uncaught exception!" )
1704 main.cleanup()
1705 main.exit()
1706 main.log.info( "Checking Intent Paritions for Change in Leadership" )
1707 mismatch = False
1708 for dict1 in leaders1:
1709 if "intent" in dict1.get( "topic", [] ):
1710 for dict2 in leaders2:
1711 if dict1.get( "topic", 0 ) == dict2.get( "topic", 0 ) and \
1712 dict1.get( "leader", 0 ) != dict2.get( "leader", 0 ):
1713 mismatch = True
1714 main.log.error( "{0} changed leader from {1} to {2}".\
1715 format( dict1.get( "topic", "no-topic" ),\
1716 dict1.get( "leader", "no-leader" ),\
1717 dict2.get( "leader", "no-leader" ) ) )
1718 if mismatch:
1719 return main.FALSE
1720 else:
1721 return main.TRUE
1722
1723
Jeremy2f190ca2016-01-29 15:23:57 -08001724def report( main ):
1725 """
1726 Report errors/warnings/exceptions
1727 """
1728 main.ONOSbench.logReport( main.ONOSip[ 0 ],
1729 [ "INFO",
1730 "FOLLOWER",
1731 "WARN",
1732 "flow",
1733 "ERROR",
1734 "Except" ],
1735 "s" )
1736
1737 main.log.info( "ERROR report: \n" )
1738 for i in range( main.numCtrls ):
1739 main.ONOSbench.logReport( main.ONOSip[ i ],
1740 [ "ERROR" ],
1741 "d" )
1742
1743 main.log.info( "EXCEPTIONS report: \n" )
1744 for i in range( main.numCtrls ):
1745 main.ONOSbench.logReport( main.ONOSip[ i ],
1746 [ "Except" ],
1747 "d" )
1748
1749 main.log.info( "WARNING report: \n" )
1750 for i in range( main.numCtrls ):
1751 main.ONOSbench.logReport( main.ONOSip[ i ],
1752 [ "WARN" ],
1753 "d" )