blob: cefb0776ff2c4cab9b53ce2f605343753be934ca [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 ):
1422 topologyResult = main.CLIs[ i ].topology()
You Wang24139872016-05-03 11:48:47 -07001423 statusResult = main.CLIs[ i ].checkStatus( topologyResult,
kelvin-onlab44147802015-07-27 17:57:31 -07001424 main.numSwitch,
1425 expectedLink )\
1426 and statusResult
1427 if not statusResult:
1428 main.log.error( itemName + ": Topology mismatch" )
1429 else:
1430 main.log.info( itemName + ": Topology match" )
1431 return statusResult
1432
1433def checkIntentState( main, intentsId ):
1434 """
1435 This function will check intent state to make sure all the intents
1436 are in INSTALLED state
1437 """
1438
1439 intentResult = main.TRUE
1440 results = []
1441
1442 main.log.info( itemName + ": Checking intents state" )
1443 # First check of intents
1444 for i in range( main.numCtrls ):
1445 tempResult = main.CLIs[ i ].checkIntentState( intentsId=intentsId )
1446 results.append( tempResult )
1447
1448 expectedState = [ 'INSTALLED', 'INSTALLING' ]
1449
1450 if all( result == main.TRUE for result in results ):
1451 main.log.info( itemName + ": Intents are installed correctly" )
1452 else:
1453 # Wait for at least 5 second before checking the intents again
Jeremy2f190ca2016-01-29 15:23:57 -08001454 main.log.error( "Intents are not installed correctly. Waiting 5 sec" )
kelvin-onlab44147802015-07-27 17:57:31 -07001455 time.sleep( 5 )
1456 results = []
1457 # Second check of intents since some of the intents may be in
1458 # INSTALLING state, they should be in INSTALLED at this time
1459 for i in range( main.numCtrls ):
Jeremy2f190ca2016-01-29 15:23:57 -08001460 tempResult = main.CLIs[ i ].checkIntentState( intentsId=intentsId )
kelvin-onlab44147802015-07-27 17:57:31 -07001461 results.append( tempResult )
1462 if all( result == main.TRUE for result in results ):
1463 main.log.info( itemName + ": Intents are installed correctly" )
Jeremy2f190ca2016-01-29 15:23:57 -08001464 intentResult = main.TRUE
kelvin-onlab44147802015-07-27 17:57:31 -07001465 else:
1466 main.log.error( itemName + ": Intents are NOT installed correctly" )
1467 intentResult = main.FALSE
1468
1469 return intentResult
1470
1471def checkFlowsState( main ):
1472
1473 main.log.info( itemName + ": Check flows state" )
1474 checkFlowsResult = main.CLIs[ 0 ].checkFlowsState()
1475 return checkFlowsResult
1476
1477def link( main, sw1, sw2, option):
1478
1479 # link down
1480 main.log.info( itemName + ": Bring link " + option + "between " +
1481 sw1 + " and " + sw2 )
1482 linkResult = main.Mininet1.link( end1=sw1, end2=sw2, option=option )
1483 return linkResult
1484
1485def removeAllIntents( main ):
1486 """
1487 Remove all intents in the intentsId
1488 """
1489
1490 onosSummary = []
1491 removeIntentResult = main.TRUE
1492 # Remove intents
1493 removeIntentResult = main.CLIs[ 0 ].removeAllIntents( )
1494
1495 if removeIntentResult:
1496 main.log.info( itemName + ": There are no more intents remaining, " +
1497 "successfully removed all the intents." )
1498
1499 return removeIntentResult
1500
1501def checkFlowsCount( main ):
1502 """
1503 Check flows count in each node
1504 """
1505
1506 flowsCount = []
1507 main.log.info( itemName + ": Checking flows count in each ONOS node" )
1508 for i in range( main.numCtrls ):
1509 flowsCount.append( len( json.loads( main.CLIs[ i ].flows() ) ) )
1510
1511 if flowsCount:
1512 if all( flows==flowsCount[ 0 ] for flows in flowsCount ):
1513 main.log.info( itemName + ": There are " + str( flowsCount[ 0 ] ) +
1514 " flows in all ONOS node" )
1515 else:
1516 for i in range( main.numCtrls ):
1517 main.log.debug( itemName + ": ONOS node " + str( i + 1 ) +
Jeremy2f190ca2016-01-29 15:23:57 -08001518 " has " + str( flowsCount[ i ] ) + " flows" )
kelvin-onlab44147802015-07-27 17:57:31 -07001519 else:
1520 main.log.error( "Checking flows count failed, check summary command" )
1521 return main.FALSE
1522
1523 return main.TRUE
1524
Jeremy2f190ca2016-01-29 15:23:57 -08001525def sendDiscoveryArp( main, hosts=None ):
1526 """
1527 Sends Discovery ARP packets from each host provided
1528 Defaults to each host in main.scapyHosts
1529 """
1530 # Send an arp ping from each host
1531 if not hosts:
1532 hosts = main.scapyHosts
1533 for host in hosts:
1534 pkt = 'Ether( src="{0}")/ARP( psrc="{1}")'.format( host.hostMac ,host.hostIp )
1535 # Send from the VLAN interface if there is one so ONOS discovers the VLAN correctly
1536 iface = None
1537 for interface in host.getIfList():
1538 if '.' in interface:
1539 main.log.debug( "Detected VLAN interface {0}. Sending ARP packet from {0}".format( interface ) )
1540 iface = interface
1541 break
1542 host.sendPacket( packet=pkt, iface=iface )
1543 main.log.info( "Sending ARP packet from {0}".format( host.name ) )
1544
1545def confirmHostDiscovery( main ):
1546 """
1547 Confirms that all ONOS nodes have discovered all scapy hosts
1548 """
1549 import collections
1550 scapyHostCount = len( main.scapyHosts )
1551 hosts = main.topo.getAllHosts( main ) # Get host data from each ONOS node
1552 hostFails = [] # Reset for each failed attempt
1553
1554 # Check for matching hosts on each node
1555 scapyHostIPs = [ x.hostIp for x in main.scapyHosts if x.hostIp != "0.0.0.0" ]
1556 for controller in range( main.numCtrls ):
1557 controllerStr = str( controller + 1 ) # ONOS node number
1558 # Compare Hosts
1559 # Load hosts data for controller node
Jeremydd9bda62016-04-18 12:02:32 -07001560 try:
1561 if hosts[ controller ]:
1562 main.log.info( "Hosts discovered" )
Jeremy2f190ca2016-01-29 15:23:57 -08001563 else:
Jeremydd9bda62016-04-18 12:02:32 -07001564 main.log.error( "Problem discovering hosts" )
1565 if hosts[ controller ] and "Error" not in hosts[ controller ]:
1566 try:
1567 hostData = json.loads( hosts[ controller ] )
1568 except ( TypeError, ValueError ):
1569 main.log.error( "Could not load json:" + str( hosts[ controller ] ) )
Jeremy2f190ca2016-01-29 15:23:57 -08001570 hostFails.append( controllerStr )
Jeremydd9bda62016-04-18 12:02:32 -07001571 else:
1572 onosHostIPs = [ x.get( "ipAddresses" )[ 0 ]
1573 for x in hostData
1574 if len( x.get( "ipAddresses" ) ) > 0 ]
1575 if not set( collections.Counter( scapyHostIPs ) ).issubset( set ( collections.Counter( onosHostIPs ) ) ):
1576 main.log.warn( "Controller {0} only sees nodes with {1} IPs. It should see all of the following: {2}".format( controllerStr, onosHostIPs, scapyHostIPs ) )
1577 hostFails.append( controllerStr )
1578 else:
1579 main.log.error( "Hosts returned nothing or an error." )
1580 hostFails.append( controllerStr )
1581 except IndexError:
1582 main.log.error( "Hosts returned nothing, Failed to discover hosts." )
1583 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -08001584
1585 if hostFails:
1586 main.log.error( "List of failed ONOS Nodes:" + ', '.join(map(str, hostFails )) )
1587 return main.FALSE
1588 else:
1589 return main.TRUE
1590
1591def populateHostData( main ):
1592 """
1593 Populates hostsData
1594 """
1595 import json
1596 try:
1597 hostsJson = json.loads( main.CLIs[ 0 ].hosts() )
1598 hosts = main.Mininet1.getHosts().keys()
1599 # TODO: Make better use of new getHosts function
1600 for host in hosts:
1601 main.hostsData[ host ] = {}
1602 main.hostsData[ host ][ 'mac' ] = \
1603 main.Mininet1.getMacAddress( host ).upper()
1604 for hostj in hostsJson:
1605 if main.hostsData[ host ][ 'mac' ] == hostj[ 'mac' ]:
1606 main.hostsData[ host ][ 'id' ] = hostj[ 'id' ]
1607 main.hostsData[ host ][ 'vlan' ] = hostj[ 'vlan' ]
1608 main.hostsData[ host ][ 'location' ] = \
1609 hostj[ 'location' ][ 'elementId' ] + '/' + \
1610 hostj[ 'location' ][ 'port' ]
1611 main.hostsData[ host ][ 'ipAddresses' ] = hostj[ 'ipAddresses' ]
1612 return main.TRUE
Jeremydd9bda62016-04-18 12:02:32 -07001613 except ValueError:
1614 main.log.error( "ValueError while populating hostsData" )
1615 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -08001616 except KeyError:
1617 main.log.error( "KeyError while populating hostsData")
1618 return main.FALSE
Jeremydd9bda62016-04-18 12:02:32 -07001619 except IndexError:
1620 main.log.error( "IndexError while populating hostsData" )
1621 return main.FALSE
1622 except TypeError:
1623 main.log.error( "TypeError while populating hostsData" )
1624 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -08001625
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001626def scapyCheckConnection( main, senders, recipients, vlanId=None, useTCP=False, packet=None, packetFilter=None, expectFailure=False ):
Jeremy2f190ca2016-01-29 15:23:57 -08001627 """
1628 Checks the connectivity between all given sender hosts and all given recipient hosts
1629 Packet may be specified. Defaults to Ether/IP packet
1630 Packet Filter may be specified. Defaults to Ether/IP from current sender MAC
1631 Todo: Optional packet and packet filter attributes for sender and recipients
1632 Expect Failure when the sender and recipient are not supposed to have connectivity
1633 Timeout of 1 second, returns main.TRUE if the filter is not triggered and kills the filter
1634
1635 """
1636 connectionsFunctional = main.TRUE
1637
1638 if not packetFilter:
1639 packetFilter = 'ether host {}'
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001640 if useTCP:
1641 packetFilter += ' ip proto \\tcp tcp port {}'.format(main.params[ 'SDNIP' ][ 'dstPort' ])
Jeremy2f190ca2016-01-29 15:23:57 -08001642 if expectFailure:
1643 timeout = 1
1644 else:
1645 timeout = 10
1646
1647 for sender in senders:
1648 try:
1649 senderComp = getattr( main, sender )
1650 except AttributeError:
1651 main.log.error( "main has no attribute {}".format( sender ) )
1652 connectionsFunctional = main.FALSE
1653 continue
1654
1655 for recipient in recipients:
1656 # Do not send packets to self since recipient CLI will already be busy
1657 if recipient == sender:
1658 continue
1659 try:
1660 recipientComp = getattr( main, recipient )
1661 except AttributeError:
1662 main.log.error( "main has no attribute {}".format( recipient ) )
1663 connectionsFunctional = main.FALSE
1664 continue
1665
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001666 if vlanId:
1667 recipientComp.startFilter( pktFilter = ( "vlan {}".format( vlanId ) + " && " + packetFilter.format( senderComp.hostMac ) ) )
1668 else:
1669 recipientComp.startFilter( pktFilter = packetFilter.format( senderComp.hostMac ) )
Jeremy2f190ca2016-01-29 15:23:57 -08001670
1671 if not packet:
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001672 if vlanId:
1673 pkt = 'Ether( src="{0}", dst="{2}" )/Dot1Q(vlan={4})/IP( src="{1}", dst="{3}" )'.format(
1674 senderComp.hostMac,
1675 senderComp.hostIp,
1676 recipientComp.hostMac,
1677 recipientComp.hostIp,
1678 vlanId )
1679 else:
1680 pkt = 'Ether( src="{0}", dst="{2}" )/IP( src="{1}", dst="{3}" )'.format(
1681 senderComp.hostMac,
1682 senderComp.hostIp,
1683 recipientComp.hostMac,
1684 recipientComp.hostIp )
Jeremy2f190ca2016-01-29 15:23:57 -08001685 else:
1686 pkt = packet
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001687 if vlanId:
1688 senderComp.sendPacket( iface=( "{0}-eth0.{1}".format( sender, vlanId ) ), packet = pkt )
1689 else:
1690 senderComp.sendPacket( packet = pkt )
Jeremy2f190ca2016-01-29 15:23:57 -08001691
1692 if recipientComp.checkFilter( timeout ):
1693 if expectFailure:
1694 main.log.error( "Packet from {0} successfully received by {1} when it should not have been".format( sender , recipient ) )
1695 connectionsFunctional = main.FALSE
1696 else:
1697 main.log.info( "Packet from {0} successfully received by {1}".format( sender , recipient ) )
1698 else:
1699 recipientComp.killFilter()
1700 if expectFailure:
1701 main.log.info( "As expected, packet from {0} was not received by {1}".format( sender , recipient ) )
1702 else:
1703 main.log.error( "Packet from {0} was not received by {1}".format( sender , recipient ) )
1704 connectionsFunctional = main.FALSE
1705
1706 return connectionsFunctional
1707
Jeremye1ea0602016-02-08 16:35:05 -08001708def checkLeaderChange( leaders1, leaders2 ):
1709 """
1710 Checks for a change in intent partition leadership.
1711
1712 Takes the output of leaders -c in json string format before and after
1713 a potential change as input
1714
1715 Returns main.TRUE if no mismatches are detected
1716 Returns main.FALSE if there is a mismatch or on error loading the input
1717 """
1718 try:
1719 leaders1 = json.loads( leaders1 )
1720 leaders2 = json.loads( leaders2 )
1721 except ( AttributeError, TypeError):
1722 main.log.exception( self.name + ": Object not as expected" )
1723 return main.FALSE
1724 except Exception:
1725 main.log.exception( self.name + ": Uncaught exception!" )
1726 main.cleanup()
1727 main.exit()
1728 main.log.info( "Checking Intent Paritions for Change in Leadership" )
1729 mismatch = False
1730 for dict1 in leaders1:
1731 if "intent" in dict1.get( "topic", [] ):
1732 for dict2 in leaders2:
1733 if dict1.get( "topic", 0 ) == dict2.get( "topic", 0 ) and \
1734 dict1.get( "leader", 0 ) != dict2.get( "leader", 0 ):
1735 mismatch = True
1736 main.log.error( "{0} changed leader from {1} to {2}".\
1737 format( dict1.get( "topic", "no-topic" ),\
1738 dict1.get( "leader", "no-leader" ),\
1739 dict2.get( "leader", "no-leader" ) ) )
1740 if mismatch:
1741 return main.FALSE
1742 else:
1743 return main.TRUE
1744
1745
Jeremy2f190ca2016-01-29 15:23:57 -08001746def report( main ):
1747 """
1748 Report errors/warnings/exceptions
1749 """
1750 main.ONOSbench.logReport( main.ONOSip[ 0 ],
1751 [ "INFO",
1752 "FOLLOWER",
1753 "WARN",
1754 "flow",
1755 "ERROR",
1756 "Except" ],
1757 "s" )
1758
1759 main.log.info( "ERROR report: \n" )
1760 for i in range( main.numCtrls ):
1761 main.ONOSbench.logReport( main.ONOSip[ i ],
1762 [ "ERROR" ],
1763 "d" )
1764
1765 main.log.info( "EXCEPTIONS report: \n" )
1766 for i in range( main.numCtrls ):
1767 main.ONOSbench.logReport( main.ONOSip[ i ],
1768 [ "Except" ],
1769 "d" )
1770
1771 main.log.info( "WARNING report: \n" )
1772 for i in range( main.numCtrls ):
1773 main.ONOSbench.logReport( main.ONOSip[ i ],
1774 [ "WARN" ],
1775 "d" )