blob: 5d526deb1f7ae4620a3618ff6568f398f2abdeee [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" )
Jeremy Songsterae2dd452016-05-17 16:44:35 -070078 vlanId = host1.get( "vlanId" )
kelvin-onlab44147802015-07-27 17:57:31 -070079
Jeremydd9bda62016-04-18 12:02:32 -070080 # Adding host intents
81 main.log.info( itemName + ": Adding host intents" )
kelvin-onlab44147802015-07-27 17:57:31 -070082
Jeremydd9bda62016-04-18 12:02:32 -070083 intent1 = main.CLIs[ onosNode ].addHostIntent( hostIdOne=host1.get( "id" ),
Jeremy Songsterae2dd452016-05-17 16:44:35 -070084 hostIdTwo=host2.get( "id" ),
85 vlanId=vlanId )
kelvin-onlab44147802015-07-27 17:57:31 -070086
Jeremydd9bda62016-04-18 12:02:32 -070087 # Get all intents ID in the system, time delay right after intents are added
88 time.sleep( main.addIntentSleep )
89 intentsId = main.CLIs[ 0 ].getIntentsId()
90 except (KeyError, TypeError):
91 errorMsg = "There was a problem loading the hosts data."
92 if intentsId:
93 errorMsg += " There was a problem installing host to host intent."
94 main.log.error( errorMsg )
95 return main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -070096
Jeremy2f190ca2016-01-29 15:23:57 -080097 if utilities.retry ( f=checkIntentState, retValue=main.FALSE,
98 args = (main, intentsId ), sleep=main.checkIntentSleep ):
99 return intentsId
100 else:
101 main.log.error( "Host Intent did not install correctly" )
102 return main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700103
Jeremy2f190ca2016-01-29 15:23:57 -0800104def testHostIntent( main,
105 name,
106 intentId,
107 host1,
108 host2,
109 onosNode=0,
110 sw1="s5",
111 sw2="s2",
112 expectedLink=0):
113 """
114 Test a Host Intent
kelvin-onlab44147802015-07-27 17:57:31 -0700115
Jeremy2f190ca2016-01-29 15:23:57 -0800116 Description:
117 Test a host intent of given ID between given hosts
kelvin-onlab44147802015-07-27 17:57:31 -0700118
Jeremy2f190ca2016-01-29 15:23:57 -0800119 Steps:
120 - Fetch host data if not given
121 - Check Intent State
122 - Check Flow State
123 - Check Connectivity
124 - Check Lack of Connectivity Between Hosts not in the Intent
125 - Reroute
126 - Take Expected Link Down
127 - Check Intent State
128 - Check Flow State
129 - Check Topology
130 - Check Connectivity
131 - Bring Expected Link Up
132 - Check Intent State
133 - Check Flow State
134 - Check Topology
135 - Check Connectivity
136 - Remove Topology
kelvin-onlab44147802015-07-27 17:57:31 -0700137
Jeremy2f190ca2016-01-29 15:23:57 -0800138 Required:
139 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
140 intentId - intent ID to be tested ( and removed )
141 host1 - Dictionary for host1
142 { "name":"h8", "id":"of:0000000000000005/8" }
143 host2 - Dictionary for host2
144 { "name":"h16", "id":"of:0000000000000006/8" }
145 Optional:
146 onosNode - ONOS node to install the intents in main.CLIs[ ]
147 0 by default so that it will always use the first
148 ONOS node
149 sw1 - First switch to bring down & up for rerouting purpose
150 sw2 - Second switch to bring down & up for rerouting purpose
151 expectedLink - Expected link when the switches are down, it should
152 be two links lower than the links before the two
153 switches are down
kelvin-onlab44147802015-07-27 17:57:31 -0700154
155 """
kelvin-onlab44147802015-07-27 17:57:31 -0700156
Jeremy2f190ca2016-01-29 15:23:57 -0800157 # Parameter Validity Check
kelvin-onlab44147802015-07-27 17:57:31 -0700158 assert main, "There is no main variable"
Jeremy2f190ca2016-01-29 15:23:57 -0800159 assert host1, "You must specify host1"
160 assert host2, "You must specify host2"
kelvin-onlab44147802015-07-27 17:57:31 -0700161
162 global itemName
163 itemName = name
Jeremy2f190ca2016-01-29 15:23:57 -0800164 tempHostsData = {}
kelvin-onlab44147802015-07-27 17:57:31 -0700165 onosNode = int( onosNode )
166
Jeremy2f190ca2016-01-29 15:23:57 -0800167 main.log.info( itemName + ": Testing Host Intent" )
kelvin-onlab44147802015-07-27 17:57:31 -0700168
Jeremydd9bda62016-04-18 12:02:32 -0700169 try:
170 if not host1.get( "id" ):
171 main.log.warn( "Id not given for host1 {0}. Loading from main.hostData".format( host1.get( "name" ) ) )
172 host1[ "id" ] = main.hostsData.get( host1.get( "name" ) ).get( "location" )
kelvin-onlab0e684682015-08-11 18:51:41 -0700173
Jeremydd9bda62016-04-18 12:02:32 -0700174 if not host2.get( "id" ):
175 main.log.warn( "Id not given for host2 {0}. Loading from main.hostData".format( host2.get( "name" ) ) )
176 host2[ "id" ] = main.hostsData.get( host2.get( "name" ) ).get( "location" )
kelvin-onlab44147802015-07-27 17:57:31 -0700177
Jeremydd9bda62016-04-18 12:02:32 -0700178 senderNames = [ host1.get( "name" ), host2.get( "name" ) ]
179 recipientNames = [ host1.get( "name" ), host2.get( "name" ) ]
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700180 vlanId = host1.get( "vlanId" )
Jeremydd9bda62016-04-18 12:02:32 -0700181 except ( KeyError, TypeError ):
182 main.log.error( "There was a problem loading the hosts data." )
183 return main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700184
Jeremy2f190ca2016-01-29 15:23:57 -0800185 testResult = main.TRUE
186 main.log.info( itemName + ": Adding single point to multi point intents" )
187
188 # Check intent state
189 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
190 main.assertReturnString += 'Initial Intent State Passed\n'
191 else:
192 main.assertReturnString += 'Initial Intent State Failed\n'
193 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700194
195 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800196 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 -0800197 main.assertReturnString += 'Initial Flow State Passed\n'
198 else:
199 main.assertReturnString += 'Intial Flow State Failed\n'
200 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700201
Jeremy2f190ca2016-01-29 15:23:57 -0800202 # Check Connectivity
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700203 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId ) ):
Jeremy2f190ca2016-01-29 15:23:57 -0800204 main.assertReturnString += 'Initial Ping Passed\n'
205 else:
206 main.assertReturnString += 'Initial Ping Failed\n'
207 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700208
209 # Test rerouting if these variables exist
210 if sw1 and sw2 and expectedLink:
Jeremy2f190ca2016-01-29 15:23:57 -0800211 # Take link down
212 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "down" ) ):
213 main.assertReturnString += 'Link Down Passed\n'
214 else:
215 main.assertReturnString += 'Link Down Failed\n'
216 testResult = main.FALSE
217
218 # Check intent state
219 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
220 main.assertReturnString += 'Link Down Intent State Passed\n'
221 else:
222 main.assertReturnString += 'Link Down Intent State Failed\n'
223 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700224
225 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800226 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 -0800227 main.assertReturnString += 'Link Down Flow State Passed\n'
228 else:
229 main.assertReturnString += 'Link Down Flow State Failed\n'
230 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700231
232 # Check OnosTopology
Jeremybc6a0aa2016-02-05 14:10:08 -0800233 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, expectedLink ), sleep=10 ):
Jeremy2f190ca2016-01-29 15:23:57 -0800234 main.assertReturnString += 'Link Down Topology State Passed\n'
kelvin-onlab44147802015-07-27 17:57:31 -0700235 else:
Jeremy2f190ca2016-01-29 15:23:57 -0800236 main.assertReturnString += 'Link Down Topology State Failed\n'
237 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700238
Jeremy2f190ca2016-01-29 15:23:57 -0800239 # Check Connection
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700240 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId ) ):
Jeremy2f190ca2016-01-29 15:23:57 -0800241 main.assertReturnString += 'Link Down Pingall Passed\n'
242 else:
243 main.assertReturnString += 'Link Down Pingall Failed\n'
244 testResult = main.FALSE
245
246 # Bring link up
247 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "up" ) ):
248 main.assertReturnString += 'Link Up Passed\n'
249 else:
250 main.assertReturnString += 'Link Up Failed\n'
251 testResult = main.FALSE
252
253 # Wait for reroute
kelvin-onlab44147802015-07-27 17:57:31 -0700254 time.sleep( main.rerouteSleep )
255
Jeremy2f190ca2016-01-29 15:23:57 -0800256 # Check Intents
257 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
258 main.assertReturnString += 'Link Up Intent State Passed\n'
259 else:
260 main.assertReturnString += 'Link Up Intent State Failed\n'
261 testResult = main.FALSE
262
kelvin-onlab44147802015-07-27 17:57:31 -0700263 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800264 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 -0800265 main.assertReturnString += 'Link Up Flow State Passed\n'
266 else:
267 main.assertReturnString += 'Link Up Flow State Failed\n'
268 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700269
270 # Check OnosTopology
Jeremy2f190ca2016-01-29 15:23:57 -0800271 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, main.numLinks ) ):
272 main.assertReturnString += 'Link Up Topology State Passed\n'
kelvin-onlab44147802015-07-27 17:57:31 -0700273 else:
Jeremy2f190ca2016-01-29 15:23:57 -0800274 main.assertReturnString += 'Link Up Topology State Failed\n'
275 testResult = main.FALSE
276
277 # Check Connection
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700278 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId ) ):
Jeremy2f190ca2016-01-29 15:23:57 -0800279 main.assertReturnString += 'Link Up Pingall Passed\n'
280 else:
281 main.assertReturnString += 'Link Up Pingall Failed\n'
282 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700283
284 # Remove all intents
Jeremy2f190ca2016-01-29 15:23:57 -0800285 if utilities.retry( f=removeAllIntents, retValue=main.FALSE, args=( main, ) ):
286 main.assertReturnString += 'Remove Intents Passed'
287 else:
288 main.assertReturnString += 'Remove Intents Failed'
289 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700290
Jeremy2f190ca2016-01-29 15:23:57 -0800291 return testResult
kelvin-onlab44147802015-07-27 17:57:31 -0700292
Jeremy2f190ca2016-01-29 15:23:57 -0800293def installPointIntent( main,
294 name,
295 senders,
296 recipients,
297 onosNode=0,
298 ethType="",
299 bandwidth="",
300 lambdaAlloc=False,
301 ipProto="",
302 ipSrc="",
303 ipDst="",
304 tcpSrc="",
305 tcpDst=""):
306 """
307 Installs a Single to Single Point Intent
308
309 Description:
310 Install a single to single point intent
311
312 Steps:
313 - Fetch host data if not given
314 - Add point intent
315 - Ingress device is the first sender device
316 - Egress device is the first recipient device
317 - Ports if defined in senders or recipients
318 - MAC address ethSrc loaded from Ingress device
319 - Check intent state with retry
320 Required:
321 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
322 senders - List of host dictionaries i.e.
323 [ { "name":"h8", "device":"of:0000000000000005/8","mac":"00:00:00:00:00:08" } ]
324 recipients - List of host dictionaries i.e.
325 [ { "name":"h16", "device":"of:0000000000000006/8", "mac":"00:00:00:00:00:10" } ]
326 Optional:
327 onosNode - ONOS node to install the intents in main.CLIs[ ]
328 0 by default so that it will always use the first
329 ONOS node
330 ethType - Ethernet type eg. IPV4, IPV6
331 bandwidth - Bandwidth capacity
332 lambdaAlloc - Allocate lambda, defaults to False
333 ipProto - IP protocol
334 tcp - TCP ports in the same order as the hosts in hostNames
335 sw1 - First switch to bring down & up for rerouting purpose
336 sw2 - Second switch to bring down & up for rerouting purpose
337 expectedLink - Expected link when the switches are down, it should
338 be two links lower than the links before the two
339 switches are down
340 """
341
342 assert main, "There is no main variable"
343 assert senders, "You must specify a sender"
344 assert recipients, "You must specify a recipient"
345 # Assert devices or main.hostsData, "You must specify devices"
346
347 global itemName # The name of this run. Used for logs.
348 itemName = name
349 onosNode = int( onosNode )
350
351 main.log.info( itemName + ": Adding single to single point intents" )
352
Jeremydd9bda62016-04-18 12:02:32 -0700353 try:
354 for sender in senders:
355 if not sender.get( "device" ):
356 main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
357 sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )
Jeremy2f190ca2016-01-29 15:23:57 -0800358
Jeremydd9bda62016-04-18 12:02:32 -0700359 for recipient in recipients:
360 if not recipient.get( "device" ):
361 main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
362 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700363 vlanId = senders[ 0 ].get( "vlanId" )
Jeremy2f190ca2016-01-29 15:23:57 -0800364
365
Jeremydd9bda62016-04-18 12:02:32 -0700366 ingressDevice = senders[ 0 ].get( "device" )
367 egressDevice = recipients[ 0 ].get( "device" )
Jeremy2f190ca2016-01-29 15:23:57 -0800368
Jeremydd9bda62016-04-18 12:02:32 -0700369 portIngress = senders[ 0 ].get( "port", "" )
370 portEgress = recipients[ 0 ].get( "port", "" )
371 main.log.debug( ingressDevice )
372 main.log.debug( egressDevice )
Jeremy2f190ca2016-01-29 15:23:57 -0800373
Jeremydd9bda62016-04-18 12:02:32 -0700374 srcMac = senders[ 0 ].get( "mac" )
375 dstMac = recipients[ 0 ].get( "mac" )
Jeremy2f190ca2016-01-29 15:23:57 -0800376
Jeremydd9bda62016-04-18 12:02:32 -0700377 ipSrc = senders[ 0 ].get( "ip" )
378 ipDst = recipients[ 0 ].get( "ip" )
Jeremy2f190ca2016-01-29 15:23:57 -0800379
Jeremydd9bda62016-04-18 12:02:32 -0700380 intent1 = main.CLIs[ onosNode ].addPointIntent(
381 ingressDevice=ingressDevice,
382 egressDevice=egressDevice,
383 ingressPort=portIngress,
384 egressPort=portEgress,
385 ethType=ethType,
386 ethSrc=srcMac,
387 ethDst=dstMac,
388 bandwidth=bandwidth,
389 lambdaAlloc=lambdaAlloc,
390 ipProto=ipProto,
391 ipSrc=ipSrc,
392 ipDst=ipDst,
393 tcpSrc=tcpSrc,
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700394 tcpDst=tcpDst,
395 vlanId=vlanId )
Jeremy2f190ca2016-01-29 15:23:57 -0800396
Jeremydd9bda62016-04-18 12:02:32 -0700397 time.sleep( main.addIntentSleep )
398 intentsId = main.CLIs[ 0 ].getIntentsId()
399 except (KeyError, TypeError):
400 errorMsg = "There was a problem loading the hosts data."
401 if intentId:
402 errorMsg += " There was a problem installing Point to Point intent."
403 main.log.error( errorMsg )
404 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -0800405
Jeremydd9bda62016-04-18 12:02:32 -0700406 # Check intent state
Jeremy2f190ca2016-01-29 15:23:57 -0800407 if utilities.retry ( f=checkIntentState, retValue=main.FALSE,
408 args = (main, intentsId ), sleep=main.checkIntentSleep ):
409 return intentsId
410 else:
411 main.log.error( "Single to Single point intent did not install correctly" )
412 return main.FALSE
413
Jeremy2f190ca2016-01-29 15:23:57 -0800414def testPointIntent( main,
415 name,
416 intentId,
417 senders,
418 recipients,
419 badSenders={},
420 badRecipients={},
421 onosNode=0,
422 ethType="",
423 bandwidth="",
424 lambdaAlloc=False,
425 ipProto="",
426 ipAddresses="",
427 tcp="",
428 sw1="s5",
429 sw2="s2",
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700430 expectedLink=0,
431 useTCP=False ):
Jeremy2f190ca2016-01-29 15:23:57 -0800432 """
433 Test a Point Intent
434
435 Description:
436 Test a point intent
437
438 Steps:
439 - Fetch host data if not given
440 - Check Intent State
441 - Check Flow State
442 - Check Connectivity
443 - Check Lack of Connectivity Between Hosts not in the Intent
444 - Reroute
445 - Take Expected Link Down
446 - Check Intent State
447 - Check Flow State
448 - Check Topology
449 - Check Connectivity
450 - Bring Expected Link Up
451 - Check Intent State
452 - Check Flow State
453 - Check Topology
454 - Check Connectivity
455 - Remove Topology
456
457 Required:
458 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
459
460 senders - List of host dictionaries i.e.
461 { "name":"h8", "device":"of:0000000000000005/8","mac":"00:00:00:00:00:08" }
462 recipients - List of host dictionaries i.e.
463 { "name":"h16", "device":"of:0000000000000006/8", "mac":"00:00:00:00:00:10" }
464 Optional:
465 onosNode - ONOS node to install the intents in main.CLIs[ ]
466 0 by default so that it will always use the first
467 ONOS node
468 ethType - Ethernet type eg. IPV4, IPV6
469 bandwidth - Bandwidth capacity
470 lambdaAlloc - Allocate lambda, defaults to False
471 ipProto - IP protocol
472 tcp - TCP ports in the same order as the hosts in hostNames
473 sw1 - First switch to bring down & up for rerouting purpose
474 sw2 - Second switch to bring down & up for rerouting purpose
475 expectedLink - Expected link when the switches are down, it should
476 be two links lower than the links before the two
477 switches are down
478
479 """
480
481 # Parameter Validity Check
482 assert main, "There is no main variable"
483 assert senders, "You must specify a sender"
484 assert recipients, "You must specify a recipient"
485
486 global itemName
487 itemName = name
488 tempHostsData = {}
489 onosNode = int( onosNode )
490
491 main.log.info( itemName + ": Testing Point Intent" )
492
Jeremydd9bda62016-04-18 12:02:32 -0700493 try:
494 # Names for scapy
495 senderNames = [ x.get( "name" ) for x in senders ]
496 recipientNames = [ x.get( "name" ) for x in recipients ]
497 badSenderNames = [ x.get( "name" ) for x in badSenders ]
498 badRecipientNames = [ x.get( "name" ) for x in badRecipients ]
Jeremy2f190ca2016-01-29 15:23:57 -0800499
Jeremydd9bda62016-04-18 12:02:32 -0700500 for sender in senders:
501 if not sender.get( "device" ):
502 main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
503 sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )
Jeremy2f190ca2016-01-29 15:23:57 -0800504
Jeremydd9bda62016-04-18 12:02:32 -0700505 for recipient in recipients:
506 if not recipient.get( "device" ):
507 main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
508 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700509 vlanId=senders[ 0 ].get( "vlanId" )
Jeremydd9bda62016-04-18 12:02:32 -0700510 except (KeyError, TypeError):
511 main.log.error( "There was a problem loading the hosts data." )
512 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -0800513
514 testResult = main.TRUE
515 main.log.info( itemName + ": Testing point intents" )
516
517 # Check intent state
518 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
519 main.assertReturnString += 'Initial Intent State Passed\n'
520 else:
521 main.assertReturnString += 'Initial Intent State Failed\n'
522 testResult = main.FALSE
523
524 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800525 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 -0800526 main.assertReturnString += 'Initial Flow State Passed\n'
527 else:
528 main.assertReturnString += 'Intial Flow State Failed\n'
529 testResult = main.FALSE
530
531 # Check Connectivity
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700532 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId, useTCP ) ):
Jeremy2f190ca2016-01-29 15:23:57 -0800533 main.assertReturnString += 'Initial Ping Passed\n'
534 else:
535 main.assertReturnString += 'Initial Ping Failed\n'
536 testResult = main.FALSE
537
538 # Check connections that shouldn't work
539 if badSenderNames:
540 main.log.info( "Checking that packets from incorrect sender do not go through" )
541 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, badSenderNames, recipientNames ), kwargs={ "expectFailure":True } ):
542 main.assertReturnString += 'Bad Sender Ping Passed\n'
543 else:
544 main.assertReturnString += 'Bad Sender Ping Failed\n'
545 testResult = main.FALSE
546
547 if badRecipientNames:
548 main.log.info( "Checking that packets to incorrect recipients do not go through" )
549 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, badRecipientNames ), kwargs={ "expectFailure":True } ):
550 main.assertReturnString += 'Bad Recipient Ping Passed\n'
551 else:
552 main.assertReturnString += 'Bad Recipient Ping Failed\n'
553 testResult = main.FALSE
554
555 # Test rerouting if these variables exist
556 if sw1 and sw2 and expectedLink:
557 # Take link down
558 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "down" ) ):
559 main.assertReturnString += 'Link Down Passed\n'
560 else:
561 main.assertReturnString += 'Link Down Failed\n'
562 testResult = main.FALSE
563
564 # Check intent state
565 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
566 main.assertReturnString += 'Link Down Intent State Passed\n'
567 else:
568 main.assertReturnString += 'Link Down Intent State Failed\n'
569 testResult = main.FALSE
570
571 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800572 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 -0800573 main.assertReturnString += 'Link Down Flow State Passed\n'
574 else:
575 main.assertReturnString += 'Link Down Flow State Failed\n'
576 testResult = main.FALSE
577
578 # Check OnosTopology
Jeremybc6a0aa2016-02-05 14:10:08 -0800579 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, expectedLink ), sleep=10 ):
Jeremy2f190ca2016-01-29 15:23:57 -0800580 main.assertReturnString += 'Link Down Topology State Passed\n'
581 else:
582 main.assertReturnString += 'Link Down Topology State Failed\n'
583 testResult = main.FALSE
584
585 # Check Connection
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700586 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId, useTCP ) ):
Jeremy2f190ca2016-01-29 15:23:57 -0800587 main.assertReturnString += 'Link Down Pingall Passed\n'
588 else:
589 main.assertReturnString += 'Link Down Pingall Failed\n'
590 testResult = main.FALSE
591
592 # Bring link up
593 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "up" ) ):
594 main.assertReturnString += 'Link Up Passed\n'
595 else:
596 main.assertReturnString += 'Link Up Failed\n'
597 testResult = main.FALSE
598
599 # Wait for reroute
600 time.sleep( main.rerouteSleep )
601
602 # Check Intents
603 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
604 main.assertReturnString += 'Link Up Intent State Passed\n'
605 else:
606 main.assertReturnString += 'Link Up Intent State Failed\n'
607 testResult = main.FALSE
608
609 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800610 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 -0800611 main.assertReturnString += 'Link Up Flow State Passed\n'
612 else:
613 main.assertReturnString += 'Link Up Flow State Failed\n'
614 testResult = main.FALSE
615
616 # Check OnosTopology
617 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, main.numLinks ) ):
618 main.assertReturnString += 'Link Up Topology State Passed\n'
619 else:
620 main.assertReturnString += 'Link Up Topology State Failed\n'
621 testResult = main.FALSE
622
623 # Check Connection
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700624 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId, useTCP ) ):
Jeremy2f190ca2016-01-29 15:23:57 -0800625 main.assertReturnString += 'Link Up Scapy Packet Received Passed\n'
626 else:
627 main.assertReturnString += 'Link Up Scapy Packet Recieved Failed\n'
628 testResult = main.FALSE
629
630 # Remove all intents
631 if utilities.retry( f=removeAllIntents, retValue=main.FALSE, args=( main, ) ):
632 main.assertReturnString += 'Remove Intents Passed'
633 else:
634 main.assertReturnString += 'Remove Intents Failed'
635 testResult = main.FALSE
636
637 return testResult
kelvin-onlab44147802015-07-27 17:57:31 -0700638
kelvin-onlab0e684682015-08-11 18:51:41 -0700639def pointIntentTcp( main,
640 name,
641 host1,
642 host2,
643 onosNode=0,
644 deviceId1="",
645 deviceId2="",
646 port1="",
647 port2="",
648 ethType="",
649 mac1="",
650 mac2="",
651 bandwidth="",
652 lambdaAlloc=False,
653 ipProto="",
654 ip1="",
655 ip2="",
656 tcp1="",
657 tcp2="",
658 sw1="",
659 sw2="",
660 expectedLink=0 ):
661
662 """
663 Description:
664 Verify add-point-intent only for TCP
665 Steps:
666 - Get device ids | ports
667 - Add point intents
668 - Check intents
669 - Verify flows
670 - Ping hosts
671 - Reroute
672 - Link down
673 - Verify flows
674 - Check topology
675 - Ping hosts
676 - Link up
677 - Verify flows
678 - Check topology
679 - Ping hosts
680 - Remove intents
681 Required:
682 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
683 host1 - Name of first host
684 host2 - Name of second host
685 Optional:
686 onosNode - ONOS node to install the intents in main.CLIs[ ]
687 0 by default so that it will always use the first
688 ONOS node
689 deviceId1 - ONOS device id of the first switch, the same as the
690 location of the first host eg. of:0000000000000001/1,
691 located at device 1 port 1
692 deviceId2 - ONOS device id of the second switch
693 port1 - The port number where the first host is attached
694 port2 - The port number where the second host is attached
695 ethType - Ethernet type eg. IPV4, IPV6
696 mac1 - Mac address of first host
697 mac2 - Mac address of the second host
698 bandwidth - Bandwidth capacity
699 lambdaAlloc - Allocate lambda, defaults to False
700 ipProto - IP protocol
701 ip1 - IP address of first host
702 ip2 - IP address of second host
703 tcp1 - TCP port of first host
704 tcp2 - TCP port of second host
705 sw1 - First switch to bring down & up for rerouting purpose
706 sw2 - Second switch to bring down & up for rerouting purpose
707 expectedLink - Expected link when the switches are down, it should
708 be two links lower than the links before the two
709 switches are down
710 """
711
712 assert main, "There is no main variable"
713 assert name, "variable name is empty"
714 assert host1 and host2, "You must specify hosts"
715
716 global itemName
717 itemName = name
718 host1 = host1
719 host2 = host2
720 hostNames = [ host1, host2 ]
721 intentsId = []
722
723 iperfResult = main.TRUE
724 intentResult = main.TRUE
725 removeIntentResult = main.TRUE
726 flowResult = main.TRUE
727 topoResult = main.TRUE
728 linkDownResult = main.TRUE
729 linkUpResult = main.TRUE
730 onosNode = int( onosNode )
731
732 # Adding bidirectional point intents
733 main.log.info( itemName + ": Adding point intents" )
734 intent1 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
735 egressDevice=deviceId2,
736 ingressPort=port1,
737 egressPort=port2,
738 ethType=ethType,
739 ethSrc=mac1,
740 ethDst=mac2,
741 bandwidth=bandwidth,
742 lambdaAlloc=lambdaAlloc,
743 ipProto=ipProto,
744 ipSrc=ip1,
745 ipDst=ip2,
746 tcpSrc=tcp1,
747 tcpDst="" )
748
749 intent2 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
750 egressDevice=deviceId1,
751 ingressPort=port2,
752 egressPort=port1,
753 ethType=ethType,
754 ethSrc=mac2,
755 ethDst=mac1,
756 bandwidth=bandwidth,
757 lambdaAlloc=lambdaAlloc,
758 ipProto=ipProto,
759 ipSrc=ip2,
760 ipDst=ip1,
761 tcpSrc=tcp2,
762 tcpDst="" )
763
764 intent3 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
765 egressDevice=deviceId2,
766 ingressPort=port1,
767 egressPort=port2,
768 ethType=ethType,
769 ethSrc=mac1,
770 ethDst=mac2,
771 bandwidth=bandwidth,
772 lambdaAlloc=lambdaAlloc,
773 ipProto=ipProto,
774 ipSrc=ip1,
775 ipDst=ip2,
776 tcpSrc="",
777 tcpDst=tcp2 )
778
779 intent4 = main.CLIs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
780 egressDevice=deviceId1,
781 ingressPort=port2,
782 egressPort=port1,
783 ethType=ethType,
784 ethSrc=mac2,
785 ethDst=mac1,
786 bandwidth=bandwidth,
787 lambdaAlloc=lambdaAlloc,
788 ipProto=ipProto,
789 ipSrc=ip2,
790 ipDst=ip1,
791 tcpSrc="",
792 tcpDst=tcp1 )
793
794 # Get all intents ID in the system, time delay right after intents are added
795 time.sleep( main.addIntentSleep )
796 intentsId = main.CLIs[ 0 ].getIntentsId()
797 # Check intents state
798 time.sleep( main.checkIntentSleep )
799 intentResult = checkIntentState( main, intentsId )
800 # Check flows count in each node
801 checkFlowsCount( main )
802
803 # Check intents state again if first check fails...
804 if not intentResult:
805 intentResult = checkIntentState( main, intentsId )
806
807 # Check flows count in each node
808 checkFlowsCount( main )
809
810 # Verify flows
811 checkFlowsState( main )
812
813 # Run iperf to both host
814 iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
815 host2, 10 )
816
817 # Test rerouting if these variables exist
818 if sw1 and sw2 and expectedLink:
819 # link down
820 linkDownResult = link( main, sw1, sw2, "down" )
821 intentResult = intentResult and checkIntentState( main, intentsId )
822
823 # Check flows count in each node
824 checkFlowsCount( main )
825 # Verify flows
826 checkFlowsState( main )
827
828 # Check OnosTopology
829 topoResult = checkTopology( main, expectedLink )
830
831 # Run iperf to both host
832 iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
833 host2, 10 )
834
835 intentResult = checkIntentState( main, intentsId )
836
837 # Checks ONOS state in link down
838 if linkDownResult and topoResult and iperfResult and intentResult:
839 main.log.info( itemName + ": Successfully brought link down" )
840 else:
841 main.log.error( itemName + ": Failed to bring link down" )
842
843 # link up
844 linkUpResult = link( main, sw1, sw2, "up" )
845 time.sleep( main.rerouteSleep )
846
847 # Check flows count in each node
848 checkFlowsCount( main )
849 # Verify flows
850 checkFlowsState( main )
851
852 # Check OnosTopology
853 topoResult = checkTopology( main, main.numLinks )
854
855 # Run iperf to both host
856 iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
857 host2, 10 )
858
859 intentResult = checkIntentState( main, intentsId )
860
861 # Checks ONOS state in link up
862 if linkUpResult and topoResult and iperfResult and intentResult:
863 main.log.info( itemName + ": Successfully brought link back up" )
864 else:
865 main.log.error( itemName + ": Failed to bring link back up" )
866
867 # Remove all intents
868 removeIntentResult = removeAllIntents( main )
869
870 stepResult = iperfResult and linkDownResult and linkUpResult \
871 and intentResult and removeIntentResult
872
873 return stepResult
874
kelvin-onlab44147802015-07-27 17:57:31 -0700875def singleToMultiIntent( main,
876 name,
877 hostNames,
878 onosNode=0,
879 devices="",
880 ports=None,
881 ethType="",
882 macs=None,
883 bandwidth="",
884 lambdaAlloc=False,
885 ipProto="",
886 ipAddresses="",
887 tcp="",
888 sw1="",
889 sw2="",
890 expectedLink=0 ):
891 """
892 Verify Single to Multi Point intents
893 NOTE:If main.hostsData is not defined, variables data should be passed
894 in the same order index wise. All devices in the list should have the
895 same format, either all the devices have its port or it doesn't.
896 eg. hostName = [ 'h1', 'h2' ,.. ]
897 devices = [ 'of:0000000000000001', 'of:0000000000000002', ...]
898 ports = [ '1', '1', ..]
899 ...
900 Description:
901 Verify add-single-to-multi-intent iterates through the list of given
902 host | devices and add intents
903 Steps:
904 - Get device ids | ports
905 - Add single to multi point intents
906 - Check intents
907 - Verify flows
908 - Ping hosts
909 - Reroute
910 - Link down
911 - Verify flows
912 - Check topology
913 - Ping hosts
914 - Link up
915 - Verify flows
916 - Check topology
917 - Ping hosts
918 - Remove intents
919 Required:
920 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
921 hostNames - List of host names
922 Optional:
923 onosNode - ONOS node to install the intents in main.CLIs[ ]
924 0 by default so that it will always use the first
925 ONOS node
926 devices - List of device ids in the same order as the hosts
927 in hostNames
928 ports - List of port numbers in the same order as the device in
929 devices
930 ethType - Ethernet type eg. IPV4, IPV6
931 macs - List of hosts mac address in the same order as the hosts in
932 hostNames
933 bandwidth - Bandwidth capacity
934 lambdaAlloc - Allocate lambda, defaults to False
935 ipProto - IP protocol
936 ipAddresses - IP addresses of host in the same order as the hosts in
937 hostNames
938 tcp - TCP ports in the same order as the hosts in hostNames
939 sw1 - First switch to bring down & up for rerouting purpose
940 sw2 - Second switch to bring down & up for rerouting purpose
941 expectedLink - Expected link when the switches are down, it should
942 be two links lower than the links before the two
943 switches are down
944 """
945
946 assert main, "There is no main variable"
947 assert hostNames, "You must specify hosts"
948 assert devices or main.hostsData, "You must specify devices"
949
950 global itemName
951 itemName = name
952 tempHostsData = {}
953 intentsId = []
954 onosNode = int( onosNode )
955
956 macsDict = {}
957 ipDict = {}
958 if hostNames and devices:
959 if len( hostNames ) != len( devices ):
960 main.log.debug( "hosts and devices does not have the same length" )
961 #print "len hostNames = ", len( hostNames )
962 #print "len devices = ", len( devices )
963 return main.FALSE
964 if ports:
965 if len( ports ) != len( devices ):
966 main.log.error( "Ports and devices does " +
967 "not have the same length" )
968 #print "len devices = ", len( devices )
969 #print "len ports = ", len( ports )
970 return main.FALSE
971 else:
972 main.log.info( "Device Ports are not specified" )
973 if macs:
974 for i in range( len( devices ) ):
975 macsDict[ devices[ i ] ] = macs[ i ]
976
977 elif hostNames and not devices and main.hostsData:
978 devices = []
979 main.log.info( "singleToMultiIntent function is using main.hostsData" )
980 for host in hostNames:
981 devices.append( main.hostsData.get( host ).get( 'location' ) )
982 macsDict[ main.hostsData.get( host ).get( 'location' ) ] = \
983 main.hostsData.get( host ).get( 'mac' )
984 ipDict[ main.hostsData.get( host ).get( 'location' ) ] = \
985 main.hostsData.get( host ).get( 'ipAddresses' )
986 #print main.hostsData
987
988 #print 'host names = ', hostNames
989 #print 'devices = ', devices
990 #print "macsDict = ", macsDict
991
992 pingResult = main.TRUE
993 intentResult = main.TRUE
994 removeIntentResult = main.TRUE
995 flowResult = main.TRUE
996 topoResult = main.TRUE
997 linkDownResult = main.TRUE
998 linkUpResult = main.TRUE
999
1000 devicesCopy = copy.copy( devices )
1001 if ports:
1002 portsCopy = copy.copy( ports )
1003 main.log.info( itemName + ": Adding single point to multi point intents" )
1004
1005 # Check flows count in each node
1006 checkFlowsCount( main )
1007
1008 # Adding bidirectional point intents
1009 for i in range( len( devices ) ):
1010 ingressDevice = devicesCopy[ i ]
1011 egressDeviceList = copy.copy( devicesCopy )
1012 egressDeviceList.remove( ingressDevice )
1013 if ports:
1014 portIngress = portsCopy[ i ]
1015 portEgressList = copy.copy( portsCopy )
1016 del portEgressList[ i ]
1017 else:
1018 portIngress = ""
1019 portEgressList = None
1020 if not macsDict:
1021 srcMac = ""
1022 else:
1023 srcMac = macsDict[ ingressDevice ]
1024 if srcMac == None:
1025 main.log.debug( "There is no MAC in device - " + ingressDevice )
1026 srcMac = ""
1027
1028 intentsId.append(
1029 main.CLIs[ onosNode ].addSinglepointToMultipointIntent(
1030 ingressDevice=ingressDevice,
1031 egressDeviceList=egressDeviceList,
1032 portIngress=portIngress,
1033 portEgressList=portEgressList,
1034 ethType=ethType,
1035 ethSrc=srcMac,
1036 bandwidth=bandwidth,
1037 lambdaAlloc=lambdaAlloc,
1038 ipProto=ipProto,
1039 ipSrc="",
1040 ipDst="",
1041 tcpSrc="",
1042 tcpDst="" ) )
1043
1044 # Wait some time for the flow to go through when using multi instance
1045 pingResult = pingallHosts( main, hostNames )
1046
1047 # Check intents state
1048 time.sleep( main.checkIntentSleep )
1049 intentResult = checkIntentState( main, intentsId )
1050
1051 # Check intents state again if first check fails...
1052 if not intentResult:
1053 intentResult = checkIntentState( main, intentsId )
1054
1055 # Check flows count in each node
1056 checkFlowsCount( main )
1057 # Verify flows
1058 checkFlowsState( main )
1059
1060 pingResult = pingResult and pingallHosts( main, hostNames )
1061
1062 # Test rerouting if these variables exist
1063 if sw1 and sw2 and expectedLink:
1064 # link down
1065 linkDownResult = link( main, sw1, sw2, "down" )
1066 intentResult = intentResult and checkIntentState( main, intentsId )
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, expectedLink )
1075
1076 # Ping hosts
1077 pingResult = pingResult and pingallHosts( main, hostNames )
1078
1079 intentResult = checkIntentState( main, intentsId )
1080
1081 # Checks ONOS state in link down
1082 if linkDownResult and topoResult and pingResult and intentResult:
1083 main.log.info( itemName + ": Successfully brought link down" )
1084 else:
1085 main.log.error( itemName + ": Failed to bring link down" )
1086
1087 # link up
1088 linkUpResult = link( main, sw1, sw2, "up" )
1089 time.sleep( main.rerouteSleep )
1090
1091 # Check flows count in each node
1092 checkFlowsCount( main )
1093 # Verify flows
1094 checkFlowsState( main )
1095
1096 # Check OnosTopology
1097 topoResult = checkTopology( main, main.numLinks )
1098
1099 # Ping hosts
1100 pingResult = pingResult and pingallHosts( main, hostNames )
1101
1102 intentResult = checkIntentState( main, intentsId )
1103
1104 # Checks ONOS state in link up
1105 if linkUpResult and topoResult and pingResult and intentResult:
1106 main.log.info( itemName + ": Successfully brought link back up" )
1107 else:
1108 main.log.error( itemName + ": Failed to bring link back up" )
1109
1110 # Remove all intents
1111 removeIntentResult = removeAllIntents( main, intentsId )
1112
1113 stepResult = pingResult and linkDownResult and linkUpResult \
1114 and intentResult and removeIntentResult
1115
1116 return stepResult
1117
1118def multiToSingleIntent( main,
1119 name,
1120 hostNames,
1121 onosNode=0,
1122 devices="",
1123 ports=None,
1124 ethType="",
1125 macs=None,
1126 bandwidth="",
1127 lambdaAlloc=False,
1128 ipProto="",
1129 ipAddresses="",
1130 tcp="",
1131 sw1="",
1132 sw2="",
1133 expectedLink=0 ):
1134 """
1135 Verify Single to Multi Point intents
1136 NOTE:If main.hostsData is not defined, variables data should be passed in the
1137 same order index wise. All devices in the list should have the same
1138 format, either all the devices have its port or it doesn't.
1139 eg. hostName = [ 'h1', 'h2' ,.. ]
1140 devices = [ 'of:0000000000000001', 'of:0000000000000002', ...]
1141 ports = [ '1', '1', ..]
1142 ...
1143 Description:
1144 Verify add-multi-to-single-intent
1145 Steps:
1146 - Get device ids | ports
1147 - Add multi to single point intents
1148 - Check intents
1149 - Verify flows
1150 - Ping hosts
1151 - Reroute
1152 - Link down
1153 - Verify flows
1154 - Check topology
1155 - Ping hosts
1156 - Link up
1157 - Verify flows
1158 - Check topology
1159 - Ping hosts
1160 - Remove intents
1161 Required:
1162 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
1163 hostNames - List of host names
1164 Optional:
1165 onosNode - ONOS node to install the intents in main.CLIs[ ]
1166 0 by default so that it will always use the first
1167 ONOS node
1168 devices - List of device ids in the same order as the hosts
1169 in hostNames
1170 ports - List of port numbers in the same order as the device in
1171 devices
1172 ethType - Ethernet type eg. IPV4, IPV6
1173 macs - List of hosts mac address in the same order as the hosts in
1174 hostNames
1175 bandwidth - Bandwidth capacity
1176 lambdaAlloc - Allocate lambda, defaults to False
1177 ipProto - IP protocol
1178 ipAddresses - IP addresses of host in the same order as the hosts in
1179 hostNames
1180 tcp - TCP ports in the same order as the hosts in hostNames
1181 sw1 - First switch to bring down & up for rerouting purpose
1182 sw2 - Second switch to bring down & up for rerouting purpose
1183 expectedLink - Expected link when the switches are down, it should
1184 be two links lower than the links before the two
1185 switches are down
1186 """
1187
1188 assert main, "There is no main variable"
1189 assert hostNames, "You must specify hosts"
1190 assert devices or main.hostsData, "You must specify devices"
1191
1192 global itemName
1193 itemName = name
1194 tempHostsData = {}
1195 intentsId = []
1196 onosNode = int( onosNode )
1197
1198 macsDict = {}
1199 ipDict = {}
1200 if hostNames and devices:
1201 if len( hostNames ) != len( devices ):
1202 main.log.debug( "hosts and devices does not have the same length" )
1203 #print "len hostNames = ", len( hostNames )
1204 #print "len devices = ", len( devices )
1205 return main.FALSE
1206 if ports:
1207 if len( ports ) != len( devices ):
1208 main.log.error( "Ports and devices does " +
1209 "not have the same length" )
1210 #print "len devices = ", len( devices )
1211 #print "len ports = ", len( ports )
1212 return main.FALSE
1213 else:
1214 main.log.info( "Device Ports are not specified" )
1215 if macs:
1216 for i in range( len( devices ) ):
1217 macsDict[ devices[ i ] ] = macs[ i ]
1218 elif hostNames and not devices and main.hostsData:
1219 devices = []
1220 main.log.info( "multiToSingleIntent function is using main.hostsData" )
1221 for host in hostNames:
1222 devices.append( main.hostsData.get( host ).get( 'location' ) )
1223 macsDict[ main.hostsData.get( host ).get( 'location' ) ] = \
1224 main.hostsData.get( host ).get( 'mac' )
1225 ipDict[ main.hostsData.get( host ).get( 'location' ) ] = \
1226 main.hostsData.get( host ).get( 'ipAddresses' )
1227 #print main.hostsData
1228
1229 #print 'host names = ', hostNames
1230 #print 'devices = ', devices
1231 #print "macsDict = ", macsDict
1232
1233 pingResult = main.TRUE
1234 intentResult = main.TRUE
1235 removeIntentResult = main.TRUE
1236 flowResult = main.TRUE
1237 topoResult = main.TRUE
1238 linkDownResult = main.TRUE
1239 linkUpResult = main.TRUE
1240
1241 devicesCopy = copy.copy( devices )
1242 if ports:
1243 portsCopy = copy.copy( ports )
1244 main.log.info( itemName + ": Adding multi point to single point intents" )
1245
1246 # Check flows count in each node
1247 checkFlowsCount( main )
1248
1249 # Adding bidirectional point intents
1250 for i in range( len( devices ) ):
1251 egressDevice = devicesCopy[ i ]
1252 ingressDeviceList = copy.copy( devicesCopy )
1253 ingressDeviceList.remove( egressDevice )
1254 if ports:
1255 portEgress = portsCopy[ i ]
1256 portIngressList = copy.copy( portsCopy )
1257 del portIngressList[ i ]
1258 else:
1259 portEgress = ""
1260 portIngressList = None
1261 if not macsDict:
1262 dstMac = ""
1263 else:
1264 dstMac = macsDict[ egressDevice ]
1265 if dstMac == None:
1266 main.log.debug( "There is no MAC in device - " + egressDevice )
1267 dstMac = ""
1268
1269 intentsId.append(
1270 main.CLIs[ onosNode ].addMultipointToSinglepointIntent(
1271 ingressDeviceList=ingressDeviceList,
1272 egressDevice=egressDevice,
1273 portIngressList=portIngressList,
1274 portEgress=portEgress,
1275 ethType=ethType,
1276 ethDst=dstMac,
1277 bandwidth=bandwidth,
1278 lambdaAlloc=lambdaAlloc,
1279 ipProto=ipProto,
1280 ipSrc="",
1281 ipDst="",
1282 tcpSrc="",
1283 tcpDst="" ) )
1284
1285 pingResult = pingallHosts( main, hostNames )
1286
1287 # Check intents state
1288 time.sleep( main.checkIntentSleep )
1289 intentResult = checkIntentState( main, intentsId )
1290
1291 # Check intents state again if first check fails...
1292 if not intentResult:
1293 intentResult = checkIntentState( main, intentsId )
1294
1295 # Check flows count in each node
1296 checkFlowsCount( main )
1297 # Verify flows
1298 checkFlowsState( main )
1299
1300 # Ping hosts
1301 pingResult = pingResult and pingallHosts( main, hostNames )
1302 # Ping hosts again...
1303 pingResult = pingResult and pingallHosts( main, hostNames )
1304
1305 # Test rerouting if these variables exist
1306 if sw1 and sw2 and expectedLink:
1307 # link down
1308 linkDownResult = link( main, sw1, sw2, "down" )
1309 intentResult = intentResult and checkIntentState( main, intentsId )
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, expectedLink )
1318
1319 # Ping hosts
1320 pingResult = pingResult and pingallHosts( main, hostNames )
1321
1322 intentResult = checkIntentState( main, intentsId )
1323
1324 # Checks ONOS state in link down
1325 if linkDownResult and topoResult and pingResult and intentResult:
1326 main.log.info( itemName + ": Successfully brought link down" )
1327 else:
1328 main.log.error( itemName + ": Failed to bring link down" )
1329
1330 # link up
1331 linkUpResult = link( main, sw1, sw2, "up" )
1332 time.sleep( main.rerouteSleep )
1333
1334 # Check flows count in each node
1335 checkFlowsCount( main )
1336 # Verify flows
1337 checkFlowsState( main )
1338
1339 # Check OnosTopology
1340 topoResult = checkTopology( main, main.numLinks )
1341
1342 # Ping hosts
1343 pingResult = pingResult and pingallHosts( main, hostNames )
1344
1345 intentResult = checkIntentState( main, intentsId )
1346
1347 # Checks ONOS state in link up
1348 if linkUpResult and topoResult and pingResult and intentResult:
1349 main.log.info( itemName + ": Successfully brought link back up" )
1350 else:
1351 main.log.error( itemName + ": Failed to bring link back up" )
1352
1353 # Remove all intents
1354 removeIntentResult = removeAllIntents( main, intentsId )
1355
1356 stepResult = pingResult and linkDownResult and linkUpResult \
1357 and intentResult and removeIntentResult
1358
1359 return stepResult
1360
kelvin-onlab0e684682015-08-11 18:51:41 -07001361def pingallHosts( main, hostList ):
kelvin-onlab44147802015-07-27 17:57:31 -07001362 # Ping all host in the hosts list variable
1363 print "Pinging : ", hostList
1364 pingResult = main.TRUE
kelvin-onlab0e684682015-08-11 18:51:41 -07001365 pingResult = main.Mininet1.pingallHosts( hostList )
kelvin-onlab44147802015-07-27 17:57:31 -07001366 return pingResult
1367
kelvin-onlab0e684682015-08-11 18:51:41 -07001368def getHostsData( main, hostList ):
kelvin-onlab44147802015-07-27 17:57:31 -07001369 """
1370 Use fwd app and pingall to discover all the hosts
1371 """
1372
1373 activateResult = main.TRUE
1374 appCheck = main.TRUE
1375 getDataResult = main.TRUE
1376 main.log.info( "Activating reactive forwarding app " )
1377 activateResult = main.CLIs[ 0 ].activateApp( "org.onosproject.fwd" )
1378 if not activateResult:
1379 main.log.error( "Something went wrong installing fwd app" )
1380 time.sleep( main.fwdSleep )
kelvin-onlab0e684682015-08-11 18:51:41 -07001381 if isinstance( hostList[ 0 ], types.StringType ):
1382 main.Mininet1.pingallHosts( hostList )
1383 elif isinstance( hostList[ 0 ], types.ListType ):
1384 for i in xrange( len( hostList ) ):
1385 main.Mininet1.pingallHosts( hostList[ i ] )
1386
kelvin-onlab44147802015-07-27 17:57:31 -07001387 hostsJson = json.loads( main.CLIs[ 0 ].hosts() )
1388 hosts = main.Mininet1.getHosts().keys()
1389 # TODO: Make better use of new getHosts function
1390 for host in hosts:
1391 main.hostsData[ host ] = {}
1392 main.hostsData[ host ][ 'mac' ] = \
1393 main.Mininet1.getMacAddress( host ).upper()
1394 for hostj in hostsJson:
1395 if main.hostsData[ host ][ 'mac' ] == hostj[ 'mac' ]:
1396 main.hostsData[ host ][ 'id' ] = hostj[ 'id' ]
1397 main.hostsData[ host ][ 'vlan' ] = hostj[ 'vlan' ]
1398 main.hostsData[ host ][ 'location' ] = \
1399 hostj[ 'location' ][ 'elementId' ] + '/' + \
1400 hostj[ 'location' ][ 'port' ]
1401 main.hostsData[ host ][ 'ipAddresses' ] = hostj[ 'ipAddresses' ]
1402
1403 main.log.info( "Deactivating reactive forwarding app " )
1404 deactivateResult = main.CLIs[ 0 ].deactivateApp( "org.onosproject.fwd" )
1405 if activateResult and deactivateResult and main.hostsData:
1406 main.log.info( "Successfully used fwd app to discover hosts " )
1407 getDataResult = main.TRUE
1408 else:
1409 main.log.info( "Failed to use fwd app to discover hosts " )
1410 getDataResult = main.FALSE
1411
1412 print main.hostsData
1413
1414 return getDataResult
1415
1416def checkTopology( main, expectedLink ):
1417 statusResult = main.TRUE
1418 # Check onos topology
1419 main.log.info( itemName + ": Checking ONOS topology " )
1420
1421 for i in range( main.numCtrls ):
Flavio Castro82ee2f62016-06-07 15:04:12 -07001422 statusResult = main.CLIs[ i ].checkStatus( main.numSwitch,
kelvin-onlab44147802015-07-27 17:57:31 -07001423 expectedLink )\
1424 and statusResult
1425 if not statusResult:
1426 main.log.error( itemName + ": Topology mismatch" )
1427 else:
1428 main.log.info( itemName + ": Topology match" )
1429 return statusResult
1430
1431def checkIntentState( main, intentsId ):
1432 """
1433 This function will check intent state to make sure all the intents
1434 are in INSTALLED state
1435 """
1436
1437 intentResult = main.TRUE
1438 results = []
1439
1440 main.log.info( itemName + ": Checking intents state" )
1441 # First check of intents
1442 for i in range( main.numCtrls ):
1443 tempResult = main.CLIs[ i ].checkIntentState( intentsId=intentsId )
1444 results.append( tempResult )
1445
1446 expectedState = [ 'INSTALLED', 'INSTALLING' ]
1447
1448 if all( result == main.TRUE for result in results ):
1449 main.log.info( itemName + ": Intents are installed correctly" )
1450 else:
1451 # Wait for at least 5 second before checking the intents again
Jeremy2f190ca2016-01-29 15:23:57 -08001452 main.log.error( "Intents are not installed correctly. Waiting 5 sec" )
kelvin-onlab44147802015-07-27 17:57:31 -07001453 time.sleep( 5 )
1454 results = []
1455 # Second check of intents since some of the intents may be in
1456 # INSTALLING state, they should be in INSTALLED at this time
1457 for i in range( main.numCtrls ):
Jeremy2f190ca2016-01-29 15:23:57 -08001458 tempResult = main.CLIs[ i ].checkIntentState( intentsId=intentsId )
kelvin-onlab44147802015-07-27 17:57:31 -07001459 results.append( tempResult )
1460 if all( result == main.TRUE for result in results ):
1461 main.log.info( itemName + ": Intents are installed correctly" )
Jeremy2f190ca2016-01-29 15:23:57 -08001462 intentResult = main.TRUE
kelvin-onlab44147802015-07-27 17:57:31 -07001463 else:
1464 main.log.error( itemName + ": Intents are NOT installed correctly" )
1465 intentResult = main.FALSE
1466
1467 return intentResult
1468
1469def checkFlowsState( main ):
1470
1471 main.log.info( itemName + ": Check flows state" )
1472 checkFlowsResult = main.CLIs[ 0 ].checkFlowsState()
1473 return checkFlowsResult
1474
1475def link( main, sw1, sw2, option):
1476
1477 # link down
1478 main.log.info( itemName + ": Bring link " + option + "between " +
1479 sw1 + " and " + sw2 )
1480 linkResult = main.Mininet1.link( end1=sw1, end2=sw2, option=option )
1481 return linkResult
1482
1483def removeAllIntents( main ):
1484 """
1485 Remove all intents in the intentsId
1486 """
1487
1488 onosSummary = []
1489 removeIntentResult = main.TRUE
1490 # Remove intents
1491 removeIntentResult = main.CLIs[ 0 ].removeAllIntents( )
1492
1493 if removeIntentResult:
1494 main.log.info( itemName + ": There are no more intents remaining, " +
1495 "successfully removed all the intents." )
1496
1497 return removeIntentResult
1498
1499def checkFlowsCount( main ):
1500 """
1501 Check flows count in each node
1502 """
1503
1504 flowsCount = []
1505 main.log.info( itemName + ": Checking flows count in each ONOS node" )
1506 for i in range( main.numCtrls ):
1507 flowsCount.append( len( json.loads( main.CLIs[ i ].flows() ) ) )
1508
1509 if flowsCount:
1510 if all( flows==flowsCount[ 0 ] for flows in flowsCount ):
1511 main.log.info( itemName + ": There are " + str( flowsCount[ 0 ] ) +
1512 " flows in all ONOS node" )
1513 else:
1514 for i in range( main.numCtrls ):
1515 main.log.debug( itemName + ": ONOS node " + str( i + 1 ) +
Jeremy2f190ca2016-01-29 15:23:57 -08001516 " has " + str( flowsCount[ i ] ) + " flows" )
kelvin-onlab44147802015-07-27 17:57:31 -07001517 else:
1518 main.log.error( "Checking flows count failed, check summary command" )
1519 return main.FALSE
1520
1521 return main.TRUE
1522
Jeremy2f190ca2016-01-29 15:23:57 -08001523def sendDiscoveryArp( main, hosts=None ):
1524 """
1525 Sends Discovery ARP packets from each host provided
1526 Defaults to each host in main.scapyHosts
1527 """
1528 # Send an arp ping from each host
1529 if not hosts:
1530 hosts = main.scapyHosts
1531 for host in hosts:
1532 pkt = 'Ether( src="{0}")/ARP( psrc="{1}")'.format( host.hostMac ,host.hostIp )
1533 # Send from the VLAN interface if there is one so ONOS discovers the VLAN correctly
1534 iface = None
1535 for interface in host.getIfList():
1536 if '.' in interface:
1537 main.log.debug( "Detected VLAN interface {0}. Sending ARP packet from {0}".format( interface ) )
1538 iface = interface
1539 break
1540 host.sendPacket( packet=pkt, iface=iface )
1541 main.log.info( "Sending ARP packet from {0}".format( host.name ) )
1542
1543def confirmHostDiscovery( main ):
1544 """
1545 Confirms that all ONOS nodes have discovered all scapy hosts
1546 """
1547 import collections
1548 scapyHostCount = len( main.scapyHosts )
1549 hosts = main.topo.getAllHosts( main ) # Get host data from each ONOS node
1550 hostFails = [] # Reset for each failed attempt
1551
1552 # Check for matching hosts on each node
1553 scapyHostIPs = [ x.hostIp for x in main.scapyHosts if x.hostIp != "0.0.0.0" ]
1554 for controller in range( main.numCtrls ):
1555 controllerStr = str( controller + 1 ) # ONOS node number
1556 # Compare Hosts
1557 # Load hosts data for controller node
Jeremydd9bda62016-04-18 12:02:32 -07001558 try:
1559 if hosts[ controller ]:
1560 main.log.info( "Hosts discovered" )
Jeremy2f190ca2016-01-29 15:23:57 -08001561 else:
Jeremydd9bda62016-04-18 12:02:32 -07001562 main.log.error( "Problem discovering hosts" )
1563 if hosts[ controller ] and "Error" not in hosts[ controller ]:
1564 try:
1565 hostData = json.loads( hosts[ controller ] )
1566 except ( TypeError, ValueError ):
1567 main.log.error( "Could not load json:" + str( hosts[ controller ] ) )
Jeremy2f190ca2016-01-29 15:23:57 -08001568 hostFails.append( controllerStr )
Jeremydd9bda62016-04-18 12:02:32 -07001569 else:
1570 onosHostIPs = [ x.get( "ipAddresses" )[ 0 ]
1571 for x in hostData
1572 if len( x.get( "ipAddresses" ) ) > 0 ]
1573 if not set( collections.Counter( scapyHostIPs ) ).issubset( set ( collections.Counter( onosHostIPs ) ) ):
1574 main.log.warn( "Controller {0} only sees nodes with {1} IPs. It should see all of the following: {2}".format( controllerStr, onosHostIPs, scapyHostIPs ) )
1575 hostFails.append( controllerStr )
1576 else:
1577 main.log.error( "Hosts returned nothing or an error." )
1578 hostFails.append( controllerStr )
1579 except IndexError:
1580 main.log.error( "Hosts returned nothing, Failed to discover hosts." )
1581 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -08001582
1583 if hostFails:
1584 main.log.error( "List of failed ONOS Nodes:" + ', '.join(map(str, hostFails )) )
1585 return main.FALSE
1586 else:
1587 return main.TRUE
1588
1589def populateHostData( main ):
1590 """
1591 Populates hostsData
1592 """
1593 import json
1594 try:
1595 hostsJson = json.loads( main.CLIs[ 0 ].hosts() )
1596 hosts = main.Mininet1.getHosts().keys()
1597 # TODO: Make better use of new getHosts function
1598 for host in hosts:
1599 main.hostsData[ host ] = {}
1600 main.hostsData[ host ][ 'mac' ] = \
1601 main.Mininet1.getMacAddress( host ).upper()
1602 for hostj in hostsJson:
1603 if main.hostsData[ host ][ 'mac' ] == hostj[ 'mac' ]:
1604 main.hostsData[ host ][ 'id' ] = hostj[ 'id' ]
1605 main.hostsData[ host ][ 'vlan' ] = hostj[ 'vlan' ]
1606 main.hostsData[ host ][ 'location' ] = \
1607 hostj[ 'location' ][ 'elementId' ] + '/' + \
1608 hostj[ 'location' ][ 'port' ]
1609 main.hostsData[ host ][ 'ipAddresses' ] = hostj[ 'ipAddresses' ]
1610 return main.TRUE
Jeremydd9bda62016-04-18 12:02:32 -07001611 except ValueError:
1612 main.log.error( "ValueError while populating hostsData" )
1613 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -08001614 except KeyError:
1615 main.log.error( "KeyError while populating hostsData")
1616 return main.FALSE
Jeremydd9bda62016-04-18 12:02:32 -07001617 except IndexError:
1618 main.log.error( "IndexError while populating hostsData" )
1619 return main.FALSE
1620 except TypeError:
1621 main.log.error( "TypeError while populating hostsData" )
1622 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -08001623
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001624def scapyCheckConnection( main, senders, recipients, vlanId=None, useTCP=False, packet=None, packetFilter=None, expectFailure=False ):
Jeremy2f190ca2016-01-29 15:23:57 -08001625 """
1626 Checks the connectivity between all given sender hosts and all given recipient hosts
1627 Packet may be specified. Defaults to Ether/IP packet
1628 Packet Filter may be specified. Defaults to Ether/IP from current sender MAC
1629 Todo: Optional packet and packet filter attributes for sender and recipients
1630 Expect Failure when the sender and recipient are not supposed to have connectivity
1631 Timeout of 1 second, returns main.TRUE if the filter is not triggered and kills the filter
1632
1633 """
1634 connectionsFunctional = main.TRUE
1635
1636 if not packetFilter:
1637 packetFilter = 'ether host {}'
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001638 if useTCP:
1639 packetFilter += ' ip proto \\tcp tcp port {}'.format(main.params[ 'SDNIP' ][ 'dstPort' ])
Jeremy2f190ca2016-01-29 15:23:57 -08001640 if expectFailure:
1641 timeout = 1
1642 else:
1643 timeout = 10
1644
1645 for sender in senders:
1646 try:
1647 senderComp = getattr( main, sender )
1648 except AttributeError:
1649 main.log.error( "main has no attribute {}".format( sender ) )
1650 connectionsFunctional = main.FALSE
1651 continue
1652
1653 for recipient in recipients:
1654 # Do not send packets to self since recipient CLI will already be busy
1655 if recipient == sender:
1656 continue
1657 try:
1658 recipientComp = getattr( main, recipient )
1659 except AttributeError:
1660 main.log.error( "main has no attribute {}".format( recipient ) )
1661 connectionsFunctional = main.FALSE
1662 continue
1663
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001664 if vlanId:
1665 recipientComp.startFilter( pktFilter = ( "vlan {}".format( vlanId ) + " && " + packetFilter.format( senderComp.hostMac ) ) )
1666 else:
1667 recipientComp.startFilter( pktFilter = packetFilter.format( senderComp.hostMac ) )
Jeremy2f190ca2016-01-29 15:23:57 -08001668
1669 if not packet:
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001670 if vlanId:
1671 pkt = 'Ether( src="{0}", dst="{2}" )/Dot1Q(vlan={4})/IP( src="{1}", dst="{3}" )'.format(
1672 senderComp.hostMac,
1673 senderComp.hostIp,
1674 recipientComp.hostMac,
1675 recipientComp.hostIp,
1676 vlanId )
1677 else:
1678 pkt = 'Ether( src="{0}", dst="{2}" )/IP( src="{1}", dst="{3}" )'.format(
1679 senderComp.hostMac,
1680 senderComp.hostIp,
1681 recipientComp.hostMac,
1682 recipientComp.hostIp )
Jeremy2f190ca2016-01-29 15:23:57 -08001683 else:
1684 pkt = packet
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001685 if vlanId:
1686 senderComp.sendPacket( iface=( "{0}-eth0.{1}".format( sender, vlanId ) ), packet = pkt )
1687 else:
1688 senderComp.sendPacket( packet = pkt )
Jeremy2f190ca2016-01-29 15:23:57 -08001689
1690 if recipientComp.checkFilter( timeout ):
1691 if expectFailure:
1692 main.log.error( "Packet from {0} successfully received by {1} when it should not have been".format( sender , recipient ) )
1693 connectionsFunctional = main.FALSE
1694 else:
1695 main.log.info( "Packet from {0} successfully received by {1}".format( sender , recipient ) )
1696 else:
1697 recipientComp.killFilter()
1698 if expectFailure:
1699 main.log.info( "As expected, packet from {0} was not received by {1}".format( sender , recipient ) )
1700 else:
1701 main.log.error( "Packet from {0} was not received by {1}".format( sender , recipient ) )
1702 connectionsFunctional = main.FALSE
1703
1704 return connectionsFunctional
1705
Jeremye1ea0602016-02-08 16:35:05 -08001706def checkLeaderChange( leaders1, leaders2 ):
1707 """
1708 Checks for a change in intent partition leadership.
1709
1710 Takes the output of leaders -c in json string format before and after
1711 a potential change as input
1712
1713 Returns main.TRUE if no mismatches are detected
1714 Returns main.FALSE if there is a mismatch or on error loading the input
1715 """
1716 try:
1717 leaders1 = json.loads( leaders1 )
1718 leaders2 = json.loads( leaders2 )
1719 except ( AttributeError, TypeError):
1720 main.log.exception( self.name + ": Object not as expected" )
1721 return main.FALSE
1722 except Exception:
1723 main.log.exception( self.name + ": Uncaught exception!" )
1724 main.cleanup()
1725 main.exit()
1726 main.log.info( "Checking Intent Paritions for Change in Leadership" )
1727 mismatch = False
1728 for dict1 in leaders1:
1729 if "intent" in dict1.get( "topic", [] ):
1730 for dict2 in leaders2:
1731 if dict1.get( "topic", 0 ) == dict2.get( "topic", 0 ) and \
1732 dict1.get( "leader", 0 ) != dict2.get( "leader", 0 ):
1733 mismatch = True
1734 main.log.error( "{0} changed leader from {1} to {2}".\
1735 format( dict1.get( "topic", "no-topic" ),\
1736 dict1.get( "leader", "no-leader" ),\
1737 dict2.get( "leader", "no-leader" ) ) )
1738 if mismatch:
1739 return main.FALSE
1740 else:
1741 return main.TRUE
1742
1743
Jeremy2f190ca2016-01-29 15:23:57 -08001744def report( main ):
1745 """
1746 Report errors/warnings/exceptions
1747 """
1748 main.ONOSbench.logReport( main.ONOSip[ 0 ],
1749 [ "INFO",
1750 "FOLLOWER",
1751 "WARN",
1752 "flow",
1753 "ERROR",
1754 "Except" ],
1755 "s" )
1756
1757 main.log.info( "ERROR report: \n" )
1758 for i in range( main.numCtrls ):
1759 main.ONOSbench.logReport( main.ONOSip[ i ],
1760 [ "ERROR" ],
1761 "d" )
1762
1763 main.log.info( "EXCEPTIONS report: \n" )
1764 for i in range( main.numCtrls ):
1765 main.ONOSbench.logReport( main.ONOSip[ i ],
1766 [ "Except" ],
1767 "d" )
1768
1769 main.log.info( "WARNING report: \n" )
1770 for i in range( main.numCtrls ):
1771 main.ONOSbench.logReport( main.ONOSip[ i ],
1772 [ "WARN" ],
1773 "d" )