blob: 8fa65f2372834c963e321b908c5896435eaea273 [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,
alisonda157272016-12-22 01:13:21 -0800308 protected=False,
Jeremy2f190ca2016-01-29 15:23:57 -0800309 ipProto="",
310 ipSrc="",
311 ipDst="",
312 tcpSrc="",
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700313 tcpDst="" ):
Jeremy2f190ca2016-01-29 15:23:57 -0800314 """
315 Installs a Single to Single Point Intent
316
317 Description:
318 Install a single to single point intent
319
320 Steps:
321 - Fetch host data if not given
322 - Add point intent
323 - Ingress device is the first sender device
324 - Egress device is the first recipient device
325 - Ports if defined in senders or recipients
326 - MAC address ethSrc loaded from Ingress device
327 - Check intent state with retry
328 Required:
329 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
330 senders - List of host dictionaries i.e.
331 [ { "name":"h8", "device":"of:0000000000000005/8","mac":"00:00:00:00:00:08" } ]
332 recipients - List of host dictionaries i.e.
333 [ { "name":"h16", "device":"of:0000000000000006/8", "mac":"00:00:00:00:00:10" } ]
334 Optional:
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700335 onosNode - ONOS node to install the intents in main.RESTs[ ]
Jeremy2f190ca2016-01-29 15:23:57 -0800336 0 by default so that it will always use the first
337 ONOS node
338 ethType - Ethernet type eg. IPV4, IPV6
339 bandwidth - Bandwidth capacity
340 lambdaAlloc - Allocate lambda, defaults to False
341 ipProto - IP protocol
342 tcp - TCP ports in the same order as the hosts in hostNames
343 sw1 - First switch to bring down & up for rerouting purpose
344 sw2 - Second switch to bring down & up for rerouting purpose
345 expectedLink - Expected link when the switches are down, it should
346 be two links lower than the links before the two
347 switches are down
348 """
349
350 assert main, "There is no main variable"
351 assert senders, "You must specify a sender"
352 assert recipients, "You must specify a recipient"
353 # Assert devices or main.hostsData, "You must specify devices"
354
355 global itemName # The name of this run. Used for logs.
356 itemName = name
357 onosNode = int( onosNode )
358
359 main.log.info( itemName + ": Adding single to single point intents" )
360
Jeremydd9bda62016-04-18 12:02:32 -0700361 try:
362 for sender in senders:
363 if not sender.get( "device" ):
364 main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
365 sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )
Jeremy2f190ca2016-01-29 15:23:57 -0800366
Jeremydd9bda62016-04-18 12:02:32 -0700367 for recipient in recipients:
368 if not recipient.get( "device" ):
369 main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
370 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700371 vlanId = senders[ 0 ].get( "vlanId" )
Jeremy2f190ca2016-01-29 15:23:57 -0800372
373
Jeremydd9bda62016-04-18 12:02:32 -0700374 ingressDevice = senders[ 0 ].get( "device" )
375 egressDevice = recipients[ 0 ].get( "device" )
Jeremy2f190ca2016-01-29 15:23:57 -0800376
Jeremydd9bda62016-04-18 12:02:32 -0700377 portIngress = senders[ 0 ].get( "port", "" )
378 portEgress = recipients[ 0 ].get( "port", "" )
379 main.log.debug( ingressDevice )
380 main.log.debug( egressDevice )
Jeremy2f190ca2016-01-29 15:23:57 -0800381
Jeremydd9bda62016-04-18 12:02:32 -0700382 srcMac = senders[ 0 ].get( "mac" )
383 dstMac = recipients[ 0 ].get( "mac" )
Jeremy2f190ca2016-01-29 15:23:57 -0800384
Jeremydd9bda62016-04-18 12:02:32 -0700385 ipSrc = senders[ 0 ].get( "ip" )
386 ipDst = recipients[ 0 ].get( "ip" )
Jeremy2f190ca2016-01-29 15:23:57 -0800387
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700388 intent1 = main.RESTs[ onosNode ].addPointIntent(
Jeremydd9bda62016-04-18 12:02:32 -0700389 ingressDevice=ingressDevice,
390 egressDevice=egressDevice,
391 ingressPort=portIngress,
392 egressPort=portEgress,
393 ethType=ethType,
394 ethSrc=srcMac,
395 ethDst=dstMac,
396 bandwidth=bandwidth,
397 lambdaAlloc=lambdaAlloc,
alisonda157272016-12-22 01:13:21 -0800398 protected=protected,
Jeremydd9bda62016-04-18 12:02:32 -0700399 ipProto=ipProto,
400 ipSrc=ipSrc,
401 ipDst=ipDst,
402 tcpSrc=tcpSrc,
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700403 tcpDst=tcpDst,
404 vlanId=vlanId )
Jeremy2f190ca2016-01-29 15:23:57 -0800405
Jeremydd9bda62016-04-18 12:02:32 -0700406 time.sleep( main.addIntentSleep )
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700407 intentsId = main.RESTs[ 0 ].getIntentsId()
408 except( KeyError, TypeError ):
Jeremydd9bda62016-04-18 12:02:32 -0700409 errorMsg = "There was a problem loading the hosts data."
Jeremy Songster306ed7a2016-07-19 10:59:07 -0700410 if intentsId:
Jeremydd9bda62016-04-18 12:02:32 -0700411 errorMsg += " There was a problem installing Point to Point intent."
412 main.log.error( errorMsg )
413 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -0800414
Jeremydd9bda62016-04-18 12:02:32 -0700415 # Check intent state
Jeremy Songster306ed7a2016-07-19 10:59:07 -0700416 if utilities.retry( f=checkIntentState, retValue=main.FALSE,
417 args=( main, intentsId ), sleep=main.checkIntentSleep ):
418 main.assertReturnString += 'Install Intent State Passed\n'
419 if flowDuration( main ):
420 main.assertReturnString += 'Flow duration check Passed\n'
421 return intentsId
422 else:
423 main.assertReturnString += 'Flow duration check failed\n'
424 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -0800425 else:
Jeremy Songster306ed7a2016-07-19 10:59:07 -0700426 main.log.error( "Host Intent did not install correctly" )
427 main.assertReturnString += 'Install Intent State Failed\n'
Jeremy2f190ca2016-01-29 15:23:57 -0800428 return main.FALSE
429
Jeremy2f190ca2016-01-29 15:23:57 -0800430def testPointIntent( main,
431 name,
432 intentId,
433 senders,
434 recipients,
435 badSenders={},
436 badRecipients={},
437 onosNode=0,
438 ethType="",
439 bandwidth="",
440 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -0800441 protected=False,
Jeremy2f190ca2016-01-29 15:23:57 -0800442 ipProto="",
443 ipAddresses="",
444 tcp="",
445 sw1="s5",
446 sw2="s2",
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700447 expectedLink=0,
448 useTCP=False ):
Jeremy2f190ca2016-01-29 15:23:57 -0800449 """
450 Test a Point Intent
451
452 Description:
453 Test a point intent
454
455 Steps:
456 - Fetch host data if not given
457 - Check Intent State
458 - Check Flow State
459 - Check Connectivity
460 - Check Lack of Connectivity Between Hosts not in the Intent
461 - Reroute
462 - Take Expected Link Down
463 - Check Intent State
464 - Check Flow State
465 - Check Topology
466 - Check Connectivity
467 - Bring Expected Link Up
468 - Check Intent State
469 - Check Flow State
470 - Check Topology
471 - Check Connectivity
472 - Remove Topology
473
474 Required:
475 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
476
477 senders - List of host dictionaries i.e.
478 { "name":"h8", "device":"of:0000000000000005/8","mac":"00:00:00:00:00:08" }
479 recipients - List of host dictionaries i.e.
480 { "name":"h16", "device":"of:0000000000000006/8", "mac":"00:00:00:00:00:10" }
481 Optional:
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700482 onosNode - ONOS node to install the intents in main.RESTs[ ]
Jeremy2f190ca2016-01-29 15:23:57 -0800483 0 by default so that it will always use the first
484 ONOS node
485 ethType - Ethernet type eg. IPV4, IPV6
486 bandwidth - Bandwidth capacity
487 lambdaAlloc - Allocate lambda, defaults to False
488 ipProto - IP protocol
489 tcp - TCP ports in the same order as the hosts in hostNames
490 sw1 - First switch to bring down & up for rerouting purpose
491 sw2 - Second switch to bring down & up for rerouting purpose
492 expectedLink - Expected link when the switches are down, it should
493 be two links lower than the links before the two
494 switches are down
495
496 """
497
498 # Parameter Validity Check
499 assert main, "There is no main variable"
500 assert senders, "You must specify a sender"
501 assert recipients, "You must specify a recipient"
502
503 global itemName
504 itemName = name
505 tempHostsData = {}
506 onosNode = int( onosNode )
507
508 main.log.info( itemName + ": Testing Point Intent" )
509
Jeremydd9bda62016-04-18 12:02:32 -0700510 try:
511 # Names for scapy
512 senderNames = [ x.get( "name" ) for x in senders ]
513 recipientNames = [ x.get( "name" ) for x in recipients ]
514 badSenderNames = [ x.get( "name" ) for x in badSenders ]
515 badRecipientNames = [ x.get( "name" ) for x in badRecipients ]
Jeremy2f190ca2016-01-29 15:23:57 -0800516
Jeremydd9bda62016-04-18 12:02:32 -0700517 for sender in senders:
518 if not sender.get( "device" ):
519 main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
520 sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )
Jeremy2f190ca2016-01-29 15:23:57 -0800521
Jeremydd9bda62016-04-18 12:02:32 -0700522 for recipient in recipients:
523 if not recipient.get( "device" ):
524 main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
525 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700526 vlanId=senders[ 0 ].get( "vlanId" )
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700527 except( KeyError, TypeError ):
Jeremydd9bda62016-04-18 12:02:32 -0700528 main.log.error( "There was a problem loading the hosts data." )
529 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -0800530
531 testResult = main.TRUE
532 main.log.info( itemName + ": Testing point intents" )
533
534 # Check intent state
535 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
536 main.assertReturnString += 'Initial Intent State Passed\n'
537 else:
538 main.assertReturnString += 'Initial Intent State Failed\n'
539 testResult = main.FALSE
540
541 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800542 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 -0800543 main.assertReturnString += 'Initial Flow State Passed\n'
544 else:
545 main.assertReturnString += 'Intial Flow State Failed\n'
546 testResult = main.FALSE
547
548 # Check Connectivity
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700549 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId, useTCP ) ):
Jeremy2f190ca2016-01-29 15:23:57 -0800550 main.assertReturnString += 'Initial Ping Passed\n'
551 else:
552 main.assertReturnString += 'Initial Ping Failed\n'
553 testResult = main.FALSE
554
555 # Check connections that shouldn't work
556 if badSenderNames:
557 main.log.info( "Checking that packets from incorrect sender do not go through" )
558 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, badSenderNames, recipientNames ), kwargs={ "expectFailure":True } ):
559 main.assertReturnString += 'Bad Sender Ping Passed\n'
560 else:
561 main.assertReturnString += 'Bad Sender Ping Failed\n'
562 testResult = main.FALSE
563
564 if badRecipientNames:
565 main.log.info( "Checking that packets to incorrect recipients do not go through" )
566 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, badRecipientNames ), kwargs={ "expectFailure":True } ):
567 main.assertReturnString += 'Bad Recipient Ping Passed\n'
568 else:
569 main.assertReturnString += 'Bad Recipient Ping Failed\n'
570 testResult = main.FALSE
571
572 # Test rerouting if these variables exist
573 if sw1 and sw2 and expectedLink:
574 # Take link down
575 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "down" ) ):
576 main.assertReturnString += 'Link Down Passed\n'
577 else:
578 main.assertReturnString += 'Link Down Failed\n'
579 testResult = main.FALSE
580
alisonda157272016-12-22 01:13:21 -0800581 if protected:
582 # Check Connection
583 if utilities.retry(f=scapyCheckConnection, retValue=main.FALSE,
584 args=(main, senderNames, recipientNames, vlanId, useTCP)):
585 main.assertReturnString += 'Link down Scapy Packet Received Passed\n'
586 else:
587 main.assertReturnString += 'Link down Scapy Packet Recieved Failed\n'
588 testResult = main.FALSE
589
590 if ProtectedIntentCheck(main):
591 main.assertReturnString += 'Protected Intent Check Passed\n'
592 else:
593 main.assertReturnString += 'Protected Intent Check Failed\n'
594 testResult = main.FALSE
595
Jeremy2f190ca2016-01-29 15:23:57 -0800596 # Check intent state
597 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
598 main.assertReturnString += 'Link Down Intent State Passed\n'
599 else:
600 main.assertReturnString += 'Link Down Intent State Failed\n'
601 testResult = main.FALSE
602
603 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800604 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 -0800605 main.assertReturnString += 'Link Down Flow State Passed\n'
606 else:
607 main.assertReturnString += 'Link Down Flow State Failed\n'
608 testResult = main.FALSE
609
610 # Check OnosTopology
Jeremybc6a0aa2016-02-05 14:10:08 -0800611 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, expectedLink ), sleep=10 ):
Jeremy2f190ca2016-01-29 15:23:57 -0800612 main.assertReturnString += 'Link Down Topology State Passed\n'
613 else:
614 main.assertReturnString += 'Link Down Topology State Failed\n'
615 testResult = main.FALSE
616
617 # Check Connection
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700618 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId, useTCP ) ):
Jeremy2f190ca2016-01-29 15:23:57 -0800619 main.assertReturnString += 'Link Down Pingall Passed\n'
620 else:
621 main.assertReturnString += 'Link Down Pingall Failed\n'
622 testResult = main.FALSE
623
624 # Bring link up
625 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "up" ) ):
626 main.assertReturnString += 'Link Up Passed\n'
627 else:
628 main.assertReturnString += 'Link Up Failed\n'
629 testResult = main.FALSE
630
631 # Wait for reroute
632 time.sleep( main.rerouteSleep )
633
634 # Check Intents
635 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
636 main.assertReturnString += 'Link Up Intent State Passed\n'
637 else:
638 main.assertReturnString += 'Link Up Intent State Failed\n'
639 testResult = main.FALSE
640
641 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800642 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 -0800643 main.assertReturnString += 'Link Up Flow State Passed\n'
644 else:
645 main.assertReturnString += 'Link Up Flow State Failed\n'
646 testResult = main.FALSE
647
648 # Check OnosTopology
649 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, main.numLinks ) ):
650 main.assertReturnString += 'Link Up Topology State Passed\n'
651 else:
652 main.assertReturnString += 'Link Up Topology State Failed\n'
653 testResult = main.FALSE
654
655 # Check Connection
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700656 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId, useTCP ) ):
Jeremy2f190ca2016-01-29 15:23:57 -0800657 main.assertReturnString += 'Link Up Scapy Packet Received Passed\n'
658 else:
659 main.assertReturnString += 'Link Up Scapy Packet Recieved Failed\n'
660 testResult = main.FALSE
661
662 # Remove all intents
663 if utilities.retry( f=removeAllIntents, retValue=main.FALSE, args=( main, ) ):
664 main.assertReturnString += 'Remove Intents Passed'
665 else:
666 main.assertReturnString += 'Remove Intents Failed'
667 testResult = main.FALSE
668
669 return testResult
kelvin-onlab44147802015-07-27 17:57:31 -0700670
kelvin-onlab0e684682015-08-11 18:51:41 -0700671def pointIntentTcp( main,
672 name,
673 host1,
674 host2,
675 onosNode=0,
676 deviceId1="",
677 deviceId2="",
678 port1="",
679 port2="",
680 ethType="",
681 mac1="",
682 mac2="",
683 bandwidth="",
684 lambdaAlloc=False,
685 ipProto="",
686 ip1="",
687 ip2="",
688 tcp1="",
689 tcp2="",
690 sw1="",
691 sw2="",
692 expectedLink=0 ):
693
694 """
695 Description:
696 Verify add-point-intent only for TCP
697 Steps:
698 - Get device ids | ports
699 - Add point intents
700 - Check intents
701 - Verify flows
702 - Ping hosts
703 - Reroute
704 - Link down
705 - Verify flows
706 - Check topology
707 - Ping hosts
708 - Link up
709 - Verify flows
710 - Check topology
711 - Ping hosts
712 - Remove intents
713 Required:
714 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
715 host1 - Name of first host
716 host2 - Name of second host
717 Optional:
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700718 onosNode - ONOS node to install the intents in main.RESTs[ ]
kelvin-onlab0e684682015-08-11 18:51:41 -0700719 0 by default so that it will always use the first
720 ONOS node
721 deviceId1 - ONOS device id of the first switch, the same as the
722 location of the first host eg. of:0000000000000001/1,
723 located at device 1 port 1
724 deviceId2 - ONOS device id of the second switch
725 port1 - The port number where the first host is attached
726 port2 - The port number where the second host is attached
727 ethType - Ethernet type eg. IPV4, IPV6
728 mac1 - Mac address of first host
729 mac2 - Mac address of the second host
730 bandwidth - Bandwidth capacity
731 lambdaAlloc - Allocate lambda, defaults to False
732 ipProto - IP protocol
733 ip1 - IP address of first host
734 ip2 - IP address of second host
735 tcp1 - TCP port of first host
736 tcp2 - TCP port of second host
737 sw1 - First switch to bring down & up for rerouting purpose
738 sw2 - Second switch to bring down & up for rerouting purpose
739 expectedLink - Expected link when the switches are down, it should
740 be two links lower than the links before the two
741 switches are down
742 """
743
744 assert main, "There is no main variable"
745 assert name, "variable name is empty"
746 assert host1 and host2, "You must specify hosts"
747
748 global itemName
749 itemName = name
750 host1 = host1
751 host2 = host2
752 hostNames = [ host1, host2 ]
753 intentsId = []
754
755 iperfResult = main.TRUE
756 intentResult = main.TRUE
757 removeIntentResult = main.TRUE
758 flowResult = main.TRUE
759 topoResult = main.TRUE
760 linkDownResult = main.TRUE
761 linkUpResult = main.TRUE
762 onosNode = int( onosNode )
763
764 # Adding bidirectional point intents
765 main.log.info( itemName + ": Adding point intents" )
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700766 intent1 = main.RESTs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
kelvin-onlab0e684682015-08-11 18:51:41 -0700767 egressDevice=deviceId2,
768 ingressPort=port1,
769 egressPort=port2,
770 ethType=ethType,
771 ethSrc=mac1,
772 ethDst=mac2,
773 bandwidth=bandwidth,
774 lambdaAlloc=lambdaAlloc,
775 ipProto=ipProto,
776 ipSrc=ip1,
777 ipDst=ip2,
778 tcpSrc=tcp1,
779 tcpDst="" )
780
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700781 intent2 = main.RESTs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
kelvin-onlab0e684682015-08-11 18:51:41 -0700782 egressDevice=deviceId1,
783 ingressPort=port2,
784 egressPort=port1,
785 ethType=ethType,
786 ethSrc=mac2,
787 ethDst=mac1,
788 bandwidth=bandwidth,
789 lambdaAlloc=lambdaAlloc,
790 ipProto=ipProto,
791 ipSrc=ip2,
792 ipDst=ip1,
793 tcpSrc=tcp2,
794 tcpDst="" )
795
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700796 intent3 = main.RESTs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
kelvin-onlab0e684682015-08-11 18:51:41 -0700797 egressDevice=deviceId2,
798 ingressPort=port1,
799 egressPort=port2,
800 ethType=ethType,
801 ethSrc=mac1,
802 ethDst=mac2,
803 bandwidth=bandwidth,
804 lambdaAlloc=lambdaAlloc,
805 ipProto=ipProto,
806 ipSrc=ip1,
807 ipDst=ip2,
808 tcpSrc="",
809 tcpDst=tcp2 )
810
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700811 intent4 = main.RESTs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
kelvin-onlab0e684682015-08-11 18:51:41 -0700812 egressDevice=deviceId1,
813 ingressPort=port2,
814 egressPort=port1,
815 ethType=ethType,
816 ethSrc=mac2,
817 ethDst=mac1,
818 bandwidth=bandwidth,
819 lambdaAlloc=lambdaAlloc,
820 ipProto=ipProto,
821 ipSrc=ip2,
822 ipDst=ip1,
823 tcpSrc="",
824 tcpDst=tcp1 )
825
826 # Get all intents ID in the system, time delay right after intents are added
827 time.sleep( main.addIntentSleep )
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700828 intentsId = main.RESTs[ 0 ].getIntentsId()
kelvin-onlab0e684682015-08-11 18:51:41 -0700829 # Check intents state
830 time.sleep( main.checkIntentSleep )
831 intentResult = checkIntentState( main, intentsId )
832 # Check flows count in each node
833 checkFlowsCount( main )
834
835 # Check intents state again if first check fails...
836 if not intentResult:
837 intentResult = checkIntentState( main, intentsId )
838
839 # Check flows count in each node
840 checkFlowsCount( main )
841
842 # Verify flows
843 checkFlowsState( main )
844
845 # Run iperf to both host
846 iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
847 host2, 10 )
848
849 # Test rerouting if these variables exist
850 if sw1 and sw2 and expectedLink:
851 # link down
852 linkDownResult = link( main, sw1, sw2, "down" )
853 intentResult = intentResult and checkIntentState( main, intentsId )
854
855 # Check flows count in each node
856 checkFlowsCount( main )
857 # Verify flows
858 checkFlowsState( main )
859
860 # Check OnosTopology
861 topoResult = checkTopology( main, expectedLink )
862
863 # Run iperf to both host
864 iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
865 host2, 10 )
866
867 intentResult = checkIntentState( main, intentsId )
868
869 # Checks ONOS state in link down
870 if linkDownResult and topoResult and iperfResult and intentResult:
871 main.log.info( itemName + ": Successfully brought link down" )
872 else:
873 main.log.error( itemName + ": Failed to bring link down" )
874
875 # link up
876 linkUpResult = link( main, sw1, sw2, "up" )
877 time.sleep( main.rerouteSleep )
878
879 # Check flows count in each node
880 checkFlowsCount( main )
881 # Verify flows
882 checkFlowsState( main )
883
884 # Check OnosTopology
885 topoResult = checkTopology( main, main.numLinks )
886
887 # Run iperf to both host
888 iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
889 host2, 10 )
890
891 intentResult = checkIntentState( main, intentsId )
892
893 # Checks ONOS state in link up
894 if linkUpResult and topoResult and iperfResult and intentResult:
895 main.log.info( itemName + ": Successfully brought link back up" )
896 else:
897 main.log.error( itemName + ": Failed to bring link back up" )
898
899 # Remove all intents
900 removeIntentResult = removeAllIntents( main )
901
902 stepResult = iperfResult and linkDownResult and linkUpResult \
903 and intentResult and removeIntentResult
904
905 return stepResult
906
Ming Yan Shuab2f7f52016-08-03 15:21:24 -0700907
908def installSingleToMultiIntent( main,
909 name,
910 senders,
911 recipients,
912 onosNode=0,
913 ethType="",
914 bandwidth="",
915 lambdaAlloc=False,
916 ipProto="",
917 ipAddresses="",
918 tcp="",
919 sw1="",
920 sw2="",
921 partial=False ):
kelvin-onlab44147802015-07-27 17:57:31 -0700922 """
923 Verify Single to Multi Point intents
924 NOTE:If main.hostsData is not defined, variables data should be passed
925 in the same order index wise. All devices in the list should have the
926 same format, either all the devices have its port or it doesn't.
927 eg. hostName = [ 'h1', 'h2' ,.. ]
928 devices = [ 'of:0000000000000001', 'of:0000000000000002', ...]
929 ports = [ '1', '1', ..]
930 ...
931 Description:
932 Verify add-single-to-multi-intent iterates through the list of given
933 host | devices and add intents
934 Steps:
935 - Get device ids | ports
936 - Add single to multi point intents
937 - Check intents
938 - Verify flows
939 - Ping hosts
940 - Reroute
941 - Link down
942 - Verify flows
943 - Check topology
944 - Ping hosts
945 - Link up
946 - Verify flows
947 - Check topology
948 - Ping hosts
949 - Remove intents
950 Required:
951 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
952 hostNames - List of host names
953 Optional:
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700954 onosNode - ONOS node to install the intents in main.RESTs[ ]
kelvin-onlab44147802015-07-27 17:57:31 -0700955 0 by default so that it will always use the first
956 ONOS node
957 devices - List of device ids in the same order as the hosts
958 in hostNames
959 ports - List of port numbers in the same order as the device in
960 devices
961 ethType - Ethernet type eg. IPV4, IPV6
962 macs - List of hosts mac address in the same order as the hosts in
963 hostNames
964 bandwidth - Bandwidth capacity
965 lambdaAlloc - Allocate lambda, defaults to False
966 ipProto - IP protocol
967 ipAddresses - IP addresses of host in the same order as the hosts in
968 hostNames
969 tcp - TCP ports in the same order as the hosts in hostNames
970 sw1 - First switch to bring down & up for rerouting purpose
971 sw2 - Second switch to bring down & up for rerouting purpose
972 expectedLink - Expected link when the switches are down, it should
973 be two links lower than the links before the two
974 switches are down
975 """
976
977 assert main, "There is no main variable"
Ming Yan Shuab2f7f52016-08-03 15:21:24 -0700978 assert senders, "You must specify a sender"
979 assert recipients, "You must specify a recipient"
980 # Assert devices or main.hostsData, "You must specify devices"
kelvin-onlab44147802015-07-27 17:57:31 -0700981
Ming Yan Shuab2f7f52016-08-03 15:21:24 -0700982 global itemName # The name of this run. Used for logs.
kelvin-onlab44147802015-07-27 17:57:31 -0700983 itemName = name
kelvin-onlab44147802015-07-27 17:57:31 -0700984 onosNode = int( onosNode )
985
kelvin-onlab44147802015-07-27 17:57:31 -0700986 main.log.info( itemName + ": Adding single point to multi point intents" )
987
Ming Yan Shuab2f7f52016-08-03 15:21:24 -0700988 try:
989 for sender in senders:
990 if not sender.get( "device" ):
991 main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
992 sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )
kelvin-onlab44147802015-07-27 17:57:31 -0700993
Ming Yan Shuab2f7f52016-08-03 15:21:24 -0700994 for recipient in recipients:
995 if not recipient.get( "device" ):
996 main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
997 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
998 vlanId = senders[ 0 ].get( "vlanId" )
kelvin-onlab44147802015-07-27 17:57:31 -0700999
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001000 ingressDevice = senders[ 0 ].get( "device" )
1001 egressDeviceList = [ x.get( "device" ) for x in recipients if x.get( "device" ) ]
1002
1003 portIngress = senders[ 0 ].get( "port", "" )
1004 portEgressList = [ x.get( "port" ) for x in recipients if x.get( "port" ) ]
1005 if not portEgressList:
1006 portEgressList = []
1007
1008 main.log.debug( ingressDevice )
1009 main.log.debug( egressDeviceList )
1010
1011 srcMac = senders[ 0 ].get( "mac" )
1012 dstMac = []
1013 for r in recipients:
1014 mac = r.get( "mac" )
1015 dstMac.append( mac )
1016
1017 ipSrc = senders[ 0 ].get( "ip" )
1018 ipDst = []
1019 for r in recipients:
1020 ip = r.get( "ip" )
1021 ipDst.append( ip )
1022
1023 # Adding point intent
1024 intentId = main.RESTs[ onosNode ].addSinglepointToMultipointIntent(
kelvin-onlab44147802015-07-27 17:57:31 -07001025 ingressDevice=ingressDevice,
1026 egressDeviceList=egressDeviceList,
1027 portIngress=portIngress,
1028 portEgressList=portEgressList,
1029 ethType=ethType,
1030 ethSrc=srcMac,
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001031 #ethDst=dstMac, #Isn't working because of ONOS itself
kelvin-onlab44147802015-07-27 17:57:31 -07001032 bandwidth=bandwidth,
1033 lambdaAlloc=lambdaAlloc,
1034 ipProto=ipProto,
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001035 ipSrc=ipSrc,
1036 ipDst=ipDst,
kelvin-onlab44147802015-07-27 17:57:31 -07001037 tcpSrc="",
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001038 tcpDst="",
1039 vlanId=vlanId,
1040 partial=partial )
kelvin-onlab44147802015-07-27 17:57:31 -07001041
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001042 time.sleep( main.addIntentSleep )
1043 intentsId = main.RESTs[ 0 ].getIntentsId()
1044 except ( KeyError, TypeError ):
1045 errorMsg = "There was a problem loading the hosts data."
1046 if intentId:
1047 errorMsg += " There was a problem installing Singlepoint to Multipoint intent."
1048 main.log.error( errorMsg )
1049 return main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -07001050
1051 # Check intents state
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001052 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentsId ), sleep=main.checkIntentSleep ):
1053 return intentsId
1054 else:
1055 main.log.error( "Single to Multi Intent did not install correctly" )
1056 return main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -07001057
1058def multiToSingleIntent( main,
1059 name,
1060 hostNames,
1061 onosNode=0,
1062 devices="",
1063 ports=None,
1064 ethType="",
1065 macs=None,
1066 bandwidth="",
1067 lambdaAlloc=False,
1068 ipProto="",
1069 ipAddresses="",
1070 tcp="",
1071 sw1="",
1072 sw2="",
1073 expectedLink=0 ):
1074 """
1075 Verify Single to Multi Point intents
1076 NOTE:If main.hostsData is not defined, variables data should be passed in the
1077 same order index wise. All devices in the list should have the same
1078 format, either all the devices have its port or it doesn't.
1079 eg. hostName = [ 'h1', 'h2' ,.. ]
1080 devices = [ 'of:0000000000000001', 'of:0000000000000002', ...]
1081 ports = [ '1', '1', ..]
1082 ...
1083 Description:
1084 Verify add-multi-to-single-intent
1085 Steps:
1086 - Get device ids | ports
1087 - Add multi to single point intents
1088 - Check intents
1089 - Verify flows
1090 - Ping hosts
1091 - Reroute
1092 - Link down
1093 - Verify flows
1094 - Check topology
1095 - Ping hosts
1096 - Link up
1097 - Verify flows
1098 - Check topology
1099 - Ping hosts
1100 - Remove intents
1101 Required:
1102 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
1103 hostNames - List of host names
1104 Optional:
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001105 onosNode - ONOS node to install the intents in main.RESTs[ ]
kelvin-onlab44147802015-07-27 17:57:31 -07001106 0 by default so that it will always use the first
1107 ONOS node
1108 devices - List of device ids in the same order as the hosts
1109 in hostNames
1110 ports - List of port numbers in the same order as the device in
1111 devices
1112 ethType - Ethernet type eg. IPV4, IPV6
1113 macs - List of hosts mac address in the same order as the hosts in
1114 hostNames
1115 bandwidth - Bandwidth capacity
1116 lambdaAlloc - Allocate lambda, defaults to False
1117 ipProto - IP protocol
1118 ipAddresses - IP addresses of host in the same order as the hosts in
1119 hostNames
1120 tcp - TCP ports in the same order as the hosts in hostNames
1121 sw1 - First switch to bring down & up for rerouting purpose
1122 sw2 - Second switch to bring down & up for rerouting purpose
1123 expectedLink - Expected link when the switches are down, it should
1124 be two links lower than the links before the two
1125 switches are down
1126 """
1127
1128 assert main, "There is no main variable"
1129 assert hostNames, "You must specify hosts"
1130 assert devices or main.hostsData, "You must specify devices"
1131
1132 global itemName
1133 itemName = name
1134 tempHostsData = {}
1135 intentsId = []
1136 onosNode = int( onosNode )
1137
1138 macsDict = {}
1139 ipDict = {}
1140 if hostNames and devices:
1141 if len( hostNames ) != len( devices ):
1142 main.log.debug( "hosts and devices does not have the same length" )
1143 #print "len hostNames = ", len( hostNames )
1144 #print "len devices = ", len( devices )
1145 return main.FALSE
1146 if ports:
1147 if len( ports ) != len( devices ):
1148 main.log.error( "Ports and devices does " +
1149 "not have the same length" )
1150 #print "len devices = ", len( devices )
1151 #print "len ports = ", len( ports )
1152 return main.FALSE
1153 else:
1154 main.log.info( "Device Ports are not specified" )
1155 if macs:
1156 for i in range( len( devices ) ):
1157 macsDict[ devices[ i ] ] = macs[ i ]
1158 elif hostNames and not devices and main.hostsData:
1159 devices = []
1160 main.log.info( "multiToSingleIntent function is using main.hostsData" )
1161 for host in hostNames:
1162 devices.append( main.hostsData.get( host ).get( 'location' ) )
1163 macsDict[ main.hostsData.get( host ).get( 'location' ) ] = \
1164 main.hostsData.get( host ).get( 'mac' )
1165 ipDict[ main.hostsData.get( host ).get( 'location' ) ] = \
1166 main.hostsData.get( host ).get( 'ipAddresses' )
1167 #print main.hostsData
1168
1169 #print 'host names = ', hostNames
1170 #print 'devices = ', devices
1171 #print "macsDict = ", macsDict
1172
1173 pingResult = main.TRUE
1174 intentResult = main.TRUE
1175 removeIntentResult = main.TRUE
1176 flowResult = main.TRUE
1177 topoResult = main.TRUE
1178 linkDownResult = main.TRUE
1179 linkUpResult = main.TRUE
1180
1181 devicesCopy = copy.copy( devices )
1182 if ports:
1183 portsCopy = copy.copy( ports )
1184 main.log.info( itemName + ": Adding multi point to single point intents" )
1185
1186 # Check flows count in each node
1187 checkFlowsCount( main )
1188
1189 # Adding bidirectional point intents
1190 for i in range( len( devices ) ):
1191 egressDevice = devicesCopy[ i ]
1192 ingressDeviceList = copy.copy( devicesCopy )
1193 ingressDeviceList.remove( egressDevice )
1194 if ports:
1195 portEgress = portsCopy[ i ]
1196 portIngressList = copy.copy( portsCopy )
1197 del portIngressList[ i ]
1198 else:
1199 portEgress = ""
1200 portIngressList = None
1201 if not macsDict:
1202 dstMac = ""
1203 else:
1204 dstMac = macsDict[ egressDevice ]
1205 if dstMac == None:
1206 main.log.debug( "There is no MAC in device - " + egressDevice )
1207 dstMac = ""
1208
1209 intentsId.append(
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001210 main.RESTs[ onosNode ].addMultipointToSinglepointIntent(
kelvin-onlab44147802015-07-27 17:57:31 -07001211 ingressDeviceList=ingressDeviceList,
1212 egressDevice=egressDevice,
1213 portIngressList=portIngressList,
1214 portEgress=portEgress,
1215 ethType=ethType,
1216 ethDst=dstMac,
1217 bandwidth=bandwidth,
1218 lambdaAlloc=lambdaAlloc,
1219 ipProto=ipProto,
1220 ipSrc="",
1221 ipDst="",
1222 tcpSrc="",
1223 tcpDst="" ) )
1224
1225 pingResult = pingallHosts( main, hostNames )
1226
1227 # Check intents state
1228 time.sleep( main.checkIntentSleep )
1229 intentResult = checkIntentState( main, intentsId )
1230
1231 # Check intents state again if first check fails...
1232 if not intentResult:
1233 intentResult = checkIntentState( main, intentsId )
1234
1235 # Check flows count in each node
1236 checkFlowsCount( main )
1237 # Verify flows
1238 checkFlowsState( main )
1239
1240 # Ping hosts
1241 pingResult = pingResult and pingallHosts( main, hostNames )
1242 # Ping hosts again...
1243 pingResult = pingResult and pingallHosts( main, hostNames )
1244
1245 # Test rerouting if these variables exist
1246 if sw1 and sw2 and expectedLink:
1247 # link down
1248 linkDownResult = link( main, sw1, sw2, "down" )
1249 intentResult = intentResult and checkIntentState( main, intentsId )
1250
1251 # Check flows count in each node
1252 checkFlowsCount( main )
1253 # Verify flows
1254 checkFlowsState( main )
1255
1256 # Check OnosTopology
1257 topoResult = checkTopology( main, expectedLink )
1258
1259 # Ping hosts
1260 pingResult = pingResult and pingallHosts( main, hostNames )
1261
1262 intentResult = checkIntentState( main, intentsId )
1263
1264 # Checks ONOS state in link down
1265 if linkDownResult and topoResult and pingResult and intentResult:
1266 main.log.info( itemName + ": Successfully brought link down" )
1267 else:
1268 main.log.error( itemName + ": Failed to bring link down" )
1269
1270 # link up
1271 linkUpResult = link( main, sw1, sw2, "up" )
1272 time.sleep( main.rerouteSleep )
1273
1274 # Check flows count in each node
1275 checkFlowsCount( main )
1276 # Verify flows
1277 checkFlowsState( main )
1278
1279 # Check OnosTopology
1280 topoResult = checkTopology( main, main.numLinks )
1281
1282 # Ping hosts
1283 pingResult = pingResult and pingallHosts( main, hostNames )
1284
1285 intentResult = checkIntentState( main, intentsId )
1286
1287 # Checks ONOS state in link up
1288 if linkUpResult and topoResult and pingResult and intentResult:
1289 main.log.info( itemName + ": Successfully brought link back up" )
1290 else:
1291 main.log.error( itemName + ": Failed to bring link back up" )
1292
1293 # Remove all intents
1294 removeIntentResult = removeAllIntents( main, intentsId )
1295
1296 stepResult = pingResult and linkDownResult and linkUpResult \
1297 and intentResult and removeIntentResult
1298
1299 return stepResult
1300
kelvin-onlab0e684682015-08-11 18:51:41 -07001301def pingallHosts( main, hostList ):
kelvin-onlab44147802015-07-27 17:57:31 -07001302 # Ping all host in the hosts list variable
1303 print "Pinging : ", hostList
1304 pingResult = main.TRUE
kelvin-onlab0e684682015-08-11 18:51:41 -07001305 pingResult = main.Mininet1.pingallHosts( hostList )
kelvin-onlab44147802015-07-27 17:57:31 -07001306 return pingResult
1307
kelvin-onlab0e684682015-08-11 18:51:41 -07001308def getHostsData( main, hostList ):
kelvin-onlab44147802015-07-27 17:57:31 -07001309 """
1310 Use fwd app and pingall to discover all the hosts
1311 """
1312
1313 activateResult = main.TRUE
1314 appCheck = main.TRUE
1315 getDataResult = main.TRUE
1316 main.log.info( "Activating reactive forwarding app " )
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001317 activateResult = main.RESTs[ 0 ].activateApp( "org.onosproject.fwd" )
kelvin-onlab44147802015-07-27 17:57:31 -07001318 if not activateResult:
1319 main.log.error( "Something went wrong installing fwd app" )
1320 time.sleep( main.fwdSleep )
kelvin-onlab0e684682015-08-11 18:51:41 -07001321 if isinstance( hostList[ 0 ], types.StringType ):
1322 main.Mininet1.pingallHosts( hostList )
1323 elif isinstance( hostList[ 0 ], types.ListType ):
1324 for i in xrange( len( hostList ) ):
1325 main.Mininet1.pingallHosts( hostList[ i ] )
1326
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001327 hostsJson = json.loads( main.RESTs[ 0 ].hosts() )
kelvin-onlab44147802015-07-27 17:57:31 -07001328 hosts = main.Mininet1.getHosts().keys()
1329 # TODO: Make better use of new getHosts function
1330 for host in hosts:
1331 main.hostsData[ host ] = {}
1332 main.hostsData[ host ][ 'mac' ] = \
1333 main.Mininet1.getMacAddress( host ).upper()
1334 for hostj in hostsJson:
1335 if main.hostsData[ host ][ 'mac' ] == hostj[ 'mac' ]:
1336 main.hostsData[ host ][ 'id' ] = hostj[ 'id' ]
1337 main.hostsData[ host ][ 'vlan' ] = hostj[ 'vlan' ]
1338 main.hostsData[ host ][ 'location' ] = \
1339 hostj[ 'location' ][ 'elementId' ] + '/' + \
1340 hostj[ 'location' ][ 'port' ]
1341 main.hostsData[ host ][ 'ipAddresses' ] = hostj[ 'ipAddresses' ]
1342
1343 main.log.info( "Deactivating reactive forwarding app " )
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001344 deactivateResult = main.RESTs[ 0 ].deactivateApp( "org.onosproject.fwd" )
kelvin-onlab44147802015-07-27 17:57:31 -07001345 if activateResult and deactivateResult and main.hostsData:
1346 main.log.info( "Successfully used fwd app to discover hosts " )
1347 getDataResult = main.TRUE
1348 else:
1349 main.log.info( "Failed to use fwd app to discover hosts " )
1350 getDataResult = main.FALSE
1351
1352 print main.hostsData
1353
1354 return getDataResult
1355
1356def checkTopology( main, expectedLink ):
1357 statusResult = main.TRUE
1358 # Check onos topology
1359 main.log.info( itemName + ": Checking ONOS topology " )
1360
1361 for i in range( main.numCtrls ):
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001362 statusResult = main.RESTs[ i ].checkStatus( main.numSwitch,
kelvin-onlab44147802015-07-27 17:57:31 -07001363 expectedLink )\
1364 and statusResult
1365 if not statusResult:
1366 main.log.error( itemName + ": Topology mismatch" )
1367 else:
1368 main.log.info( itemName + ": Topology match" )
1369 return statusResult
1370
1371def checkIntentState( main, intentsId ):
1372 """
1373 This function will check intent state to make sure all the intents
1374 are in INSTALLED state
1375 """
1376
1377 intentResult = main.TRUE
1378 results = []
1379
1380 main.log.info( itemName + ": Checking intents state" )
1381 # First check of intents
1382 for i in range( main.numCtrls ):
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001383 tempResult = main.RESTs[ i ].checkIntentState( intentsId=intentsId )
kelvin-onlab44147802015-07-27 17:57:31 -07001384 results.append( tempResult )
1385
1386 expectedState = [ 'INSTALLED', 'INSTALLING' ]
1387
1388 if all( result == main.TRUE for result in results ):
1389 main.log.info( itemName + ": Intents are installed correctly" )
1390 else:
1391 # Wait for at least 5 second before checking the intents again
Jeremy2f190ca2016-01-29 15:23:57 -08001392 main.log.error( "Intents are not installed correctly. Waiting 5 sec" )
kelvin-onlab44147802015-07-27 17:57:31 -07001393 time.sleep( 5 )
1394 results = []
1395 # Second check of intents since some of the intents may be in
1396 # INSTALLING state, they should be in INSTALLED at this time
1397 for i in range( main.numCtrls ):
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001398 tempResult = main.RESTs[ i ].checkIntentState( intentsId=intentsId )
kelvin-onlab44147802015-07-27 17:57:31 -07001399 results.append( tempResult )
1400 if all( result == main.TRUE for result in results ):
1401 main.log.info( itemName + ": Intents are installed correctly" )
Jeremy2f190ca2016-01-29 15:23:57 -08001402 intentResult = main.TRUE
kelvin-onlab44147802015-07-27 17:57:31 -07001403 else:
1404 main.log.error( itemName + ": Intents are NOT installed correctly" )
1405 intentResult = main.FALSE
1406
1407 return intentResult
1408
1409def checkFlowsState( main ):
1410
1411 main.log.info( itemName + ": Check flows state" )
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001412 checkFlowsResult = main.RESTs[ 0 ].checkFlowsState()
kelvin-onlab44147802015-07-27 17:57:31 -07001413 return checkFlowsResult
1414
1415def link( main, sw1, sw2, option):
1416
1417 # link down
1418 main.log.info( itemName + ": Bring link " + option + "between " +
1419 sw1 + " and " + sw2 )
1420 linkResult = main.Mininet1.link( end1=sw1, end2=sw2, option=option )
1421 return linkResult
1422
1423def removeAllIntents( main ):
1424 """
1425 Remove all intents in the intentsId
1426 """
1427
1428 onosSummary = []
1429 removeIntentResult = main.TRUE
1430 # Remove intents
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001431 removeIntentResult = main.RESTs[ 0 ].removeAllIntents( )
kelvin-onlab44147802015-07-27 17:57:31 -07001432
1433 if removeIntentResult:
1434 main.log.info( itemName + ": There are no more intents remaining, " +
1435 "successfully removed all the intents." )
1436
1437 return removeIntentResult
1438
1439def checkFlowsCount( main ):
1440 """
1441 Check flows count in each node
1442 """
1443
1444 flowsCount = []
1445 main.log.info( itemName + ": Checking flows count in each ONOS node" )
1446 for i in range( main.numCtrls ):
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001447 flowsCount.append( len( json.loads( main.RESTs[ i ].flows() ) ) )
kelvin-onlab44147802015-07-27 17:57:31 -07001448
1449 if flowsCount:
1450 if all( flows==flowsCount[ 0 ] for flows in flowsCount ):
1451 main.log.info( itemName + ": There are " + str( flowsCount[ 0 ] ) +
1452 " flows in all ONOS node" )
1453 else:
1454 for i in range( main.numCtrls ):
1455 main.log.debug( itemName + ": ONOS node " + str( i + 1 ) +
Jeremy2f190ca2016-01-29 15:23:57 -08001456 " has " + str( flowsCount[ i ] ) + " flows" )
kelvin-onlab44147802015-07-27 17:57:31 -07001457 else:
1458 main.log.error( "Checking flows count failed, check summary command" )
1459 return main.FALSE
1460
1461 return main.TRUE
1462
Jeremy2f190ca2016-01-29 15:23:57 -08001463def sendDiscoveryArp( main, hosts=None ):
1464 """
1465 Sends Discovery ARP packets from each host provided
1466 Defaults to each host in main.scapyHosts
1467 """
1468 # Send an arp ping from each host
1469 if not hosts:
1470 hosts = main.scapyHosts
1471 for host in hosts:
1472 pkt = 'Ether( src="{0}")/ARP( psrc="{1}")'.format( host.hostMac ,host.hostIp )
1473 # Send from the VLAN interface if there is one so ONOS discovers the VLAN correctly
1474 iface = None
1475 for interface in host.getIfList():
1476 if '.' in interface:
1477 main.log.debug( "Detected VLAN interface {0}. Sending ARP packet from {0}".format( interface ) )
1478 iface = interface
1479 break
1480 host.sendPacket( packet=pkt, iface=iface )
1481 main.log.info( "Sending ARP packet from {0}".format( host.name ) )
1482
1483def confirmHostDiscovery( main ):
1484 """
1485 Confirms that all ONOS nodes have discovered all scapy hosts
1486 """
1487 import collections
1488 scapyHostCount = len( main.scapyHosts )
1489 hosts = main.topo.getAllHosts( main ) # Get host data from each ONOS node
1490 hostFails = [] # Reset for each failed attempt
1491
1492 # Check for matching hosts on each node
1493 scapyHostIPs = [ x.hostIp for x in main.scapyHosts if x.hostIp != "0.0.0.0" ]
1494 for controller in range( main.numCtrls ):
1495 controllerStr = str( controller + 1 ) # ONOS node number
1496 # Compare Hosts
1497 # Load hosts data for controller node
Jeremydd9bda62016-04-18 12:02:32 -07001498 try:
1499 if hosts[ controller ]:
1500 main.log.info( "Hosts discovered" )
Jeremy2f190ca2016-01-29 15:23:57 -08001501 else:
Jeremydd9bda62016-04-18 12:02:32 -07001502 main.log.error( "Problem discovering hosts" )
1503 if hosts[ controller ] and "Error" not in hosts[ controller ]:
1504 try:
1505 hostData = json.loads( hosts[ controller ] )
1506 except ( TypeError, ValueError ):
1507 main.log.error( "Could not load json:" + str( hosts[ controller ] ) )
Jeremy2f190ca2016-01-29 15:23:57 -08001508 hostFails.append( controllerStr )
Jeremydd9bda62016-04-18 12:02:32 -07001509 else:
1510 onosHostIPs = [ x.get( "ipAddresses" )[ 0 ]
1511 for x in hostData
1512 if len( x.get( "ipAddresses" ) ) > 0 ]
1513 if not set( collections.Counter( scapyHostIPs ) ).issubset( set ( collections.Counter( onosHostIPs ) ) ):
1514 main.log.warn( "Controller {0} only sees nodes with {1} IPs. It should see all of the following: {2}".format( controllerStr, onosHostIPs, scapyHostIPs ) )
1515 hostFails.append( controllerStr )
1516 else:
1517 main.log.error( "Hosts returned nothing or an error." )
1518 hostFails.append( controllerStr )
1519 except IndexError:
1520 main.log.error( "Hosts returned nothing, Failed to discover hosts." )
1521 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -08001522
1523 if hostFails:
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001524 main.log.error( "List of failed ONOS Nodes:" + ', '.join( map( str, hostFails ) ) )
Jeremy2f190ca2016-01-29 15:23:57 -08001525 return main.FALSE
1526 else:
1527 return main.TRUE
1528
1529def populateHostData( main ):
1530 """
1531 Populates hostsData
1532 """
1533 import json
1534 try:
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001535 hostsJson = json.loads( main.RESTs[ 0 ].hosts() )
Jeremy2f190ca2016-01-29 15:23:57 -08001536 hosts = main.Mininet1.getHosts().keys()
1537 # TODO: Make better use of new getHosts function
1538 for host in hosts:
1539 main.hostsData[ host ] = {}
1540 main.hostsData[ host ][ 'mac' ] = \
1541 main.Mininet1.getMacAddress( host ).upper()
1542 for hostj in hostsJson:
1543 if main.hostsData[ host ][ 'mac' ] == hostj[ 'mac' ]:
1544 main.hostsData[ host ][ 'id' ] = hostj[ 'id' ]
1545 main.hostsData[ host ][ 'vlan' ] = hostj[ 'vlan' ]
1546 main.hostsData[ host ][ 'location' ] = \
1547 hostj[ 'location' ][ 'elementId' ] + '/' + \
1548 hostj[ 'location' ][ 'port' ]
1549 main.hostsData[ host ][ 'ipAddresses' ] = hostj[ 'ipAddresses' ]
1550 return main.TRUE
Jeremydd9bda62016-04-18 12:02:32 -07001551 except ValueError:
1552 main.log.error( "ValueError while populating hostsData" )
1553 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -08001554 except KeyError:
1555 main.log.error( "KeyError while populating hostsData")
1556 return main.FALSE
Jeremydd9bda62016-04-18 12:02:32 -07001557 except IndexError:
1558 main.log.error( "IndexError while populating hostsData" )
1559 return main.FALSE
1560 except TypeError:
1561 main.log.error( "TypeError while populating hostsData" )
1562 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -08001563
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001564def scapyCheckConnection( main, senders, recipients, vlanId=None, useTCP=False, packet=None, packetFilter=None, expectFailure=False ):
Jeremy2f190ca2016-01-29 15:23:57 -08001565 """
1566 Checks the connectivity between all given sender hosts and all given recipient hosts
1567 Packet may be specified. Defaults to Ether/IP packet
1568 Packet Filter may be specified. Defaults to Ether/IP from current sender MAC
1569 Todo: Optional packet and packet filter attributes for sender and recipients
1570 Expect Failure when the sender and recipient are not supposed to have connectivity
1571 Timeout of 1 second, returns main.TRUE if the filter is not triggered and kills the filter
1572
1573 """
1574 connectionsFunctional = main.TRUE
1575
1576 if not packetFilter:
1577 packetFilter = 'ether host {}'
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001578 if useTCP:
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001579 packetFilter += ' ip proto \\tcp tcp port {}'.format( main.params[ 'SDNIP' ][ 'dstPort' ] )
Jeremy2f190ca2016-01-29 15:23:57 -08001580 if expectFailure:
1581 timeout = 1
1582 else:
1583 timeout = 10
1584
1585 for sender in senders:
1586 try:
1587 senderComp = getattr( main, sender )
1588 except AttributeError:
1589 main.log.error( "main has no attribute {}".format( sender ) )
1590 connectionsFunctional = main.FALSE
1591 continue
1592
1593 for recipient in recipients:
1594 # Do not send packets to self since recipient CLI will already be busy
1595 if recipient == sender:
1596 continue
1597 try:
1598 recipientComp = getattr( main, recipient )
1599 except AttributeError:
1600 main.log.error( "main has no attribute {}".format( recipient ) )
1601 connectionsFunctional = main.FALSE
1602 continue
1603
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001604 if vlanId:
1605 recipientComp.startFilter( pktFilter = ( "vlan {}".format( vlanId ) + " && " + packetFilter.format( senderComp.hostMac ) ) )
1606 else:
1607 recipientComp.startFilter( pktFilter = packetFilter.format( senderComp.hostMac ) )
Jeremy2f190ca2016-01-29 15:23:57 -08001608
1609 if not packet:
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001610 if vlanId:
1611 pkt = 'Ether( src="{0}", dst="{2}" )/Dot1Q(vlan={4})/IP( src="{1}", dst="{3}" )'.format(
1612 senderComp.hostMac,
1613 senderComp.hostIp,
1614 recipientComp.hostMac,
1615 recipientComp.hostIp,
1616 vlanId )
1617 else:
1618 pkt = 'Ether( src="{0}", dst="{2}" )/IP( src="{1}", dst="{3}" )'.format(
1619 senderComp.hostMac,
1620 senderComp.hostIp,
1621 recipientComp.hostMac,
1622 recipientComp.hostIp )
Jeremy2f190ca2016-01-29 15:23:57 -08001623 else:
1624 pkt = packet
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001625 if vlanId:
1626 senderComp.sendPacket( iface=( "{0}-eth0.{1}".format( sender, vlanId ) ), packet = pkt )
1627 else:
1628 senderComp.sendPacket( packet = pkt )
Jeremy2f190ca2016-01-29 15:23:57 -08001629
1630 if recipientComp.checkFilter( timeout ):
1631 if expectFailure:
1632 main.log.error( "Packet from {0} successfully received by {1} when it should not have been".format( sender , recipient ) )
1633 connectionsFunctional = main.FALSE
1634 else:
1635 main.log.info( "Packet from {0} successfully received by {1}".format( sender , recipient ) )
1636 else:
1637 recipientComp.killFilter()
1638 if expectFailure:
1639 main.log.info( "As expected, packet from {0} was not received by {1}".format( sender , recipient ) )
1640 else:
1641 main.log.error( "Packet from {0} was not received by {1}".format( sender , recipient ) )
1642 connectionsFunctional = main.FALSE
1643
1644 return connectionsFunctional
1645
Jeremye1ea0602016-02-08 16:35:05 -08001646def checkLeaderChange( leaders1, leaders2 ):
1647 """
1648 Checks for a change in intent partition leadership.
1649
1650 Takes the output of leaders -c in json string format before and after
1651 a potential change as input
1652
1653 Returns main.TRUE if no mismatches are detected
1654 Returns main.FALSE if there is a mismatch or on error loading the input
1655 """
1656 try:
1657 leaders1 = json.loads( leaders1 )
1658 leaders2 = json.loads( leaders2 )
1659 except ( AttributeError, TypeError):
1660 main.log.exception( self.name + ": Object not as expected" )
1661 return main.FALSE
1662 except Exception:
1663 main.log.exception( self.name + ": Uncaught exception!" )
1664 main.cleanup()
1665 main.exit()
1666 main.log.info( "Checking Intent Paritions for Change in Leadership" )
1667 mismatch = False
1668 for dict1 in leaders1:
1669 if "intent" in dict1.get( "topic", [] ):
1670 for dict2 in leaders2:
1671 if dict1.get( "topic", 0 ) == dict2.get( "topic", 0 ) and \
1672 dict1.get( "leader", 0 ) != dict2.get( "leader", 0 ):
1673 mismatch = True
1674 main.log.error( "{0} changed leader from {1} to {2}".\
1675 format( dict1.get( "topic", "no-topic" ),\
1676 dict1.get( "leader", "no-leader" ),\
1677 dict2.get( "leader", "no-leader" ) ) )
1678 if mismatch:
1679 return main.FALSE
1680 else:
1681 return main.TRUE
1682
1683
Jeremy2f190ca2016-01-29 15:23:57 -08001684def report( main ):
1685 """
1686 Report errors/warnings/exceptions
1687 """
1688 main.ONOSbench.logReport( main.ONOSip[ 0 ],
1689 [ "INFO",
1690 "FOLLOWER",
1691 "WARN",
1692 "flow",
1693 "ERROR",
1694 "Except" ],
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001695 "s" )
Jeremy2f190ca2016-01-29 15:23:57 -08001696
1697 main.log.info( "ERROR report: \n" )
1698 for i in range( main.numCtrls ):
1699 main.ONOSbench.logReport( main.ONOSip[ i ],
1700 [ "ERROR" ],
1701 "d" )
1702
1703 main.log.info( "EXCEPTIONS report: \n" )
1704 for i in range( main.numCtrls ):
1705 main.ONOSbench.logReport( main.ONOSip[ i ],
1706 [ "Except" ],
1707 "d" )
1708
1709 main.log.info( "WARNING report: \n" )
1710 for i in range( main.numCtrls ):
1711 main.ONOSbench.logReport( main.ONOSip[ i ],
1712 [ "WARN" ],
1713 "d" )
Jeremy Songster306ed7a2016-07-19 10:59:07 -07001714
1715def flowDuration( main ):
1716 """
1717 Check age of flows to see if flows are being overwritten
1718 """
1719 import time
1720 main.log.info( "Getting current flow durations" )
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001721 flowsJson1 = main.RESTs[ 0 ].flows()
Jeremy Songster306ed7a2016-07-19 10:59:07 -07001722 try:
1723 flowsJson1 = json.loads( flowsJson1 )
1724 except ValueError:
1725 main.log.error( "Unable to read flows" )
1726 return main.FALSE
1727 flowLife = []
1728 waitFlowLife = []
1729 for flow in flowsJson1:
1730 if flow[ 'appId' ] == "org.onosproject.net.intent":
1731 flowLife.append( flow[ 'life' ] )
1732 main.log.info( "Sleeping for {} seconds".format( main.flowDurationSleep ) )
1733 time.sleep( main.flowDurationSleep )
1734 main.log.info( "Getting new flow durations" )
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001735 flowsJson2 = main.RESTs[ 0 ].flows()
Jeremy Songster306ed7a2016-07-19 10:59:07 -07001736 try:
1737 flowsJson2 = json.loads( flowsJson2 )
1738 except ValueError:
1739 main.log.error( "Unable to read flows" )
1740 return main.FALSE
1741 for flow in flowsJson2:
1742 if flow[ 'appId' ] == "org.onosproject.net.intent":
1743 waitFlowLife.append( flow[ 'life' ] )
1744 main.log.info( "Determining whether flows where overwritten" )
1745 if len( flowLife ) == len( waitFlowLife ):
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001746 for i in range( len( flowLife ) ):
Jeremy Songster306ed7a2016-07-19 10:59:07 -07001747 if waitFlowLife[ i ] - flowLife[ i ] < main.flowDurationSleep:
1748 return main.FALSE
1749 else:
1750 return main.FALSE
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001751 return main.TRUE
alisonda157272016-12-22 01:13:21 -08001752
1753def ProtectedIntentCheck( main ):
1754 intent = main.RESTs[ 0 ].intents()
1755 main.log.debug(intent)
1756 main.stop()
1757 if "Protection" in intent:
1758 return main.TRUE
1759 return main.FALSE