blob: 088d38dedabad544735c6c9f837d8e272fceae7f [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="",
Jeremy Songstere7f3b342016-08-17 14:56:49 -070026 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:
Jeremy Songstere7f3b342016-08-17 14:56:49 -070049 onosNode - ONOS node to install the intents in main.RESTs[ ]
Jeremy2f190ca2016-01-29 15:23:57 -080050 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
Jeremy Songstere7f3b342016-08-17 14:56:49 -070083 intent1 = main.RESTs[ 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 )
Jeremy Songstere7f3b342016-08-17 14:56:49 -070089 intentsId = main.RESTs[ 0 ].getIntentsId()
90 except( KeyError, TypeError ):
Jeremydd9bda62016-04-18 12:02:32 -070091 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
Jeremy Songster306ed7a2016-07-19 10:59:07 -070097 if utilities.retry( f=checkIntentState, retValue=main.FALSE,
98 args=( main, intentsId ), sleep=main.checkIntentSleep, attempts=5 ):
99 main.assertReturnString += 'Install Intent State Passed\n'
100 if flowDuration( main ):
101 main.assertReturnString += 'Flow duration check Passed\n'
102 return intentsId
103 else:
104 main.assertReturnString += 'Flow duration check failed\n'
105 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -0800106 else:
107 main.log.error( "Host Intent did not install correctly" )
Jeremy Songster306ed7a2016-07-19 10:59:07 -0700108 main.assertReturnString += 'Install Intent State Failed\n'
Jeremy2f190ca2016-01-29 15:23:57 -0800109 return main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700110
Jeremy2f190ca2016-01-29 15:23:57 -0800111def testHostIntent( main,
112 name,
113 intentId,
114 host1,
115 host2,
116 onosNode=0,
117 sw1="s5",
118 sw2="s2",
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700119 expectedLink=0 ):
Jeremy2f190ca2016-01-29 15:23:57 -0800120 """
121 Test a Host Intent
kelvin-onlab44147802015-07-27 17:57:31 -0700122
Jeremy2f190ca2016-01-29 15:23:57 -0800123 Description:
124 Test a host intent of given ID between given hosts
kelvin-onlab44147802015-07-27 17:57:31 -0700125
Jeremy2f190ca2016-01-29 15:23:57 -0800126 Steps:
127 - Fetch host data if not given
128 - Check Intent State
129 - Check Flow State
130 - Check Connectivity
131 - Check Lack of Connectivity Between Hosts not in the Intent
132 - Reroute
133 - Take Expected Link Down
134 - Check Intent State
135 - Check Flow State
136 - Check Topology
137 - Check Connectivity
138 - Bring Expected Link Up
139 - Check Intent State
140 - Check Flow State
141 - Check Topology
142 - Check Connectivity
143 - Remove Topology
kelvin-onlab44147802015-07-27 17:57:31 -0700144
Jeremy2f190ca2016-01-29 15:23:57 -0800145 Required:
146 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
147 intentId - intent ID to be tested ( and removed )
148 host1 - Dictionary for host1
149 { "name":"h8", "id":"of:0000000000000005/8" }
150 host2 - Dictionary for host2
151 { "name":"h16", "id":"of:0000000000000006/8" }
152 Optional:
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700153 onosNode - ONOS node to install the intents in main.RESTs[ ]
Jeremy2f190ca2016-01-29 15:23:57 -0800154 0 by default so that it will always use the first
155 ONOS node
156 sw1 - First switch to bring down & up for rerouting purpose
157 sw2 - Second switch to bring down & up for rerouting purpose
158 expectedLink - Expected link when the switches are down, it should
159 be two links lower than the links before the two
160 switches are down
kelvin-onlab44147802015-07-27 17:57:31 -0700161
162 """
kelvin-onlab44147802015-07-27 17:57:31 -0700163
Jeremy2f190ca2016-01-29 15:23:57 -0800164 # Parameter Validity Check
kelvin-onlab44147802015-07-27 17:57:31 -0700165 assert main, "There is no main variable"
Jeremy2f190ca2016-01-29 15:23:57 -0800166 assert host1, "You must specify host1"
167 assert host2, "You must specify host2"
kelvin-onlab44147802015-07-27 17:57:31 -0700168
169 global itemName
170 itemName = name
Jeremy2f190ca2016-01-29 15:23:57 -0800171 tempHostsData = {}
kelvin-onlab44147802015-07-27 17:57:31 -0700172 onosNode = int( onosNode )
173
Jeremy2f190ca2016-01-29 15:23:57 -0800174 main.log.info( itemName + ": Testing Host Intent" )
kelvin-onlab44147802015-07-27 17:57:31 -0700175
Jeremydd9bda62016-04-18 12:02:32 -0700176 try:
177 if not host1.get( "id" ):
178 main.log.warn( "Id not given for host1 {0}. Loading from main.hostData".format( host1.get( "name" ) ) )
179 host1[ "id" ] = main.hostsData.get( host1.get( "name" ) ).get( "location" )
kelvin-onlab0e684682015-08-11 18:51:41 -0700180
Jeremydd9bda62016-04-18 12:02:32 -0700181 if not host2.get( "id" ):
182 main.log.warn( "Id not given for host2 {0}. Loading from main.hostData".format( host2.get( "name" ) ) )
183 host2[ "id" ] = main.hostsData.get( host2.get( "name" ) ).get( "location" )
kelvin-onlab44147802015-07-27 17:57:31 -0700184
Jeremydd9bda62016-04-18 12:02:32 -0700185 senderNames = [ host1.get( "name" ), host2.get( "name" ) ]
186 recipientNames = [ host1.get( "name" ), host2.get( "name" ) ]
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700187 vlanId = host1.get( "vlanId" )
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700188 except( KeyError, TypeError ):
Jeremydd9bda62016-04-18 12:02:32 -0700189 main.log.error( "There was a problem loading the hosts data." )
190 return main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700191
Jeremy2f190ca2016-01-29 15:23:57 -0800192 testResult = main.TRUE
193 main.log.info( itemName + ": Adding single point to multi point intents" )
194
195 # Check intent state
196 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
197 main.assertReturnString += 'Initial Intent State Passed\n'
198 else:
199 main.assertReturnString += 'Initial Intent State Failed\n'
200 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700201
202 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800203 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 -0800204 main.assertReturnString += 'Initial Flow State Passed\n'
205 else:
206 main.assertReturnString += 'Intial Flow State Failed\n'
207 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700208
Jeremy2f190ca2016-01-29 15:23:57 -0800209 # Check Connectivity
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700210 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId ) ):
Jeremy2f190ca2016-01-29 15:23:57 -0800211 main.assertReturnString += 'Initial Ping Passed\n'
212 else:
213 main.assertReturnString += 'Initial Ping Failed\n'
214 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700215
216 # Test rerouting if these variables exist
217 if sw1 and sw2 and expectedLink:
Jeremy2f190ca2016-01-29 15:23:57 -0800218 # Take link down
219 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "down" ) ):
220 main.assertReturnString += 'Link Down Passed\n'
221 else:
222 main.assertReturnString += 'Link Down Failed\n'
223 testResult = main.FALSE
224
225 # Check intent state
226 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
227 main.assertReturnString += 'Link Down Intent State Passed\n'
228 else:
229 main.assertReturnString += 'Link Down Intent State Failed\n'
230 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700231
232 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800233 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 -0800234 main.assertReturnString += 'Link Down Flow State Passed\n'
235 else:
236 main.assertReturnString += 'Link Down Flow State Failed\n'
237 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700238
239 # Check OnosTopology
Jeremybc6a0aa2016-02-05 14:10:08 -0800240 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, expectedLink ), sleep=10 ):
Jeremy2f190ca2016-01-29 15:23:57 -0800241 main.assertReturnString += 'Link Down Topology State Passed\n'
kelvin-onlab44147802015-07-27 17:57:31 -0700242 else:
Jeremy2f190ca2016-01-29 15:23:57 -0800243 main.assertReturnString += 'Link Down Topology State Failed\n'
244 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700245
Jeremy2f190ca2016-01-29 15:23:57 -0800246 # Check Connection
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700247 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId ) ):
Jeremy2f190ca2016-01-29 15:23:57 -0800248 main.assertReturnString += 'Link Down Pingall Passed\n'
249 else:
250 main.assertReturnString += 'Link Down Pingall Failed\n'
251 testResult = main.FALSE
252
253 # Bring link up
254 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "up" ) ):
255 main.assertReturnString += 'Link Up Passed\n'
256 else:
257 main.assertReturnString += 'Link Up Failed\n'
258 testResult = main.FALSE
259
260 # Wait for reroute
kelvin-onlab44147802015-07-27 17:57:31 -0700261 time.sleep( main.rerouteSleep )
262
Jeremy2f190ca2016-01-29 15:23:57 -0800263 # Check Intents
264 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
265 main.assertReturnString += 'Link Up Intent State Passed\n'
266 else:
267 main.assertReturnString += 'Link Up Intent State Failed\n'
268 testResult = main.FALSE
269
kelvin-onlab44147802015-07-27 17:57:31 -0700270 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800271 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 -0800272 main.assertReturnString += 'Link Up Flow State Passed\n'
273 else:
274 main.assertReturnString += 'Link Up Flow State Failed\n'
275 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700276
277 # Check OnosTopology
Jeremy2f190ca2016-01-29 15:23:57 -0800278 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, main.numLinks ) ):
279 main.assertReturnString += 'Link Up Topology State Passed\n'
kelvin-onlab44147802015-07-27 17:57:31 -0700280 else:
Jeremy2f190ca2016-01-29 15:23:57 -0800281 main.assertReturnString += 'Link Up Topology State Failed\n'
282 testResult = main.FALSE
283
284 # Check Connection
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700285 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId ) ):
Jeremy2f190ca2016-01-29 15:23:57 -0800286 main.assertReturnString += 'Link Up Pingall Passed\n'
287 else:
288 main.assertReturnString += 'Link Up Pingall Failed\n'
289 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700290
291 # Remove all intents
Jeremy2f190ca2016-01-29 15:23:57 -0800292 if utilities.retry( f=removeAllIntents, retValue=main.FALSE, args=( main, ) ):
293 main.assertReturnString += 'Remove Intents Passed'
294 else:
295 main.assertReturnString += 'Remove Intents Failed'
296 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700297
Jeremy2f190ca2016-01-29 15:23:57 -0800298 return testResult
kelvin-onlab44147802015-07-27 17:57:31 -0700299
Jeremy2f190ca2016-01-29 15:23:57 -0800300def installPointIntent( main,
301 name,
302 senders,
303 recipients,
304 onosNode=0,
305 ethType="",
306 bandwidth="",
307 lambdaAlloc=False,
308 ipProto="",
309 ipSrc="",
310 ipDst="",
311 tcpSrc="",
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700312 tcpDst="" ):
Jeremy2f190ca2016-01-29 15:23:57 -0800313 """
314 Installs a Single to Single Point Intent
315
316 Description:
317 Install a single to single point intent
318
319 Steps:
320 - Fetch host data if not given
321 - Add point intent
322 - Ingress device is the first sender device
323 - Egress device is the first recipient device
324 - Ports if defined in senders or recipients
325 - MAC address ethSrc loaded from Ingress device
326 - Check intent state with retry
327 Required:
328 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
329 senders - List of host dictionaries i.e.
330 [ { "name":"h8", "device":"of:0000000000000005/8","mac":"00:00:00:00:00:08" } ]
331 recipients - List of host dictionaries i.e.
332 [ { "name":"h16", "device":"of:0000000000000006/8", "mac":"00:00:00:00:00:10" } ]
333 Optional:
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700334 onosNode - ONOS node to install the intents in main.RESTs[ ]
Jeremy2f190ca2016-01-29 15:23:57 -0800335 0 by default so that it will always use the first
336 ONOS node
337 ethType - Ethernet type eg. IPV4, IPV6
338 bandwidth - Bandwidth capacity
339 lambdaAlloc - Allocate lambda, defaults to False
340 ipProto - IP protocol
341 tcp - TCP ports in the same order as the hosts in hostNames
342 sw1 - First switch to bring down & up for rerouting purpose
343 sw2 - Second switch to bring down & up for rerouting purpose
344 expectedLink - Expected link when the switches are down, it should
345 be two links lower than the links before the two
346 switches are down
347 """
348
349 assert main, "There is no main variable"
350 assert senders, "You must specify a sender"
351 assert recipients, "You must specify a recipient"
352 # Assert devices or main.hostsData, "You must specify devices"
353
354 global itemName # The name of this run. Used for logs.
355 itemName = name
356 onosNode = int( onosNode )
357
358 main.log.info( itemName + ": Adding single to single point intents" )
359
Jeremydd9bda62016-04-18 12:02:32 -0700360 try:
361 for sender in senders:
362 if not sender.get( "device" ):
363 main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
364 sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )
Jeremy2f190ca2016-01-29 15:23:57 -0800365
Jeremydd9bda62016-04-18 12:02:32 -0700366 for recipient in recipients:
367 if not recipient.get( "device" ):
368 main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
369 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700370 vlanId = senders[ 0 ].get( "vlanId" )
Jeremy2f190ca2016-01-29 15:23:57 -0800371
372
Jeremydd9bda62016-04-18 12:02:32 -0700373 ingressDevice = senders[ 0 ].get( "device" )
374 egressDevice = recipients[ 0 ].get( "device" )
Jeremy2f190ca2016-01-29 15:23:57 -0800375
Jeremydd9bda62016-04-18 12:02:32 -0700376 portIngress = senders[ 0 ].get( "port", "" )
377 portEgress = recipients[ 0 ].get( "port", "" )
378 main.log.debug( ingressDevice )
379 main.log.debug( egressDevice )
Jeremy2f190ca2016-01-29 15:23:57 -0800380
Jeremydd9bda62016-04-18 12:02:32 -0700381 srcMac = senders[ 0 ].get( "mac" )
382 dstMac = recipients[ 0 ].get( "mac" )
Jeremy2f190ca2016-01-29 15:23:57 -0800383
Jeremydd9bda62016-04-18 12:02:32 -0700384 ipSrc = senders[ 0 ].get( "ip" )
385 ipDst = recipients[ 0 ].get( "ip" )
Jeremy2f190ca2016-01-29 15:23:57 -0800386
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700387 intent1 = main.RESTs[ onosNode ].addPointIntent(
Jeremydd9bda62016-04-18 12:02:32 -0700388 ingressDevice=ingressDevice,
389 egressDevice=egressDevice,
390 ingressPort=portIngress,
391 egressPort=portEgress,
392 ethType=ethType,
393 ethSrc=srcMac,
394 ethDst=dstMac,
395 bandwidth=bandwidth,
396 lambdaAlloc=lambdaAlloc,
397 ipProto=ipProto,
398 ipSrc=ipSrc,
399 ipDst=ipDst,
400 tcpSrc=tcpSrc,
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700401 tcpDst=tcpDst,
402 vlanId=vlanId )
Jeremy2f190ca2016-01-29 15:23:57 -0800403
Jeremydd9bda62016-04-18 12:02:32 -0700404 time.sleep( main.addIntentSleep )
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700405 intentsId = main.RESTs[ 0 ].getIntentsId()
406 except( KeyError, TypeError ):
Jeremydd9bda62016-04-18 12:02:32 -0700407 errorMsg = "There was a problem loading the hosts data."
Jeremy Songster306ed7a2016-07-19 10:59:07 -0700408 if intentsId:
Jeremydd9bda62016-04-18 12:02:32 -0700409 errorMsg += " There was a problem installing Point to Point intent."
410 main.log.error( errorMsg )
411 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -0800412
Jeremydd9bda62016-04-18 12:02:32 -0700413 # Check intent state
Jeremy Songster306ed7a2016-07-19 10:59:07 -0700414 if utilities.retry( f=checkIntentState, retValue=main.FALSE,
415 args=( main, intentsId ), sleep=main.checkIntentSleep ):
416 main.assertReturnString += 'Install Intent State Passed\n'
417 if flowDuration( main ):
418 main.assertReturnString += 'Flow duration check Passed\n'
419 return intentsId
420 else:
421 main.assertReturnString += 'Flow duration check failed\n'
422 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -0800423 else:
Jeremy Songster306ed7a2016-07-19 10:59:07 -0700424 main.log.error( "Host Intent did not install correctly" )
425 main.assertReturnString += 'Install Intent State Failed\n'
Jeremy2f190ca2016-01-29 15:23:57 -0800426 return main.FALSE
427
Jeremy2f190ca2016-01-29 15:23:57 -0800428def testPointIntent( main,
429 name,
430 intentId,
431 senders,
432 recipients,
433 badSenders={},
434 badRecipients={},
435 onosNode=0,
436 ethType="",
437 bandwidth="",
438 lambdaAlloc=False,
439 ipProto="",
440 ipAddresses="",
441 tcp="",
442 sw1="s5",
443 sw2="s2",
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700444 expectedLink=0,
445 useTCP=False ):
Jeremy2f190ca2016-01-29 15:23:57 -0800446 """
447 Test a Point Intent
448
449 Description:
450 Test a point intent
451
452 Steps:
453 - Fetch host data if not given
454 - Check Intent State
455 - Check Flow State
456 - Check Connectivity
457 - Check Lack of Connectivity Between Hosts not in the Intent
458 - Reroute
459 - Take Expected Link Down
460 - Check Intent State
461 - Check Flow State
462 - Check Topology
463 - Check Connectivity
464 - Bring Expected Link Up
465 - Check Intent State
466 - Check Flow State
467 - Check Topology
468 - Check Connectivity
469 - Remove Topology
470
471 Required:
472 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
473
474 senders - List of host dictionaries i.e.
475 { "name":"h8", "device":"of:0000000000000005/8","mac":"00:00:00:00:00:08" }
476 recipients - List of host dictionaries i.e.
477 { "name":"h16", "device":"of:0000000000000006/8", "mac":"00:00:00:00:00:10" }
478 Optional:
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700479 onosNode - ONOS node to install the intents in main.RESTs[ ]
Jeremy2f190ca2016-01-29 15:23:57 -0800480 0 by default so that it will always use the first
481 ONOS node
482 ethType - Ethernet type eg. IPV4, IPV6
483 bandwidth - Bandwidth capacity
484 lambdaAlloc - Allocate lambda, defaults to False
485 ipProto - IP protocol
486 tcp - TCP ports in the same order as the hosts in hostNames
487 sw1 - First switch to bring down & up for rerouting purpose
488 sw2 - Second switch to bring down & up for rerouting purpose
489 expectedLink - Expected link when the switches are down, it should
490 be two links lower than the links before the two
491 switches are down
492
493 """
494
495 # Parameter Validity Check
496 assert main, "There is no main variable"
497 assert senders, "You must specify a sender"
498 assert recipients, "You must specify a recipient"
499
500 global itemName
501 itemName = name
502 tempHostsData = {}
503 onosNode = int( onosNode )
504
505 main.log.info( itemName + ": Testing Point Intent" )
506
Jeremydd9bda62016-04-18 12:02:32 -0700507 try:
508 # Names for scapy
509 senderNames = [ x.get( "name" ) for x in senders ]
510 recipientNames = [ x.get( "name" ) for x in recipients ]
511 badSenderNames = [ x.get( "name" ) for x in badSenders ]
512 badRecipientNames = [ x.get( "name" ) for x in badRecipients ]
Jeremy2f190ca2016-01-29 15:23:57 -0800513
Jeremydd9bda62016-04-18 12:02:32 -0700514 for sender in senders:
515 if not sender.get( "device" ):
516 main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
517 sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )
Jeremy2f190ca2016-01-29 15:23:57 -0800518
Jeremydd9bda62016-04-18 12:02:32 -0700519 for recipient in recipients:
520 if not recipient.get( "device" ):
521 main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
522 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700523 vlanId=senders[ 0 ].get( "vlanId" )
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700524 except( KeyError, TypeError ):
Jeremydd9bda62016-04-18 12:02:32 -0700525 main.log.error( "There was a problem loading the hosts data." )
526 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -0800527
528 testResult = main.TRUE
529 main.log.info( itemName + ": Testing point intents" )
530
531 # Check intent state
532 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
533 main.assertReturnString += 'Initial Intent State Passed\n'
534 else:
535 main.assertReturnString += 'Initial Intent State Failed\n'
536 testResult = main.FALSE
537
538 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800539 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 -0800540 main.assertReturnString += 'Initial Flow State Passed\n'
541 else:
542 main.assertReturnString += 'Intial Flow State Failed\n'
543 testResult = main.FALSE
544
545 # Check Connectivity
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700546 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId, useTCP ) ):
Jeremy2f190ca2016-01-29 15:23:57 -0800547 main.assertReturnString += 'Initial Ping Passed\n'
548 else:
549 main.assertReturnString += 'Initial Ping Failed\n'
550 testResult = main.FALSE
551
552 # Check connections that shouldn't work
553 if badSenderNames:
554 main.log.info( "Checking that packets from incorrect sender do not go through" )
555 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, badSenderNames, recipientNames ), kwargs={ "expectFailure":True } ):
556 main.assertReturnString += 'Bad Sender Ping Passed\n'
557 else:
558 main.assertReturnString += 'Bad Sender Ping Failed\n'
559 testResult = main.FALSE
560
561 if badRecipientNames:
562 main.log.info( "Checking that packets to incorrect recipients do not go through" )
563 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, badRecipientNames ), kwargs={ "expectFailure":True } ):
564 main.assertReturnString += 'Bad Recipient Ping Passed\n'
565 else:
566 main.assertReturnString += 'Bad Recipient Ping Failed\n'
567 testResult = main.FALSE
568
569 # Test rerouting if these variables exist
570 if sw1 and sw2 and expectedLink:
571 # Take link down
572 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "down" ) ):
573 main.assertReturnString += 'Link Down Passed\n'
574 else:
575 main.assertReturnString += 'Link Down Failed\n'
576 testResult = main.FALSE
577
578 # Check intent state
579 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
580 main.assertReturnString += 'Link Down Intent State Passed\n'
581 else:
582 main.assertReturnString += 'Link Down Intent State Failed\n'
583 testResult = main.FALSE
584
585 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800586 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 -0800587 main.assertReturnString += 'Link Down Flow State Passed\n'
588 else:
589 main.assertReturnString += 'Link Down Flow State Failed\n'
590 testResult = main.FALSE
591
592 # Check OnosTopology
Jeremybc6a0aa2016-02-05 14:10:08 -0800593 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, expectedLink ), sleep=10 ):
Jeremy2f190ca2016-01-29 15:23:57 -0800594 main.assertReturnString += 'Link Down Topology State Passed\n'
595 else:
596 main.assertReturnString += 'Link Down Topology State Failed\n'
597 testResult = main.FALSE
598
599 # Check Connection
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700600 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId, useTCP ) ):
Jeremy2f190ca2016-01-29 15:23:57 -0800601 main.assertReturnString += 'Link Down Pingall Passed\n'
602 else:
603 main.assertReturnString += 'Link Down Pingall Failed\n'
604 testResult = main.FALSE
605
606 # Bring link up
607 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "up" ) ):
608 main.assertReturnString += 'Link Up Passed\n'
609 else:
610 main.assertReturnString += 'Link Up Failed\n'
611 testResult = main.FALSE
612
613 # Wait for reroute
614 time.sleep( main.rerouteSleep )
615
616 # Check Intents
617 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
618 main.assertReturnString += 'Link Up Intent State Passed\n'
619 else:
620 main.assertReturnString += 'Link Up Intent State Failed\n'
621 testResult = main.FALSE
622
623 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800624 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 -0800625 main.assertReturnString += 'Link Up Flow State Passed\n'
626 else:
627 main.assertReturnString += 'Link Up Flow State Failed\n'
628 testResult = main.FALSE
629
630 # Check OnosTopology
631 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, main.numLinks ) ):
632 main.assertReturnString += 'Link Up Topology State Passed\n'
633 else:
634 main.assertReturnString += 'Link Up Topology State Failed\n'
635 testResult = main.FALSE
636
637 # Check Connection
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700638 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId, useTCP ) ):
Jeremy2f190ca2016-01-29 15:23:57 -0800639 main.assertReturnString += 'Link Up Scapy Packet Received Passed\n'
640 else:
641 main.assertReturnString += 'Link Up Scapy Packet Recieved Failed\n'
642 testResult = main.FALSE
643
644 # Remove all intents
645 if utilities.retry( f=removeAllIntents, retValue=main.FALSE, args=( main, ) ):
646 main.assertReturnString += 'Remove Intents Passed'
647 else:
648 main.assertReturnString += 'Remove Intents Failed'
649 testResult = main.FALSE
650
651 return testResult
kelvin-onlab44147802015-07-27 17:57:31 -0700652
kelvin-onlab0e684682015-08-11 18:51:41 -0700653def pointIntentTcp( main,
654 name,
655 host1,
656 host2,
657 onosNode=0,
658 deviceId1="",
659 deviceId2="",
660 port1="",
661 port2="",
662 ethType="",
663 mac1="",
664 mac2="",
665 bandwidth="",
666 lambdaAlloc=False,
667 ipProto="",
668 ip1="",
669 ip2="",
670 tcp1="",
671 tcp2="",
672 sw1="",
673 sw2="",
674 expectedLink=0 ):
675
676 """
677 Description:
678 Verify add-point-intent only for TCP
679 Steps:
680 - Get device ids | ports
681 - Add point intents
682 - Check intents
683 - Verify flows
684 - Ping hosts
685 - Reroute
686 - Link down
687 - Verify flows
688 - Check topology
689 - Ping hosts
690 - Link up
691 - Verify flows
692 - Check topology
693 - Ping hosts
694 - Remove intents
695 Required:
696 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
697 host1 - Name of first host
698 host2 - Name of second host
699 Optional:
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700700 onosNode - ONOS node to install the intents in main.RESTs[ ]
kelvin-onlab0e684682015-08-11 18:51:41 -0700701 0 by default so that it will always use the first
702 ONOS node
703 deviceId1 - ONOS device id of the first switch, the same as the
704 location of the first host eg. of:0000000000000001/1,
705 located at device 1 port 1
706 deviceId2 - ONOS device id of the second switch
707 port1 - The port number where the first host is attached
708 port2 - The port number where the second host is attached
709 ethType - Ethernet type eg. IPV4, IPV6
710 mac1 - Mac address of first host
711 mac2 - Mac address of the second host
712 bandwidth - Bandwidth capacity
713 lambdaAlloc - Allocate lambda, defaults to False
714 ipProto - IP protocol
715 ip1 - IP address of first host
716 ip2 - IP address of second host
717 tcp1 - TCP port of first host
718 tcp2 - TCP port of second host
719 sw1 - First switch to bring down & up for rerouting purpose
720 sw2 - Second switch to bring down & up for rerouting purpose
721 expectedLink - Expected link when the switches are down, it should
722 be two links lower than the links before the two
723 switches are down
724 """
725
726 assert main, "There is no main variable"
727 assert name, "variable name is empty"
728 assert host1 and host2, "You must specify hosts"
729
730 global itemName
731 itemName = name
732 host1 = host1
733 host2 = host2
734 hostNames = [ host1, host2 ]
735 intentsId = []
736
737 iperfResult = main.TRUE
738 intentResult = main.TRUE
739 removeIntentResult = main.TRUE
740 flowResult = main.TRUE
741 topoResult = main.TRUE
742 linkDownResult = main.TRUE
743 linkUpResult = main.TRUE
744 onosNode = int( onosNode )
745
746 # Adding bidirectional point intents
747 main.log.info( itemName + ": Adding point intents" )
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700748 intent1 = main.RESTs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
kelvin-onlab0e684682015-08-11 18:51:41 -0700749 egressDevice=deviceId2,
750 ingressPort=port1,
751 egressPort=port2,
752 ethType=ethType,
753 ethSrc=mac1,
754 ethDst=mac2,
755 bandwidth=bandwidth,
756 lambdaAlloc=lambdaAlloc,
757 ipProto=ipProto,
758 ipSrc=ip1,
759 ipDst=ip2,
760 tcpSrc=tcp1,
761 tcpDst="" )
762
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700763 intent2 = main.RESTs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
kelvin-onlab0e684682015-08-11 18:51:41 -0700764 egressDevice=deviceId1,
765 ingressPort=port2,
766 egressPort=port1,
767 ethType=ethType,
768 ethSrc=mac2,
769 ethDst=mac1,
770 bandwidth=bandwidth,
771 lambdaAlloc=lambdaAlloc,
772 ipProto=ipProto,
773 ipSrc=ip2,
774 ipDst=ip1,
775 tcpSrc=tcp2,
776 tcpDst="" )
777
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700778 intent3 = main.RESTs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
kelvin-onlab0e684682015-08-11 18:51:41 -0700779 egressDevice=deviceId2,
780 ingressPort=port1,
781 egressPort=port2,
782 ethType=ethType,
783 ethSrc=mac1,
784 ethDst=mac2,
785 bandwidth=bandwidth,
786 lambdaAlloc=lambdaAlloc,
787 ipProto=ipProto,
788 ipSrc=ip1,
789 ipDst=ip2,
790 tcpSrc="",
791 tcpDst=tcp2 )
792
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700793 intent4 = main.RESTs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
kelvin-onlab0e684682015-08-11 18:51:41 -0700794 egressDevice=deviceId1,
795 ingressPort=port2,
796 egressPort=port1,
797 ethType=ethType,
798 ethSrc=mac2,
799 ethDst=mac1,
800 bandwidth=bandwidth,
801 lambdaAlloc=lambdaAlloc,
802 ipProto=ipProto,
803 ipSrc=ip2,
804 ipDst=ip1,
805 tcpSrc="",
806 tcpDst=tcp1 )
807
808 # Get all intents ID in the system, time delay right after intents are added
809 time.sleep( main.addIntentSleep )
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700810 intentsId = main.RESTs[ 0 ].getIntentsId()
kelvin-onlab0e684682015-08-11 18:51:41 -0700811 # Check intents state
812 time.sleep( main.checkIntentSleep )
813 intentResult = checkIntentState( main, intentsId )
814 # Check flows count in each node
815 checkFlowsCount( main )
816
817 # Check intents state again if first check fails...
818 if not intentResult:
819 intentResult = checkIntentState( main, intentsId )
820
821 # Check flows count in each node
822 checkFlowsCount( main )
823
824 # Verify flows
825 checkFlowsState( main )
826
827 # Run iperf to both host
828 iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
829 host2, 10 )
830
831 # Test rerouting if these variables exist
832 if sw1 and sw2 and expectedLink:
833 # link down
834 linkDownResult = link( main, sw1, sw2, "down" )
835 intentResult = intentResult and checkIntentState( main, intentsId )
836
837 # Check flows count in each node
838 checkFlowsCount( main )
839 # Verify flows
840 checkFlowsState( main )
841
842 # Check OnosTopology
843 topoResult = checkTopology( main, expectedLink )
844
845 # Run iperf to both host
846 iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
847 host2, 10 )
848
849 intentResult = checkIntentState( main, intentsId )
850
851 # Checks ONOS state in link down
852 if linkDownResult and topoResult and iperfResult and intentResult:
853 main.log.info( itemName + ": Successfully brought link down" )
854 else:
855 main.log.error( itemName + ": Failed to bring link down" )
856
857 # link up
858 linkUpResult = link( main, sw1, sw2, "up" )
859 time.sleep( main.rerouteSleep )
860
861 # Check flows count in each node
862 checkFlowsCount( main )
863 # Verify flows
864 checkFlowsState( main )
865
866 # Check OnosTopology
867 topoResult = checkTopology( main, main.numLinks )
868
869 # Run iperf to both host
870 iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
871 host2, 10 )
872
873 intentResult = checkIntentState( main, intentsId )
874
875 # Checks ONOS state in link up
876 if linkUpResult and topoResult and iperfResult and intentResult:
877 main.log.info( itemName + ": Successfully brought link back up" )
878 else:
879 main.log.error( itemName + ": Failed to bring link back up" )
880
881 # Remove all intents
882 removeIntentResult = removeAllIntents( main )
883
884 stepResult = iperfResult and linkDownResult and linkUpResult \
885 and intentResult and removeIntentResult
886
887 return stepResult
888
Ming Yan Shuab2f7f52016-08-03 15:21:24 -0700889
890def installSingleToMultiIntent( main,
891 name,
892 senders,
893 recipients,
894 onosNode=0,
895 ethType="",
896 bandwidth="",
897 lambdaAlloc=False,
898 ipProto="",
899 ipAddresses="",
900 tcp="",
901 sw1="",
902 sw2="",
903 partial=False ):
kelvin-onlab44147802015-07-27 17:57:31 -0700904 """
905 Verify Single to Multi Point intents
906 NOTE:If main.hostsData is not defined, variables data should be passed
907 in the same order index wise. All devices in the list should have the
908 same format, either all the devices have its port or it doesn't.
909 eg. hostName = [ 'h1', 'h2' ,.. ]
910 devices = [ 'of:0000000000000001', 'of:0000000000000002', ...]
911 ports = [ '1', '1', ..]
912 ...
913 Description:
914 Verify add-single-to-multi-intent iterates through the list of given
915 host | devices and add intents
916 Steps:
917 - Get device ids | ports
918 - Add single to multi point intents
919 - Check intents
920 - Verify flows
921 - Ping hosts
922 - Reroute
923 - Link down
924 - Verify flows
925 - Check topology
926 - Ping hosts
927 - Link up
928 - Verify flows
929 - Check topology
930 - Ping hosts
931 - Remove intents
932 Required:
933 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
934 hostNames - List of host names
935 Optional:
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700936 onosNode - ONOS node to install the intents in main.RESTs[ ]
kelvin-onlab44147802015-07-27 17:57:31 -0700937 0 by default so that it will always use the first
938 ONOS node
939 devices - List of device ids in the same order as the hosts
940 in hostNames
941 ports - List of port numbers in the same order as the device in
942 devices
943 ethType - Ethernet type eg. IPV4, IPV6
944 macs - List of hosts mac address in the same order as the hosts in
945 hostNames
946 bandwidth - Bandwidth capacity
947 lambdaAlloc - Allocate lambda, defaults to False
948 ipProto - IP protocol
949 ipAddresses - IP addresses of host in the same order as the hosts in
950 hostNames
951 tcp - TCP ports in the same order as the hosts in hostNames
952 sw1 - First switch to bring down & up for rerouting purpose
953 sw2 - Second switch to bring down & up for rerouting purpose
954 expectedLink - Expected link when the switches are down, it should
955 be two links lower than the links before the two
956 switches are down
957 """
958
959 assert main, "There is no main variable"
Ming Yan Shuab2f7f52016-08-03 15:21:24 -0700960 assert senders, "You must specify a sender"
961 assert recipients, "You must specify a recipient"
962 # Assert devices or main.hostsData, "You must specify devices"
kelvin-onlab44147802015-07-27 17:57:31 -0700963
Ming Yan Shuab2f7f52016-08-03 15:21:24 -0700964 global itemName # The name of this run. Used for logs.
kelvin-onlab44147802015-07-27 17:57:31 -0700965 itemName = name
kelvin-onlab44147802015-07-27 17:57:31 -0700966 onosNode = int( onosNode )
967
kelvin-onlab44147802015-07-27 17:57:31 -0700968 main.log.info( itemName + ": Adding single point to multi point intents" )
969
Ming Yan Shuab2f7f52016-08-03 15:21:24 -0700970 try:
971 for sender in senders:
972 if not sender.get( "device" ):
973 main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
974 sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )
kelvin-onlab44147802015-07-27 17:57:31 -0700975
Ming Yan Shuab2f7f52016-08-03 15:21:24 -0700976 for recipient in recipients:
977 if not recipient.get( "device" ):
978 main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
979 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
980 vlanId = senders[ 0 ].get( "vlanId" )
kelvin-onlab44147802015-07-27 17:57:31 -0700981
Ming Yan Shuab2f7f52016-08-03 15:21:24 -0700982 ingressDevice = senders[ 0 ].get( "device" )
983 egressDeviceList = [ x.get( "device" ) for x in recipients if x.get( "device" ) ]
984
985 portIngress = senders[ 0 ].get( "port", "" )
986 portEgressList = [ x.get( "port" ) for x in recipients if x.get( "port" ) ]
987 if not portEgressList:
988 portEgressList = []
989
990 main.log.debug( ingressDevice )
991 main.log.debug( egressDeviceList )
992
993 srcMac = senders[ 0 ].get( "mac" )
994 dstMac = []
995 for r in recipients:
996 mac = r.get( "mac" )
997 dstMac.append( mac )
998
999 ipSrc = senders[ 0 ].get( "ip" )
1000 ipDst = []
1001 for r in recipients:
1002 ip = r.get( "ip" )
1003 ipDst.append( ip )
1004
1005 # Adding point intent
1006 intentId = main.RESTs[ onosNode ].addSinglepointToMultipointIntent(
kelvin-onlab44147802015-07-27 17:57:31 -07001007 ingressDevice=ingressDevice,
1008 egressDeviceList=egressDeviceList,
1009 portIngress=portIngress,
1010 portEgressList=portEgressList,
1011 ethType=ethType,
1012 ethSrc=srcMac,
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001013 #ethDst=dstMac, #Isn't working because of ONOS itself
kelvin-onlab44147802015-07-27 17:57:31 -07001014 bandwidth=bandwidth,
1015 lambdaAlloc=lambdaAlloc,
1016 ipProto=ipProto,
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001017 ipSrc=ipSrc,
1018 ipDst=ipDst,
kelvin-onlab44147802015-07-27 17:57:31 -07001019 tcpSrc="",
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001020 tcpDst="",
1021 vlanId=vlanId,
1022 partial=partial )
kelvin-onlab44147802015-07-27 17:57:31 -07001023
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001024 time.sleep( main.addIntentSleep )
1025 intentsId = main.RESTs[ 0 ].getIntentsId()
1026 except ( KeyError, TypeError ):
1027 errorMsg = "There was a problem loading the hosts data."
1028 if intentId:
1029 errorMsg += " There was a problem installing Singlepoint to Multipoint intent."
1030 main.log.error( errorMsg )
1031 return main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -07001032
1033 # Check intents state
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001034 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentsId ), sleep=main.checkIntentSleep ):
1035 return intentsId
1036 else:
1037 main.log.error( "Single to Multi Intent did not install correctly" )
1038 return main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -07001039
1040def multiToSingleIntent( main,
1041 name,
1042 hostNames,
1043 onosNode=0,
1044 devices="",
1045 ports=None,
1046 ethType="",
1047 macs=None,
1048 bandwidth="",
1049 lambdaAlloc=False,
1050 ipProto="",
1051 ipAddresses="",
1052 tcp="",
1053 sw1="",
1054 sw2="",
1055 expectedLink=0 ):
1056 """
1057 Verify Single to Multi Point intents
1058 NOTE:If main.hostsData is not defined, variables data should be passed in the
1059 same order index wise. All devices in the list should have the same
1060 format, either all the devices have its port or it doesn't.
1061 eg. hostName = [ 'h1', 'h2' ,.. ]
1062 devices = [ 'of:0000000000000001', 'of:0000000000000002', ...]
1063 ports = [ '1', '1', ..]
1064 ...
1065 Description:
1066 Verify add-multi-to-single-intent
1067 Steps:
1068 - Get device ids | ports
1069 - Add multi to single point intents
1070 - Check intents
1071 - Verify flows
1072 - Ping hosts
1073 - Reroute
1074 - Link down
1075 - Verify flows
1076 - Check topology
1077 - Ping hosts
1078 - Link up
1079 - Verify flows
1080 - Check topology
1081 - Ping hosts
1082 - Remove intents
1083 Required:
1084 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
1085 hostNames - List of host names
1086 Optional:
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001087 onosNode - ONOS node to install the intents in main.RESTs[ ]
kelvin-onlab44147802015-07-27 17:57:31 -07001088 0 by default so that it will always use the first
1089 ONOS node
1090 devices - List of device ids in the same order as the hosts
1091 in hostNames
1092 ports - List of port numbers in the same order as the device in
1093 devices
1094 ethType - Ethernet type eg. IPV4, IPV6
1095 macs - List of hosts mac address in the same order as the hosts in
1096 hostNames
1097 bandwidth - Bandwidth capacity
1098 lambdaAlloc - Allocate lambda, defaults to False
1099 ipProto - IP protocol
1100 ipAddresses - IP addresses of host in the same order as the hosts in
1101 hostNames
1102 tcp - TCP ports in the same order as the hosts in hostNames
1103 sw1 - First switch to bring down & up for rerouting purpose
1104 sw2 - Second switch to bring down & up for rerouting purpose
1105 expectedLink - Expected link when the switches are down, it should
1106 be two links lower than the links before the two
1107 switches are down
1108 """
1109
1110 assert main, "There is no main variable"
1111 assert hostNames, "You must specify hosts"
1112 assert devices or main.hostsData, "You must specify devices"
1113
1114 global itemName
1115 itemName = name
1116 tempHostsData = {}
1117 intentsId = []
1118 onosNode = int( onosNode )
1119
1120 macsDict = {}
1121 ipDict = {}
1122 if hostNames and devices:
1123 if len( hostNames ) != len( devices ):
1124 main.log.debug( "hosts and devices does not have the same length" )
1125 #print "len hostNames = ", len( hostNames )
1126 #print "len devices = ", len( devices )
1127 return main.FALSE
1128 if ports:
1129 if len( ports ) != len( devices ):
1130 main.log.error( "Ports and devices does " +
1131 "not have the same length" )
1132 #print "len devices = ", len( devices )
1133 #print "len ports = ", len( ports )
1134 return main.FALSE
1135 else:
1136 main.log.info( "Device Ports are not specified" )
1137 if macs:
1138 for i in range( len( devices ) ):
1139 macsDict[ devices[ i ] ] = macs[ i ]
1140 elif hostNames and not devices and main.hostsData:
1141 devices = []
1142 main.log.info( "multiToSingleIntent function is using main.hostsData" )
1143 for host in hostNames:
1144 devices.append( main.hostsData.get( host ).get( 'location' ) )
1145 macsDict[ main.hostsData.get( host ).get( 'location' ) ] = \
1146 main.hostsData.get( host ).get( 'mac' )
1147 ipDict[ main.hostsData.get( host ).get( 'location' ) ] = \
1148 main.hostsData.get( host ).get( 'ipAddresses' )
1149 #print main.hostsData
1150
1151 #print 'host names = ', hostNames
1152 #print 'devices = ', devices
1153 #print "macsDict = ", macsDict
1154
1155 pingResult = main.TRUE
1156 intentResult = main.TRUE
1157 removeIntentResult = main.TRUE
1158 flowResult = main.TRUE
1159 topoResult = main.TRUE
1160 linkDownResult = main.TRUE
1161 linkUpResult = main.TRUE
1162
1163 devicesCopy = copy.copy( devices )
1164 if ports:
1165 portsCopy = copy.copy( ports )
1166 main.log.info( itemName + ": Adding multi point to single point intents" )
1167
1168 # Check flows count in each node
1169 checkFlowsCount( main )
1170
1171 # Adding bidirectional point intents
1172 for i in range( len( devices ) ):
1173 egressDevice = devicesCopy[ i ]
1174 ingressDeviceList = copy.copy( devicesCopy )
1175 ingressDeviceList.remove( egressDevice )
1176 if ports:
1177 portEgress = portsCopy[ i ]
1178 portIngressList = copy.copy( portsCopy )
1179 del portIngressList[ i ]
1180 else:
1181 portEgress = ""
1182 portIngressList = None
1183 if not macsDict:
1184 dstMac = ""
1185 else:
1186 dstMac = macsDict[ egressDevice ]
1187 if dstMac == None:
1188 main.log.debug( "There is no MAC in device - " + egressDevice )
1189 dstMac = ""
1190
1191 intentsId.append(
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001192 main.RESTs[ onosNode ].addMultipointToSinglepointIntent(
kelvin-onlab44147802015-07-27 17:57:31 -07001193 ingressDeviceList=ingressDeviceList,
1194 egressDevice=egressDevice,
1195 portIngressList=portIngressList,
1196 portEgress=portEgress,
1197 ethType=ethType,
1198 ethDst=dstMac,
1199 bandwidth=bandwidth,
1200 lambdaAlloc=lambdaAlloc,
1201 ipProto=ipProto,
1202 ipSrc="",
1203 ipDst="",
1204 tcpSrc="",
1205 tcpDst="" ) )
1206
1207 pingResult = pingallHosts( main, hostNames )
1208
1209 # Check intents state
1210 time.sleep( main.checkIntentSleep )
1211 intentResult = checkIntentState( main, intentsId )
1212
1213 # Check intents state again if first check fails...
1214 if not intentResult:
1215 intentResult = checkIntentState( main, intentsId )
1216
1217 # Check flows count in each node
1218 checkFlowsCount( main )
1219 # Verify flows
1220 checkFlowsState( main )
1221
1222 # Ping hosts
1223 pingResult = pingResult and pingallHosts( main, hostNames )
1224 # Ping hosts again...
1225 pingResult = pingResult and pingallHosts( main, hostNames )
1226
1227 # Test rerouting if these variables exist
1228 if sw1 and sw2 and expectedLink:
1229 # link down
1230 linkDownResult = link( main, sw1, sw2, "down" )
1231 intentResult = intentResult and checkIntentState( main, intentsId )
1232
1233 # Check flows count in each node
1234 checkFlowsCount( main )
1235 # Verify flows
1236 checkFlowsState( main )
1237
1238 # Check OnosTopology
1239 topoResult = checkTopology( main, expectedLink )
1240
1241 # Ping hosts
1242 pingResult = pingResult and pingallHosts( main, hostNames )
1243
1244 intentResult = checkIntentState( main, intentsId )
1245
1246 # Checks ONOS state in link down
1247 if linkDownResult and topoResult and pingResult and intentResult:
1248 main.log.info( itemName + ": Successfully brought link down" )
1249 else:
1250 main.log.error( itemName + ": Failed to bring link down" )
1251
1252 # link up
1253 linkUpResult = link( main, sw1, sw2, "up" )
1254 time.sleep( main.rerouteSleep )
1255
1256 # Check flows count in each node
1257 checkFlowsCount( main )
1258 # Verify flows
1259 checkFlowsState( main )
1260
1261 # Check OnosTopology
1262 topoResult = checkTopology( main, main.numLinks )
1263
1264 # Ping hosts
1265 pingResult = pingResult and pingallHosts( main, hostNames )
1266
1267 intentResult = checkIntentState( main, intentsId )
1268
1269 # Checks ONOS state in link up
1270 if linkUpResult and topoResult and pingResult and intentResult:
1271 main.log.info( itemName + ": Successfully brought link back up" )
1272 else:
1273 main.log.error( itemName + ": Failed to bring link back up" )
1274
1275 # Remove all intents
1276 removeIntentResult = removeAllIntents( main, intentsId )
1277
1278 stepResult = pingResult and linkDownResult and linkUpResult \
1279 and intentResult and removeIntentResult
1280
1281 return stepResult
1282
kelvin-onlab0e684682015-08-11 18:51:41 -07001283def pingallHosts( main, hostList ):
kelvin-onlab44147802015-07-27 17:57:31 -07001284 # Ping all host in the hosts list variable
1285 print "Pinging : ", hostList
1286 pingResult = main.TRUE
kelvin-onlab0e684682015-08-11 18:51:41 -07001287 pingResult = main.Mininet1.pingallHosts( hostList )
kelvin-onlab44147802015-07-27 17:57:31 -07001288 return pingResult
1289
kelvin-onlab0e684682015-08-11 18:51:41 -07001290def getHostsData( main, hostList ):
kelvin-onlab44147802015-07-27 17:57:31 -07001291 """
1292 Use fwd app and pingall to discover all the hosts
1293 """
1294
1295 activateResult = main.TRUE
1296 appCheck = main.TRUE
1297 getDataResult = main.TRUE
1298 main.log.info( "Activating reactive forwarding app " )
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001299 activateResult = main.RESTs[ 0 ].activateApp( "org.onosproject.fwd" )
kelvin-onlab44147802015-07-27 17:57:31 -07001300 if not activateResult:
1301 main.log.error( "Something went wrong installing fwd app" )
1302 time.sleep( main.fwdSleep )
kelvin-onlab0e684682015-08-11 18:51:41 -07001303 if isinstance( hostList[ 0 ], types.StringType ):
1304 main.Mininet1.pingallHosts( hostList )
1305 elif isinstance( hostList[ 0 ], types.ListType ):
1306 for i in xrange( len( hostList ) ):
1307 main.Mininet1.pingallHosts( hostList[ i ] )
1308
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001309 hostsJson = json.loads( main.RESTs[ 0 ].hosts() )
kelvin-onlab44147802015-07-27 17:57:31 -07001310 hosts = main.Mininet1.getHosts().keys()
1311 # TODO: Make better use of new getHosts function
1312 for host in hosts:
1313 main.hostsData[ host ] = {}
1314 main.hostsData[ host ][ 'mac' ] = \
1315 main.Mininet1.getMacAddress( host ).upper()
1316 for hostj in hostsJson:
1317 if main.hostsData[ host ][ 'mac' ] == hostj[ 'mac' ]:
1318 main.hostsData[ host ][ 'id' ] = hostj[ 'id' ]
1319 main.hostsData[ host ][ 'vlan' ] = hostj[ 'vlan' ]
1320 main.hostsData[ host ][ 'location' ] = \
1321 hostj[ 'location' ][ 'elementId' ] + '/' + \
1322 hostj[ 'location' ][ 'port' ]
1323 main.hostsData[ host ][ 'ipAddresses' ] = hostj[ 'ipAddresses' ]
1324
1325 main.log.info( "Deactivating reactive forwarding app " )
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001326 deactivateResult = main.RESTs[ 0 ].deactivateApp( "org.onosproject.fwd" )
kelvin-onlab44147802015-07-27 17:57:31 -07001327 if activateResult and deactivateResult and main.hostsData:
1328 main.log.info( "Successfully used fwd app to discover hosts " )
1329 getDataResult = main.TRUE
1330 else:
1331 main.log.info( "Failed to use fwd app to discover hosts " )
1332 getDataResult = main.FALSE
1333
1334 print main.hostsData
1335
1336 return getDataResult
1337
1338def checkTopology( main, expectedLink ):
1339 statusResult = main.TRUE
1340 # Check onos topology
1341 main.log.info( itemName + ": Checking ONOS topology " )
1342
1343 for i in range( main.numCtrls ):
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001344 statusResult = main.RESTs[ i ].checkStatus( main.numSwitch,
kelvin-onlab44147802015-07-27 17:57:31 -07001345 expectedLink )\
1346 and statusResult
1347 if not statusResult:
1348 main.log.error( itemName + ": Topology mismatch" )
1349 else:
1350 main.log.info( itemName + ": Topology match" )
1351 return statusResult
1352
1353def checkIntentState( main, intentsId ):
1354 """
1355 This function will check intent state to make sure all the intents
1356 are in INSTALLED state
1357 """
1358
1359 intentResult = main.TRUE
1360 results = []
1361
1362 main.log.info( itemName + ": Checking intents state" )
1363 # First check of intents
1364 for i in range( main.numCtrls ):
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001365 tempResult = main.RESTs[ i ].checkIntentState( intentsId=intentsId )
kelvin-onlab44147802015-07-27 17:57:31 -07001366 results.append( tempResult )
1367
1368 expectedState = [ 'INSTALLED', 'INSTALLING' ]
1369
1370 if all( result == main.TRUE for result in results ):
1371 main.log.info( itemName + ": Intents are installed correctly" )
1372 else:
1373 # Wait for at least 5 second before checking the intents again
Jeremy2f190ca2016-01-29 15:23:57 -08001374 main.log.error( "Intents are not installed correctly. Waiting 5 sec" )
kelvin-onlab44147802015-07-27 17:57:31 -07001375 time.sleep( 5 )
1376 results = []
1377 # Second check of intents since some of the intents may be in
1378 # INSTALLING state, they should be in INSTALLED at this time
1379 for i in range( main.numCtrls ):
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001380 tempResult = main.RESTs[ i ].checkIntentState( intentsId=intentsId )
kelvin-onlab44147802015-07-27 17:57:31 -07001381 results.append( tempResult )
1382 if all( result == main.TRUE for result in results ):
1383 main.log.info( itemName + ": Intents are installed correctly" )
Jeremy2f190ca2016-01-29 15:23:57 -08001384 intentResult = main.TRUE
kelvin-onlab44147802015-07-27 17:57:31 -07001385 else:
1386 main.log.error( itemName + ": Intents are NOT installed correctly" )
1387 intentResult = main.FALSE
1388
1389 return intentResult
1390
1391def checkFlowsState( main ):
1392
1393 main.log.info( itemName + ": Check flows state" )
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001394 checkFlowsResult = main.RESTs[ 0 ].checkFlowsState()
kelvin-onlab44147802015-07-27 17:57:31 -07001395 return checkFlowsResult
1396
1397def link( main, sw1, sw2, option):
1398
1399 # link down
1400 main.log.info( itemName + ": Bring link " + option + "between " +
1401 sw1 + " and " + sw2 )
1402 linkResult = main.Mininet1.link( end1=sw1, end2=sw2, option=option )
1403 return linkResult
1404
1405def removeAllIntents( main ):
1406 """
1407 Remove all intents in the intentsId
1408 """
1409
1410 onosSummary = []
1411 removeIntentResult = main.TRUE
1412 # Remove intents
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001413 removeIntentResult = main.RESTs[ 0 ].removeAllIntents( )
kelvin-onlab44147802015-07-27 17:57:31 -07001414
1415 if removeIntentResult:
1416 main.log.info( itemName + ": There are no more intents remaining, " +
1417 "successfully removed all the intents." )
1418
1419 return removeIntentResult
1420
1421def checkFlowsCount( main ):
1422 """
1423 Check flows count in each node
1424 """
1425
1426 flowsCount = []
1427 main.log.info( itemName + ": Checking flows count in each ONOS node" )
1428 for i in range( main.numCtrls ):
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001429 flowsCount.append( len( json.loads( main.RESTs[ i ].flows() ) ) )
kelvin-onlab44147802015-07-27 17:57:31 -07001430
1431 if flowsCount:
1432 if all( flows==flowsCount[ 0 ] for flows in flowsCount ):
1433 main.log.info( itemName + ": There are " + str( flowsCount[ 0 ] ) +
1434 " flows in all ONOS node" )
1435 else:
1436 for i in range( main.numCtrls ):
1437 main.log.debug( itemName + ": ONOS node " + str( i + 1 ) +
Jeremy2f190ca2016-01-29 15:23:57 -08001438 " has " + str( flowsCount[ i ] ) + " flows" )
kelvin-onlab44147802015-07-27 17:57:31 -07001439 else:
1440 main.log.error( "Checking flows count failed, check summary command" )
1441 return main.FALSE
1442
1443 return main.TRUE
1444
Jeremy2f190ca2016-01-29 15:23:57 -08001445def sendDiscoveryArp( main, hosts=None ):
1446 """
1447 Sends Discovery ARP packets from each host provided
1448 Defaults to each host in main.scapyHosts
1449 """
1450 # Send an arp ping from each host
1451 if not hosts:
1452 hosts = main.scapyHosts
1453 for host in hosts:
1454 pkt = 'Ether( src="{0}")/ARP( psrc="{1}")'.format( host.hostMac ,host.hostIp )
1455 # Send from the VLAN interface if there is one so ONOS discovers the VLAN correctly
1456 iface = None
1457 for interface in host.getIfList():
1458 if '.' in interface:
1459 main.log.debug( "Detected VLAN interface {0}. Sending ARP packet from {0}".format( interface ) )
1460 iface = interface
1461 break
1462 host.sendPacket( packet=pkt, iface=iface )
1463 main.log.info( "Sending ARP packet from {0}".format( host.name ) )
1464
1465def confirmHostDiscovery( main ):
1466 """
1467 Confirms that all ONOS nodes have discovered all scapy hosts
1468 """
1469 import collections
1470 scapyHostCount = len( main.scapyHosts )
1471 hosts = main.topo.getAllHosts( main ) # Get host data from each ONOS node
1472 hostFails = [] # Reset for each failed attempt
1473
1474 # Check for matching hosts on each node
1475 scapyHostIPs = [ x.hostIp for x in main.scapyHosts if x.hostIp != "0.0.0.0" ]
1476 for controller in range( main.numCtrls ):
1477 controllerStr = str( controller + 1 ) # ONOS node number
1478 # Compare Hosts
1479 # Load hosts data for controller node
Jeremydd9bda62016-04-18 12:02:32 -07001480 try:
1481 if hosts[ controller ]:
1482 main.log.info( "Hosts discovered" )
Jeremy2f190ca2016-01-29 15:23:57 -08001483 else:
Jeremydd9bda62016-04-18 12:02:32 -07001484 main.log.error( "Problem discovering hosts" )
1485 if hosts[ controller ] and "Error" not in hosts[ controller ]:
1486 try:
1487 hostData = json.loads( hosts[ controller ] )
1488 except ( TypeError, ValueError ):
1489 main.log.error( "Could not load json:" + str( hosts[ controller ] ) )
Jeremy2f190ca2016-01-29 15:23:57 -08001490 hostFails.append( controllerStr )
Jeremydd9bda62016-04-18 12:02:32 -07001491 else:
1492 onosHostIPs = [ x.get( "ipAddresses" )[ 0 ]
1493 for x in hostData
1494 if len( x.get( "ipAddresses" ) ) > 0 ]
1495 if not set( collections.Counter( scapyHostIPs ) ).issubset( set ( collections.Counter( onosHostIPs ) ) ):
1496 main.log.warn( "Controller {0} only sees nodes with {1} IPs. It should see all of the following: {2}".format( controllerStr, onosHostIPs, scapyHostIPs ) )
1497 hostFails.append( controllerStr )
1498 else:
1499 main.log.error( "Hosts returned nothing or an error." )
1500 hostFails.append( controllerStr )
1501 except IndexError:
1502 main.log.error( "Hosts returned nothing, Failed to discover hosts." )
1503 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -08001504
1505 if hostFails:
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001506 main.log.error( "List of failed ONOS Nodes:" + ', '.join( map( str, hostFails ) ) )
Jeremy2f190ca2016-01-29 15:23:57 -08001507 return main.FALSE
1508 else:
1509 return main.TRUE
1510
1511def populateHostData( main ):
1512 """
1513 Populates hostsData
1514 """
1515 import json
1516 try:
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001517 hostsJson = json.loads( main.RESTs[ 0 ].hosts() )
Jeremy2f190ca2016-01-29 15:23:57 -08001518 hosts = main.Mininet1.getHosts().keys()
1519 # TODO: Make better use of new getHosts function
1520 for host in hosts:
1521 main.hostsData[ host ] = {}
1522 main.hostsData[ host ][ 'mac' ] = \
1523 main.Mininet1.getMacAddress( host ).upper()
1524 for hostj in hostsJson:
1525 if main.hostsData[ host ][ 'mac' ] == hostj[ 'mac' ]:
1526 main.hostsData[ host ][ 'id' ] = hostj[ 'id' ]
1527 main.hostsData[ host ][ 'vlan' ] = hostj[ 'vlan' ]
1528 main.hostsData[ host ][ 'location' ] = \
1529 hostj[ 'location' ][ 'elementId' ] + '/' + \
1530 hostj[ 'location' ][ 'port' ]
1531 main.hostsData[ host ][ 'ipAddresses' ] = hostj[ 'ipAddresses' ]
1532 return main.TRUE
Jeremydd9bda62016-04-18 12:02:32 -07001533 except ValueError:
1534 main.log.error( "ValueError while populating hostsData" )
1535 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -08001536 except KeyError:
1537 main.log.error( "KeyError while populating hostsData")
1538 return main.FALSE
Jeremydd9bda62016-04-18 12:02:32 -07001539 except IndexError:
1540 main.log.error( "IndexError while populating hostsData" )
1541 return main.FALSE
1542 except TypeError:
1543 main.log.error( "TypeError while populating hostsData" )
1544 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -08001545
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001546def scapyCheckConnection( main, senders, recipients, vlanId=None, useTCP=False, packet=None, packetFilter=None, expectFailure=False ):
Jeremy2f190ca2016-01-29 15:23:57 -08001547 """
1548 Checks the connectivity between all given sender hosts and all given recipient hosts
1549 Packet may be specified. Defaults to Ether/IP packet
1550 Packet Filter may be specified. Defaults to Ether/IP from current sender MAC
1551 Todo: Optional packet and packet filter attributes for sender and recipients
1552 Expect Failure when the sender and recipient are not supposed to have connectivity
1553 Timeout of 1 second, returns main.TRUE if the filter is not triggered and kills the filter
1554
1555 """
1556 connectionsFunctional = main.TRUE
1557
1558 if not packetFilter:
1559 packetFilter = 'ether host {}'
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001560 if useTCP:
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001561 packetFilter += ' ip proto \\tcp tcp port {}'.format( main.params[ 'SDNIP' ][ 'dstPort' ] )
Jeremy2f190ca2016-01-29 15:23:57 -08001562 if expectFailure:
1563 timeout = 1
1564 else:
1565 timeout = 10
1566
1567 for sender in senders:
1568 try:
1569 senderComp = getattr( main, sender )
1570 except AttributeError:
1571 main.log.error( "main has no attribute {}".format( sender ) )
1572 connectionsFunctional = main.FALSE
1573 continue
1574
1575 for recipient in recipients:
1576 # Do not send packets to self since recipient CLI will already be busy
1577 if recipient == sender:
1578 continue
1579 try:
1580 recipientComp = getattr( main, recipient )
1581 except AttributeError:
1582 main.log.error( "main has no attribute {}".format( recipient ) )
1583 connectionsFunctional = main.FALSE
1584 continue
1585
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001586 if vlanId:
1587 recipientComp.startFilter( pktFilter = ( "vlan {}".format( vlanId ) + " && " + packetFilter.format( senderComp.hostMac ) ) )
1588 else:
1589 recipientComp.startFilter( pktFilter = packetFilter.format( senderComp.hostMac ) )
Jeremy2f190ca2016-01-29 15:23:57 -08001590
1591 if not packet:
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001592 if vlanId:
1593 pkt = 'Ether( src="{0}", dst="{2}" )/Dot1Q(vlan={4})/IP( src="{1}", dst="{3}" )'.format(
1594 senderComp.hostMac,
1595 senderComp.hostIp,
1596 recipientComp.hostMac,
1597 recipientComp.hostIp,
1598 vlanId )
1599 else:
1600 pkt = 'Ether( src="{0}", dst="{2}" )/IP( src="{1}", dst="{3}" )'.format(
1601 senderComp.hostMac,
1602 senderComp.hostIp,
1603 recipientComp.hostMac,
1604 recipientComp.hostIp )
Jeremy2f190ca2016-01-29 15:23:57 -08001605 else:
1606 pkt = packet
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001607 if vlanId:
1608 senderComp.sendPacket( iface=( "{0}-eth0.{1}".format( sender, vlanId ) ), packet = pkt )
1609 else:
1610 senderComp.sendPacket( packet = pkt )
Jeremy2f190ca2016-01-29 15:23:57 -08001611
1612 if recipientComp.checkFilter( timeout ):
1613 if expectFailure:
1614 main.log.error( "Packet from {0} successfully received by {1} when it should not have been".format( sender , recipient ) )
1615 connectionsFunctional = main.FALSE
1616 else:
1617 main.log.info( "Packet from {0} successfully received by {1}".format( sender , recipient ) )
1618 else:
1619 recipientComp.killFilter()
1620 if expectFailure:
1621 main.log.info( "As expected, packet from {0} was not received by {1}".format( sender , recipient ) )
1622 else:
1623 main.log.error( "Packet from {0} was not received by {1}".format( sender , recipient ) )
1624 connectionsFunctional = main.FALSE
1625
1626 return connectionsFunctional
1627
Jeremye1ea0602016-02-08 16:35:05 -08001628def checkLeaderChange( leaders1, leaders2 ):
1629 """
1630 Checks for a change in intent partition leadership.
1631
1632 Takes the output of leaders -c in json string format before and after
1633 a potential change as input
1634
1635 Returns main.TRUE if no mismatches are detected
1636 Returns main.FALSE if there is a mismatch or on error loading the input
1637 """
1638 try:
1639 leaders1 = json.loads( leaders1 )
1640 leaders2 = json.loads( leaders2 )
1641 except ( AttributeError, TypeError):
1642 main.log.exception( self.name + ": Object not as expected" )
1643 return main.FALSE
1644 except Exception:
1645 main.log.exception( self.name + ": Uncaught exception!" )
1646 main.cleanup()
1647 main.exit()
1648 main.log.info( "Checking Intent Paritions for Change in Leadership" )
1649 mismatch = False
1650 for dict1 in leaders1:
1651 if "intent" in dict1.get( "topic", [] ):
1652 for dict2 in leaders2:
1653 if dict1.get( "topic", 0 ) == dict2.get( "topic", 0 ) and \
1654 dict1.get( "leader", 0 ) != dict2.get( "leader", 0 ):
1655 mismatch = True
1656 main.log.error( "{0} changed leader from {1} to {2}".\
1657 format( dict1.get( "topic", "no-topic" ),\
1658 dict1.get( "leader", "no-leader" ),\
1659 dict2.get( "leader", "no-leader" ) ) )
1660 if mismatch:
1661 return main.FALSE
1662 else:
1663 return main.TRUE
1664
1665
Jeremy2f190ca2016-01-29 15:23:57 -08001666def report( main ):
1667 """
1668 Report errors/warnings/exceptions
1669 """
1670 main.ONOSbench.logReport( main.ONOSip[ 0 ],
1671 [ "INFO",
1672 "FOLLOWER",
1673 "WARN",
1674 "flow",
1675 "ERROR",
1676 "Except" ],
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001677 "s" )
Jeremy2f190ca2016-01-29 15:23:57 -08001678
1679 main.log.info( "ERROR report: \n" )
1680 for i in range( main.numCtrls ):
1681 main.ONOSbench.logReport( main.ONOSip[ i ],
1682 [ "ERROR" ],
1683 "d" )
1684
1685 main.log.info( "EXCEPTIONS report: \n" )
1686 for i in range( main.numCtrls ):
1687 main.ONOSbench.logReport( main.ONOSip[ i ],
1688 [ "Except" ],
1689 "d" )
1690
1691 main.log.info( "WARNING report: \n" )
1692 for i in range( main.numCtrls ):
1693 main.ONOSbench.logReport( main.ONOSip[ i ],
1694 [ "WARN" ],
1695 "d" )
Jeremy Songster306ed7a2016-07-19 10:59:07 -07001696
1697def flowDuration( main ):
1698 """
1699 Check age of flows to see if flows are being overwritten
1700 """
1701 import time
1702 main.log.info( "Getting current flow durations" )
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001703 flowsJson1 = main.RESTs[ 0 ].flows()
Jeremy Songster306ed7a2016-07-19 10:59:07 -07001704 try:
1705 flowsJson1 = json.loads( flowsJson1 )
1706 except ValueError:
1707 main.log.error( "Unable to read flows" )
1708 return main.FALSE
1709 flowLife = []
1710 waitFlowLife = []
1711 for flow in flowsJson1:
1712 if flow[ 'appId' ] == "org.onosproject.net.intent":
1713 flowLife.append( flow[ 'life' ] )
1714 main.log.info( "Sleeping for {} seconds".format( main.flowDurationSleep ) )
1715 time.sleep( main.flowDurationSleep )
1716 main.log.info( "Getting new flow durations" )
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001717 flowsJson2 = main.RESTs[ 0 ].flows()
Jeremy Songster306ed7a2016-07-19 10:59:07 -07001718 try:
1719 flowsJson2 = json.loads( flowsJson2 )
1720 except ValueError:
1721 main.log.error( "Unable to read flows" )
1722 return main.FALSE
1723 for flow in flowsJson2:
1724 if flow[ 'appId' ] == "org.onosproject.net.intent":
1725 waitFlowLife.append( flow[ 'life' ] )
1726 main.log.info( "Determining whether flows where overwritten" )
1727 if len( flowLife ) == len( waitFlowLife ):
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001728 for i in range( len( flowLife ) ):
Jeremy Songster306ed7a2016-07-19 10:59:07 -07001729 if waitFlowLife[ i ] - flowLife[ i ] < main.flowDurationSleep:
1730 return main.FALSE
1731 else:
1732 return main.FALSE
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001733 return main.TRUE