blob: 0a6765836ca0d62a78a63019a511b581ad183a9b [file] [log] [blame]
kelvin-onlab44147802015-07-27 17:57:31 -07001"""
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -07002Copyright 2015 Open Networking Foundation (ONF)
3
4Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
5the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
6or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
7
8 TestON is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 2 of the License, or
11 (at your option) any later version.
12
13 TestON is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with TestON. If not, see <http://www.gnu.org/licenses/>.
20
21
kelvin-onlab44147802015-07-27 17:57:31 -070022 Wrapper functions for FuncIntent
23 This functions include Onosclidriver and Mininetclidriver driver functions
24 Author: kelvin@onlab.us
25"""
26import time
27import copy
28import json
kelvin-onlab0e684682015-08-11 18:51:41 -070029import types
kelvin-onlab44147802015-07-27 17:57:31 -070030
Jon Hall02758ac2017-05-24 16:20:28 -070031
kelvin-onlab44147802015-07-27 17:57:31 -070032def __init__( self ):
33 self.default = ''
34
Jon Hall02758ac2017-05-24 16:20:28 -070035
Jeremy2f190ca2016-01-29 15:23:57 -080036def installHostIntent( main,
37 name,
38 host1,
39 host2,
40 onosNode=0,
41 ethType="",
42 bandwidth="",
43 lambdaAlloc=False,
44 ipProto="",
45 ipAddresses="",
46 tcp="",
47 sw1="",
Jeremy Songstere7f3b342016-08-17 14:56:49 -070048 sw2="" ):
kelvin-onlab44147802015-07-27 17:57:31 -070049 """
Jeremy2f190ca2016-01-29 15:23:57 -080050 Installs a Host Intent
51
52 Description:
53 Install a host intent using
54 add-host-intent
55
56 Steps:
57 - Fetch host data if not given
58 - Add host intent
59 - Ingress device is the first sender host
60 - Egress devices are the recipient devices
61 - Ports if defined in senders or recipients
62 - MAC address ethSrc loaded from Ingress device
63 - Check intent state with retry
64 Required:
65 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
66 host1 - Dictionary for host1
67 { "name":"h8", "id":"of:0000000000000005/8" }
68 host2 - Dictionary for host2
69 { "name":"h16", "id":"of:0000000000000006/8" }
70 Optional:
Jeremy Songstere7f3b342016-08-17 14:56:49 -070071 onosNode - ONOS node to install the intents in main.RESTs[ ]
Jeremy2f190ca2016-01-29 15:23:57 -080072 0 by default so that it will always use the first
73 ONOS node
74 ethType - Ethernet type eg. IPV4, IPV6
75 bandwidth - Bandwidth capacity
76 lambdaAlloc - Allocate lambda, defaults to False
77 ipProto - IP protocol
78 tcp - TCP ports in the same order as the hosts in hostNames
kelvin-onlab44147802015-07-27 17:57:31 -070079 """
kelvin-onlab44147802015-07-27 17:57:31 -070080 assert main, "There is no main variable"
Jeremy2f190ca2016-01-29 15:23:57 -080081 assert host1, "You must specify host1"
82 assert host2, "You must specify host2"
kelvin-onlab44147802015-07-27 17:57:31 -070083
Jeremy2f190ca2016-01-29 15:23:57 -080084 global itemName # The name of this run. Used for logs.
kelvin-onlab44147802015-07-27 17:57:31 -070085 itemName = name
kelvin-onlab44147802015-07-27 17:57:31 -070086 onosNode = int( onosNode )
87
Jeremy2f190ca2016-01-29 15:23:57 -080088 main.log.info( itemName + ": Adding single point to multi point intents" )
kelvin-onlab44147802015-07-27 17:57:31 -070089
Jeremydd9bda62016-04-18 12:02:32 -070090 try:
91 if not host1.get( "id" ):
92 main.log.warn( "ID not given for host1 {0}. Loading from main.hostData".format( host1.get( "name" ) ) )
93 main.log.debug( main.hostsData.get( host1.get( "name" ) ) )
94 host1[ "id" ] = main.hostsData.get( host1.get( "name" ) ).get( "id" )
kelvin-onlab44147802015-07-27 17:57:31 -070095
Jeremydd9bda62016-04-18 12:02:32 -070096 if not host2.get( "id" ):
97 main.log.warn( "ID not given for host2 {0}. Loading from main.hostData".format( host2.get( "name" ) ) )
98 host2[ "id" ] = main.hostsData.get( host2.get( "name" ) ).get( "id" )
Jeremy Songsterae2dd452016-05-17 16:44:35 -070099 vlanId = host1.get( "vlanId" )
kelvin-onlab44147802015-07-27 17:57:31 -0700100
Jeremydd9bda62016-04-18 12:02:32 -0700101 # Adding host intents
102 main.log.info( itemName + ": Adding host intents" )
kelvin-onlab44147802015-07-27 17:57:31 -0700103
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700104 intent1 = main.RESTs[ onosNode ].addHostIntent( hostIdOne=host1.get( "id" ),
Jon Hall02758ac2017-05-24 16:20:28 -0700105 hostIdTwo=host2.get( "id" ),
106 vlanId=vlanId )
kelvin-onlab44147802015-07-27 17:57:31 -0700107
Jeremydd9bda62016-04-18 12:02:32 -0700108 # Get all intents ID in the system, time delay right after intents are added
109 time.sleep( main.addIntentSleep )
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700110 intentsId = main.RESTs[ 0 ].getIntentsId()
111 except( KeyError, TypeError ):
Jeremydd9bda62016-04-18 12:02:32 -0700112 errorMsg = "There was a problem loading the hosts data."
113 if intentsId:
114 errorMsg += " There was a problem installing host to host intent."
115 main.log.error( errorMsg )
116 return main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700117
Jeremy Songster306ed7a2016-07-19 10:59:07 -0700118 if utilities.retry( f=checkIntentState, retValue=main.FALSE,
119 args=( main, intentsId ), sleep=main.checkIntentSleep, attempts=5 ):
120 main.assertReturnString += 'Install Intent State Passed\n'
121 if flowDuration( main ):
122 main.assertReturnString += 'Flow duration check Passed\n'
123 return intentsId
124 else:
125 main.assertReturnString += 'Flow duration check failed\n'
126 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -0800127 else:
128 main.log.error( "Host Intent did not install correctly" )
Jeremy Songster306ed7a2016-07-19 10:59:07 -0700129 main.assertReturnString += 'Install Intent State Failed\n'
Jeremy2f190ca2016-01-29 15:23:57 -0800130 return main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700131
Jon Hall02758ac2017-05-24 16:20:28 -0700132
Jeremy2f190ca2016-01-29 15:23:57 -0800133def testHostIntent( main,
134 name,
135 intentId,
136 host1,
137 host2,
138 onosNode=0,
139 sw1="s5",
140 sw2="s2",
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700141 expectedLink=0 ):
Jeremy2f190ca2016-01-29 15:23:57 -0800142 """
143 Test a Host Intent
kelvin-onlab44147802015-07-27 17:57:31 -0700144
Jeremy2f190ca2016-01-29 15:23:57 -0800145 Description:
146 Test a host intent of given ID between given hosts
kelvin-onlab44147802015-07-27 17:57:31 -0700147
Jeremy2f190ca2016-01-29 15:23:57 -0800148 Steps:
149 - Fetch host data if not given
150 - Check Intent State
151 - Check Flow State
152 - Check Connectivity
153 - Check Lack of Connectivity Between Hosts not in the Intent
154 - Reroute
155 - Take Expected Link Down
156 - Check Intent State
157 - Check Flow State
158 - Check Topology
159 - Check Connectivity
160 - Bring Expected Link Up
161 - Check Intent State
162 - Check Flow State
163 - Check Topology
164 - Check Connectivity
165 - Remove Topology
kelvin-onlab44147802015-07-27 17:57:31 -0700166
Jeremy2f190ca2016-01-29 15:23:57 -0800167 Required:
168 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
169 intentId - intent ID to be tested ( and removed )
170 host1 - Dictionary for host1
171 { "name":"h8", "id":"of:0000000000000005/8" }
172 host2 - Dictionary for host2
173 { "name":"h16", "id":"of:0000000000000006/8" }
174 Optional:
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700175 onosNode - ONOS node to install the intents in main.RESTs[ ]
Jeremy2f190ca2016-01-29 15:23:57 -0800176 0 by default so that it will always use the first
177 ONOS node
178 sw1 - First switch to bring down & up for rerouting purpose
179 sw2 - Second switch to bring down & up for rerouting purpose
180 expectedLink - Expected link when the switches are down, it should
181 be two links lower than the links before the two
182 switches are down
kelvin-onlab44147802015-07-27 17:57:31 -0700183
184 """
Jeremy2f190ca2016-01-29 15:23:57 -0800185 # Parameter Validity Check
kelvin-onlab44147802015-07-27 17:57:31 -0700186 assert main, "There is no main variable"
Jeremy2f190ca2016-01-29 15:23:57 -0800187 assert host1, "You must specify host1"
188 assert host2, "You must specify host2"
kelvin-onlab44147802015-07-27 17:57:31 -0700189
190 global itemName
191 itemName = name
Jeremy2f190ca2016-01-29 15:23:57 -0800192 tempHostsData = {}
kelvin-onlab44147802015-07-27 17:57:31 -0700193 onosNode = int( onosNode )
194
Jeremy2f190ca2016-01-29 15:23:57 -0800195 main.log.info( itemName + ": Testing Host Intent" )
kelvin-onlab44147802015-07-27 17:57:31 -0700196
Jeremydd9bda62016-04-18 12:02:32 -0700197 try:
198 if not host1.get( "id" ):
199 main.log.warn( "Id not given for host1 {0}. Loading from main.hostData".format( host1.get( "name" ) ) )
200 host1[ "id" ] = main.hostsData.get( host1.get( "name" ) ).get( "location" )
kelvin-onlab0e684682015-08-11 18:51:41 -0700201
Jeremydd9bda62016-04-18 12:02:32 -0700202 if not host2.get( "id" ):
203 main.log.warn( "Id not given for host2 {0}. Loading from main.hostData".format( host2.get( "name" ) ) )
204 host2[ "id" ] = main.hostsData.get( host2.get( "name" ) ).get( "location" )
kelvin-onlab44147802015-07-27 17:57:31 -0700205
Jeremydd9bda62016-04-18 12:02:32 -0700206 senderNames = [ host1.get( "name" ), host2.get( "name" ) ]
207 recipientNames = [ host1.get( "name" ), host2.get( "name" ) ]
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700208 vlanId = host1.get( "vlanId" )
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700209 except( KeyError, TypeError ):
Jeremydd9bda62016-04-18 12:02:32 -0700210 main.log.error( "There was a problem loading the hosts data." )
211 return main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700212
Jeremy2f190ca2016-01-29 15:23:57 -0800213 testResult = main.TRUE
214 main.log.info( itemName + ": Adding single point to multi point intents" )
215
216 # Check intent state
217 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
218 main.assertReturnString += 'Initial Intent State Passed\n'
219 else:
220 main.assertReturnString += 'Initial Intent State Failed\n'
221 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700222
223 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800224 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 -0800225 main.assertReturnString += 'Initial Flow State Passed\n'
226 else:
227 main.assertReturnString += 'Intial Flow State Failed\n'
228 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700229
Jeremy2f190ca2016-01-29 15:23:57 -0800230 # Check Connectivity
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700231 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId ) ):
Jeremy2f190ca2016-01-29 15:23:57 -0800232 main.assertReturnString += 'Initial Ping Passed\n'
233 else:
234 main.assertReturnString += 'Initial Ping Failed\n'
235 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700236
237 # Test rerouting if these variables exist
238 if sw1 and sw2 and expectedLink:
Jeremy2f190ca2016-01-29 15:23:57 -0800239 # Take link down
240 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "down" ) ):
241 main.assertReturnString += 'Link Down Passed\n'
242 else:
243 main.assertReturnString += 'Link Down Failed\n'
244 testResult = main.FALSE
245
246 # Check intent state
247 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
248 main.assertReturnString += 'Link Down Intent State Passed\n'
249 else:
250 main.assertReturnString += 'Link Down Intent State Failed\n'
251 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700252
253 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800254 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 -0800255 main.assertReturnString += 'Link Down Flow State Passed\n'
256 else:
257 main.assertReturnString += 'Link Down Flow State Failed\n'
258 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700259
260 # Check OnosTopology
Jeremybc6a0aa2016-02-05 14:10:08 -0800261 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, expectedLink ), sleep=10 ):
Jeremy2f190ca2016-01-29 15:23:57 -0800262 main.assertReturnString += 'Link Down Topology State Passed\n'
kelvin-onlab44147802015-07-27 17:57:31 -0700263 else:
Jeremy2f190ca2016-01-29 15:23:57 -0800264 main.assertReturnString += 'Link Down Topology State Failed\n'
265 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700266
Jeremy2f190ca2016-01-29 15:23:57 -0800267 # Check Connection
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700268 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId ) ):
Jeremy2f190ca2016-01-29 15:23:57 -0800269 main.assertReturnString += 'Link Down Pingall Passed\n'
270 else:
271 main.assertReturnString += 'Link Down Pingall Failed\n'
272 testResult = main.FALSE
273
274 # Bring link up
275 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "up" ) ):
276 main.assertReturnString += 'Link Up Passed\n'
277 else:
278 main.assertReturnString += 'Link Up Failed\n'
279 testResult = main.FALSE
280
281 # Wait for reroute
kelvin-onlab44147802015-07-27 17:57:31 -0700282 time.sleep( main.rerouteSleep )
283
Jeremy2f190ca2016-01-29 15:23:57 -0800284 # Check Intents
285 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
286 main.assertReturnString += 'Link Up Intent State Passed\n'
287 else:
288 main.assertReturnString += 'Link Up Intent State Failed\n'
289 testResult = main.FALSE
290
kelvin-onlab44147802015-07-27 17:57:31 -0700291 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800292 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 -0800293 main.assertReturnString += 'Link Up Flow State Passed\n'
294 else:
295 main.assertReturnString += 'Link Up Flow State Failed\n'
296 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700297
298 # Check OnosTopology
Jeremy2f190ca2016-01-29 15:23:57 -0800299 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, main.numLinks ) ):
300 main.assertReturnString += 'Link Up Topology State Passed\n'
kelvin-onlab44147802015-07-27 17:57:31 -0700301 else:
Jeremy2f190ca2016-01-29 15:23:57 -0800302 main.assertReturnString += 'Link Up Topology State Failed\n'
303 testResult = main.FALSE
304
305 # Check Connection
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700306 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId ) ):
Jeremy2f190ca2016-01-29 15:23:57 -0800307 main.assertReturnString += 'Link Up Pingall Passed\n'
308 else:
309 main.assertReturnString += 'Link Up Pingall Failed\n'
310 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700311
312 # Remove all intents
Jeremy2f190ca2016-01-29 15:23:57 -0800313 if utilities.retry( f=removeAllIntents, retValue=main.FALSE, args=( main, ) ):
314 main.assertReturnString += 'Remove Intents Passed'
315 else:
316 main.assertReturnString += 'Remove Intents Failed'
317 testResult = main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -0700318
Jeremy2f190ca2016-01-29 15:23:57 -0800319 return testResult
kelvin-onlab44147802015-07-27 17:57:31 -0700320
Jon Hall02758ac2017-05-24 16:20:28 -0700321
Jeremy2f190ca2016-01-29 15:23:57 -0800322def installPointIntent( main,
323 name,
324 senders,
325 recipients,
326 onosNode=0,
327 ethType="",
328 bandwidth="",
329 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -0800330 protected=False,
Jeremy2f190ca2016-01-29 15:23:57 -0800331 ipProto="",
332 ipSrc="",
333 ipDst="",
334 tcpSrc="",
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700335 tcpDst="" ):
Jeremy2f190ca2016-01-29 15:23:57 -0800336 """
337 Installs a Single to Single Point Intent
338
339 Description:
340 Install a single to single point intent
341
342 Steps:
343 - Fetch host data if not given
344 - Add point intent
345 - Ingress device is the first sender device
346 - Egress device is the first recipient device
347 - Ports if defined in senders or recipients
348 - MAC address ethSrc loaded from Ingress device
349 - Check intent state with retry
350 Required:
351 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
352 senders - List of host dictionaries i.e.
353 [ { "name":"h8", "device":"of:0000000000000005/8","mac":"00:00:00:00:00:08" } ]
354 recipients - List of host dictionaries i.e.
355 [ { "name":"h16", "device":"of:0000000000000006/8", "mac":"00:00:00:00:00:10" } ]
356 Optional:
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700357 onosNode - ONOS node to install the intents in main.RESTs[ ]
Jeremy2f190ca2016-01-29 15:23:57 -0800358 0 by default so that it will always use the first
359 ONOS node
360 ethType - Ethernet type eg. IPV4, IPV6
361 bandwidth - Bandwidth capacity
362 lambdaAlloc - Allocate lambda, defaults to False
363 ipProto - IP protocol
364 tcp - TCP ports in the same order as the hosts in hostNames
365 sw1 - First switch to bring down & up for rerouting purpose
366 sw2 - Second switch to bring down & up for rerouting purpose
367 expectedLink - Expected link when the switches are down, it should
368 be two links lower than the links before the two
369 switches are down
370 """
Jeremy2f190ca2016-01-29 15:23:57 -0800371 assert main, "There is no main variable"
372 assert senders, "You must specify a sender"
373 assert recipients, "You must specify a recipient"
374 # Assert devices or main.hostsData, "You must specify devices"
375
376 global itemName # The name of this run. Used for logs.
377 itemName = name
378 onosNode = int( onosNode )
379
380 main.log.info( itemName + ": Adding single to single point intents" )
381
Jeremydd9bda62016-04-18 12:02:32 -0700382 try:
383 for sender in senders:
384 if not sender.get( "device" ):
385 main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
386 sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )
Jeremy2f190ca2016-01-29 15:23:57 -0800387
Jeremydd9bda62016-04-18 12:02:32 -0700388 for recipient in recipients:
389 if not recipient.get( "device" ):
390 main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
391 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700392 vlanId = senders[ 0 ].get( "vlanId" )
Jeremy2f190ca2016-01-29 15:23:57 -0800393
Jeremydd9bda62016-04-18 12:02:32 -0700394 ingressDevice = senders[ 0 ].get( "device" )
395 egressDevice = recipients[ 0 ].get( "device" )
Jeremy2f190ca2016-01-29 15:23:57 -0800396
Jeremydd9bda62016-04-18 12:02:32 -0700397 portIngress = senders[ 0 ].get( "port", "" )
398 portEgress = recipients[ 0 ].get( "port", "" )
399 main.log.debug( ingressDevice )
400 main.log.debug( egressDevice )
Jeremy2f190ca2016-01-29 15:23:57 -0800401
Jeremydd9bda62016-04-18 12:02:32 -0700402 srcMac = senders[ 0 ].get( "mac" )
403 dstMac = recipients[ 0 ].get( "mac" )
Jeremy2f190ca2016-01-29 15:23:57 -0800404
Jeremydd9bda62016-04-18 12:02:32 -0700405 ipSrc = senders[ 0 ].get( "ip" )
406 ipDst = recipients[ 0 ].get( "ip" )
Jeremy2f190ca2016-01-29 15:23:57 -0800407
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700408 intent1 = main.RESTs[ onosNode ].addPointIntent(
Jeremydd9bda62016-04-18 12:02:32 -0700409 ingressDevice=ingressDevice,
410 egressDevice=egressDevice,
411 ingressPort=portIngress,
412 egressPort=portEgress,
413 ethType=ethType,
414 ethSrc=srcMac,
415 ethDst=dstMac,
416 bandwidth=bandwidth,
417 lambdaAlloc=lambdaAlloc,
alisonda157272016-12-22 01:13:21 -0800418 protected=protected,
Jeremydd9bda62016-04-18 12:02:32 -0700419 ipProto=ipProto,
420 ipSrc=ipSrc,
421 ipDst=ipDst,
422 tcpSrc=tcpSrc,
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700423 tcpDst=tcpDst,
424 vlanId=vlanId )
Jeremy2f190ca2016-01-29 15:23:57 -0800425
Jeremydd9bda62016-04-18 12:02:32 -0700426 time.sleep( main.addIntentSleep )
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700427 intentsId = main.RESTs[ 0 ].getIntentsId()
428 except( KeyError, TypeError ):
Jeremydd9bda62016-04-18 12:02:32 -0700429 errorMsg = "There was a problem loading the hosts data."
Jeremy Songster306ed7a2016-07-19 10:59:07 -0700430 if intentsId:
Jeremydd9bda62016-04-18 12:02:32 -0700431 errorMsg += " There was a problem installing Point to Point intent."
432 main.log.error( errorMsg )
433 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -0800434
Jeremydd9bda62016-04-18 12:02:32 -0700435 # Check intent state
Jeremy Songster306ed7a2016-07-19 10:59:07 -0700436 if utilities.retry( f=checkIntentState, retValue=main.FALSE,
437 args=( main, intentsId ), sleep=main.checkIntentSleep ):
438 main.assertReturnString += 'Install Intent State Passed\n'
439 if flowDuration( main ):
440 main.assertReturnString += 'Flow duration check Passed\n'
441 return intentsId
442 else:
443 main.assertReturnString += 'Flow duration check failed\n'
444 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -0800445 else:
Jeremy Songster306ed7a2016-07-19 10:59:07 -0700446 main.log.error( "Host Intent did not install correctly" )
447 main.assertReturnString += 'Install Intent State Failed\n'
Jeremy2f190ca2016-01-29 15:23:57 -0800448 return main.FALSE
449
Jon Hall02758ac2017-05-24 16:20:28 -0700450
Jeremy2f190ca2016-01-29 15:23:57 -0800451def testPointIntent( main,
452 name,
453 intentId,
454 senders,
455 recipients,
456 badSenders={},
457 badRecipients={},
458 onosNode=0,
459 ethType="",
460 bandwidth="",
461 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -0800462 protected=False,
Jeremy2f190ca2016-01-29 15:23:57 -0800463 ipProto="",
464 ipAddresses="",
465 tcp="",
466 sw1="s5",
467 sw2="s2",
Jeremy Songsterae2dd452016-05-17 16:44:35 -0700468 expectedLink=0,
469 useTCP=False ):
Jeremy2f190ca2016-01-29 15:23:57 -0800470 """
471 Test a Point Intent
472
473 Description:
474 Test a point intent
475
476 Steps:
477 - Fetch host data if not given
478 - Check Intent State
479 - Check Flow State
480 - Check Connectivity
481 - Check Lack of Connectivity Between Hosts not in the Intent
482 - Reroute
483 - Take Expected Link Down
484 - Check Intent State
485 - Check Flow State
486 - Check Topology
487 - Check Connectivity
488 - Bring Expected Link Up
489 - Check Intent State
490 - Check Flow State
491 - Check Topology
492 - Check Connectivity
493 - Remove Topology
494
495 Required:
496 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
497
498 senders - List of host dictionaries i.e.
499 { "name":"h8", "device":"of:0000000000000005/8","mac":"00:00:00:00:00:08" }
500 recipients - List of host dictionaries i.e.
501 { "name":"h16", "device":"of:0000000000000006/8", "mac":"00:00:00:00:00:10" }
502 Optional:
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700503 onosNode - ONOS node to install the intents in main.RESTs[ ]
Jeremy2f190ca2016-01-29 15:23:57 -0800504 0 by default so that it will always use the first
505 ONOS node
506 ethType - Ethernet type eg. IPV4, IPV6
507 bandwidth - Bandwidth capacity
508 lambdaAlloc - Allocate lambda, defaults to False
509 ipProto - IP protocol
510 tcp - TCP ports in the same order as the hosts in hostNames
511 sw1 - First switch to bring down & up for rerouting purpose
512 sw2 - Second switch to bring down & up for rerouting purpose
513 expectedLink - Expected link when the switches are down, it should
514 be two links lower than the links before the two
515 switches are down
516
517 """
Jeremy2f190ca2016-01-29 15:23:57 -0800518 # Parameter Validity Check
519 assert main, "There is no main variable"
520 assert senders, "You must specify a sender"
521 assert recipients, "You must specify a recipient"
522
523 global itemName
524 itemName = name
525 tempHostsData = {}
526 onosNode = int( onosNode )
527
528 main.log.info( itemName + ": Testing Point Intent" )
529
Jeremydd9bda62016-04-18 12:02:32 -0700530 try:
531 # Names for scapy
532 senderNames = [ x.get( "name" ) for x in senders ]
533 recipientNames = [ x.get( "name" ) for x in recipients ]
534 badSenderNames = [ x.get( "name" ) for x in badSenders ]
535 badRecipientNames = [ x.get( "name" ) for x in badRecipients ]
Jeremy2f190ca2016-01-29 15:23:57 -0800536
Jeremydd9bda62016-04-18 12:02:32 -0700537 for sender in senders:
538 if not sender.get( "device" ):
539 main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
540 sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )
Jeremy2f190ca2016-01-29 15:23:57 -0800541
Jeremydd9bda62016-04-18 12:02:32 -0700542 for recipient in recipients:
543 if not recipient.get( "device" ):
544 main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
545 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
Jon Hall02758ac2017-05-24 16:20:28 -0700546 vlanId = senders[ 0 ].get( "vlanId" )
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700547 except( KeyError, TypeError ):
Jeremydd9bda62016-04-18 12:02:32 -0700548 main.log.error( "There was a problem loading the hosts data." )
549 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -0800550
551 testResult = main.TRUE
552 main.log.info( itemName + ": Testing point intents" )
553
554 # Check intent state
555 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
556 main.assertReturnString += 'Initial Intent State Passed\n'
557 else:
558 main.assertReturnString += 'Initial Intent State Failed\n'
559 testResult = main.FALSE
560
561 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800562 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 -0800563 main.assertReturnString += 'Initial Flow State Passed\n'
564 else:
565 main.assertReturnString += 'Intial Flow State Failed\n'
566 testResult = main.FALSE
567
568 # Check Connectivity
Jon Hall02758ac2017-05-24 16:20:28 -0700569 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId, useTCP ) ):
Jeremy2f190ca2016-01-29 15:23:57 -0800570 main.assertReturnString += 'Initial Ping Passed\n'
571 else:
572 main.assertReturnString += 'Initial Ping Failed\n'
573 testResult = main.FALSE
574
575 # Check connections that shouldn't work
576 if badSenderNames:
577 main.log.info( "Checking that packets from incorrect sender do not go through" )
Jon Hall02758ac2017-05-24 16:20:28 -0700578 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, badSenderNames, recipientNames ), kwargs={ "expectFailure": True } ):
Jeremy2f190ca2016-01-29 15:23:57 -0800579 main.assertReturnString += 'Bad Sender Ping Passed\n'
580 else:
581 main.assertReturnString += 'Bad Sender Ping Failed\n'
582 testResult = main.FALSE
583
584 if badRecipientNames:
585 main.log.info( "Checking that packets to incorrect recipients do not go through" )
Jon Hall02758ac2017-05-24 16:20:28 -0700586 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, badRecipientNames ), kwargs={ "expectFailure": True } ):
Jeremy2f190ca2016-01-29 15:23:57 -0800587 main.assertReturnString += 'Bad Recipient Ping Passed\n'
588 else:
589 main.assertReturnString += 'Bad Recipient Ping Failed\n'
590 testResult = main.FALSE
591
592 # Test rerouting if these variables exist
593 if sw1 and sw2 and expectedLink:
594 # Take link down
595 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "down" ) ):
596 main.assertReturnString += 'Link Down Passed\n'
597 else:
598 main.assertReturnString += 'Link Down Failed\n'
599 testResult = main.FALSE
600
alisonda157272016-12-22 01:13:21 -0800601 if protected:
602 # Check Connection
Jon Hall02758ac2017-05-24 16:20:28 -0700603 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE,
604 args=( main, senderNames, recipientNames, vlanId, useTCP ) ):
alisonda157272016-12-22 01:13:21 -0800605 main.assertReturnString += 'Link down Scapy Packet Received Passed\n'
606 else:
607 main.assertReturnString += 'Link down Scapy Packet Recieved Failed\n'
608 testResult = main.FALSE
609
Jon Hall02758ac2017-05-24 16:20:28 -0700610 if ProtectedIntentCheck( main ):
alisonda157272016-12-22 01:13:21 -0800611 main.assertReturnString += 'Protected Intent Check Passed\n'
612 else:
613 main.assertReturnString += 'Protected Intent Check Failed\n'
614 testResult = main.FALSE
615
Jeremy2f190ca2016-01-29 15:23:57 -0800616 # Check intent state
617 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
618 main.assertReturnString += 'Link Down Intent State Passed\n'
619 else:
620 main.assertReturnString += 'Link Down 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 Down Flow State Passed\n'
626 else:
627 main.assertReturnString += 'Link Down Flow State Failed\n'
628 testResult = main.FALSE
629
630 # Check OnosTopology
Jeremybc6a0aa2016-02-05 14:10:08 -0800631 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, expectedLink ), sleep=10 ):
Jeremy2f190ca2016-01-29 15:23:57 -0800632 main.assertReturnString += 'Link Down Topology State Passed\n'
633 else:
634 main.assertReturnString += 'Link Down Topology State Failed\n'
635 testResult = main.FALSE
636
637 # Check Connection
Jon Hall02758ac2017-05-24 16:20:28 -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 Down Pingall Passed\n'
640 else:
641 main.assertReturnString += 'Link Down Pingall Failed\n'
642 testResult = main.FALSE
643
644 # Bring link up
645 if utilities.retry( f=link, retValue=main.FALSE, args=( main, sw1, sw2, "up" ) ):
646 main.assertReturnString += 'Link Up Passed\n'
647 else:
648 main.assertReturnString += 'Link Up Failed\n'
649 testResult = main.FALSE
650
651 # Wait for reroute
652 time.sleep( main.rerouteSleep )
653
654 # Check Intents
655 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentId ), sleep=main.checkIntentSleep ):
656 main.assertReturnString += 'Link Up Intent State Passed\n'
657 else:
658 main.assertReturnString += 'Link Up Intent State Failed\n'
659 testResult = main.FALSE
660
661 # Check flows count in each node
Jeremybc6a0aa2016-02-05 14:10:08 -0800662 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 -0800663 main.assertReturnString += 'Link Up Flow State Passed\n'
664 else:
665 main.assertReturnString += 'Link Up Flow State Failed\n'
666 testResult = main.FALSE
667
668 # Check OnosTopology
669 if utilities.retry( f=checkTopology, retValue=main.FALSE, args=( main, main.numLinks ) ):
670 main.assertReturnString += 'Link Up Topology State Passed\n'
671 else:
672 main.assertReturnString += 'Link Up Topology State Failed\n'
673 testResult = main.FALSE
674
675 # Check Connection
Jon Hall02758ac2017-05-24 16:20:28 -0700676 if utilities.retry( f=scapyCheckConnection, retValue=main.FALSE, args=( main, senderNames, recipientNames, vlanId, useTCP ) ):
Jeremy2f190ca2016-01-29 15:23:57 -0800677 main.assertReturnString += 'Link Up Scapy Packet Received Passed\n'
678 else:
679 main.assertReturnString += 'Link Up Scapy Packet Recieved Failed\n'
680 testResult = main.FALSE
681
682 # Remove all intents
683 if utilities.retry( f=removeAllIntents, retValue=main.FALSE, args=( main, ) ):
684 main.assertReturnString += 'Remove Intents Passed'
685 else:
686 main.assertReturnString += 'Remove Intents Failed'
687 testResult = main.FALSE
688
689 return testResult
kelvin-onlab44147802015-07-27 17:57:31 -0700690
Jon Hall02758ac2017-05-24 16:20:28 -0700691
kelvin-onlab0e684682015-08-11 18:51:41 -0700692def pointIntentTcp( main,
693 name,
694 host1,
695 host2,
696 onosNode=0,
697 deviceId1="",
698 deviceId2="",
699 port1="",
700 port2="",
701 ethType="",
702 mac1="",
703 mac2="",
704 bandwidth="",
705 lambdaAlloc=False,
706 ipProto="",
707 ip1="",
708 ip2="",
709 tcp1="",
710 tcp2="",
711 sw1="",
712 sw2="",
713 expectedLink=0 ):
kelvin-onlab0e684682015-08-11 18:51:41 -0700714 """
715 Description:
716 Verify add-point-intent only for TCP
717 Steps:
718 - Get device ids | ports
719 - Add point intents
720 - Check intents
721 - Verify flows
722 - Ping hosts
723 - Reroute
724 - Link down
725 - Verify flows
726 - Check topology
727 - Ping hosts
728 - Link up
729 - Verify flows
730 - Check topology
731 - Ping hosts
732 - Remove intents
733 Required:
734 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
735 host1 - Name of first host
736 host2 - Name of second host
737 Optional:
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700738 onosNode - ONOS node to install the intents in main.RESTs[ ]
kelvin-onlab0e684682015-08-11 18:51:41 -0700739 0 by default so that it will always use the first
740 ONOS node
741 deviceId1 - ONOS device id of the first switch, the same as the
742 location of the first host eg. of:0000000000000001/1,
743 located at device 1 port 1
744 deviceId2 - ONOS device id of the second switch
745 port1 - The port number where the first host is attached
746 port2 - The port number where the second host is attached
747 ethType - Ethernet type eg. IPV4, IPV6
748 mac1 - Mac address of first host
749 mac2 - Mac address of the second host
750 bandwidth - Bandwidth capacity
751 lambdaAlloc - Allocate lambda, defaults to False
752 ipProto - IP protocol
753 ip1 - IP address of first host
754 ip2 - IP address of second host
755 tcp1 - TCP port of first host
756 tcp2 - TCP port of second host
757 sw1 - First switch to bring down & up for rerouting purpose
758 sw2 - Second switch to bring down & up for rerouting purpose
759 expectedLink - Expected link when the switches are down, it should
760 be two links lower than the links before the two
761 switches are down
762 """
kelvin-onlab0e684682015-08-11 18:51:41 -0700763 assert main, "There is no main variable"
764 assert name, "variable name is empty"
765 assert host1 and host2, "You must specify hosts"
766
767 global itemName
768 itemName = name
769 host1 = host1
770 host2 = host2
771 hostNames = [ host1, host2 ]
772 intentsId = []
773
774 iperfResult = main.TRUE
775 intentResult = main.TRUE
776 removeIntentResult = main.TRUE
777 flowResult = main.TRUE
778 topoResult = main.TRUE
779 linkDownResult = main.TRUE
780 linkUpResult = main.TRUE
781 onosNode = int( onosNode )
782
783 # Adding bidirectional point intents
784 main.log.info( itemName + ": Adding point intents" )
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700785 intent1 = main.RESTs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
Jon Hall02758ac2017-05-24 16:20:28 -0700786 egressDevice=deviceId2,
787 ingressPort=port1,
788 egressPort=port2,
789 ethType=ethType,
790 ethSrc=mac1,
791 ethDst=mac2,
792 bandwidth=bandwidth,
793 lambdaAlloc=lambdaAlloc,
794 ipProto=ipProto,
795 ipSrc=ip1,
796 ipDst=ip2,
797 tcpSrc=tcp1,
798 tcpDst="" )
kelvin-onlab0e684682015-08-11 18:51:41 -0700799
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700800 intent2 = main.RESTs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
Jon Hall02758ac2017-05-24 16:20:28 -0700801 egressDevice=deviceId1,
802 ingressPort=port2,
803 egressPort=port1,
804 ethType=ethType,
805 ethSrc=mac2,
806 ethDst=mac1,
807 bandwidth=bandwidth,
808 lambdaAlloc=lambdaAlloc,
809 ipProto=ipProto,
810 ipSrc=ip2,
811 ipDst=ip1,
812 tcpSrc=tcp2,
813 tcpDst="" )
kelvin-onlab0e684682015-08-11 18:51:41 -0700814
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700815 intent3 = main.RESTs[ onosNode ].addPointIntent( ingressDevice=deviceId1,
Jon Hall02758ac2017-05-24 16:20:28 -0700816 egressDevice=deviceId2,
817 ingressPort=port1,
818 egressPort=port2,
819 ethType=ethType,
820 ethSrc=mac1,
821 ethDst=mac2,
822 bandwidth=bandwidth,
823 lambdaAlloc=lambdaAlloc,
824 ipProto=ipProto,
825 ipSrc=ip1,
826 ipDst=ip2,
827 tcpSrc="",
828 tcpDst=tcp2 )
kelvin-onlab0e684682015-08-11 18:51:41 -0700829
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700830 intent4 = main.RESTs[ onosNode ].addPointIntent( ingressDevice=deviceId2,
Jon Hall02758ac2017-05-24 16:20:28 -0700831 egressDevice=deviceId1,
832 ingressPort=port2,
833 egressPort=port1,
834 ethType=ethType,
835 ethSrc=mac2,
836 ethDst=mac1,
837 bandwidth=bandwidth,
838 lambdaAlloc=lambdaAlloc,
839 ipProto=ipProto,
840 ipSrc=ip2,
841 ipDst=ip1,
842 tcpSrc="",
843 tcpDst=tcp1 )
kelvin-onlab0e684682015-08-11 18:51:41 -0700844
845 # Get all intents ID in the system, time delay right after intents are added
846 time.sleep( main.addIntentSleep )
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700847 intentsId = main.RESTs[ 0 ].getIntentsId()
kelvin-onlab0e684682015-08-11 18:51:41 -0700848 # Check intents state
849 time.sleep( main.checkIntentSleep )
850 intentResult = checkIntentState( main, intentsId )
851 # Check flows count in each node
852 checkFlowsCount( main )
853
854 # Check intents state again if first check fails...
855 if not intentResult:
856 intentResult = checkIntentState( main, intentsId )
857
858 # Check flows count in each node
859 checkFlowsCount( main )
860
861 # Verify flows
862 checkFlowsState( main )
863
864 # Run iperf to both host
865 iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
866 host2, 10 )
867
868 # Test rerouting if these variables exist
869 if sw1 and sw2 and expectedLink:
870 # link down
871 linkDownResult = link( main, sw1, sw2, "down" )
872 intentResult = intentResult and checkIntentState( main, intentsId )
873
874 # Check flows count in each node
875 checkFlowsCount( main )
876 # Verify flows
877 checkFlowsState( main )
878
879 # Check OnosTopology
880 topoResult = checkTopology( main, expectedLink )
881
882 # Run iperf to both host
883 iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
884 host2, 10 )
885
886 intentResult = checkIntentState( main, intentsId )
887
888 # Checks ONOS state in link down
889 if linkDownResult and topoResult and iperfResult and intentResult:
890 main.log.info( itemName + ": Successfully brought link down" )
891 else:
892 main.log.error( itemName + ": Failed to bring link down" )
893
894 # link up
895 linkUpResult = link( main, sw1, sw2, "up" )
896 time.sleep( main.rerouteSleep )
897
898 # Check flows count in each node
899 checkFlowsCount( main )
900 # Verify flows
901 checkFlowsState( main )
902
903 # Check OnosTopology
904 topoResult = checkTopology( main, main.numLinks )
905
906 # Run iperf to both host
907 iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
908 host2, 10 )
909
910 intentResult = checkIntentState( main, intentsId )
911
912 # Checks ONOS state in link up
913 if linkUpResult and topoResult and iperfResult and intentResult:
914 main.log.info( itemName + ": Successfully brought link back up" )
915 else:
916 main.log.error( itemName + ": Failed to bring link back up" )
917
918 # Remove all intents
919 removeIntentResult = removeAllIntents( main )
920
921 stepResult = iperfResult and linkDownResult and linkUpResult \
922 and intentResult and removeIntentResult
923
924 return stepResult
925
Ming Yan Shuab2f7f52016-08-03 15:21:24 -0700926
927def installSingleToMultiIntent( main,
928 name,
929 senders,
930 recipients,
931 onosNode=0,
932 ethType="",
933 bandwidth="",
934 lambdaAlloc=False,
935 ipProto="",
936 ipAddresses="",
937 tcp="",
938 sw1="",
939 sw2="",
940 partial=False ):
kelvin-onlab44147802015-07-27 17:57:31 -0700941 """
942 Verify Single to Multi Point intents
943 NOTE:If main.hostsData is not defined, variables data should be passed
944 in the same order index wise. All devices in the list should have the
945 same format, either all the devices have its port or it doesn't.
946 eg. hostName = [ 'h1', 'h2' ,.. ]
Jon Hall02758ac2017-05-24 16:20:28 -0700947 devices = [ 'of:0000000000000001', 'of:0000000000000002', ... ]
948 ports = [ '1', '1', .. ]
kelvin-onlab44147802015-07-27 17:57:31 -0700949 ...
950 Description:
951 Verify add-single-to-multi-intent iterates through the list of given
952 host | devices and add intents
953 Steps:
954 - Get device ids | ports
955 - Add single to multi point intents
956 - Check intents
957 - Verify flows
958 - Ping hosts
959 - Reroute
960 - Link down
961 - Verify flows
962 - Check topology
963 - Ping hosts
964 - Link up
965 - Verify flows
966 - Check topology
967 - Ping hosts
968 - Remove intents
969 Required:
970 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
971 hostNames - List of host names
972 Optional:
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700973 onosNode - ONOS node to install the intents in main.RESTs[ ]
kelvin-onlab44147802015-07-27 17:57:31 -0700974 0 by default so that it will always use the first
975 ONOS node
976 devices - List of device ids in the same order as the hosts
977 in hostNames
978 ports - List of port numbers in the same order as the device in
979 devices
980 ethType - Ethernet type eg. IPV4, IPV6
981 macs - List of hosts mac address in the same order as the hosts in
982 hostNames
983 bandwidth - Bandwidth capacity
984 lambdaAlloc - Allocate lambda, defaults to False
985 ipProto - IP protocol
986 ipAddresses - IP addresses of host in the same order as the hosts in
987 hostNames
988 tcp - TCP ports in the same order as the hosts in hostNames
989 sw1 - First switch to bring down & up for rerouting purpose
990 sw2 - Second switch to bring down & up for rerouting purpose
991 expectedLink - Expected link when the switches are down, it should
992 be two links lower than the links before the two
993 switches are down
994 """
kelvin-onlab44147802015-07-27 17:57:31 -0700995 assert main, "There is no main variable"
Ming Yan Shuab2f7f52016-08-03 15:21:24 -0700996 assert senders, "You must specify a sender"
997 assert recipients, "You must specify a recipient"
998 # Assert devices or main.hostsData, "You must specify devices"
kelvin-onlab44147802015-07-27 17:57:31 -0700999
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001000 global itemName # The name of this run. Used for logs.
kelvin-onlab44147802015-07-27 17:57:31 -07001001 itemName = name
kelvin-onlab44147802015-07-27 17:57:31 -07001002 onosNode = int( onosNode )
1003
kelvin-onlab44147802015-07-27 17:57:31 -07001004 main.log.info( itemName + ": Adding single point to multi point intents" )
1005
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001006 try:
1007 for sender in senders:
1008 if not sender.get( "device" ):
1009 main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
1010 sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )
kelvin-onlab44147802015-07-27 17:57:31 -07001011
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001012 for recipient in recipients:
1013 if not recipient.get( "device" ):
1014 main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
1015 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
1016 vlanId = senders[ 0 ].get( "vlanId" )
kelvin-onlab44147802015-07-27 17:57:31 -07001017
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001018 ingressDevice = senders[ 0 ].get( "device" )
1019 egressDeviceList = [ x.get( "device" ) for x in recipients if x.get( "device" ) ]
1020
1021 portIngress = senders[ 0 ].get( "port", "" )
1022 portEgressList = [ x.get( "port" ) for x in recipients if x.get( "port" ) ]
1023 if not portEgressList:
1024 portEgressList = []
1025
1026 main.log.debug( ingressDevice )
1027 main.log.debug( egressDeviceList )
1028
1029 srcMac = senders[ 0 ].get( "mac" )
1030 dstMac = []
1031 for r in recipients:
1032 mac = r.get( "mac" )
1033 dstMac.append( mac )
1034
1035 ipSrc = senders[ 0 ].get( "ip" )
1036 ipDst = []
1037 for r in recipients:
1038 ip = r.get( "ip" )
1039 ipDst.append( ip )
1040
1041 # Adding point intent
1042 intentId = main.RESTs[ onosNode ].addSinglepointToMultipointIntent(
kelvin-onlab44147802015-07-27 17:57:31 -07001043 ingressDevice=ingressDevice,
1044 egressDeviceList=egressDeviceList,
1045 portIngress=portIngress,
1046 portEgressList=portEgressList,
1047 ethType=ethType,
1048 ethSrc=srcMac,
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001049 #ethDst=dstMac, #Isn't working because of ONOS itself
kelvin-onlab44147802015-07-27 17:57:31 -07001050 bandwidth=bandwidth,
1051 lambdaAlloc=lambdaAlloc,
1052 ipProto=ipProto,
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001053 ipSrc=ipSrc,
1054 ipDst=ipDst,
kelvin-onlab44147802015-07-27 17:57:31 -07001055 tcpSrc="",
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001056 tcpDst="",
1057 vlanId=vlanId,
1058 partial=partial )
kelvin-onlab44147802015-07-27 17:57:31 -07001059
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001060 time.sleep( main.addIntentSleep )
1061 intentsId = main.RESTs[ 0 ].getIntentsId()
1062 except ( KeyError, TypeError ):
1063 errorMsg = "There was a problem loading the hosts data."
1064 if intentId:
1065 errorMsg += " There was a problem installing Singlepoint to Multipoint intent."
1066 main.log.error( errorMsg )
1067 return main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -07001068
1069 # Check intents state
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001070 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentsId ), sleep=main.checkIntentSleep ):
1071 return intentsId
1072 else:
1073 main.log.error( "Single to Multi Intent did not install correctly" )
1074 return main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -07001075
Jon Hall02758ac2017-05-24 16:20:28 -07001076
kelvin-onlab44147802015-07-27 17:57:31 -07001077def multiToSingleIntent( main,
1078 name,
1079 hostNames,
1080 onosNode=0,
1081 devices="",
1082 ports=None,
1083 ethType="",
1084 macs=None,
1085 bandwidth="",
1086 lambdaAlloc=False,
1087 ipProto="",
1088 ipAddresses="",
1089 tcp="",
1090 sw1="",
1091 sw2="",
1092 expectedLink=0 ):
1093 """
1094 Verify Single to Multi Point intents
1095 NOTE:If main.hostsData is not defined, variables data should be passed in the
1096 same order index wise. All devices in the list should have the same
1097 format, either all the devices have its port or it doesn't.
1098 eg. hostName = [ 'h1', 'h2' ,.. ]
Jon Hall02758ac2017-05-24 16:20:28 -07001099 devices = [ 'of:0000000000000001', 'of:0000000000000002', ... ]
1100 ports = [ '1', '1', .. ]
kelvin-onlab44147802015-07-27 17:57:31 -07001101 ...
1102 Description:
1103 Verify add-multi-to-single-intent
1104 Steps:
1105 - Get device ids | ports
1106 - Add multi to single point intents
1107 - Check intents
1108 - Verify flows
1109 - Ping hosts
1110 - Reroute
1111 - Link down
1112 - Verify flows
1113 - Check topology
1114 - Ping hosts
1115 - Link up
1116 - Verify flows
1117 - Check topology
1118 - Ping hosts
1119 - Remove intents
1120 Required:
1121 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
1122 hostNames - List of host names
1123 Optional:
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001124 onosNode - ONOS node to install the intents in main.RESTs[ ]
kelvin-onlab44147802015-07-27 17:57:31 -07001125 0 by default so that it will always use the first
1126 ONOS node
1127 devices - List of device ids in the same order as the hosts
1128 in hostNames
1129 ports - List of port numbers in the same order as the device in
1130 devices
1131 ethType - Ethernet type eg. IPV4, IPV6
1132 macs - List of hosts mac address in the same order as the hosts in
1133 hostNames
1134 bandwidth - Bandwidth capacity
1135 lambdaAlloc - Allocate lambda, defaults to False
1136 ipProto - IP protocol
1137 ipAddresses - IP addresses of host in the same order as the hosts in
1138 hostNames
1139 tcp - TCP ports in the same order as the hosts in hostNames
1140 sw1 - First switch to bring down & up for rerouting purpose
1141 sw2 - Second switch to bring down & up for rerouting purpose
1142 expectedLink - Expected link when the switches are down, it should
1143 be two links lower than the links before the two
1144 switches are down
1145 """
kelvin-onlab44147802015-07-27 17:57:31 -07001146 assert main, "There is no main variable"
1147 assert hostNames, "You must specify hosts"
1148 assert devices or main.hostsData, "You must specify devices"
1149
1150 global itemName
1151 itemName = name
1152 tempHostsData = {}
1153 intentsId = []
1154 onosNode = int( onosNode )
1155
1156 macsDict = {}
1157 ipDict = {}
1158 if hostNames and devices:
1159 if len( hostNames ) != len( devices ):
1160 main.log.debug( "hosts and devices does not have the same length" )
1161 #print "len hostNames = ", len( hostNames )
1162 #print "len devices = ", len( devices )
1163 return main.FALSE
1164 if ports:
1165 if len( ports ) != len( devices ):
1166 main.log.error( "Ports and devices does " +
1167 "not have the same length" )
1168 #print "len devices = ", len( devices )
1169 #print "len ports = ", len( ports )
1170 return main.FALSE
1171 else:
1172 main.log.info( "Device Ports are not specified" )
1173 if macs:
1174 for i in range( len( devices ) ):
1175 macsDict[ devices[ i ] ] = macs[ i ]
1176 elif hostNames and not devices and main.hostsData:
1177 devices = []
1178 main.log.info( "multiToSingleIntent function is using main.hostsData" )
1179 for host in hostNames:
Jon Hall02758ac2017-05-24 16:20:28 -07001180 devices.append( main.hostsData.get( host ).get( 'location' ) )
1181 macsDict[ main.hostsData.get( host ).get( 'location' ) ] = \
1182 main.hostsData.get( host ).get( 'mac' )
1183 ipDict[ main.hostsData.get( host ).get( 'location' ) ] = \
1184 main.hostsData.get( host ).get( 'ipAddresses' )
kelvin-onlab44147802015-07-27 17:57:31 -07001185 #print main.hostsData
1186
1187 #print 'host names = ', hostNames
1188 #print 'devices = ', devices
1189 #print "macsDict = ", macsDict
1190
1191 pingResult = main.TRUE
1192 intentResult = main.TRUE
1193 removeIntentResult = main.TRUE
1194 flowResult = main.TRUE
1195 topoResult = main.TRUE
1196 linkDownResult = main.TRUE
1197 linkUpResult = main.TRUE
1198
1199 devicesCopy = copy.copy( devices )
1200 if ports:
1201 portsCopy = copy.copy( ports )
1202 main.log.info( itemName + ": Adding multi point to single point intents" )
1203
1204 # Check flows count in each node
1205 checkFlowsCount( main )
1206
1207 # Adding bidirectional point intents
1208 for i in range( len( devices ) ):
1209 egressDevice = devicesCopy[ i ]
1210 ingressDeviceList = copy.copy( devicesCopy )
1211 ingressDeviceList.remove( egressDevice )
1212 if ports:
1213 portEgress = portsCopy[ i ]
1214 portIngressList = copy.copy( portsCopy )
1215 del portIngressList[ i ]
1216 else:
1217 portEgress = ""
1218 portIngressList = None
1219 if not macsDict:
1220 dstMac = ""
1221 else:
1222 dstMac = macsDict[ egressDevice ]
Jon Hall02758ac2017-05-24 16:20:28 -07001223 if dstMac is None:
kelvin-onlab44147802015-07-27 17:57:31 -07001224 main.log.debug( "There is no MAC in device - " + egressDevice )
1225 dstMac = ""
1226
1227 intentsId.append(
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001228 main.RESTs[ onosNode ].addMultipointToSinglepointIntent(
kelvin-onlab44147802015-07-27 17:57:31 -07001229 ingressDeviceList=ingressDeviceList,
1230 egressDevice=egressDevice,
1231 portIngressList=portIngressList,
1232 portEgress=portEgress,
1233 ethType=ethType,
1234 ethDst=dstMac,
1235 bandwidth=bandwidth,
1236 lambdaAlloc=lambdaAlloc,
1237 ipProto=ipProto,
1238 ipSrc="",
1239 ipDst="",
1240 tcpSrc="",
1241 tcpDst="" ) )
1242
1243 pingResult = pingallHosts( main, hostNames )
1244
1245 # Check intents state
1246 time.sleep( main.checkIntentSleep )
1247 intentResult = checkIntentState( main, intentsId )
1248
1249 # Check intents state again if first check fails...
1250 if not intentResult:
1251 intentResult = checkIntentState( main, intentsId )
1252
1253 # Check flows count in each node
1254 checkFlowsCount( main )
1255 # Verify flows
1256 checkFlowsState( main )
1257
1258 # Ping hosts
1259 pingResult = pingResult and pingallHosts( main, hostNames )
1260 # Ping hosts again...
1261 pingResult = pingResult and pingallHosts( main, hostNames )
1262
1263 # Test rerouting if these variables exist
1264 if sw1 and sw2 and expectedLink:
1265 # link down
1266 linkDownResult = link( main, sw1, sw2, "down" )
1267 intentResult = intentResult and checkIntentState( main, intentsId )
1268
1269 # Check flows count in each node
1270 checkFlowsCount( main )
1271 # Verify flows
1272 checkFlowsState( main )
1273
1274 # Check OnosTopology
1275 topoResult = checkTopology( main, expectedLink )
1276
1277 # Ping hosts
1278 pingResult = pingResult and pingallHosts( main, hostNames )
1279
1280 intentResult = checkIntentState( main, intentsId )
1281
1282 # Checks ONOS state in link down
1283 if linkDownResult and topoResult and pingResult and intentResult:
1284 main.log.info( itemName + ": Successfully brought link down" )
1285 else:
1286 main.log.error( itemName + ": Failed to bring link down" )
1287
1288 # link up
1289 linkUpResult = link( main, sw1, sw2, "up" )
1290 time.sleep( main.rerouteSleep )
1291
1292 # Check flows count in each node
1293 checkFlowsCount( main )
1294 # Verify flows
1295 checkFlowsState( main )
1296
1297 # Check OnosTopology
1298 topoResult = checkTopology( main, main.numLinks )
1299
1300 # Ping hosts
1301 pingResult = pingResult and pingallHosts( main, hostNames )
1302
1303 intentResult = checkIntentState( main, intentsId )
1304
1305 # Checks ONOS state in link up
1306 if linkUpResult and topoResult and pingResult and intentResult:
1307 main.log.info( itemName + ": Successfully brought link back up" )
1308 else:
1309 main.log.error( itemName + ": Failed to bring link back up" )
1310
1311 # Remove all intents
1312 removeIntentResult = removeAllIntents( main, intentsId )
1313
1314 stepResult = pingResult and linkDownResult and linkUpResult \
1315 and intentResult and removeIntentResult
1316
1317 return stepResult
1318
Jon Hall02758ac2017-05-24 16:20:28 -07001319
kelvin-onlab0e684682015-08-11 18:51:41 -07001320def pingallHosts( main, hostList ):
kelvin-onlab44147802015-07-27 17:57:31 -07001321 # Ping all host in the hosts list variable
1322 print "Pinging : ", hostList
1323 pingResult = main.TRUE
kelvin-onlab0e684682015-08-11 18:51:41 -07001324 pingResult = main.Mininet1.pingallHosts( hostList )
kelvin-onlab44147802015-07-27 17:57:31 -07001325 return pingResult
1326
Jon Hall02758ac2017-05-24 16:20:28 -07001327
kelvin-onlab0e684682015-08-11 18:51:41 -07001328def getHostsData( main, hostList ):
kelvin-onlab44147802015-07-27 17:57:31 -07001329 """
1330 Use fwd app and pingall to discover all the hosts
1331 """
kelvin-onlab44147802015-07-27 17:57:31 -07001332 activateResult = main.TRUE
1333 appCheck = main.TRUE
1334 getDataResult = main.TRUE
1335 main.log.info( "Activating reactive forwarding app " )
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001336 activateResult = main.RESTs[ 0 ].activateApp( "org.onosproject.fwd" )
kelvin-onlab44147802015-07-27 17:57:31 -07001337 if not activateResult:
1338 main.log.error( "Something went wrong installing fwd app" )
1339 time.sleep( main.fwdSleep )
kelvin-onlab0e684682015-08-11 18:51:41 -07001340 if isinstance( hostList[ 0 ], types.StringType ):
1341 main.Mininet1.pingallHosts( hostList )
1342 elif isinstance( hostList[ 0 ], types.ListType ):
1343 for i in xrange( len( hostList ) ):
1344 main.Mininet1.pingallHosts( hostList[ i ] )
1345
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001346 hostsJson = json.loads( main.RESTs[ 0 ].hosts() )
kelvin-onlab44147802015-07-27 17:57:31 -07001347 hosts = main.Mininet1.getHosts().keys()
1348 # TODO: Make better use of new getHosts function
1349 for host in hosts:
1350 main.hostsData[ host ] = {}
1351 main.hostsData[ host ][ 'mac' ] = \
1352 main.Mininet1.getMacAddress( host ).upper()
1353 for hostj in hostsJson:
1354 if main.hostsData[ host ][ 'mac' ] == hostj[ 'mac' ]:
1355 main.hostsData[ host ][ 'id' ] = hostj[ 'id' ]
1356 main.hostsData[ host ][ 'vlan' ] = hostj[ 'vlan' ]
1357 main.hostsData[ host ][ 'location' ] = \
Jeremy Ronquillo0e538bc2017-06-13 15:16:09 -07001358 hostj[ 'locations' ][ 0 ][ 'elementId' ] + '/' + \
1359 hostj[ 'locations' ][ 0 ][ 'port' ]
kelvin-onlab44147802015-07-27 17:57:31 -07001360 main.hostsData[ host ][ 'ipAddresses' ] = hostj[ 'ipAddresses' ]
1361
1362 main.log.info( "Deactivating reactive forwarding app " )
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001363 deactivateResult = main.RESTs[ 0 ].deactivateApp( "org.onosproject.fwd" )
kelvin-onlab44147802015-07-27 17:57:31 -07001364 if activateResult and deactivateResult and main.hostsData:
1365 main.log.info( "Successfully used fwd app to discover hosts " )
1366 getDataResult = main.TRUE
1367 else:
1368 main.log.info( "Failed to use fwd app to discover hosts " )
1369 getDataResult = main.FALSE
1370
1371 print main.hostsData
1372
1373 return getDataResult
1374
Jon Hall02758ac2017-05-24 16:20:28 -07001375
kelvin-onlab44147802015-07-27 17:57:31 -07001376def checkTopology( main, expectedLink ):
1377 statusResult = main.TRUE
1378 # Check onos topology
1379 main.log.info( itemName + ": Checking ONOS topology " )
1380
1381 for i in range( main.numCtrls ):
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001382 statusResult = main.RESTs[ i ].checkStatus( main.numSwitch,
Jon Hall02758ac2017-05-24 16:20:28 -07001383 expectedLink )\
kelvin-onlab44147802015-07-27 17:57:31 -07001384 and statusResult
1385 if not statusResult:
1386 main.log.error( itemName + ": Topology mismatch" )
1387 else:
1388 main.log.info( itemName + ": Topology match" )
1389 return statusResult
1390
Jon Hall02758ac2017-05-24 16:20:28 -07001391
kelvin-onlab44147802015-07-27 17:57:31 -07001392def checkIntentState( main, intentsId ):
1393 """
1394 This function will check intent state to make sure all the intents
1395 are in INSTALLED state
1396 """
kelvin-onlab44147802015-07-27 17:57:31 -07001397 intentResult = main.TRUE
1398 results = []
1399
1400 main.log.info( itemName + ": Checking intents state" )
1401 # First check of intents
1402 for i in range( main.numCtrls ):
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001403 tempResult = main.RESTs[ i ].checkIntentState( intentsId=intentsId )
kelvin-onlab44147802015-07-27 17:57:31 -07001404 results.append( tempResult )
1405
1406 expectedState = [ 'INSTALLED', 'INSTALLING' ]
1407
1408 if all( result == main.TRUE for result in results ):
1409 main.log.info( itemName + ": Intents are installed correctly" )
1410 else:
1411 # Wait for at least 5 second before checking the intents again
Jeremy2f190ca2016-01-29 15:23:57 -08001412 main.log.error( "Intents are not installed correctly. Waiting 5 sec" )
kelvin-onlab44147802015-07-27 17:57:31 -07001413 time.sleep( 5 )
1414 results = []
1415 # Second check of intents since some of the intents may be in
1416 # INSTALLING state, they should be in INSTALLED at this time
1417 for i in range( main.numCtrls ):
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001418 tempResult = main.RESTs[ i ].checkIntentState( intentsId=intentsId )
kelvin-onlab44147802015-07-27 17:57:31 -07001419 results.append( tempResult )
1420 if all( result == main.TRUE for result in results ):
1421 main.log.info( itemName + ": Intents are installed correctly" )
Jeremy2f190ca2016-01-29 15:23:57 -08001422 intentResult = main.TRUE
kelvin-onlab44147802015-07-27 17:57:31 -07001423 else:
1424 main.log.error( itemName + ": Intents are NOT installed correctly" )
1425 intentResult = main.FALSE
1426
1427 return intentResult
1428
Jon Hall02758ac2017-05-24 16:20:28 -07001429
kelvin-onlab44147802015-07-27 17:57:31 -07001430def checkFlowsState( main ):
1431
1432 main.log.info( itemName + ": Check flows state" )
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001433 checkFlowsResult = main.RESTs[ 0 ].checkFlowsState()
kelvin-onlab44147802015-07-27 17:57:31 -07001434 return checkFlowsResult
1435
Jon Hall02758ac2017-05-24 16:20:28 -07001436
1437def link( main, sw1, sw2, option ):
kelvin-onlab44147802015-07-27 17:57:31 -07001438
1439 # link down
1440 main.log.info( itemName + ": Bring link " + option + "between " +
1441 sw1 + " and " + sw2 )
1442 linkResult = main.Mininet1.link( end1=sw1, end2=sw2, option=option )
1443 return linkResult
1444
Jon Hall02758ac2017-05-24 16:20:28 -07001445
kelvin-onlab44147802015-07-27 17:57:31 -07001446def removeAllIntents( main ):
1447 """
1448 Remove all intents in the intentsId
1449 """
kelvin-onlab44147802015-07-27 17:57:31 -07001450 onosSummary = []
1451 removeIntentResult = main.TRUE
1452 # Remove intents
Jon Hall02758ac2017-05-24 16:20:28 -07001453 removeIntentResult = main.RESTs[ 0 ].removeAllIntents()
kelvin-onlab44147802015-07-27 17:57:31 -07001454
1455 if removeIntentResult:
1456 main.log.info( itemName + ": There are no more intents remaining, " +
1457 "successfully removed all the intents." )
1458
1459 return removeIntentResult
1460
Jon Hall02758ac2017-05-24 16:20:28 -07001461
kelvin-onlab44147802015-07-27 17:57:31 -07001462def checkFlowsCount( main ):
1463 """
1464 Check flows count in each node
1465 """
kelvin-onlab44147802015-07-27 17:57:31 -07001466 flowsCount = []
1467 main.log.info( itemName + ": Checking flows count in each ONOS node" )
1468 for i in range( main.numCtrls ):
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001469 flowsCount.append( len( json.loads( main.RESTs[ i ].flows() ) ) )
kelvin-onlab44147802015-07-27 17:57:31 -07001470
1471 if flowsCount:
Jon Hall02758ac2017-05-24 16:20:28 -07001472 if all( flows == flowsCount[ 0 ] for flows in flowsCount ):
kelvin-onlab44147802015-07-27 17:57:31 -07001473 main.log.info( itemName + ": There are " + str( flowsCount[ 0 ] ) +
1474 " flows in all ONOS node" )
1475 else:
1476 for i in range( main.numCtrls ):
1477 main.log.debug( itemName + ": ONOS node " + str( i + 1 ) +
Jeremy2f190ca2016-01-29 15:23:57 -08001478 " has " + str( flowsCount[ i ] ) + " flows" )
kelvin-onlab44147802015-07-27 17:57:31 -07001479 else:
1480 main.log.error( "Checking flows count failed, check summary command" )
1481 return main.FALSE
1482
1483 return main.TRUE
1484
Jon Hall02758ac2017-05-24 16:20:28 -07001485
Jeremy2f190ca2016-01-29 15:23:57 -08001486def sendDiscoveryArp( main, hosts=None ):
1487 """
1488 Sends Discovery ARP packets from each host provided
1489 Defaults to each host in main.scapyHosts
1490 """
1491 # Send an arp ping from each host
1492 if not hosts:
1493 hosts = main.scapyHosts
1494 for host in hosts:
Jon Hall02758ac2017-05-24 16:20:28 -07001495 pkt = 'Ether( src="{0}")/ARP( psrc="{1}")'.format( host.hostMac, host.hostIp )
Jeremy2f190ca2016-01-29 15:23:57 -08001496 # Send from the VLAN interface if there is one so ONOS discovers the VLAN correctly
1497 iface = None
1498 for interface in host.getIfList():
1499 if '.' in interface:
1500 main.log.debug( "Detected VLAN interface {0}. Sending ARP packet from {0}".format( interface ) )
1501 iface = interface
1502 break
1503 host.sendPacket( packet=pkt, iface=iface )
1504 main.log.info( "Sending ARP packet from {0}".format( host.name ) )
1505
Jon Hall02758ac2017-05-24 16:20:28 -07001506
Jeremy2f190ca2016-01-29 15:23:57 -08001507def confirmHostDiscovery( main ):
1508 """
1509 Confirms that all ONOS nodes have discovered all scapy hosts
1510 """
1511 import collections
1512 scapyHostCount = len( main.scapyHosts )
Devin Lim58046fa2017-07-05 16:55:00 -07001513 try:
1514 from tests.dependencies.topology import Topology
1515 except Exception:
1516 main.log.error( "Topology not found exiting the test" )
1517 main.exit()
1518 try:
1519 main.topoRelated
1520 except ( NameError, AttributeError ):
1521 main.topoRelated = Topology()
1522 hosts = main.topoRelated.getAllHosts( main.numCtrls, False ) # Get host data from each ONOS node
Jeremy2f190ca2016-01-29 15:23:57 -08001523 hostFails = [] # Reset for each failed attempt
1524
1525 # Check for matching hosts on each node
1526 scapyHostIPs = [ x.hostIp for x in main.scapyHosts if x.hostIp != "0.0.0.0" ]
1527 for controller in range( main.numCtrls ):
1528 controllerStr = str( controller + 1 ) # ONOS node number
1529 # Compare Hosts
1530 # Load hosts data for controller node
Jeremydd9bda62016-04-18 12:02:32 -07001531 try:
1532 if hosts[ controller ]:
1533 main.log.info( "Hosts discovered" )
Jeremy2f190ca2016-01-29 15:23:57 -08001534 else:
Jeremydd9bda62016-04-18 12:02:32 -07001535 main.log.error( "Problem discovering hosts" )
1536 if hosts[ controller ] and "Error" not in hosts[ controller ]:
1537 try:
1538 hostData = json.loads( hosts[ controller ] )
1539 except ( TypeError, ValueError ):
1540 main.log.error( "Could not load json:" + str( hosts[ controller ] ) )
Jeremy2f190ca2016-01-29 15:23:57 -08001541 hostFails.append( controllerStr )
Jeremydd9bda62016-04-18 12:02:32 -07001542 else:
1543 onosHostIPs = [ x.get( "ipAddresses" )[ 0 ]
1544 for x in hostData
1545 if len( x.get( "ipAddresses" ) ) > 0 ]
Jon Hall02758ac2017-05-24 16:20:28 -07001546 if not set( collections.Counter( scapyHostIPs ) ).issubset( set( collections.Counter( onosHostIPs ) ) ):
Jeremydd9bda62016-04-18 12:02:32 -07001547 main.log.warn( "Controller {0} only sees nodes with {1} IPs. It should see all of the following: {2}".format( controllerStr, onosHostIPs, scapyHostIPs ) )
1548 hostFails.append( controllerStr )
1549 else:
1550 main.log.error( "Hosts returned nothing or an error." )
1551 hostFails.append( controllerStr )
1552 except IndexError:
1553 main.log.error( "Hosts returned nothing, Failed to discover hosts." )
1554 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -08001555
1556 if hostFails:
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001557 main.log.error( "List of failed ONOS Nodes:" + ', '.join( map( str, hostFails ) ) )
Jeremy2f190ca2016-01-29 15:23:57 -08001558 return main.FALSE
1559 else:
1560 return main.TRUE
1561
Jon Hall02758ac2017-05-24 16:20:28 -07001562
Jeremy2f190ca2016-01-29 15:23:57 -08001563def populateHostData( main ):
1564 """
1565 Populates hostsData
1566 """
1567 import json
1568 try:
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001569 hostsJson = json.loads( main.RESTs[ 0 ].hosts() )
Jeremy2f190ca2016-01-29 15:23:57 -08001570 hosts = main.Mininet1.getHosts().keys()
1571 # TODO: Make better use of new getHosts function
1572 for host in hosts:
1573 main.hostsData[ host ] = {}
1574 main.hostsData[ host ][ 'mac' ] = \
1575 main.Mininet1.getMacAddress( host ).upper()
1576 for hostj in hostsJson:
1577 if main.hostsData[ host ][ 'mac' ] == hostj[ 'mac' ]:
1578 main.hostsData[ host ][ 'id' ] = hostj[ 'id' ]
1579 main.hostsData[ host ][ 'vlan' ] = hostj[ 'vlan' ]
1580 main.hostsData[ host ][ 'location' ] = \
Jeremy Ronquillo0e538bc2017-06-13 15:16:09 -07001581 hostj[ 'locations' ][ 0 ][ 'elementId' ] + '/' + \
1582 hostj[ 'locations' ][ 0 ][ 'port' ]
Jeremy2f190ca2016-01-29 15:23:57 -08001583 main.hostsData[ host ][ 'ipAddresses' ] = hostj[ 'ipAddresses' ]
1584 return main.TRUE
Jeremydd9bda62016-04-18 12:02:32 -07001585 except ValueError:
1586 main.log.error( "ValueError while populating hostsData" )
1587 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -08001588 except KeyError:
Jon Hall02758ac2017-05-24 16:20:28 -07001589 main.log.error( "KeyError while populating hostsData" )
Jeremy2f190ca2016-01-29 15:23:57 -08001590 return main.FALSE
Jeremydd9bda62016-04-18 12:02:32 -07001591 except IndexError:
1592 main.log.error( "IndexError while populating hostsData" )
1593 return main.FALSE
1594 except TypeError:
1595 main.log.error( "TypeError while populating hostsData" )
1596 return main.FALSE
Jeremy2f190ca2016-01-29 15:23:57 -08001597
Jon Hall02758ac2017-05-24 16:20:28 -07001598
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001599def scapyCheckConnection( main, senders, recipients, vlanId=None, useTCP=False, packet=None, packetFilter=None, expectFailure=False ):
Jeremy2f190ca2016-01-29 15:23:57 -08001600 """
1601 Checks the connectivity between all given sender hosts and all given recipient hosts
1602 Packet may be specified. Defaults to Ether/IP packet
1603 Packet Filter may be specified. Defaults to Ether/IP from current sender MAC
1604 Todo: Optional packet and packet filter attributes for sender and recipients
1605 Expect Failure when the sender and recipient are not supposed to have connectivity
1606 Timeout of 1 second, returns main.TRUE if the filter is not triggered and kills the filter
1607
1608 """
1609 connectionsFunctional = main.TRUE
1610
1611 if not packetFilter:
1612 packetFilter = 'ether host {}'
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001613 if useTCP:
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001614 packetFilter += ' ip proto \\tcp tcp port {}'.format( main.params[ 'SDNIP' ][ 'dstPort' ] )
Jeremy2f190ca2016-01-29 15:23:57 -08001615 if expectFailure:
1616 timeout = 1
1617 else:
1618 timeout = 10
1619
1620 for sender in senders:
1621 try:
1622 senderComp = getattr( main, sender )
1623 except AttributeError:
1624 main.log.error( "main has no attribute {}".format( sender ) )
1625 connectionsFunctional = main.FALSE
1626 continue
1627
1628 for recipient in recipients:
1629 # Do not send packets to self since recipient CLI will already be busy
1630 if recipient == sender:
1631 continue
1632 try:
1633 recipientComp = getattr( main, recipient )
1634 except AttributeError:
1635 main.log.error( "main has no attribute {}".format( recipient ) )
1636 connectionsFunctional = main.FALSE
1637 continue
1638
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001639 if vlanId:
Jon Hall02758ac2017-05-24 16:20:28 -07001640 recipientComp.startFilter( pktFilter=( "vlan {}".format( vlanId ) + " && " + packetFilter.format( senderComp.hostMac ) ) )
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001641 else:
Jon Hall02758ac2017-05-24 16:20:28 -07001642 recipientComp.startFilter( pktFilter=packetFilter.format( senderComp.hostMac ) )
Jeremy2f190ca2016-01-29 15:23:57 -08001643
1644 if not packet:
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001645 if vlanId:
1646 pkt = 'Ether( src="{0}", dst="{2}" )/Dot1Q(vlan={4})/IP( src="{1}", dst="{3}" )'.format(
1647 senderComp.hostMac,
1648 senderComp.hostIp,
1649 recipientComp.hostMac,
1650 recipientComp.hostIp,
1651 vlanId )
1652 else:
1653 pkt = 'Ether( src="{0}", dst="{2}" )/IP( src="{1}", dst="{3}" )'.format(
1654 senderComp.hostMac,
1655 senderComp.hostIp,
1656 recipientComp.hostMac,
1657 recipientComp.hostIp )
Jeremy2f190ca2016-01-29 15:23:57 -08001658 else:
1659 pkt = packet
Jeremy Songsterae2dd452016-05-17 16:44:35 -07001660 if vlanId:
1661 senderComp.sendPacket( iface=( "{0}-eth0.{1}".format( sender, vlanId ) ), packet = pkt )
1662 else:
Jon Hall02758ac2017-05-24 16:20:28 -07001663 senderComp.sendPacket( packet=pkt )
Jeremy2f190ca2016-01-29 15:23:57 -08001664
1665 if recipientComp.checkFilter( timeout ):
1666 if expectFailure:
Jon Hall02758ac2017-05-24 16:20:28 -07001667 main.log.error( "Packet from {0} successfully received by {1} when it should not have been".format( sender, recipient ) )
Jeremy2f190ca2016-01-29 15:23:57 -08001668 connectionsFunctional = main.FALSE
1669 else:
Jon Hall02758ac2017-05-24 16:20:28 -07001670 main.log.info( "Packet from {0} successfully received by {1}".format( sender, recipient ) )
Jeremy2f190ca2016-01-29 15:23:57 -08001671 else:
1672 recipientComp.killFilter()
1673 if expectFailure:
Jon Hall02758ac2017-05-24 16:20:28 -07001674 main.log.info( "As expected, packet from {0} was not received by {1}".format( sender, recipient ) )
Jeremy2f190ca2016-01-29 15:23:57 -08001675 else:
Jon Hall02758ac2017-05-24 16:20:28 -07001676 main.log.error( "Packet from {0} was not received by {1}".format( sender, recipient ) )
Jeremy2f190ca2016-01-29 15:23:57 -08001677 connectionsFunctional = main.FALSE
1678
1679 return connectionsFunctional
1680
Jon Hall02758ac2017-05-24 16:20:28 -07001681
Jeremye1ea0602016-02-08 16:35:05 -08001682def checkLeaderChange( leaders1, leaders2 ):
1683 """
1684 Checks for a change in intent partition leadership.
1685
1686 Takes the output of leaders -c in json string format before and after
1687 a potential change as input
1688
1689 Returns main.TRUE if no mismatches are detected
1690 Returns main.FALSE if there is a mismatch or on error loading the input
1691 """
1692 try:
1693 leaders1 = json.loads( leaders1 )
1694 leaders2 = json.loads( leaders2 )
Jon Hall02758ac2017-05-24 16:20:28 -07001695 except ( AttributeError, TypeError ):
Jeremye1ea0602016-02-08 16:35:05 -08001696 main.log.exception( self.name + ": Object not as expected" )
1697 return main.FALSE
1698 except Exception:
1699 main.log.exception( self.name + ": Uncaught exception!" )
1700 main.cleanup()
1701 main.exit()
1702 main.log.info( "Checking Intent Paritions for Change in Leadership" )
1703 mismatch = False
1704 for dict1 in leaders1:
1705 if "intent" in dict1.get( "topic", [] ):
1706 for dict2 in leaders2:
1707 if dict1.get( "topic", 0 ) == dict2.get( "topic", 0 ) and \
Jon Hall02758ac2017-05-24 16:20:28 -07001708 dict1.get( "leader", 0 ) != dict2.get( "leader", 0 ):
Jeremye1ea0602016-02-08 16:35:05 -08001709 mismatch = True
Jon Hall02758ac2017-05-24 16:20:28 -07001710 main.log.error( "{0} changed leader from {1} to {2}".
1711 format( dict1.get( "topic", "no-topic" ),
1712 dict1.get( "leader", "no-leader" ),
1713 dict2.get( "leader", "no-leader" ) ) )
Jeremye1ea0602016-02-08 16:35:05 -08001714 if mismatch:
1715 return main.FALSE
1716 else:
1717 return main.TRUE
1718
1719
Jeremy2f190ca2016-01-29 15:23:57 -08001720def report( main ):
1721 """
1722 Report errors/warnings/exceptions
1723 """
1724 main.ONOSbench.logReport( main.ONOSip[ 0 ],
1725 [ "INFO",
1726 "FOLLOWER",
1727 "WARN",
1728 "flow",
1729 "ERROR",
1730 "Except" ],
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001731 "s" )
Jeremy2f190ca2016-01-29 15:23:57 -08001732
1733 main.log.info( "ERROR report: \n" )
1734 for i in range( main.numCtrls ):
1735 main.ONOSbench.logReport( main.ONOSip[ i ],
Jon Hall02758ac2017-05-24 16:20:28 -07001736 [ "ERROR" ],
1737 "d" )
Jeremy2f190ca2016-01-29 15:23:57 -08001738
1739 main.log.info( "EXCEPTIONS report: \n" )
1740 for i in range( main.numCtrls ):
1741 main.ONOSbench.logReport( main.ONOSip[ i ],
Jon Hall02758ac2017-05-24 16:20:28 -07001742 [ "Except" ],
1743 "d" )
Jeremy2f190ca2016-01-29 15:23:57 -08001744
1745 main.log.info( "WARNING report: \n" )
1746 for i in range( main.numCtrls ):
1747 main.ONOSbench.logReport( main.ONOSip[ i ],
Jon Hall02758ac2017-05-24 16:20:28 -07001748 [ "WARN" ],
1749 "d" )
1750
Jeremy Songster306ed7a2016-07-19 10:59:07 -07001751
1752def flowDuration( main ):
1753 """
1754 Check age of flows to see if flows are being overwritten
1755 """
1756 import time
1757 main.log.info( "Getting current flow durations" )
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001758 flowsJson1 = main.RESTs[ 0 ].flows()
Jeremy Songster306ed7a2016-07-19 10:59:07 -07001759 try:
1760 flowsJson1 = json.loads( flowsJson1 )
1761 except ValueError:
1762 main.log.error( "Unable to read flows" )
1763 return main.FALSE
1764 flowLife = []
1765 waitFlowLife = []
1766 for flow in flowsJson1:
1767 if flow[ 'appId' ] == "org.onosproject.net.intent":
1768 flowLife.append( flow[ 'life' ] )
1769 main.log.info( "Sleeping for {} seconds".format( main.flowDurationSleep ) )
1770 time.sleep( main.flowDurationSleep )
1771 main.log.info( "Getting new flow durations" )
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001772 flowsJson2 = main.RESTs[ 0 ].flows()
Jeremy Songster306ed7a2016-07-19 10:59:07 -07001773 try:
1774 flowsJson2 = json.loads( flowsJson2 )
1775 except ValueError:
1776 main.log.error( "Unable to read flows" )
1777 return main.FALSE
1778 for flow in flowsJson2:
1779 if flow[ 'appId' ] == "org.onosproject.net.intent":
1780 waitFlowLife.append( flow[ 'life' ] )
1781 main.log.info( "Determining whether flows where overwritten" )
1782 if len( flowLife ) == len( waitFlowLife ):
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001783 for i in range( len( flowLife ) ):
Jeremy Songster306ed7a2016-07-19 10:59:07 -07001784 if waitFlowLife[ i ] - flowLife[ i ] < main.flowDurationSleep:
1785 return main.FALSE
1786 else:
1787 return main.FALSE
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001788 return main.TRUE
alisonda157272016-12-22 01:13:21 -08001789
Jon Hall02758ac2017-05-24 16:20:28 -07001790
alisonda157272016-12-22 01:13:21 -08001791def ProtectedIntentCheck( main ):
1792 intent = main.RESTs[ 0 ].intents()
Jon Hall02758ac2017-05-24 16:20:28 -07001793 main.log.debug( intent )
alisonda157272016-12-22 01:13:21 -08001794 main.stop()
1795 if "Protection" in intent:
1796 return main.TRUE
1797 return main.FALSE