blob: 5f29037f548905397861656907a90f1e0625ccb4 [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
Devin Lim142b5342017-07-20 15:22:39 -0700104 intent1 = main.Cluster.active( onosNode ).REST.addHostIntent( hostIdOne=host1.get( "id" ),
105 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 )
Devin Lim142b5342017-07-20 15:22:39 -0700110 intentsId = main.Cluster.active( 0 ).REST.getIntentsId()
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700111 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
Devin Lim142b5342017-07-20 15:22:39 -0700408 intent1 = main.Cluster.active( onosNode ).REST.addPointIntent(
409 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,
418 protected=protected,
419 ipProto=ipProto,
420 ipSrc=ipSrc,
421 ipDst=ipDst,
422 tcpSrc=tcpSrc,
423 tcpDst=tcpDst,
424 vlanId=vlanId )
Jeremy2f190ca2016-01-29 15:23:57 -0800425
Jeremydd9bda62016-04-18 12:02:32 -0700426 time.sleep( main.addIntentSleep )
Devin Lim142b5342017-07-20 15:22:39 -0700427 intentsId = main.Cluster.active( 0 ).REST.getIntentsId()
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700428 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" )
Devin Lim142b5342017-07-20 15:22:39 -0700785 ctrl = main.Cluster.active( onosNode )
786 intent1 = ctrl.REST.addPointIntent( ingressDevice=deviceId1,
787 egressDevice=deviceId2,
788 ingressPort=port1,
789 egressPort=port2,
790 ethType=ethType,
791 ethSrc=mac1,
792 ethDst=mac2,
793 bandwidth=bandwidth,
794 lambdaAlloc=lambdaAlloc,
795 ipProto=ipProto,
796 ipSrc=ip1,
797 ipDst=ip2,
798 tcpSrc=tcp1,
799 tcpDst="" )
kelvin-onlab0e684682015-08-11 18:51:41 -0700800
Devin Lim142b5342017-07-20 15:22:39 -0700801 intent2 = ctrl.REST.addPointIntent( ingressDevice=deviceId2,
802 egressDevice=deviceId1,
803 ingressPort=port2,
804 egressPort=port1,
805 ethType=ethType,
806 ethSrc=mac2,
807 ethDst=mac1,
808 bandwidth=bandwidth,
809 lambdaAlloc=lambdaAlloc,
810 ipProto=ipProto,
811 ipSrc=ip2,
812 ipDst=ip1,
813 tcpSrc=tcp2,
814 tcpDst="" )
kelvin-onlab0e684682015-08-11 18:51:41 -0700815
Devin Lim142b5342017-07-20 15:22:39 -0700816 intent3 = ctrl.REST.addPointIntent( ingressDevice=deviceId1,
817 egressDevice=deviceId2,
818 ingressPort=port1,
819 egressPort=port2,
820 ethType=ethType,
821 ethSrc=mac1,
822 ethDst=mac2,
823 bandwidth=bandwidth,
824 lambdaAlloc=lambdaAlloc,
825 ipProto=ipProto,
826 ipSrc=ip1,
827 ipDst=ip2,
828 tcpSrc="",
829 tcpDst=tcp2 )
kelvin-onlab0e684682015-08-11 18:51:41 -0700830
Devin Lim142b5342017-07-20 15:22:39 -0700831 intent4 = ctrl.REST.addPointIntent( ingressDevice=deviceId2,
832 egressDevice=deviceId1,
833 ingressPort=port2,
834 egressPort=port1,
835 ethType=ethType,
836 ethSrc=mac2,
837 ethDst=mac1,
838 bandwidth=bandwidth,
839 lambdaAlloc=lambdaAlloc,
840 ipProto=ipProto,
841 ipSrc=ip2,
842 ipDst=ip1,
843 tcpSrc="",
844 tcpDst=tcp1 )
kelvin-onlab0e684682015-08-11 18:51:41 -0700845
846 # Get all intents ID in the system, time delay right after intents are added
847 time.sleep( main.addIntentSleep )
Devin Lim142b5342017-07-20 15:22:39 -0700848 intentsId = main.Cluster.active( 0 ).REST.getIntentsId()
kelvin-onlab0e684682015-08-11 18:51:41 -0700849 # Check intents state
850 time.sleep( main.checkIntentSleep )
851 intentResult = checkIntentState( main, intentsId )
852 # Check flows count in each node
853 checkFlowsCount( main )
854
855 # Check intents state again if first check fails...
856 if not intentResult:
857 intentResult = checkIntentState( main, intentsId )
858
859 # Check flows count in each node
860 checkFlowsCount( main )
861
862 # Verify flows
863 checkFlowsState( main )
864
865 # Run iperf to both host
866 iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
867 host2, 10 )
868
869 # Test rerouting if these variables exist
870 if sw1 and sw2 and expectedLink:
871 # link down
872 linkDownResult = link( main, sw1, sw2, "down" )
873 intentResult = intentResult and checkIntentState( main, intentsId )
874
875 # Check flows count in each node
876 checkFlowsCount( main )
877 # Verify flows
878 checkFlowsState( main )
879
880 # Check OnosTopology
881 topoResult = checkTopology( main, expectedLink )
882
883 # Run iperf to both host
884 iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
885 host2, 10 )
886
887 intentResult = checkIntentState( main, intentsId )
888
889 # Checks ONOS state in link down
890 if linkDownResult and topoResult and iperfResult and intentResult:
891 main.log.info( itemName + ": Successfully brought link down" )
892 else:
893 main.log.error( itemName + ": Failed to bring link down" )
894
895 # link up
896 linkUpResult = link( main, sw1, sw2, "up" )
897 time.sleep( main.rerouteSleep )
898
899 # Check flows count in each node
900 checkFlowsCount( main )
901 # Verify flows
902 checkFlowsState( main )
903
904 # Check OnosTopology
905 topoResult = checkTopology( main, main.numLinks )
906
907 # Run iperf to both host
908 iperfResult = iperfResult and main.Mininet1.iperftcp( host1,
909 host2, 10 )
910
911 intentResult = checkIntentState( main, intentsId )
912
913 # Checks ONOS state in link up
914 if linkUpResult and topoResult and iperfResult and intentResult:
915 main.log.info( itemName + ": Successfully brought link back up" )
916 else:
917 main.log.error( itemName + ": Failed to bring link back up" )
918
919 # Remove all intents
920 removeIntentResult = removeAllIntents( main )
921
922 stepResult = iperfResult and linkDownResult and linkUpResult \
923 and intentResult and removeIntentResult
924
925 return stepResult
926
Ming Yan Shuab2f7f52016-08-03 15:21:24 -0700927
928def installSingleToMultiIntent( main,
929 name,
930 senders,
931 recipients,
932 onosNode=0,
933 ethType="",
934 bandwidth="",
935 lambdaAlloc=False,
936 ipProto="",
937 ipAddresses="",
938 tcp="",
939 sw1="",
940 sw2="",
941 partial=False ):
kelvin-onlab44147802015-07-27 17:57:31 -0700942 """
943 Verify Single to Multi Point intents
944 NOTE:If main.hostsData is not defined, variables data should be passed
945 in the same order index wise. All devices in the list should have the
946 same format, either all the devices have its port or it doesn't.
947 eg. hostName = [ 'h1', 'h2' ,.. ]
Jon Hall02758ac2017-05-24 16:20:28 -0700948 devices = [ 'of:0000000000000001', 'of:0000000000000002', ... ]
949 ports = [ '1', '1', .. ]
kelvin-onlab44147802015-07-27 17:57:31 -0700950 ...
951 Description:
952 Verify add-single-to-multi-intent iterates through the list of given
953 host | devices and add intents
954 Steps:
955 - Get device ids | ports
956 - Add single to multi point intents
957 - Check intents
958 - Verify flows
959 - Ping hosts
960 - Reroute
961 - Link down
962 - Verify flows
963 - Check topology
964 - Ping hosts
965 - Link up
966 - Verify flows
967 - Check topology
968 - Ping hosts
969 - Remove intents
970 Required:
971 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
972 hostNames - List of host names
973 Optional:
Jeremy Songstere7f3b342016-08-17 14:56:49 -0700974 onosNode - ONOS node to install the intents in main.RESTs[ ]
kelvin-onlab44147802015-07-27 17:57:31 -0700975 0 by default so that it will always use the first
976 ONOS node
977 devices - List of device ids in the same order as the hosts
978 in hostNames
979 ports - List of port numbers in the same order as the device in
980 devices
981 ethType - Ethernet type eg. IPV4, IPV6
982 macs - List of hosts mac address in the same order as the hosts in
983 hostNames
984 bandwidth - Bandwidth capacity
985 lambdaAlloc - Allocate lambda, defaults to False
986 ipProto - IP protocol
987 ipAddresses - IP addresses of host in the same order as the hosts in
988 hostNames
989 tcp - TCP ports in the same order as the hosts in hostNames
990 sw1 - First switch to bring down & up for rerouting purpose
991 sw2 - Second switch to bring down & up for rerouting purpose
992 expectedLink - Expected link when the switches are down, it should
993 be two links lower than the links before the two
994 switches are down
995 """
kelvin-onlab44147802015-07-27 17:57:31 -0700996 assert main, "There is no main variable"
Ming Yan Shuab2f7f52016-08-03 15:21:24 -0700997 assert senders, "You must specify a sender"
998 assert recipients, "You must specify a recipient"
999 # Assert devices or main.hostsData, "You must specify devices"
kelvin-onlab44147802015-07-27 17:57:31 -07001000
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001001 global itemName # The name of this run. Used for logs.
kelvin-onlab44147802015-07-27 17:57:31 -07001002 itemName = name
kelvin-onlab44147802015-07-27 17:57:31 -07001003 onosNode = int( onosNode )
1004
kelvin-onlab44147802015-07-27 17:57:31 -07001005 main.log.info( itemName + ": Adding single point to multi point intents" )
1006
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001007 try:
1008 for sender in senders:
1009 if not sender.get( "device" ):
1010 main.log.warn( "Device not given for sender {0}. Loading from main.hostData".format( sender.get( "name" ) ) )
1011 sender[ "device" ] = main.hostsData.get( sender.get( "name" ) ).get( "location" )
kelvin-onlab44147802015-07-27 17:57:31 -07001012
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001013 for recipient in recipients:
1014 if not recipient.get( "device" ):
1015 main.log.warn( "Device not given for recipient {0}. Loading from main.hostData".format( recipient.get( "name" ) ) )
1016 recipient[ "device" ] = main.hostsData.get( recipient.get( "name" ) ).get( "location" )
1017 vlanId = senders[ 0 ].get( "vlanId" )
kelvin-onlab44147802015-07-27 17:57:31 -07001018
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001019 ingressDevice = senders[ 0 ].get( "device" )
1020 egressDeviceList = [ x.get( "device" ) for x in recipients if x.get( "device" ) ]
1021
1022 portIngress = senders[ 0 ].get( "port", "" )
1023 portEgressList = [ x.get( "port" ) for x in recipients if x.get( "port" ) ]
1024 if not portEgressList:
1025 portEgressList = []
1026
1027 main.log.debug( ingressDevice )
1028 main.log.debug( egressDeviceList )
1029
1030 srcMac = senders[ 0 ].get( "mac" )
1031 dstMac = []
1032 for r in recipients:
1033 mac = r.get( "mac" )
1034 dstMac.append( mac )
1035
1036 ipSrc = senders[ 0 ].get( "ip" )
1037 ipDst = []
1038 for r in recipients:
1039 ip = r.get( "ip" )
1040 ipDst.append( ip )
1041
1042 # Adding point intent
Devin Lim142b5342017-07-20 15:22:39 -07001043 intentId = main.Cluster.active( onosNode ).REST.addSinglepointToMultipointIntent(
1044 ingressDevice=ingressDevice,
1045 egressDeviceList=egressDeviceList,
1046 portIngress=portIngress,
1047 portEgressList=portEgressList,
1048 ethType=ethType,
1049 ethSrc=srcMac,
1050 #ethDst=dstMac, #Isn't working because of ONOS itself
1051 bandwidth=bandwidth,
1052 lambdaAlloc=lambdaAlloc,
1053 ipProto=ipProto,
1054 ipSrc=ipSrc,
1055 ipDst=ipDst,
1056 tcpSrc="",
1057 tcpDst="",
1058 vlanId=vlanId,
1059 partial=partial )
kelvin-onlab44147802015-07-27 17:57:31 -07001060
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001061 time.sleep( main.addIntentSleep )
Devin Lim142b5342017-07-20 15:22:39 -07001062 intentsId = main.Cluster.active( 0 ).REST.getIntentsId()
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001063 except ( KeyError, TypeError ):
1064 errorMsg = "There was a problem loading the hosts data."
1065 if intentId:
1066 errorMsg += " There was a problem installing Singlepoint to Multipoint intent."
1067 main.log.error( errorMsg )
1068 return main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -07001069
1070 # Check intents state
Ming Yan Shuab2f7f52016-08-03 15:21:24 -07001071 if utilities.retry( f=checkIntentState, retValue=main.FALSE, args=( main, intentsId ), sleep=main.checkIntentSleep ):
1072 return intentsId
1073 else:
1074 main.log.error( "Single to Multi Intent did not install correctly" )
1075 return main.FALSE
kelvin-onlab44147802015-07-27 17:57:31 -07001076
Jon Hall02758ac2017-05-24 16:20:28 -07001077
kelvin-onlab44147802015-07-27 17:57:31 -07001078def multiToSingleIntent( main,
1079 name,
1080 hostNames,
1081 onosNode=0,
1082 devices="",
1083 ports=None,
1084 ethType="",
1085 macs=None,
1086 bandwidth="",
1087 lambdaAlloc=False,
1088 ipProto="",
1089 ipAddresses="",
1090 tcp="",
1091 sw1="",
1092 sw2="",
1093 expectedLink=0 ):
1094 """
1095 Verify Single to Multi Point intents
1096 NOTE:If main.hostsData is not defined, variables data should be passed in the
1097 same order index wise. All devices in the list should have the same
1098 format, either all the devices have its port or it doesn't.
1099 eg. hostName = [ 'h1', 'h2' ,.. ]
Jon Hall02758ac2017-05-24 16:20:28 -07001100 devices = [ 'of:0000000000000001', 'of:0000000000000002', ... ]
1101 ports = [ '1', '1', .. ]
kelvin-onlab44147802015-07-27 17:57:31 -07001102 ...
1103 Description:
1104 Verify add-multi-to-single-intent
1105 Steps:
1106 - Get device ids | ports
1107 - Add multi to single point intents
1108 - Check intents
1109 - Verify flows
1110 - Ping hosts
1111 - Reroute
1112 - Link down
1113 - Verify flows
1114 - Check topology
1115 - Ping hosts
1116 - Link up
1117 - Verify flows
1118 - Check topology
1119 - Ping hosts
1120 - Remove intents
1121 Required:
1122 name - Type of point intent to add eg. IPV4 | VLAN | Dualstack
1123 hostNames - List of host names
1124 Optional:
Jeremy Songstere7f3b342016-08-17 14:56:49 -07001125 onosNode - ONOS node to install the intents in main.RESTs[ ]
kelvin-onlab44147802015-07-27 17:57:31 -07001126 0 by default so that it will always use the first
1127 ONOS node
1128 devices - List of device ids in the same order as the hosts
1129 in hostNames
1130 ports - List of port numbers in the same order as the device in
1131 devices
1132 ethType - Ethernet type eg. IPV4, IPV6
1133 macs - List of hosts mac address in the same order as the hosts in
1134 hostNames
1135 bandwidth - Bandwidth capacity
1136 lambdaAlloc - Allocate lambda, defaults to False
1137 ipProto - IP protocol
1138 ipAddresses - IP addresses of host in the same order as the hosts in
1139 hostNames
1140 tcp - TCP ports in the same order as the hosts in hostNames
1141 sw1 - First switch to bring down & up for rerouting purpose
1142 sw2 - Second switch to bring down & up for rerouting purpose
1143 expectedLink - Expected link when the switches are down, it should
1144 be two links lower than the links before the two
1145 switches are down
1146 """
kelvin-onlab44147802015-07-27 17:57:31 -07001147 assert main, "There is no main variable"
1148 assert hostNames, "You must specify hosts"
1149 assert devices or main.hostsData, "You must specify devices"
1150
1151 global itemName
1152 itemName = name
1153 tempHostsData = {}
1154 intentsId = []
1155 onosNode = int( onosNode )
1156
1157 macsDict = {}
1158 ipDict = {}
1159 if hostNames and devices:
1160 if len( hostNames ) != len( devices ):
1161 main.log.debug( "hosts and devices does not have the same length" )
1162 #print "len hostNames = ", len( hostNames )
1163 #print "len devices = ", len( devices )
1164 return main.FALSE
1165 if ports:
1166 if len( ports ) != len( devices ):
1167 main.log.error( "Ports and devices does " +
1168 "not have the same length" )
1169 #print "len devices = ", len( devices )
1170 #print "len ports = ", len( ports )
1171 return main.FALSE
1172 else:
1173 main.log.info( "Device Ports are not specified" )
1174 if macs:
1175 for i in range( len( devices ) ):
1176 macsDict[ devices[ i ] ] = macs[ i ]
1177 elif hostNames and not devices and main.hostsData:
1178 devices = []
1179 main.log.info( "multiToSingleIntent function is using main.hostsData" )
1180 for host in hostNames:
Jon Hall02758ac2017-05-24 16:20:28 -07001181 devices.append( main.hostsData.get( host ).get( 'location' ) )
1182 macsDict[ main.hostsData.get( host ).get( 'location' ) ] = \
1183 main.hostsData.get( host ).get( 'mac' )
1184 ipDict[ main.hostsData.get( host ).get( 'location' ) ] = \
1185 main.hostsData.get( host ).get( 'ipAddresses' )
kelvin-onlab44147802015-07-27 17:57:31 -07001186 #print main.hostsData
1187
1188 #print 'host names = ', hostNames
1189 #print 'devices = ', devices
1190 #print "macsDict = ", macsDict
1191
1192 pingResult = main.TRUE
1193 intentResult = main.TRUE
1194 removeIntentResult = main.TRUE
1195 flowResult = main.TRUE
1196 topoResult = main.TRUE
1197 linkDownResult = main.TRUE
1198 linkUpResult = main.TRUE
1199
1200 devicesCopy = copy.copy( devices )
1201 if ports:
1202 portsCopy = copy.copy( ports )
1203 main.log.info( itemName + ": Adding multi point to single point intents" )
1204
1205 # Check flows count in each node
1206 checkFlowsCount( main )
1207
1208 # Adding bidirectional point intents
1209 for i in range( len( devices ) ):
1210 egressDevice = devicesCopy[ i ]
1211 ingressDeviceList = copy.copy( devicesCopy )
1212 ingressDeviceList.remove( egressDevice )
1213 if ports:
1214 portEgress = portsCopy[ i ]
1215 portIngressList = copy.copy( portsCopy )
1216 del portIngressList[ i ]
1217 else:
1218 portEgress = ""
1219 portIngressList = None
1220 if not macsDict:
1221 dstMac = ""
1222 else:
1223 dstMac = macsDict[ egressDevice ]
Jon Hall02758ac2017-05-24 16:20:28 -07001224 if dstMac is None:
kelvin-onlab44147802015-07-27 17:57:31 -07001225 main.log.debug( "There is no MAC in device - " + egressDevice )
1226 dstMac = ""
1227
1228 intentsId.append(
Devin Lim142b5342017-07-20 15:22:39 -07001229 main.Cluster.active( onosNode ).REST.addMultipointToSinglepointIntent(
1230 ingressDeviceList=ingressDeviceList,
1231 egressDevice=egressDevice,
1232 portIngressList=portIngressList,
1233 portEgress=portEgress,
1234 ethType=ethType,
1235 ethDst=dstMac,
1236 bandwidth=bandwidth,
1237 lambdaAlloc=lambdaAlloc,
1238 ipProto=ipProto,
1239 ipSrc="",
1240 ipDst="",
1241 tcpSrc="",
1242 tcpDst="" ) )
kelvin-onlab44147802015-07-27 17:57:31 -07001243
1244 pingResult = pingallHosts( main, hostNames )
1245
1246 # Check intents state
1247 time.sleep( main.checkIntentSleep )
1248 intentResult = checkIntentState( main, intentsId )
1249
1250 # Check intents state again if first check fails...
1251 if not intentResult:
1252 intentResult = checkIntentState( main, intentsId )
1253
1254 # Check flows count in each node
1255 checkFlowsCount( main )
1256 # Verify flows
1257 checkFlowsState( main )
1258
1259 # Ping hosts
1260 pingResult = pingResult and pingallHosts( main, hostNames )
1261 # Ping hosts again...
1262 pingResult = pingResult and pingallHosts( main, hostNames )
1263
1264 # Test rerouting if these variables exist
1265 if sw1 and sw2 and expectedLink:
1266 # link down
1267 linkDownResult = link( main, sw1, sw2, "down" )
1268 intentResult = intentResult and checkIntentState( main, intentsId )
1269
1270 # Check flows count in each node
1271 checkFlowsCount( main )
1272 # Verify flows
1273 checkFlowsState( main )
1274
1275 # Check OnosTopology
1276 topoResult = checkTopology( main, expectedLink )
1277
1278 # Ping hosts
1279 pingResult = pingResult and pingallHosts( main, hostNames )
1280
1281 intentResult = checkIntentState( main, intentsId )
1282
1283 # Checks ONOS state in link down
1284 if linkDownResult and topoResult and pingResult and intentResult:
1285 main.log.info( itemName + ": Successfully brought link down" )
1286 else:
1287 main.log.error( itemName + ": Failed to bring link down" )
1288
1289 # link up
1290 linkUpResult = link( main, sw1, sw2, "up" )
1291 time.sleep( main.rerouteSleep )
1292
1293 # Check flows count in each node
1294 checkFlowsCount( main )
1295 # Verify flows
1296 checkFlowsState( main )
1297
1298 # Check OnosTopology
1299 topoResult = checkTopology( main, main.numLinks )
1300
1301 # Ping hosts
1302 pingResult = pingResult and pingallHosts( main, hostNames )
1303
1304 intentResult = checkIntentState( main, intentsId )
1305
1306 # Checks ONOS state in link up
1307 if linkUpResult and topoResult and pingResult and intentResult:
1308 main.log.info( itemName + ": Successfully brought link back up" )
1309 else:
1310 main.log.error( itemName + ": Failed to bring link back up" )
1311
1312 # Remove all intents
1313 removeIntentResult = removeAllIntents( main, intentsId )
1314
1315 stepResult = pingResult and linkDownResult and linkUpResult \
1316 and intentResult and removeIntentResult
1317
1318 return stepResult
1319
Jon Hall02758ac2017-05-24 16:20:28 -07001320
kelvin-onlab0e684682015-08-11 18:51:41 -07001321def pingallHosts( main, hostList ):
kelvin-onlab44147802015-07-27 17:57:31 -07001322 # Ping all host in the hosts list variable
1323 print "Pinging : ", hostList
1324 pingResult = main.TRUE
kelvin-onlab0e684682015-08-11 18:51:41 -07001325 pingResult = main.Mininet1.pingallHosts( hostList )
kelvin-onlab44147802015-07-27 17:57:31 -07001326 return pingResult
1327
Jon Hall02758ac2017-05-24 16:20:28 -07001328
kelvin-onlab0e684682015-08-11 18:51:41 -07001329def getHostsData( main, hostList ):
kelvin-onlab44147802015-07-27 17:57:31 -07001330 """
1331 Use fwd app and pingall to discover all the hosts
1332 """
kelvin-onlab44147802015-07-27 17:57:31 -07001333 activateResult = main.TRUE
1334 appCheck = main.TRUE
1335 getDataResult = main.TRUE
1336 main.log.info( "Activating reactive forwarding app " )
Devin Lim142b5342017-07-20 15:22:39 -07001337 activateResult = main.Cluster.active( 0 ).activateApp( "org.onosproject.fwd" )
kelvin-onlab44147802015-07-27 17:57:31 -07001338 if not activateResult:
1339 main.log.error( "Something went wrong installing fwd app" )
1340 time.sleep( main.fwdSleep )
kelvin-onlab0e684682015-08-11 18:51:41 -07001341 if isinstance( hostList[ 0 ], types.StringType ):
1342 main.Mininet1.pingallHosts( hostList )
1343 elif isinstance( hostList[ 0 ], types.ListType ):
1344 for i in xrange( len( hostList ) ):
1345 main.Mininet1.pingallHosts( hostList[ i ] )
1346
Devin Lim142b5342017-07-20 15:22:39 -07001347 hostsJson = json.loads( main.Cluster.active( 0 ).REST.hosts() )
kelvin-onlab44147802015-07-27 17:57:31 -07001348 hosts = main.Mininet1.getHosts().keys()
1349 # TODO: Make better use of new getHosts function
1350 for host in hosts:
1351 main.hostsData[ host ] = {}
1352 main.hostsData[ host ][ 'mac' ] = \
1353 main.Mininet1.getMacAddress( host ).upper()
1354 for hostj in hostsJson:
1355 if main.hostsData[ host ][ 'mac' ] == hostj[ 'mac' ]:
1356 main.hostsData[ host ][ 'id' ] = hostj[ 'id' ]
1357 main.hostsData[ host ][ 'vlan' ] = hostj[ 'vlan' ]
1358 main.hostsData[ host ][ 'location' ] = \
Jeremy Ronquillo0e538bc2017-06-13 15:16:09 -07001359 hostj[ 'locations' ][ 0 ][ 'elementId' ] + '/' + \
1360 hostj[ 'locations' ][ 0 ][ 'port' ]
kelvin-onlab44147802015-07-27 17:57:31 -07001361 main.hostsData[ host ][ 'ipAddresses' ] = hostj[ 'ipAddresses' ]
1362
1363 main.log.info( "Deactivating reactive forwarding app " )
Devin Lim142b5342017-07-20 15:22:39 -07001364 deactivateResult = main.Cluster.active( 0 ).REST.deactivateApp( "org.onosproject.fwd" )
kelvin-onlab44147802015-07-27 17:57:31 -07001365 if activateResult and deactivateResult and main.hostsData:
1366 main.log.info( "Successfully used fwd app to discover hosts " )
1367 getDataResult = main.TRUE
1368 else:
1369 main.log.info( "Failed to use fwd app to discover hosts " )
1370 getDataResult = main.FALSE
1371
1372 print main.hostsData
1373
1374 return getDataResult
1375
Jon Hall02758ac2017-05-24 16:20:28 -07001376
kelvin-onlab44147802015-07-27 17:57:31 -07001377def checkTopology( main, expectedLink ):
kelvin-onlab44147802015-07-27 17:57:31 -07001378 # Check onos topology
1379 main.log.info( itemName + ": Checking ONOS topology " )
1380
Devin Lim142b5342017-07-20 15:22:39 -07001381 statusResult = main.Cluster.command( "checkStatus",
1382 args=[ main.numSwitch, expectedLink ],
1383 returnBool=True, specificDriver=3 )
kelvin-onlab44147802015-07-27 17:57:31 -07001384 if not statusResult:
1385 main.log.error( itemName + ": Topology mismatch" )
1386 else:
1387 main.log.info( itemName + ": Topology match" )
1388 return statusResult
1389
Jon Hall02758ac2017-05-24 16:20:28 -07001390
kelvin-onlab44147802015-07-27 17:57:31 -07001391def checkIntentState( main, intentsId ):
1392 """
1393 This function will check intent state to make sure all the intents
1394 are in INSTALLED state
1395 """
kelvin-onlab44147802015-07-27 17:57:31 -07001396 intentResult = main.TRUE
1397 results = []
1398
1399 main.log.info( itemName + ": Checking intents state" )
1400 # First check of intents
Devin Lim142b5342017-07-20 15:22:39 -07001401 stateCheckResults = main.Cluster.command( "checkIntentState",
1402 kwargs={ "intentsId":intentsId },
1403 returnBool=True, specificDriver=3 )
kelvin-onlab44147802015-07-27 17:57:31 -07001404
1405 expectedState = [ 'INSTALLED', 'INSTALLING' ]
1406
Devin Lim142b5342017-07-20 15:22:39 -07001407 if stateCheckResults:
kelvin-onlab44147802015-07-27 17:57:31 -07001408 main.log.info( itemName + ": Intents are installed correctly" )
1409 else:
1410 # Wait for at least 5 second before checking the intents again
Jeremy2f190ca2016-01-29 15:23:57 -08001411 main.log.error( "Intents are not installed correctly. Waiting 5 sec" )
kelvin-onlab44147802015-07-27 17:57:31 -07001412 time.sleep( 5 )
1413 results = []
1414 # Second check of intents since some of the intents may be in
1415 # INSTALLING state, they should be in INSTALLED at this time
Devin Lim142b5342017-07-20 15:22:39 -07001416 stateCheckResults = main.Cluster.command( "checkIntentState",
1417 kwargs={ "intentsId":intentsId },
1418 returnBool=True, specificDriver=3 )
1419 if stateCheckResults:
kelvin-onlab44147802015-07-27 17:57:31 -07001420 main.log.info( itemName + ": Intents are installed correctly" )
Jeremy2f190ca2016-01-29 15:23:57 -08001421 intentResult = main.TRUE
kelvin-onlab44147802015-07-27 17:57:31 -07001422 else:
1423 main.log.error( itemName + ": Intents are NOT installed correctly" )
1424 intentResult = main.FALSE
1425
1426 return intentResult
1427
Jon Hall02758ac2017-05-24 16:20:28 -07001428
kelvin-onlab44147802015-07-27 17:57:31 -07001429def checkFlowsState( main ):
1430
1431 main.log.info( itemName + ": Check flows state" )
Devin Lim142b5342017-07-20 15:22:39 -07001432 checkFlowsResult = main.Cluster.active( 0 ).REST.checkFlowsState()
kelvin-onlab44147802015-07-27 17:57:31 -07001433 return checkFlowsResult
1434
Jon Hall02758ac2017-05-24 16:20:28 -07001435
1436def link( main, sw1, sw2, option ):
kelvin-onlab44147802015-07-27 17:57:31 -07001437
1438 # link down
1439 main.log.info( itemName + ": Bring link " + option + "between " +
1440 sw1 + " and " + sw2 )
1441 linkResult = main.Mininet1.link( end1=sw1, end2=sw2, option=option )
1442 return linkResult
1443
Jon Hall02758ac2017-05-24 16:20:28 -07001444
kelvin-onlab44147802015-07-27 17:57:31 -07001445def removeAllIntents( main ):
1446 """
1447 Remove all intents in the intentsId
1448 """
kelvin-onlab44147802015-07-27 17:57:31 -07001449 onosSummary = []
1450 removeIntentResult = main.TRUE
1451 # Remove intents
Devin Lim142b5342017-07-20 15:22:39 -07001452 removeIntentResult = main.Cluster.active( 0 ).REST.removeAllIntents()
kelvin-onlab44147802015-07-27 17:57:31 -07001453
1454 if removeIntentResult:
1455 main.log.info( itemName + ": There are no more intents remaining, " +
1456 "successfully removed all the intents." )
1457
1458 return removeIntentResult
1459
Jon Hall02758ac2017-05-24 16:20:28 -07001460
kelvin-onlab44147802015-07-27 17:57:31 -07001461def checkFlowsCount( main ):
1462 """
1463 Check flows count in each node
1464 """
kelvin-onlab44147802015-07-27 17:57:31 -07001465 flowsCount = []
1466 main.log.info( itemName + ": Checking flows count in each ONOS node" )
Devin Lim142b5342017-07-20 15:22:39 -07001467 for ctrl in main.Cluster.active():
1468 flowsCount.append( len( json.loads( ctrl.REST.flows() ) ) )
1469
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:
Devin Lim142b5342017-07-20 15:22:39 -07001476 for i in range( main.Cluster.numCtrls ):
1477 main.log.debug( itemName + ": " + main.Cluster.active( i ).name +
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()
Devin Lim142b5342017-07-20 15:22:39 -07001522 hosts = main.topoRelated.getAll( "hosts", 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" ]
Devin Lim142b5342017-07-20 15:22:39 -07001527 for controller in range( main.Cluster.numCtrls ):
Jeremy2f190ca2016-01-29 15:23:57 -08001528 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:
Devin Lim142b5342017-07-20 15:22:39 -07001569 hostsJson = json.loads( main.Cluster.active( 0 ).REST.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 """
Devin Lim142b5342017-07-20 15:22:39 -07001724 main.ONOSbench.logReport( main.Cluster.active( 0 ).ipAddress,
Jeremy2f190ca2016-01-29 15:23:57 -08001725 [ "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" )
Devin Lim142b5342017-07-20 15:22:39 -07001734 for ctrl in main.Cluster.active():
1735 main.ONOSbench.logReport( ctrl.ipAddress,
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" )
Devin Lim142b5342017-07-20 15:22:39 -07001740 for ctrl in main.Cluster.active():
1741 main.ONOSbench.logReport( ctrl.ipAddress,
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" )
Devin Lim142b5342017-07-20 15:22:39 -07001746 for ctrl in main.Cluster.active():
1747 main.ONOSbench.logReport( ctrl.ipAddress,
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" )
Devin Lim142b5342017-07-20 15:22:39 -07001758 flowsJson1 = main.Cluster.active( 0 ).REST.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" )
Devin Lim142b5342017-07-20 15:22:39 -07001772 flowsJson2 = main.Cluster.active( 0 ).REST.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 ):
Devin Lim142b5342017-07-20 15:22:39 -07001792 intent = main.Cluster.active( 0 ).REST.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