blob: ed8bfee0bafe21afd3b6a1dcc1685a2b926db166 [file] [log] [blame]
Jon Hall5cf14d52015-07-16 12:15:19 -07001"""
2Description: This test is to determine if the HA test setup is
3 working correctly. There are no failures so this test should
4 have a 100% pass rate
5
6List of test cases:
7CASE1: Compile ONOS and push it to the test machines
8CASE2: Assign devices to controllers
9CASE21: Assign mastership to controllers
10CASE3: Assign intents
11CASE4: Ping across added host intents
12CASE5: Reading state of ONOS
13CASE6: The Failure case. Since this is the Sanity test, we do nothing.
14CASE7: Check state after control plane failure
15CASE8: Compare topo
16CASE9: Link s3-s28 down
17CASE10: Link s3-s28 up
18CASE11: Switch down
19CASE12: Switch up
20CASE13: Clean up
21CASE14: start election app on all onos nodes
22CASE15: Check that Leadership Election is still functional
23CASE16: Install Distributed Primitives app
24CASE17: Check for basic functionality with distributed primitives
25"""
26
27
28class HAsanity:
29
30 def __init__( self ):
31 self.default = ''
32
33 def CASE1( self, main ):
34 """
35 CASE1 is to compile ONOS and push it to the test machines
36
37 Startup sequence:
38 cell <name>
39 onos-verify-cell
40 NOTE: temporary - onos-remove-raft-logs
41 onos-uninstall
42 start mininet
43 git pull
44 mvn clean install
45 onos-package
46 onos-install -f
47 onos-wait-for-start
48 start cli sessions
49 start tcpdump
50 """
Jon Halle1a3b752015-07-22 13:02:46 -070051 import imp
Jon Hallf3d16e72015-12-16 17:45:08 -080052 import time
Jon Halla440e872016-03-31 15:15:50 -070053 import json
Jon Hall5cf14d52015-07-16 12:15:19 -070054 main.log.info( "ONOS HA Sanity test - initialization" )
55 main.case( "Setting up test environment" )
Jon Hall783bbf92015-07-23 14:33:19 -070056 main.caseExplanation = "Setup the test environment including " +\
Jon Hall5cf14d52015-07-16 12:15:19 -070057 "installing ONOS, starting Mininet and ONOS" +\
58 "cli sessions."
Jon Hall5cf14d52015-07-16 12:15:19 -070059
60 # load some variables from the params file
61 PULLCODE = False
62 if main.params[ 'Git' ] == 'True':
63 PULLCODE = True
64 gitBranch = main.params[ 'branch' ]
65 cellName = main.params[ 'ENV' ][ 'cellName' ]
66
Jon Halle1a3b752015-07-22 13:02:46 -070067 main.numCtrls = int( main.params[ 'num_controllers' ] )
Jon Hall5cf14d52015-07-16 12:15:19 -070068 if main.ONOSbench.maxNodes:
Jon Halle1a3b752015-07-22 13:02:46 -070069 if main.ONOSbench.maxNodes < main.numCtrls:
70 main.numCtrls = int( main.ONOSbench.maxNodes )
Jon Hall5cf14d52015-07-16 12:15:19 -070071 # TODO: refactor how to get onos port, maybe put into component tag?
Jon Halle1a3b752015-07-22 13:02:46 -070072 # set global variables
Jon Hall5cf14d52015-07-16 12:15:19 -070073 global ONOS1Port
74 global ONOS2Port
75 global ONOS3Port
76 global ONOS4Port
77 global ONOS5Port
78 global ONOS6Port
79 global ONOS7Port
Jon Halla440e872016-03-31 15:15:50 -070080 # These are for csv plotting in jenkins
81 global labels
82 global data
83 labels = []
84 data = []
Jon Hall5cf14d52015-07-16 12:15:19 -070085
86 # FIXME: just get controller port from params?
87 # TODO: do we really need all these?
88 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
89 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
90 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
91 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
92 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
93 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
94 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
95
Jon Halle1a3b752015-07-22 13:02:46 -070096 try:
Jon Halla440e872016-03-31 15:15:50 -070097 from tests.HAsanity.dependencies.Counters import Counters
98 main.Counters = Counters()
Jon Halle1a3b752015-07-22 13:02:46 -070099 except Exception as e:
100 main.log.exception( e )
101 main.cleanup()
102 main.exit()
103
104 main.CLIs = []
105 main.nodes = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700106 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700107 for i in range( 1, main.numCtrls + 1 ):
108 try:
109 main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
110 main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
111 ipList.append( main.nodes[ -1 ].ip_address )
112 except AttributeError:
113 break
Jon Hall5cf14d52015-07-16 12:15:19 -0700114
115 main.step( "Create cell file" )
116 cellAppString = main.params[ 'ENV' ][ 'appString' ]
117 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
118 main.Mininet1.ip_address,
119 cellAppString, ipList )
120 main.step( "Applying cell variable to environment" )
121 cellResult = main.ONOSbench.setCell( cellName )
122 verifyResult = main.ONOSbench.verifyCell()
123
124 # FIXME:this is short term fix
125 main.log.info( "Removing raft logs" )
126 main.ONOSbench.onosRemoveRaftLogs()
127
128 main.log.info( "Uninstalling ONOS" )
Jon Halle1a3b752015-07-22 13:02:46 -0700129 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700130 main.ONOSbench.onosUninstall( node.ip_address )
131
132 # Make sure ONOS is DEAD
133 main.log.info( "Killing any ONOS processes" )
134 killResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700135 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700136 killed = main.ONOSbench.onosKill( node.ip_address )
137 killResults = killResults and killed
138
139 cleanInstallResult = main.TRUE
140 gitPullResult = main.TRUE
141
142 main.step( "Starting Mininet" )
143 # scp topo file to mininet
144 # TODO: move to params?
145 topoName = "obelisk.py"
146 filePath = main.ONOSbench.home + "/tools/test/topos/"
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700147 main.ONOSbench.scp( main.Mininet1,
148 filePath + topoName,
149 main.Mininet1.home,
150 direction="to" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700151 mnResult = main.Mininet1.startNet( )
152 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
153 onpass="Mininet Started",
154 onfail="Error starting Mininet" )
155
156 main.step( "Git checkout and pull " + gitBranch )
157 if PULLCODE:
158 main.ONOSbench.gitCheckout( gitBranch )
159 gitPullResult = main.ONOSbench.gitPull()
160 # values of 1 or 3 are good
161 utilities.assert_lesser( expect=0, actual=gitPullResult,
162 onpass="Git pull successful",
163 onfail="Git pull failed" )
164 main.ONOSbench.getVersion( report=True )
165
166 main.step( "Using mvn clean install" )
167 cleanInstallResult = main.TRUE
168 if PULLCODE and gitPullResult == main.TRUE:
169 cleanInstallResult = main.ONOSbench.cleanInstall()
170 else:
171 main.log.warn( "Did not pull new code so skipping mvn " +
172 "clean install" )
173 utilities.assert_equals( expect=main.TRUE,
174 actual=cleanInstallResult,
175 onpass="MCI successful",
176 onfail="MCI failed" )
177 # GRAPHS
178 # NOTE: important params here:
179 # job = name of Jenkins job
180 # Plot Name = Plot-HA, only can be used if multiple plots
181 # index = The number of the graph under plot name
182 job = "HAsanity"
183 plotName = "Plot-HA"
Jon Hall843f8bc2016-03-18 14:28:13 -0700184 index = "2"
Jon Hall5cf14d52015-07-16 12:15:19 -0700185 graphs = '<ac:structured-macro ac:name="html">\n'
186 graphs += '<ac:plain-text-body><![CDATA[\n'
187 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
Jon Halla9845df2016-01-15 14:55:58 -0800188 '/plot/' + plotName + '/getPlot?index=' + index +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700189 '&width=500&height=300"' +\
190 'noborder="0" width="500" height="300" scrolling="yes" ' +\
191 'seamless="seamless"></iframe>\n'
192 graphs += ']]></ac:plain-text-body>\n'
193 graphs += '</ac:structured-macro>\n'
194 main.log.wiki(graphs)
195
196 main.step( "Creating ONOS package" )
197 packageResult = main.ONOSbench.onosPackage()
198 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
199 onpass="ONOS package successful",
200 onfail="ONOS package failed" )
201
202 main.step( "Installing ONOS package" )
203 onosInstallResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700204 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700205 tmpResult = main.ONOSbench.onosInstall( options="-f",
206 node=node.ip_address )
207 onosInstallResult = onosInstallResult and tmpResult
208 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
209 onpass="ONOS install successful",
210 onfail="ONOS install failed" )
211
212 main.step( "Checking if ONOS is up yet" )
213 for i in range( 2 ):
214 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700215 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700216 started = main.ONOSbench.isup( node.ip_address )
217 if not started:
Jon Hallc6793552016-01-19 14:18:37 -0800218 main.log.error( node.name + " hasn't started" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700219 onosIsupResult = onosIsupResult and started
220 if onosIsupResult == main.TRUE:
221 break
222 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
223 onpass="ONOS startup successful",
224 onfail="ONOS startup failed" )
225
226 main.log.step( "Starting ONOS CLI sessions" )
227 cliResults = main.TRUE
228 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700229 for i in range( main.numCtrls ):
230 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -0700231 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -0700232 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -0700233 threads.append( t )
234 t.start()
235
236 for t in threads:
237 t.join()
238 cliResults = cliResults and t.result
239 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
240 onpass="ONOS cli startup successful",
241 onfail="ONOS cli startup failed" )
242
Jon Halla440e872016-03-31 15:15:50 -0700243 # Create a list of active nodes for use when some nodes are stopped
244 main.activeNodes = [ i for i in range( 0, len( main.CLIs ) ) ]
245
Jon Hall5cf14d52015-07-16 12:15:19 -0700246 if main.params[ 'tcpdump' ].lower() == "true":
247 main.step( "Start Packet Capture MN" )
248 main.Mininet2.startTcpdump(
249 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
250 + "-MN.pcap",
251 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
252 port=main.params[ 'MNtcpdump' ][ 'port' ] )
253
254 main.step( "App Ids check" )
255 appCheck = main.TRUE
256 threads = []
Jon Halla440e872016-03-31 15:15:50 -0700257 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -0700258 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700259 name="appToIDCheck-" + str( i ),
260 args=[] )
261 threads.append( t )
262 t.start()
263
264 for t in threads:
265 t.join()
266 appCheck = appCheck and t.result
267 if appCheck != main.TRUE:
Jon Halla440e872016-03-31 15:15:50 -0700268 node = main.activeNodes[0]
269 main.log.warn( main.CLIs[node].apps() )
270 main.log.warn( main.CLIs[node].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700271 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
272 onpass="App Ids seem to be correct",
273 onfail="Something is wrong with app Ids" )
274
Jon Halla440e872016-03-31 15:15:50 -0700275 main.step( "Checking ONOS nodes" )
276 nodesOutput = []
277 nodeResults = main.TRUE
278 threads = []
279 for i in main.activeNodes:
280 t = main.Thread( target=main.CLIs[i].nodes,
281 name="nodes-" + str( i ),
282 args=[ ] )
283 threads.append( t )
284 t.start()
285
286 for t in threads:
287 t.join()
288 nodesOutput.append( t.result )
289 ips = [ main.nodes[node].ip_address for node in main.activeNodes ]
290 ips.sort()
291 for i in nodesOutput:
292 try:
293 current = json.loads( i )
294 activeIps = []
295 currentResult = main.FALSE
296 for node in current:
297 if node['state'] == 'READY':
298 activeIps.append( node['ip'] )
299 activeIps.sort()
300 if ips == activeIps:
301 currentResult = main.TRUE
302 except ( ValueError, TypeError ):
303 main.log.error( "Error parsing nodes output" )
304 main.log.warn( repr( i ) )
305 currentResult = main.FALSE
306 nodeResults = nodeResults and currentResult
307 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
308 onpass="Nodes check successful",
309 onfail="Nodes check NOT successful" )
310
311 if not nodeResults:
312 for cli in main.CLIs:
313 main.log.debug( "{} components not ACTIVE: \n{}".format(
314 cli.name,
315 cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
316
Jon Hall5cf14d52015-07-16 12:15:19 -0700317 if cliResults == main.FALSE:
318 main.log.error( "Failed to start ONOS, stopping test" )
319 main.cleanup()
320 main.exit()
321
Jon Hall172b7ba2016-04-07 18:12:20 -0700322 main.step( "Activate apps defined in the params file" )
323 # get data from the params
324 apps = main.params.get( 'apps' )
325 if apps:
326 apps = apps.split(',')
327 main.log.warn( apps )
328 activateResult = True
329 for app in apps:
330 main.CLIs[ 0 ].app( app, "Activate" )
331 # TODO: check this worked
332 time.sleep( 10 ) # wait for apps to activate
333 for app in apps:
334 state = main.CLIs[ 0 ].appStatus( app )
335 if state == "ACTIVE":
336 activateResult = activeResult and True
337 else:
338 main.log.error( "{} is in {} state".format( app, state ) )
339 activeResult = False
340 utilities.assert_equals( expect=True,
341 actual=activateResult,
342 onpass="Successfully activated apps",
343 onfail="Failed to activate apps" )
344 else:
345 main.log.warn( "No apps were specified to be loaded after startup" )
346
347 main.step( "Set ONOS configurations" )
348 config = main.params.get( 'ONOS_Configuration' )
349 if config:
350 main.log.debug( config )
351 checkResult = main.TRUE
352 for component in config:
353 for setting in config[component]:
354 value = config[component][setting]
355 check = main.CLIs[ 0 ].setCfg( component, setting, value )
356 main.log.info( "Value was changed? {}".format( main.TRUE == check ) )
357 checkResult = check and checkResult
358 utilities.assert_equals( expect=main.TRUE,
359 actual=checkResult,
360 onpass="Successfully set config",
361 onfail="Failed to set config" )
362 else:
363 main.log.warn( "No configurations were specified to be changed after startup" )
364
Jon Hall5cf14d52015-07-16 12:15:19 -0700365 def CASE2( self, main ):
366 """
367 Assign devices to controllers
368 """
369 import re
Jon Halle1a3b752015-07-22 13:02:46 -0700370 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700371 assert main, "main not defined"
372 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700373 assert main.CLIs, "main.CLIs not defined"
374 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700375 assert ONOS1Port, "ONOS1Port not defined"
376 assert ONOS2Port, "ONOS2Port not defined"
377 assert ONOS3Port, "ONOS3Port not defined"
378 assert ONOS4Port, "ONOS4Port not defined"
379 assert ONOS5Port, "ONOS5Port not defined"
380 assert ONOS6Port, "ONOS6Port not defined"
381 assert ONOS7Port, "ONOS7Port not defined"
382
383 main.case( "Assigning devices to controllers" )
Jon Hall783bbf92015-07-23 14:33:19 -0700384 main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700385 "and check that an ONOS node becomes the " +\
386 "master of the device."
387 main.step( "Assign switches to controllers" )
388
389 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700390 for i in range( main.numCtrls ):
391 ipList.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -0700392 swList = []
393 for i in range( 1, 29 ):
394 swList.append( "s" + str( i ) )
395 main.Mininet1.assignSwController( sw=swList, ip=ipList )
396
397 mastershipCheck = main.TRUE
398 for i in range( 1, 29 ):
399 response = main.Mininet1.getSwController( "s" + str( i ) )
400 try:
401 main.log.info( str( response ) )
402 except Exception:
403 main.log.info( repr( response ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700404 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700405 if re.search( "tcp:" + node.ip_address, response ):
406 mastershipCheck = mastershipCheck and main.TRUE
407 else:
408 main.log.error( "Error, node " + node.ip_address + " is " +
409 "not in the list of controllers s" +
410 str( i ) + " is connecting to." )
411 mastershipCheck = main.FALSE
412 utilities.assert_equals(
413 expect=main.TRUE,
414 actual=mastershipCheck,
415 onpass="Switch mastership assigned correctly",
416 onfail="Switches not assigned correctly to controllers" )
417
418 def CASE21( self, main ):
419 """
420 Assign mastership to controllers
421 """
Jon Hall5cf14d52015-07-16 12:15:19 -0700422 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700423 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700424 assert main, "main not defined"
425 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700426 assert main.CLIs, "main.CLIs not defined"
427 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700428 assert ONOS1Port, "ONOS1Port not defined"
429 assert ONOS2Port, "ONOS2Port not defined"
430 assert ONOS3Port, "ONOS3Port not defined"
431 assert ONOS4Port, "ONOS4Port not defined"
432 assert ONOS5Port, "ONOS5Port not defined"
433 assert ONOS6Port, "ONOS6Port not defined"
434 assert ONOS7Port, "ONOS7Port not defined"
435
436 main.case( "Assigning Controller roles for switches" )
Jon Hall783bbf92015-07-23 14:33:19 -0700437 main.caseExplanation = "Check that ONOS is connected to each " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700438 "device. Then manually assign" +\
439 " mastership to specific ONOS nodes using" +\
440 " 'device-role'"
441 main.step( "Assign mastership of switches to specific controllers" )
442 # Manually assign mastership to the controller we want
443 roleCall = main.TRUE
444
445 ipList = [ ]
446 deviceList = []
Jon Halla440e872016-03-31 15:15:50 -0700447 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -0700448 try:
449 # Assign mastership to specific controllers. This assignment was
450 # determined for a 7 node cluser, but will work with any sized
451 # cluster
452 for i in range( 1, 29 ): # switches 1 through 28
453 # set up correct variables:
454 if i == 1:
455 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700456 ip = main.nodes[ c ].ip_address # ONOS1
Jon Halla440e872016-03-31 15:15:50 -0700457 deviceId = onosCli.getDevice( "1000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700458 elif i == 2:
Jon Halle1a3b752015-07-22 13:02:46 -0700459 c = 1 % main.numCtrls
460 ip = main.nodes[ c ].ip_address # ONOS2
Jon Halla440e872016-03-31 15:15:50 -0700461 deviceId = onosCli.getDevice( "2000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700462 elif i == 3:
Jon Halle1a3b752015-07-22 13:02:46 -0700463 c = 1 % main.numCtrls
464 ip = main.nodes[ c ].ip_address # ONOS2
Jon Halla440e872016-03-31 15:15:50 -0700465 deviceId = onosCli.getDevice( "3000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700466 elif i == 4:
Jon Halle1a3b752015-07-22 13:02:46 -0700467 c = 3 % main.numCtrls
468 ip = main.nodes[ c ].ip_address # ONOS4
Jon Halla440e872016-03-31 15:15:50 -0700469 deviceId = onosCli.getDevice( "3004" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700470 elif i == 5:
Jon Halle1a3b752015-07-22 13:02:46 -0700471 c = 2 % main.numCtrls
472 ip = main.nodes[ c ].ip_address # ONOS3
Jon Halla440e872016-03-31 15:15:50 -0700473 deviceId = onosCli.getDevice( "5000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700474 elif i == 6:
Jon Halle1a3b752015-07-22 13:02:46 -0700475 c = 2 % main.numCtrls
476 ip = main.nodes[ c ].ip_address # ONOS3
Jon Halla440e872016-03-31 15:15:50 -0700477 deviceId = onosCli.getDevice( "6000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700478 elif i == 7:
Jon Halle1a3b752015-07-22 13:02:46 -0700479 c = 5 % main.numCtrls
480 ip = main.nodes[ c ].ip_address # ONOS6
Jon Halla440e872016-03-31 15:15:50 -0700481 deviceId = onosCli.getDevice( "6007" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700482 elif i >= 8 and i <= 17:
Jon Halle1a3b752015-07-22 13:02:46 -0700483 c = 4 % main.numCtrls
484 ip = main.nodes[ c ].ip_address # ONOS5
Jon Hall5cf14d52015-07-16 12:15:19 -0700485 dpid = '3' + str( i ).zfill( 3 )
Jon Halla440e872016-03-31 15:15:50 -0700486 deviceId = onosCli.getDevice( dpid ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700487 elif i >= 18 and i <= 27:
Jon Halle1a3b752015-07-22 13:02:46 -0700488 c = 6 % main.numCtrls
489 ip = main.nodes[ c ].ip_address # ONOS7
Jon Hall5cf14d52015-07-16 12:15:19 -0700490 dpid = '6' + str( i ).zfill( 3 )
Jon Halla440e872016-03-31 15:15:50 -0700491 deviceId = onosCli.getDevice( dpid ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700492 elif i == 28:
493 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700494 ip = main.nodes[ c ].ip_address # ONOS1
Jon Halla440e872016-03-31 15:15:50 -0700495 deviceId = onosCli.getDevice( "2800" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700496 else:
497 main.log.error( "You didn't write an else statement for " +
498 "switch s" + str( i ) )
499 roleCall = main.FALSE
500 # Assign switch
501 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
502 # TODO: make this controller dynamic
Jon Halla440e872016-03-31 15:15:50 -0700503 roleCall = roleCall and onosCli.deviceRole( deviceId, ip )
Jon Hall5cf14d52015-07-16 12:15:19 -0700504 ipList.append( ip )
505 deviceList.append( deviceId )
506 except ( AttributeError, AssertionError ):
507 main.log.exception( "Something is wrong with ONOS device view" )
Jon Halla440e872016-03-31 15:15:50 -0700508 main.log.info( onosCli.devices() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700509 utilities.assert_equals(
510 expect=main.TRUE,
511 actual=roleCall,
512 onpass="Re-assigned switch mastership to designated controller",
513 onfail="Something wrong with deviceRole calls" )
514
515 main.step( "Check mastership was correctly assigned" )
516 roleCheck = main.TRUE
517 # NOTE: This is due to the fact that device mastership change is not
518 # atomic and is actually a multi step process
519 time.sleep( 5 )
520 for i in range( len( ipList ) ):
521 ip = ipList[i]
522 deviceId = deviceList[i]
523 # Check assignment
Jon Halla440e872016-03-31 15:15:50 -0700524 master = onosCli.getRole( deviceId ).get( 'master' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700525 if ip in master:
526 roleCheck = roleCheck and main.TRUE
527 else:
528 roleCheck = roleCheck and main.FALSE
529 main.log.error( "Error, controller " + ip + " is not" +
530 " master " + "of device " +
531 str( deviceId ) + ". Master is " +
532 repr( master ) + "." )
533 utilities.assert_equals(
534 expect=main.TRUE,
535 actual=roleCheck,
536 onpass="Switches were successfully reassigned to designated " +
537 "controller",
538 onfail="Switches were not successfully reassigned" )
539
540 def CASE3( self, main ):
541 """
542 Assign intents
543 """
544 import time
545 import json
Jon Halle1a3b752015-07-22 13:02:46 -0700546 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700547 assert main, "main not defined"
548 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700549 assert main.CLIs, "main.CLIs not defined"
550 assert main.nodes, "main.nodes not defined"
Jon Halla440e872016-03-31 15:15:50 -0700551 try:
552 labels
553 except NameError:
554 main.log.error( "labels not defined, setting to []" )
555 labels = []
556 try:
557 data
558 except NameError:
559 main.log.error( "data not defined, setting to []" )
560 data = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700561 main.case( "Adding host Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700562 main.caseExplanation = "Discover hosts by using pingall then " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700563 "assign predetermined host-to-host intents." +\
564 " After installation, check that the intent" +\
565 " is distributed to all nodes and the state" +\
566 " is INSTALLED"
567
568 # install onos-app-fwd
569 main.step( "Install reactive forwarding app" )
Jon Halla440e872016-03-31 15:15:50 -0700570 onosCli = main.CLIs[ main.activeNodes[0] ]
571 installResults = onosCli.activateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700572 utilities.assert_equals( expect=main.TRUE, actual=installResults,
573 onpass="Install fwd successful",
574 onfail="Install fwd failed" )
575
576 main.step( "Check app ids" )
577 appCheck = main.TRUE
578 threads = []
Jon Halla440e872016-03-31 15:15:50 -0700579 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -0700580 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700581 name="appToIDCheck-" + str( i ),
582 args=[] )
583 threads.append( t )
584 t.start()
585
586 for t in threads:
587 t.join()
588 appCheck = appCheck and t.result
589 if appCheck != main.TRUE:
Jon Halla440e872016-03-31 15:15:50 -0700590 main.log.warn( onosCli.apps() )
591 main.log.warn( onosCli.appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700592 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
593 onpass="App Ids seem to be correct",
594 onfail="Something is wrong with app Ids" )
595
596 main.step( "Discovering Hosts( Via pingall for now )" )
597 # FIXME: Once we have a host discovery mechanism, use that instead
598 # REACTIVE FWD test
599 pingResult = main.FALSE
Jon Hall96091e62015-09-21 17:34:17 -0700600 passMsg = "Reactive Pingall test passed"
601 time1 = time.time()
602 pingResult = main.Mininet1.pingall()
603 time2 = time.time()
604 if not pingResult:
605 main.log.warn("First pingall failed. Trying again...")
Jon Hall5cf14d52015-07-16 12:15:19 -0700606 pingResult = main.Mininet1.pingall()
Jon Hall96091e62015-09-21 17:34:17 -0700607 passMsg += " on the second try"
608 utilities.assert_equals(
609 expect=main.TRUE,
610 actual=pingResult,
611 onpass= passMsg,
612 onfail="Reactive Pingall failed, " +
613 "one or more ping pairs failed" )
614 main.log.info( "Time for pingall: %2f seconds" %
615 ( time2 - time1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -0700616 # timeout for fwd flows
617 time.sleep( 11 )
618 # uninstall onos-app-fwd
619 main.step( "Uninstall reactive forwarding app" )
Jon Halla440e872016-03-31 15:15:50 -0700620 node = main.activeNodes[0]
621 uninstallResult = main.CLIs[node].deactivateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700622 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
623 onpass="Uninstall fwd successful",
624 onfail="Uninstall fwd failed" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700625
626 main.step( "Check app ids" )
627 threads = []
628 appCheck2 = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -0700629 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -0700630 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700631 name="appToIDCheck-" + str( i ),
632 args=[] )
633 threads.append( t )
634 t.start()
635
636 for t in threads:
637 t.join()
638 appCheck2 = appCheck2 and t.result
639 if appCheck2 != main.TRUE:
Jon Halla440e872016-03-31 15:15:50 -0700640 node = main.activeNodes[0]
641 main.log.warn( main.CLIs[node].apps() )
642 main.log.warn( main.CLIs[node].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700643 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
644 onpass="App Ids seem to be correct",
645 onfail="Something is wrong with app Ids" )
646
647 main.step( "Add host intents via cli" )
648 intentIds = []
Jon Hall6e709752016-02-01 13:38:46 -0800649 # TODO: move the host numbers to params
650 # Maybe look at all the paths we ping?
Jon Hall5cf14d52015-07-16 12:15:19 -0700651 intentAddResult = True
652 hostResult = main.TRUE
653 for i in range( 8, 18 ):
654 main.log.info( "Adding host intent between h" + str( i ) +
655 " and h" + str( i + 10 ) )
656 host1 = "00:00:00:00:00:" + \
657 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
658 host2 = "00:00:00:00:00:" + \
659 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
660 # NOTE: getHost can return None
Jon Halla440e872016-03-31 15:15:50 -0700661 host1Dict = onosCli.getHost( host1 )
662 host2Dict = onosCli.getHost( host2 )
Jon Hall5cf14d52015-07-16 12:15:19 -0700663 host1Id = None
664 host2Id = None
665 if host1Dict and host2Dict:
666 host1Id = host1Dict.get( 'id', None )
667 host2Id = host2Dict.get( 'id', None )
668 if host1Id and host2Id:
Jon Halla440e872016-03-31 15:15:50 -0700669 nodeNum = ( i % len( main.activeNodes ) )
670 node = main.activeNodes[nodeNum]
671 tmpId = main.CLIs[node].addHostIntent( host1Id, host2Id )
Jon Hall5cf14d52015-07-16 12:15:19 -0700672 if tmpId:
673 main.log.info( "Added intent with id: " + tmpId )
674 intentIds.append( tmpId )
675 else:
676 main.log.error( "addHostIntent returned: " +
677 repr( tmpId ) )
678 else:
679 main.log.error( "Error, getHost() failed for h" + str( i ) +
680 " and/or h" + str( i + 10 ) )
Jon Halla440e872016-03-31 15:15:50 -0700681 node = main.activeNodes[0]
682 hosts = main.CLIs[node].hosts()
Jon Hall5cf14d52015-07-16 12:15:19 -0700683 main.log.warn( "Hosts output: " )
684 try:
685 main.log.warn( json.dumps( json.loads( hosts ),
686 sort_keys=True,
687 indent=4,
688 separators=( ',', ': ' ) ) )
689 except ( ValueError, TypeError ):
690 main.log.warn( repr( hosts ) )
691 hostResult = main.FALSE
692 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
693 onpass="Found a host id for each host",
694 onfail="Error looking up host ids" )
695
696 intentStart = time.time()
Jon Halla440e872016-03-31 15:15:50 -0700697 onosIds = onosCli.getAllIntentsId()
Jon Hall5cf14d52015-07-16 12:15:19 -0700698 main.log.info( "Submitted intents: " + str( intentIds ) )
699 main.log.info( "Intents in ONOS: " + str( onosIds ) )
700 for intent in intentIds:
701 if intent in onosIds:
702 pass # intent submitted is in onos
703 else:
704 intentAddResult = False
705 if intentAddResult:
706 intentStop = time.time()
707 else:
708 intentStop = None
709 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -0700710 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700711 intentStates = []
712 installedCheck = True
713 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
714 count = 0
715 try:
716 for intent in json.loads( intents ):
717 state = intent.get( 'state', None )
718 if "INSTALLED" not in state:
719 installedCheck = False
720 intentId = intent.get( 'id', None )
721 intentStates.append( ( intentId, state ) )
722 except ( ValueError, TypeError ):
723 main.log.exception( "Error parsing intents" )
724 # add submitted intents not in the store
725 tmplist = [ i for i, s in intentStates ]
726 missingIntents = False
727 for i in intentIds:
728 if i not in tmplist:
729 intentStates.append( ( i, " - " ) )
730 missingIntents = True
731 intentStates.sort()
732 for i, s in intentStates:
733 count += 1
734 main.log.info( "%-6s%-15s%-15s" %
735 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -0700736 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -0700737 try:
738 missing = False
739 if leaders:
740 parsedLeaders = json.loads( leaders )
741 main.log.warn( json.dumps( parsedLeaders,
742 sort_keys=True,
743 indent=4,
744 separators=( ',', ': ' ) ) )
745 # check for all intent partitions
746 topics = []
747 for i in range( 14 ):
748 topics.append( "intent-partition-" + str( i ) )
749 main.log.debug( topics )
750 ONOStopics = [ j['topic'] for j in parsedLeaders ]
751 for topic in topics:
752 if topic not in ONOStopics:
753 main.log.error( "Error: " + topic +
754 " not in leaders" )
755 missing = True
756 else:
757 main.log.error( "leaders() returned None" )
758 except ( ValueError, TypeError ):
759 main.log.exception( "Error parsing leaders" )
760 main.log.error( repr( leaders ) )
761 # Check all nodes
762 if missing:
Jon Halla440e872016-03-31 15:15:50 -0700763 for i in main.activeNodes:
764 response = main.CLIs[i].leaders( jsonFormat=False)
765 main.log.warn( str( main.CLIs[i].name ) + " leaders output: \n" +
Jon Hall5cf14d52015-07-16 12:15:19 -0700766 str( response ) )
767
Jon Halla440e872016-03-31 15:15:50 -0700768 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -0700769 try:
770 if partitions :
771 parsedPartitions = json.loads( partitions )
772 main.log.warn( json.dumps( parsedPartitions,
773 sort_keys=True,
774 indent=4,
775 separators=( ',', ': ' ) ) )
776 # TODO check for a leader in all paritions
777 # TODO check for consistency among nodes
778 else:
779 main.log.error( "partitions() returned None" )
780 except ( ValueError, TypeError ):
781 main.log.exception( "Error parsing partitions" )
782 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -0700783 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -0700784 try:
785 if pendingMap :
786 parsedPending = json.loads( pendingMap )
787 main.log.warn( json.dumps( parsedPending,
788 sort_keys=True,
789 indent=4,
790 separators=( ',', ': ' ) ) )
791 # TODO check something here?
792 else:
793 main.log.error( "pendingMap() returned None" )
794 except ( ValueError, TypeError ):
795 main.log.exception( "Error parsing pending map" )
796 main.log.error( repr( pendingMap ) )
797
798 intentAddResult = bool( intentAddResult and not missingIntents and
799 installedCheck )
800 if not intentAddResult:
801 main.log.error( "Error in pushing host intents to ONOS" )
802
803 main.step( "Intent Anti-Entropy dispersion" )
Jon Halla440e872016-03-31 15:15:50 -0700804 for j in range(100):
Jon Hall5cf14d52015-07-16 12:15:19 -0700805 correct = True
806 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Halla440e872016-03-31 15:15:50 -0700807 for i in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700808 onosIds = []
Jon Halla440e872016-03-31 15:15:50 -0700809 ids = main.CLIs[i].getAllIntentsId()
Jon Hall5cf14d52015-07-16 12:15:19 -0700810 onosIds.append( ids )
Jon Halla440e872016-03-31 15:15:50 -0700811 main.log.debug( "Intents in " + main.CLIs[i].name + ": " +
Jon Hall5cf14d52015-07-16 12:15:19 -0700812 str( sorted( onosIds ) ) )
813 if sorted( ids ) != sorted( intentIds ):
814 main.log.warn( "Set of intent IDs doesn't match" )
815 correct = False
816 break
817 else:
Jon Halla440e872016-03-31 15:15:50 -0700818 intents = json.loads( main.CLIs[i].intents() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700819 for intent in intents:
820 if intent[ 'state' ] != "INSTALLED":
821 main.log.warn( "Intent " + intent[ 'id' ] +
822 " is " + intent[ 'state' ] )
823 correct = False
824 break
825 if correct:
826 break
827 else:
828 time.sleep(1)
829 if not intentStop:
830 intentStop = time.time()
831 global gossipTime
832 gossipTime = intentStop - intentStart
833 main.log.info( "It took about " + str( gossipTime ) +
834 " seconds for all intents to appear in each node" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700835 gossipPeriod = int( main.params['timers']['gossip'] )
Jon Halla440e872016-03-31 15:15:50 -0700836 maxGossipTime = gossipPeriod * len( main.activeNodes )
Jon Hall5cf14d52015-07-16 12:15:19 -0700837 utilities.assert_greater_equals(
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700838 expect=maxGossipTime, actual=gossipTime,
Jon Hall5cf14d52015-07-16 12:15:19 -0700839 onpass="ECM anti-entropy for intents worked within " +
840 "expected time",
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700841 onfail="Intent ECM anti-entropy took too long. " +
842 "Expected time:{}, Actual time:{}".format( maxGossipTime,
843 gossipTime ) )
844 if gossipTime <= maxGossipTime:
Jon Hall5cf14d52015-07-16 12:15:19 -0700845 intentAddResult = True
846
847 if not intentAddResult or "key" in pendingMap:
848 import time
849 installedCheck = True
850 main.log.info( "Sleeping 60 seconds to see if intents are found" )
851 time.sleep( 60 )
Jon Halla440e872016-03-31 15:15:50 -0700852 onosIds = onosCli.getAllIntentsId()
Jon Hall5cf14d52015-07-16 12:15:19 -0700853 main.log.info( "Submitted intents: " + str( intentIds ) )
854 main.log.info( "Intents in ONOS: " + str( onosIds ) )
855 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -0700856 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700857 intentStates = []
858 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
859 count = 0
860 try:
861 for intent in json.loads( intents ):
862 # Iter through intents of a node
863 state = intent.get( 'state', None )
864 if "INSTALLED" not in state:
865 installedCheck = False
866 intentId = intent.get( 'id', None )
867 intentStates.append( ( intentId, state ) )
868 except ( ValueError, TypeError ):
869 main.log.exception( "Error parsing intents" )
870 # add submitted intents not in the store
871 tmplist = [ i for i, s in intentStates ]
872 for i in intentIds:
873 if i not in tmplist:
874 intentStates.append( ( i, " - " ) )
875 intentStates.sort()
876 for i, s in intentStates:
877 count += 1
878 main.log.info( "%-6s%-15s%-15s" %
879 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -0700880 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -0700881 try:
882 missing = False
883 if leaders:
884 parsedLeaders = json.loads( leaders )
885 main.log.warn( json.dumps( parsedLeaders,
886 sort_keys=True,
887 indent=4,
888 separators=( ',', ': ' ) ) )
889 # check for all intent partitions
890 # check for election
891 topics = []
892 for i in range( 14 ):
893 topics.append( "intent-partition-" + str( i ) )
894 # FIXME: this should only be after we start the app
895 topics.append( "org.onosproject.election" )
896 main.log.debug( topics )
897 ONOStopics = [ j['topic'] for j in parsedLeaders ]
898 for topic in topics:
899 if topic not in ONOStopics:
900 main.log.error( "Error: " + topic +
901 " not in leaders" )
902 missing = True
903 else:
904 main.log.error( "leaders() returned None" )
905 except ( ValueError, TypeError ):
906 main.log.exception( "Error parsing leaders" )
907 main.log.error( repr( leaders ) )
908 # Check all nodes
909 if missing:
Jon Halla440e872016-03-31 15:15:50 -0700910 for i in main.activeNodes:
911 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -0700912 response = node.leaders( jsonFormat=False)
913 main.log.warn( str( node.name ) + " leaders output: \n" +
914 str( response ) )
915
Jon Halla440e872016-03-31 15:15:50 -0700916 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -0700917 try:
918 if partitions :
919 parsedPartitions = json.loads( partitions )
920 main.log.warn( json.dumps( parsedPartitions,
921 sort_keys=True,
922 indent=4,
923 separators=( ',', ': ' ) ) )
924 # TODO check for a leader in all paritions
925 # TODO check for consistency among nodes
926 else:
927 main.log.error( "partitions() returned None" )
928 except ( ValueError, TypeError ):
929 main.log.exception( "Error parsing partitions" )
930 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -0700931 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -0700932 try:
933 if pendingMap :
934 parsedPending = json.loads( pendingMap )
935 main.log.warn( json.dumps( parsedPending,
936 sort_keys=True,
937 indent=4,
938 separators=( ',', ': ' ) ) )
939 # TODO check something here?
940 else:
941 main.log.error( "pendingMap() returned None" )
942 except ( ValueError, TypeError ):
943 main.log.exception( "Error parsing pending map" )
944 main.log.error( repr( pendingMap ) )
945
946 def CASE4( self, main ):
947 """
948 Ping across added host intents
949 """
950 import json
951 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700952 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700953 assert main, "main not defined"
954 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700955 assert main.CLIs, "main.CLIs not defined"
956 assert main.nodes, "main.nodes not defined"
Jon Halla440e872016-03-31 15:15:50 -0700957 main.case( "Verify connectivity by sending traffic across Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700958 main.caseExplanation = "Ping across added host intents to check " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700959 "functionality and check the state of " +\
960 "the intent"
961 main.step( "Ping across added host intents" )
Jon Halla440e872016-03-31 15:15:50 -0700962 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -0700963 PingResult = main.TRUE
964 for i in range( 8, 18 ):
965 ping = main.Mininet1.pingHost( src="h" + str( i ),
966 target="h" + str( i + 10 ) )
967 PingResult = PingResult and ping
968 if ping == main.FALSE:
969 main.log.warn( "Ping failed between h" + str( i ) +
970 " and h" + str( i + 10 ) )
971 elif ping == main.TRUE:
972 main.log.info( "Ping test passed!" )
973 # Don't set PingResult or you'd override failures
974 if PingResult == main.FALSE:
975 main.log.error(
976 "Intents have not been installed correctly, pings failed." )
977 # TODO: pretty print
978 main.log.warn( "ONOS1 intents: " )
979 try:
Jon Halla440e872016-03-31 15:15:50 -0700980 tmpIntents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700981 main.log.warn( json.dumps( json.loads( tmpIntents ),
982 sort_keys=True,
983 indent=4,
984 separators=( ',', ': ' ) ) )
985 except ( ValueError, TypeError ):
986 main.log.warn( repr( tmpIntents ) )
987 utilities.assert_equals(
988 expect=main.TRUE,
989 actual=PingResult,
990 onpass="Intents have been installed correctly and pings work",
991 onfail="Intents have not been installed correctly, pings failed." )
992
993 main.step( "Check Intent state" )
994 installedCheck = False
995 loopCount = 0
996 while not installedCheck and loopCount < 40:
997 installedCheck = True
998 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -0700999 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -07001000 intentStates = []
1001 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
1002 count = 0
1003 # Iter through intents of a node
1004 try:
1005 for intent in json.loads( intents ):
1006 state = intent.get( 'state', None )
1007 if "INSTALLED" not in state:
1008 installedCheck = False
1009 intentId = intent.get( 'id', None )
1010 intentStates.append( ( intentId, state ) )
1011 except ( ValueError, TypeError ):
1012 main.log.exception( "Error parsing intents." )
1013 # Print states
1014 intentStates.sort()
1015 for i, s in intentStates:
1016 count += 1
1017 main.log.info( "%-6s%-15s%-15s" %
1018 ( str( count ), str( i ), str( s ) ) )
1019 if not installedCheck:
1020 time.sleep( 1 )
1021 loopCount += 1
1022 utilities.assert_equals( expect=True, actual=installedCheck,
1023 onpass="Intents are all INSTALLED",
1024 onfail="Intents are not all in " +
1025 "INSTALLED state" )
1026
1027 main.step( "Check leadership of topics" )
Jon Halla440e872016-03-31 15:15:50 -07001028 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -07001029 topicCheck = main.TRUE
1030 try:
1031 if leaders:
1032 parsedLeaders = json.loads( leaders )
1033 main.log.warn( json.dumps( parsedLeaders,
1034 sort_keys=True,
1035 indent=4,
1036 separators=( ',', ': ' ) ) )
1037 # check for all intent partitions
1038 # check for election
1039 # TODO: Look at Devices as topics now that it uses this system
1040 topics = []
1041 for i in range( 14 ):
1042 topics.append( "intent-partition-" + str( i ) )
1043 # FIXME: this should only be after we start the app
1044 # FIXME: topics.append( "org.onosproject.election" )
1045 # Print leaders output
1046 main.log.debug( topics )
1047 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1048 for topic in topics:
1049 if topic not in ONOStopics:
1050 main.log.error( "Error: " + topic +
1051 " not in leaders" )
1052 topicCheck = main.FALSE
1053 else:
1054 main.log.error( "leaders() returned None" )
1055 topicCheck = main.FALSE
1056 except ( ValueError, TypeError ):
1057 topicCheck = main.FALSE
1058 main.log.exception( "Error parsing leaders" )
1059 main.log.error( repr( leaders ) )
1060 # TODO: Check for a leader of these topics
1061 # Check all nodes
1062 if topicCheck:
Jon Halla440e872016-03-31 15:15:50 -07001063 for i in main.activeNodes:
1064 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07001065 response = node.leaders( jsonFormat=False)
1066 main.log.warn( str( node.name ) + " leaders output: \n" +
1067 str( response ) )
1068
1069 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
1070 onpass="intent Partitions is in leaders",
1071 onfail="Some topics were lost " )
1072 # Print partitions
Jon Halla440e872016-03-31 15:15:50 -07001073 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -07001074 try:
1075 if partitions :
1076 parsedPartitions = json.loads( partitions )
1077 main.log.warn( json.dumps( parsedPartitions,
1078 sort_keys=True,
1079 indent=4,
1080 separators=( ',', ': ' ) ) )
1081 # TODO check for a leader in all paritions
1082 # TODO check for consistency among nodes
1083 else:
1084 main.log.error( "partitions() returned None" )
1085 except ( ValueError, TypeError ):
1086 main.log.exception( "Error parsing partitions" )
1087 main.log.error( repr( partitions ) )
1088 # Print Pending Map
Jon Halla440e872016-03-31 15:15:50 -07001089 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -07001090 try:
1091 if pendingMap :
1092 parsedPending = json.loads( pendingMap )
1093 main.log.warn( json.dumps( parsedPending,
1094 sort_keys=True,
1095 indent=4,
1096 separators=( ',', ': ' ) ) )
1097 # TODO check something here?
1098 else:
1099 main.log.error( "pendingMap() returned None" )
1100 except ( ValueError, TypeError ):
1101 main.log.exception( "Error parsing pending map" )
1102 main.log.error( repr( pendingMap ) )
1103
1104 if not installedCheck:
1105 main.log.info( "Waiting 60 seconds to see if the state of " +
1106 "intents change" )
1107 time.sleep( 60 )
1108 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -07001109 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -07001110 intentStates = []
1111 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
1112 count = 0
1113 # Iter through intents of a node
1114 try:
1115 for intent in json.loads( intents ):
1116 state = intent.get( 'state', None )
1117 if "INSTALLED" not in state:
1118 installedCheck = False
1119 intentId = intent.get( 'id', None )
1120 intentStates.append( ( intentId, state ) )
1121 except ( ValueError, TypeError ):
1122 main.log.exception( "Error parsing intents." )
1123 intentStates.sort()
1124 for i, s in intentStates:
1125 count += 1
1126 main.log.info( "%-6s%-15s%-15s" %
1127 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -07001128 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -07001129 try:
1130 missing = False
1131 if leaders:
1132 parsedLeaders = json.loads( leaders )
1133 main.log.warn( json.dumps( parsedLeaders,
1134 sort_keys=True,
1135 indent=4,
1136 separators=( ',', ': ' ) ) )
1137 # check for all intent partitions
1138 # check for election
1139 topics = []
1140 for i in range( 14 ):
1141 topics.append( "intent-partition-" + str( i ) )
1142 # FIXME: this should only be after we start the app
1143 topics.append( "org.onosproject.election" )
1144 main.log.debug( topics )
1145 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1146 for topic in topics:
1147 if topic not in ONOStopics:
1148 main.log.error( "Error: " + topic +
1149 " not in leaders" )
1150 missing = True
1151 else:
1152 main.log.error( "leaders() returned None" )
1153 except ( ValueError, TypeError ):
1154 main.log.exception( "Error parsing leaders" )
1155 main.log.error( repr( leaders ) )
1156 if missing:
Jon Halla440e872016-03-31 15:15:50 -07001157 for i in main.activeNodes:
1158 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07001159 response = node.leaders( jsonFormat=False)
1160 main.log.warn( str( node.name ) + " leaders output: \n" +
1161 str( response ) )
1162
Jon Halla440e872016-03-31 15:15:50 -07001163 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -07001164 try:
1165 if partitions :
1166 parsedPartitions = json.loads( partitions )
1167 main.log.warn( json.dumps( parsedPartitions,
1168 sort_keys=True,
1169 indent=4,
1170 separators=( ',', ': ' ) ) )
1171 # TODO check for a leader in all paritions
1172 # TODO check for consistency among nodes
1173 else:
1174 main.log.error( "partitions() returned None" )
1175 except ( ValueError, TypeError ):
1176 main.log.exception( "Error parsing partitions" )
1177 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -07001178 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -07001179 try:
1180 if pendingMap :
1181 parsedPending = json.loads( pendingMap )
1182 main.log.warn( json.dumps( parsedPending,
1183 sort_keys=True,
1184 indent=4,
1185 separators=( ',', ': ' ) ) )
1186 # TODO check something here?
1187 else:
1188 main.log.error( "pendingMap() returned None" )
1189 except ( ValueError, TypeError ):
1190 main.log.exception( "Error parsing pending map" )
1191 main.log.error( repr( pendingMap ) )
1192 # Print flowrules
Jon Halla440e872016-03-31 15:15:50 -07001193 node = main.activeNodes[0]
1194 main.log.debug( main.CLIs[node].flows( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001195 main.step( "Wait a minute then ping again" )
1196 # the wait is above
1197 PingResult = main.TRUE
1198 for i in range( 8, 18 ):
1199 ping = main.Mininet1.pingHost( src="h" + str( i ),
1200 target="h" + str( i + 10 ) )
1201 PingResult = PingResult and ping
1202 if ping == main.FALSE:
1203 main.log.warn( "Ping failed between h" + str( i ) +
1204 " and h" + str( i + 10 ) )
1205 elif ping == main.TRUE:
1206 main.log.info( "Ping test passed!" )
1207 # Don't set PingResult or you'd override failures
1208 if PingResult == main.FALSE:
1209 main.log.error(
1210 "Intents have not been installed correctly, pings failed." )
1211 # TODO: pretty print
1212 main.log.warn( "ONOS1 intents: " )
1213 try:
Jon Halla440e872016-03-31 15:15:50 -07001214 tmpIntents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -07001215 main.log.warn( json.dumps( json.loads( tmpIntents ),
1216 sort_keys=True,
1217 indent=4,
1218 separators=( ',', ': ' ) ) )
1219 except ( ValueError, TypeError ):
1220 main.log.warn( repr( tmpIntents ) )
1221 utilities.assert_equals(
1222 expect=main.TRUE,
1223 actual=PingResult,
1224 onpass="Intents have been installed correctly and pings work",
1225 onfail="Intents have not been installed correctly, pings failed." )
1226
1227 def CASE5( self, main ):
1228 """
1229 Reading state of ONOS
1230 """
1231 import json
1232 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001233 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001234 assert main, "main not defined"
1235 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001236 assert main.CLIs, "main.CLIs not defined"
1237 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001238
1239 main.case( "Setting up and gathering data for current state" )
1240 # The general idea for this test case is to pull the state of
1241 # ( intents,flows, topology,... ) from each ONOS node
1242 # We can then compare them with each other and also with past states
1243
1244 main.step( "Check that each switch has a master" )
1245 global mastershipState
1246 mastershipState = '[]'
1247
1248 # Assert that each device has a master
1249 rolesNotNull = main.TRUE
1250 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001251 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001252 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001253 name="rolesNotNull-" + str( i ),
1254 args=[] )
1255 threads.append( t )
1256 t.start()
1257
1258 for t in threads:
1259 t.join()
1260 rolesNotNull = rolesNotNull and t.result
1261 utilities.assert_equals(
1262 expect=main.TRUE,
1263 actual=rolesNotNull,
1264 onpass="Each device has a master",
1265 onfail="Some devices don't have a master assigned" )
1266
1267 main.step( "Get the Mastership of each switch from each controller" )
1268 ONOSMastership = []
1269 mastershipCheck = main.FALSE
1270 consistentMastership = True
1271 rolesResults = True
1272 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001273 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001274 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001275 name="roles-" + str( i ),
1276 args=[] )
1277 threads.append( t )
1278 t.start()
1279
1280 for t in threads:
1281 t.join()
1282 ONOSMastership.append( t.result )
1283
Jon Halla440e872016-03-31 15:15:50 -07001284 for i in range( len( ONOSMastership ) ):
1285 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001286 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Halla440e872016-03-31 15:15:50 -07001287 main.log.error( "Error in getting ONOS" + node + " roles" )
1288 main.log.warn( "ONOS" + node + " mastership response: " +
1289 repr( ONOSMastership[i] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001290 rolesResults = False
1291 utilities.assert_equals(
1292 expect=True,
1293 actual=rolesResults,
1294 onpass="No error in reading roles output",
1295 onfail="Error in reading roles from ONOS" )
1296
1297 main.step( "Check for consistency in roles from each controller" )
1298 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1299 main.log.info(
1300 "Switch roles are consistent across all ONOS nodes" )
1301 else:
1302 consistentMastership = False
1303 utilities.assert_equals(
1304 expect=True,
1305 actual=consistentMastership,
1306 onpass="Switch roles are consistent across all ONOS nodes",
1307 onfail="ONOS nodes have different views of switch roles" )
1308
1309 if rolesResults and not consistentMastership:
Jon Halla440e872016-03-31 15:15:50 -07001310 for i in range( len( main.activeNodes ) ):
1311 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001312 try:
1313 main.log.warn(
Jon Halla440e872016-03-31 15:15:50 -07001314 "ONOS" + node + " roles: ",
Jon Hall5cf14d52015-07-16 12:15:19 -07001315 json.dumps(
1316 json.loads( ONOSMastership[ i ] ),
1317 sort_keys=True,
1318 indent=4,
1319 separators=( ',', ': ' ) ) )
1320 except ( ValueError, TypeError ):
1321 main.log.warn( repr( ONOSMastership[ i ] ) )
1322 elif rolesResults and consistentMastership:
1323 mastershipCheck = main.TRUE
1324 mastershipState = ONOSMastership[ 0 ]
1325
1326 main.step( "Get the intents from each controller" )
1327 global intentState
1328 intentState = []
1329 ONOSIntents = []
1330 intentCheck = main.FALSE
1331 consistentIntents = True
1332 intentsResults = True
1333 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001334 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001335 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001336 name="intents-" + str( i ),
1337 args=[],
1338 kwargs={ 'jsonFormat': True } )
1339 threads.append( t )
1340 t.start()
1341
1342 for t in threads:
1343 t.join()
1344 ONOSIntents.append( t.result )
1345
Jon Halla440e872016-03-31 15:15:50 -07001346 for i in range( len( ONOSIntents ) ):
1347 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001348 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Halla440e872016-03-31 15:15:50 -07001349 main.log.error( "Error in getting ONOS" + node + " intents" )
1350 main.log.warn( "ONOS" + node + " intents response: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07001351 repr( ONOSIntents[ i ] ) )
1352 intentsResults = False
1353 utilities.assert_equals(
1354 expect=True,
1355 actual=intentsResults,
1356 onpass="No error in reading intents output",
1357 onfail="Error in reading intents from ONOS" )
1358
1359 main.step( "Check for consistency in Intents from each controller" )
1360 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1361 main.log.info( "Intents are consistent across all ONOS " +
1362 "nodes" )
1363 else:
1364 consistentIntents = False
1365 main.log.error( "Intents not consistent" )
1366 utilities.assert_equals(
1367 expect=True,
1368 actual=consistentIntents,
1369 onpass="Intents are consistent across all ONOS nodes",
1370 onfail="ONOS nodes have different views of intents" )
1371
1372 if intentsResults:
1373 # Try to make it easy to figure out what is happening
1374 #
1375 # Intent ONOS1 ONOS2 ...
1376 # 0x01 INSTALLED INSTALLING
1377 # ... ... ...
1378 # ... ... ...
1379 title = " Id"
Jon Halla440e872016-03-31 15:15:50 -07001380 for n in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001381 title += " " * 10 + "ONOS" + str( n + 1 )
1382 main.log.warn( title )
Jon Halle1a3b752015-07-22 13:02:46 -07001383 # get all intent keys in the cluster
Jon Hall5cf14d52015-07-16 12:15:19 -07001384 keys = []
1385 try:
1386 # Get the set of all intent keys
1387 for nodeStr in ONOSIntents:
1388 node = json.loads( nodeStr )
1389 for intent in node:
1390 keys.append( intent.get( 'id' ) )
1391 keys = set( keys )
1392 # For each intent key, print the state on each node
1393 for key in keys:
1394 row = "%-13s" % key
1395 for nodeStr in ONOSIntents:
1396 node = json.loads( nodeStr )
1397 for intent in node:
1398 if intent.get( 'id', "Error" ) == key:
1399 row += "%-15s" % intent.get( 'state' )
1400 main.log.warn( row )
1401 # End of intent state table
1402 except ValueError as e:
1403 main.log.exception( e )
1404 main.log.debug( "nodeStr was: " + repr( nodeStr ) )
1405
1406 if intentsResults and not consistentIntents:
1407 # print the json objects
Jon Halla440e872016-03-31 15:15:50 -07001408 n = str( main.activeNodes[-1] + 1 )
1409 main.log.debug( "ONOS" + n + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07001410 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1411 sort_keys=True,
1412 indent=4,
1413 separators=( ',', ': ' ) ) )
Jon Halla440e872016-03-31 15:15:50 -07001414 for i in range( len( ONOSIntents ) ):
1415 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001416 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
Jon Halla440e872016-03-31 15:15:50 -07001417 main.log.debug( "ONOS" + node + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07001418 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1419 sort_keys=True,
1420 indent=4,
1421 separators=( ',', ': ' ) ) )
1422 else:
Jon Halla440e872016-03-31 15:15:50 -07001423 main.log.debug( "ONOS" + node + " intents match ONOS" +
1424 n + " intents" )
Jon Hall5cf14d52015-07-16 12:15:19 -07001425 elif intentsResults and consistentIntents:
1426 intentCheck = main.TRUE
1427 intentState = ONOSIntents[ 0 ]
1428
1429 main.step( "Get the flows from each controller" )
1430 global flowState
1431 flowState = []
1432 ONOSFlows = []
1433 ONOSFlowsJson = []
1434 flowCheck = main.FALSE
1435 consistentFlows = True
1436 flowsResults = True
1437 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001438 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001439 t = main.Thread( target=main.CLIs[i].flows,
Jon Hall5cf14d52015-07-16 12:15:19 -07001440 name="flows-" + str( i ),
1441 args=[],
1442 kwargs={ 'jsonFormat': True } )
1443 threads.append( t )
1444 t.start()
1445
1446 # NOTE: Flows command can take some time to run
1447 time.sleep(30)
1448 for t in threads:
1449 t.join()
1450 result = t.result
1451 ONOSFlows.append( result )
1452
Jon Halla440e872016-03-31 15:15:50 -07001453 for i in range( len( ONOSFlows ) ):
1454 num = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001455 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1456 main.log.error( "Error in getting ONOS" + num + " flows" )
1457 main.log.warn( "ONOS" + num + " flows response: " +
1458 repr( ONOSFlows[ i ] ) )
1459 flowsResults = False
1460 ONOSFlowsJson.append( None )
1461 else:
1462 try:
1463 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1464 except ( ValueError, TypeError ):
1465 # FIXME: change this to log.error?
1466 main.log.exception( "Error in parsing ONOS" + num +
1467 " response as json." )
1468 main.log.error( repr( ONOSFlows[ i ] ) )
1469 ONOSFlowsJson.append( None )
1470 flowsResults = False
1471 utilities.assert_equals(
1472 expect=True,
1473 actual=flowsResults,
1474 onpass="No error in reading flows output",
1475 onfail="Error in reading flows from ONOS" )
1476
1477 main.step( "Check for consistency in Flows from each controller" )
1478 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1479 if all( tmp ):
1480 main.log.info( "Flow count is consistent across all ONOS nodes" )
1481 else:
1482 consistentFlows = False
1483 utilities.assert_equals(
1484 expect=True,
1485 actual=consistentFlows,
1486 onpass="The flow count is consistent across all ONOS nodes",
1487 onfail="ONOS nodes have different flow counts" )
1488
1489 if flowsResults and not consistentFlows:
Jon Halla440e872016-03-31 15:15:50 -07001490 for i in range( len( ONOSFlows ) ):
1491 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001492 try:
1493 main.log.warn(
Jon Halla440e872016-03-31 15:15:50 -07001494 "ONOS" + node + " flows: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07001495 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1496 indent=4, separators=( ',', ': ' ) ) )
1497 except ( ValueError, TypeError ):
Jon Halla440e872016-03-31 15:15:50 -07001498 main.log.warn( "ONOS" + node + " flows: " +
1499 repr( ONOSFlows[ i ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001500 elif flowsResults and consistentFlows:
1501 flowCheck = main.TRUE
1502 flowState = ONOSFlows[ 0 ]
1503
1504 main.step( "Get the OF Table entries" )
1505 global flows
1506 flows = []
1507 for i in range( 1, 29 ):
GlennRC68467eb2015-11-16 18:01:01 -08001508 flows.append( main.Mininet1.getFlowTable( "s" + str( i ), version="1.3", debug=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001509 if flowCheck == main.FALSE:
1510 for table in flows:
1511 main.log.warn( table )
1512 # TODO: Compare switch flow tables with ONOS flow tables
1513
1514 main.step( "Start continuous pings" )
1515 main.Mininet2.pingLong(
1516 src=main.params[ 'PING' ][ 'source1' ],
1517 target=main.params[ 'PING' ][ 'target1' ],
1518 pingTime=500 )
1519 main.Mininet2.pingLong(
1520 src=main.params[ 'PING' ][ 'source2' ],
1521 target=main.params[ 'PING' ][ 'target2' ],
1522 pingTime=500 )
1523 main.Mininet2.pingLong(
1524 src=main.params[ 'PING' ][ 'source3' ],
1525 target=main.params[ 'PING' ][ 'target3' ],
1526 pingTime=500 )
1527 main.Mininet2.pingLong(
1528 src=main.params[ 'PING' ][ 'source4' ],
1529 target=main.params[ 'PING' ][ 'target4' ],
1530 pingTime=500 )
1531 main.Mininet2.pingLong(
1532 src=main.params[ 'PING' ][ 'source5' ],
1533 target=main.params[ 'PING' ][ 'target5' ],
1534 pingTime=500 )
1535 main.Mininet2.pingLong(
1536 src=main.params[ 'PING' ][ 'source6' ],
1537 target=main.params[ 'PING' ][ 'target6' ],
1538 pingTime=500 )
1539 main.Mininet2.pingLong(
1540 src=main.params[ 'PING' ][ 'source7' ],
1541 target=main.params[ 'PING' ][ 'target7' ],
1542 pingTime=500 )
1543 main.Mininet2.pingLong(
1544 src=main.params[ 'PING' ][ 'source8' ],
1545 target=main.params[ 'PING' ][ 'target8' ],
1546 pingTime=500 )
1547 main.Mininet2.pingLong(
1548 src=main.params[ 'PING' ][ 'source9' ],
1549 target=main.params[ 'PING' ][ 'target9' ],
1550 pingTime=500 )
1551 main.Mininet2.pingLong(
1552 src=main.params[ 'PING' ][ 'source10' ],
1553 target=main.params[ 'PING' ][ 'target10' ],
1554 pingTime=500 )
1555
1556 main.step( "Collecting topology information from ONOS" )
1557 devices = []
1558 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001559 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001560 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07001561 name="devices-" + str( i ),
1562 args=[ ] )
1563 threads.append( t )
1564 t.start()
1565
1566 for t in threads:
1567 t.join()
1568 devices.append( t.result )
1569 hosts = []
1570 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001571 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001572 t = main.Thread( target=main.CLIs[i].hosts,
Jon Hall5cf14d52015-07-16 12:15:19 -07001573 name="hosts-" + str( i ),
1574 args=[ ] )
1575 threads.append( t )
1576 t.start()
1577
1578 for t in threads:
1579 t.join()
1580 try:
1581 hosts.append( json.loads( t.result ) )
1582 except ( ValueError, TypeError ):
1583 # FIXME: better handling of this, print which node
1584 # Maybe use thread name?
1585 main.log.exception( "Error parsing json output of hosts" )
Jon Hallf3d16e72015-12-16 17:45:08 -08001586 main.log.warn( repr( t.result ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001587 hosts.append( None )
1588
1589 ports = []
1590 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001591 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001592 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07001593 name="ports-" + str( i ),
1594 args=[ ] )
1595 threads.append( t )
1596 t.start()
1597
1598 for t in threads:
1599 t.join()
1600 ports.append( t.result )
1601 links = []
1602 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001603 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001604 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07001605 name="links-" + str( i ),
1606 args=[ ] )
1607 threads.append( t )
1608 t.start()
1609
1610 for t in threads:
1611 t.join()
1612 links.append( t.result )
1613 clusters = []
1614 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001615 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001616 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07001617 name="clusters-" + str( i ),
1618 args=[ ] )
1619 threads.append( t )
1620 t.start()
1621
1622 for t in threads:
1623 t.join()
1624 clusters.append( t.result )
1625 # Compare json objects for hosts and dataplane clusters
1626
1627 # hosts
1628 main.step( "Host view is consistent across ONOS nodes" )
1629 consistentHostsResult = main.TRUE
1630 for controller in range( len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07001631 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hallf3d16e72015-12-16 17:45:08 -08001632 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001633 if hosts[ controller ] == hosts[ 0 ]:
1634 continue
1635 else: # hosts not consistent
1636 main.log.error( "hosts from ONOS" +
1637 controllerStr +
1638 " is inconsistent with ONOS1" )
1639 main.log.warn( repr( hosts[ controller ] ) )
1640 consistentHostsResult = main.FALSE
1641
1642 else:
1643 main.log.error( "Error in getting ONOS hosts from ONOS" +
1644 controllerStr )
1645 consistentHostsResult = main.FALSE
1646 main.log.warn( "ONOS" + controllerStr +
1647 " hosts response: " +
1648 repr( hosts[ controller ] ) )
1649 utilities.assert_equals(
1650 expect=main.TRUE,
1651 actual=consistentHostsResult,
1652 onpass="Hosts view is consistent across all ONOS nodes",
1653 onfail="ONOS nodes have different views of hosts" )
1654
1655 main.step( "Each host has an IP address" )
1656 ipResult = main.TRUE
1657 for controller in range( 0, len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07001658 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hallf3d16e72015-12-16 17:45:08 -08001659 if hosts[ controller ]:
1660 for host in hosts[ controller ]:
1661 if not host.get( 'ipAddresses', [ ] ):
1662 main.log.error( "Error with host ips on controller" +
1663 controllerStr + ": " + str( host ) )
1664 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07001665 utilities.assert_equals(
1666 expect=main.TRUE,
1667 actual=ipResult,
1668 onpass="The ips of the hosts aren't empty",
1669 onfail="The ip of at least one host is missing" )
1670
1671 # Strongly connected clusters of devices
1672 main.step( "Cluster view is consistent across ONOS nodes" )
1673 consistentClustersResult = main.TRUE
1674 for controller in range( len( clusters ) ):
Jon Halla440e872016-03-31 15:15:50 -07001675 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001676 if "Error" not in clusters[ controller ]:
1677 if clusters[ controller ] == clusters[ 0 ]:
1678 continue
1679 else: # clusters not consistent
1680 main.log.error( "clusters from ONOS" + controllerStr +
1681 " is inconsistent with ONOS1" )
1682 consistentClustersResult = main.FALSE
1683
1684 else:
1685 main.log.error( "Error in getting dataplane clusters " +
1686 "from ONOS" + controllerStr )
1687 consistentClustersResult = main.FALSE
1688 main.log.warn( "ONOS" + controllerStr +
1689 " clusters response: " +
1690 repr( clusters[ controller ] ) )
1691 utilities.assert_equals(
1692 expect=main.TRUE,
1693 actual=consistentClustersResult,
1694 onpass="Clusters view is consistent across all ONOS nodes",
1695 onfail="ONOS nodes have different views of clusters" )
Jon Hall172b7ba2016-04-07 18:12:20 -07001696 if consistentClustersResult != main.TRUE:
1697 main.log.debug( clusters )
Jon Hall5cf14d52015-07-16 12:15:19 -07001698 # there should always only be one cluster
1699 main.step( "Cluster view correct across ONOS nodes" )
1700 try:
1701 numClusters = len( json.loads( clusters[ 0 ] ) )
1702 except ( ValueError, TypeError ):
1703 main.log.exception( "Error parsing clusters[0]: " +
1704 repr( clusters[ 0 ] ) )
Jon Hall6e709752016-02-01 13:38:46 -08001705 numClusters = "ERROR"
Jon Hall5cf14d52015-07-16 12:15:19 -07001706 clusterResults = main.FALSE
1707 if numClusters == 1:
1708 clusterResults = main.TRUE
1709 utilities.assert_equals(
1710 expect=1,
1711 actual=numClusters,
1712 onpass="ONOS shows 1 SCC",
1713 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1714
1715 main.step( "Comparing ONOS topology to MN" )
1716 devicesResults = main.TRUE
1717 linksResults = main.TRUE
1718 hostsResults = main.TRUE
1719 mnSwitches = main.Mininet1.getSwitches()
1720 mnLinks = main.Mininet1.getLinks()
1721 mnHosts = main.Mininet1.getHosts()
Jon Halla440e872016-03-31 15:15:50 -07001722 for controller in main.activeNodes:
1723 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001724 if devices[ controller ] and ports[ controller ] and\
1725 "Error" not in devices[ controller ] and\
1726 "Error" not in ports[ controller ]:
Jon Halla440e872016-03-31 15:15:50 -07001727 currentDevicesResult = main.Mininet1.compareSwitches(
1728 mnSwitches,
1729 json.loads( devices[ controller ] ),
1730 json.loads( ports[ controller ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001731 else:
1732 currentDevicesResult = main.FALSE
1733 utilities.assert_equals( expect=main.TRUE,
1734 actual=currentDevicesResult,
1735 onpass="ONOS" + controllerStr +
1736 " Switches view is correct",
1737 onfail="ONOS" + controllerStr +
1738 " Switches view is incorrect" )
1739 if links[ controller ] and "Error" not in links[ controller ]:
1740 currentLinksResult = main.Mininet1.compareLinks(
1741 mnSwitches, mnLinks,
1742 json.loads( links[ controller ] ) )
1743 else:
1744 currentLinksResult = main.FALSE
1745 utilities.assert_equals( expect=main.TRUE,
1746 actual=currentLinksResult,
1747 onpass="ONOS" + controllerStr +
1748 " links view is correct",
1749 onfail="ONOS" + controllerStr +
1750 " links view is incorrect" )
1751
Jon Hall657cdf62015-12-17 14:40:51 -08001752 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001753 currentHostsResult = main.Mininet1.compareHosts(
1754 mnHosts,
1755 hosts[ controller ] )
1756 else:
1757 currentHostsResult = main.FALSE
1758 utilities.assert_equals( expect=main.TRUE,
1759 actual=currentHostsResult,
1760 onpass="ONOS" + controllerStr +
1761 " hosts exist in Mininet",
1762 onfail="ONOS" + controllerStr +
1763 " hosts don't match Mininet" )
1764
1765 devicesResults = devicesResults and currentDevicesResult
1766 linksResults = linksResults and currentLinksResult
1767 hostsResults = hostsResults and currentHostsResult
1768
1769 main.step( "Device information is correct" )
1770 utilities.assert_equals(
1771 expect=main.TRUE,
1772 actual=devicesResults,
1773 onpass="Device information is correct",
1774 onfail="Device information is incorrect" )
1775
1776 main.step( "Links are correct" )
1777 utilities.assert_equals(
1778 expect=main.TRUE,
1779 actual=linksResults,
1780 onpass="Link are correct",
1781 onfail="Links are incorrect" )
1782
1783 main.step( "Hosts are correct" )
1784 utilities.assert_equals(
1785 expect=main.TRUE,
1786 actual=hostsResults,
1787 onpass="Hosts are correct",
1788 onfail="Hosts are incorrect" )
1789
1790 def CASE6( self, main ):
1791 """
1792 The Failure case. Since this is the Sanity test, we do nothing.
1793 """
1794 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001795 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001796 assert main, "main not defined"
1797 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001798 assert main.CLIs, "main.CLIs not defined"
1799 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001800 main.case( "Wait 60 seconds instead of inducing a failure" )
1801 time.sleep( 60 )
1802 utilities.assert_equals(
1803 expect=main.TRUE,
1804 actual=main.TRUE,
1805 onpass="Sleeping 60 seconds",
1806 onfail="Something is terribly wrong with my math" )
1807
1808 def CASE7( self, main ):
1809 """
1810 Check state after ONOS failure
1811 """
1812 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001813 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001814 assert main, "main not defined"
1815 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001816 assert main.CLIs, "main.CLIs not defined"
1817 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001818 main.case( "Running ONOS Constant State Tests" )
1819
1820 main.step( "Check that each switch has a master" )
1821 # Assert that each device has a master
1822 rolesNotNull = main.TRUE
1823 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001824 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001825 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001826 name="rolesNotNull-" + str( i ),
1827 args=[ ] )
1828 threads.append( t )
1829 t.start()
1830
1831 for t in threads:
1832 t.join()
1833 rolesNotNull = rolesNotNull and t.result
1834 utilities.assert_equals(
1835 expect=main.TRUE,
1836 actual=rolesNotNull,
1837 onpass="Each device has a master",
1838 onfail="Some devices don't have a master assigned" )
1839
1840 main.step( "Read device roles from ONOS" )
1841 ONOSMastership = []
1842 mastershipCheck = main.FALSE
1843 consistentMastership = True
1844 rolesResults = True
1845 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001846 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001847 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001848 name="roles-" + str( i ),
1849 args=[] )
1850 threads.append( t )
1851 t.start()
1852
1853 for t in threads:
1854 t.join()
1855 ONOSMastership.append( t.result )
1856
Jon Halla440e872016-03-31 15:15:50 -07001857 for i in range( len( ONOSMastership ) ):
1858 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001859 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Halla440e872016-03-31 15:15:50 -07001860 main.log.error( "Error in getting ONOS" + node + " roles" )
1861 main.log.warn( "ONOS" + node + " mastership response: " +
1862 repr( ONOSMastership[i] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001863 rolesResults = False
1864 utilities.assert_equals(
1865 expect=True,
1866 actual=rolesResults,
1867 onpass="No error in reading roles output",
1868 onfail="Error in reading roles from ONOS" )
1869
1870 main.step( "Check for consistency in roles from each controller" )
1871 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1872 main.log.info(
1873 "Switch roles are consistent across all ONOS nodes" )
1874 else:
1875 consistentMastership = False
1876 utilities.assert_equals(
1877 expect=True,
1878 actual=consistentMastership,
1879 onpass="Switch roles are consistent across all ONOS nodes",
1880 onfail="ONOS nodes have different views of switch roles" )
1881
1882 if rolesResults and not consistentMastership:
Jon Halla440e872016-03-31 15:15:50 -07001883 for i in range( len( ONOSMastership ) ):
1884 node = str( main.activeNodes[i] + 1 )
1885 main.log.warn( "ONOS" + node + " roles: ",
1886 json.dumps( json.loads( ONOSMastership[ i ] ),
1887 sort_keys=True,
1888 indent=4,
1889 separators=( ',', ': ' ) ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001890
1891 description2 = "Compare switch roles from before failure"
1892 main.step( description2 )
1893 try:
1894 currentJson = json.loads( ONOSMastership[0] )
1895 oldJson = json.loads( mastershipState )
1896 except ( ValueError, TypeError ):
1897 main.log.exception( "Something is wrong with parsing " +
1898 "ONOSMastership[0] or mastershipState" )
1899 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1900 main.log.error( "mastershipState" + repr( mastershipState ) )
1901 main.cleanup()
1902 main.exit()
1903 mastershipCheck = main.TRUE
1904 for i in range( 1, 29 ):
1905 switchDPID = str(
1906 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
1907 current = [ switch[ 'master' ] for switch in currentJson
1908 if switchDPID in switch[ 'id' ] ]
1909 old = [ switch[ 'master' ] for switch in oldJson
1910 if switchDPID in switch[ 'id' ] ]
1911 if current == old:
1912 mastershipCheck = mastershipCheck and main.TRUE
1913 else:
1914 main.log.warn( "Mastership of switch %s changed" % switchDPID )
1915 mastershipCheck = main.FALSE
1916 utilities.assert_equals(
1917 expect=main.TRUE,
1918 actual=mastershipCheck,
1919 onpass="Mastership of Switches was not changed",
1920 onfail="Mastership of some switches changed" )
1921 mastershipCheck = mastershipCheck and consistentMastership
1922
1923 main.step( "Get the intents and compare across all nodes" )
1924 ONOSIntents = []
1925 intentCheck = main.FALSE
1926 consistentIntents = True
1927 intentsResults = True
1928 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001929 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001930 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001931 name="intents-" + str( i ),
1932 args=[],
1933 kwargs={ 'jsonFormat': True } )
1934 threads.append( t )
1935 t.start()
1936
1937 for t in threads:
1938 t.join()
1939 ONOSIntents.append( t.result )
1940
Jon Halla440e872016-03-31 15:15:50 -07001941 for i in range( len( ONOSIntents) ):
1942 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001943 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Halla440e872016-03-31 15:15:50 -07001944 main.log.error( "Error in getting ONOS" + node + " intents" )
1945 main.log.warn( "ONOS" + node + " intents response: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07001946 repr( ONOSIntents[ i ] ) )
1947 intentsResults = False
1948 utilities.assert_equals(
1949 expect=True,
1950 actual=intentsResults,
1951 onpass="No error in reading intents output",
1952 onfail="Error in reading intents from ONOS" )
1953
1954 main.step( "Check for consistency in Intents from each controller" )
1955 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1956 main.log.info( "Intents are consistent across all ONOS " +
1957 "nodes" )
1958 else:
1959 consistentIntents = False
1960
1961 # Try to make it easy to figure out what is happening
1962 #
1963 # Intent ONOS1 ONOS2 ...
1964 # 0x01 INSTALLED INSTALLING
1965 # ... ... ...
1966 # ... ... ...
1967 title = " ID"
Jon Halla440e872016-03-31 15:15:50 -07001968 for n in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001969 title += " " * 10 + "ONOS" + str( n + 1 )
1970 main.log.warn( title )
1971 # get all intent keys in the cluster
1972 keys = []
1973 for nodeStr in ONOSIntents:
1974 node = json.loads( nodeStr )
1975 for intent in node:
1976 keys.append( intent.get( 'id' ) )
1977 keys = set( keys )
1978 for key in keys:
1979 row = "%-13s" % key
1980 for nodeStr in ONOSIntents:
1981 node = json.loads( nodeStr )
1982 for intent in node:
1983 if intent.get( 'id' ) == key:
1984 row += "%-15s" % intent.get( 'state' )
1985 main.log.warn( row )
1986 # End table view
1987
1988 utilities.assert_equals(
1989 expect=True,
1990 actual=consistentIntents,
1991 onpass="Intents are consistent across all ONOS nodes",
1992 onfail="ONOS nodes have different views of intents" )
1993 intentStates = []
1994 for node in ONOSIntents: # Iter through ONOS nodes
1995 nodeStates = []
1996 # Iter through intents of a node
1997 try:
1998 for intent in json.loads( node ):
1999 nodeStates.append( intent[ 'state' ] )
2000 except ( ValueError, TypeError ):
2001 main.log.exception( "Error in parsing intents" )
2002 main.log.error( repr( node ) )
2003 intentStates.append( nodeStates )
2004 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
2005 main.log.info( dict( out ) )
2006
2007 if intentsResults and not consistentIntents:
Jon Halla440e872016-03-31 15:15:50 -07002008 for i in range( len( main.activeNodes ) ):
2009 node = str( main.activeNodes[i] + 1 )
2010 main.log.warn( "ONOS" + node + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07002011 main.log.warn( json.dumps(
2012 json.loads( ONOSIntents[ i ] ),
2013 sort_keys=True,
2014 indent=4,
2015 separators=( ',', ': ' ) ) )
2016 elif intentsResults and consistentIntents:
2017 intentCheck = main.TRUE
2018
2019 # NOTE: Store has no durability, so intents are lost across system
2020 # restarts
2021 main.step( "Compare current intents with intents before the failure" )
2022 # NOTE: this requires case 5 to pass for intentState to be set.
2023 # maybe we should stop the test if that fails?
2024 sameIntents = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002025 try:
2026 intentState
2027 except NameError:
2028 main.log.warn( "No previous intent state was saved" )
2029 else:
2030 if intentState and intentState == ONOSIntents[ 0 ]:
2031 sameIntents = main.TRUE
2032 main.log.info( "Intents are consistent with before failure" )
2033 # TODO: possibly the states have changed? we may need to figure out
2034 # what the acceptable states are
2035 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
2036 sameIntents = main.TRUE
2037 try:
2038 before = json.loads( intentState )
2039 after = json.loads( ONOSIntents[ 0 ] )
2040 for intent in before:
2041 if intent not in after:
2042 sameIntents = main.FALSE
2043 main.log.debug( "Intent is not currently in ONOS " +
2044 "(at least in the same form):" )
2045 main.log.debug( json.dumps( intent ) )
2046 except ( ValueError, TypeError ):
2047 main.log.exception( "Exception printing intents" )
2048 main.log.debug( repr( ONOSIntents[0] ) )
2049 main.log.debug( repr( intentState ) )
2050 if sameIntents == main.FALSE:
2051 try:
2052 main.log.debug( "ONOS intents before: " )
2053 main.log.debug( json.dumps( json.loads( intentState ),
2054 sort_keys=True, indent=4,
2055 separators=( ',', ': ' ) ) )
2056 main.log.debug( "Current ONOS intents: " )
2057 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
2058 sort_keys=True, indent=4,
2059 separators=( ',', ': ' ) ) )
2060 except ( ValueError, TypeError ):
2061 main.log.exception( "Exception printing intents" )
2062 main.log.debug( repr( ONOSIntents[0] ) )
2063 main.log.debug( repr( intentState ) )
2064 utilities.assert_equals(
2065 expect=main.TRUE,
2066 actual=sameIntents,
2067 onpass="Intents are consistent with before failure",
2068 onfail="The Intents changed during failure" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002069 intentCheck = intentCheck and sameIntents
2070
2071 main.step( "Get the OF Table entries and compare to before " +
2072 "component failure" )
2073 FlowTables = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002074 for i in range( 28 ):
2075 main.log.info( "Checking flow table on s" + str( i + 1 ) )
GlennRC68467eb2015-11-16 18:01:01 -08002076 tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
2077 FlowTables = FlowTables and main.Mininet1.flowTableComp( flows[i], tmpFlows )
Jon Hall5cf14d52015-07-16 12:15:19 -07002078 if FlowTables == main.FALSE:
GlennRC68467eb2015-11-16 18:01:01 -08002079 main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002080 utilities.assert_equals(
2081 expect=main.TRUE,
2082 actual=FlowTables,
2083 onpass="No changes were found in the flow tables",
2084 onfail="Changes were found in the flow tables" )
2085
2086 main.Mininet2.pingLongKill()
2087 '''
2088 main.step( "Check the continuous pings to ensure that no packets " +
2089 "were dropped during component failure" )
2090 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
2091 main.params[ 'TESTONIP' ] )
2092 LossInPings = main.FALSE
2093 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
2094 for i in range( 8, 18 ):
2095 main.log.info(
2096 "Checking for a loss in pings along flow from s" +
2097 str( i ) )
2098 LossInPings = main.Mininet2.checkForLoss(
2099 "/tmp/ping.h" +
2100 str( i ) ) or LossInPings
2101 if LossInPings == main.TRUE:
2102 main.log.info( "Loss in ping detected" )
2103 elif LossInPings == main.ERROR:
2104 main.log.info( "There are multiple mininet process running" )
2105 elif LossInPings == main.FALSE:
2106 main.log.info( "No Loss in the pings" )
2107 main.log.info( "No loss of dataplane connectivity" )
2108 utilities.assert_equals(
2109 expect=main.FALSE,
2110 actual=LossInPings,
2111 onpass="No Loss of connectivity",
2112 onfail="Loss of dataplane connectivity detected" )
2113 '''
2114
2115 main.step( "Leadership Election is still functional" )
2116 # Test of LeadershipElection
Jon Halla440e872016-03-31 15:15:50 -07002117 leaderList = []
2118
Jon Hall5cf14d52015-07-16 12:15:19 -07002119 # NOTE: this only works for the sanity test. In case of failures,
2120 # leader will likely change
Jon Halla440e872016-03-31 15:15:50 -07002121 leader = main.nodes[ main.activeNodes[ 0 ] ].ip_address
Jon Hall5cf14d52015-07-16 12:15:19 -07002122 leaderResult = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002123
2124 for i in main.activeNodes:
2125 cli = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07002126 leaderN = cli.electionTestLeader()
Jon Halla440e872016-03-31 15:15:50 -07002127 leaderList.append( leaderN )
Jon Hall5cf14d52015-07-16 12:15:19 -07002128 # verify leader is ONOS1
2129 if leaderN == leader:
2130 # all is well
2131 # NOTE: In failure scenario, this could be a new node, maybe
2132 # check != ONOS1
2133 pass
2134 elif leaderN == main.FALSE:
2135 # error in response
2136 main.log.error( "Something is wrong with " +
2137 "electionTestLeader function, check the" +
2138 " error logs" )
2139 leaderResult = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002140 elif leaderN is None:
2141 main.log.error( cli.name +
2142 " shows no leader for the election-app was" +
2143 " elected after the old one died" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002144 leaderResult = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002145 if len( set( leaderList ) ) != 1:
2146 leaderResult = main.FALSE
2147 main.log.error(
2148 "Inconsistent view of leader for the election test app" )
2149 # TODO: print the list
Jon Hall5cf14d52015-07-16 12:15:19 -07002150 utilities.assert_equals(
2151 expect=main.TRUE,
2152 actual=leaderResult,
2153 onpass="Leadership election passed",
2154 onfail="Something went wrong with Leadership election" )
2155
2156 def CASE8( self, main ):
2157 """
2158 Compare topo
2159 """
2160 import json
2161 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002162 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002163 assert main, "main not defined"
2164 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002165 assert main.CLIs, "main.CLIs not defined"
2166 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002167
2168 main.case( "Compare ONOS Topology view to Mininet topology" )
Jon Hall783bbf92015-07-23 14:33:19 -07002169 main.caseExplanation = "Compare topology objects between Mininet" +\
Jon Hall5cf14d52015-07-16 12:15:19 -07002170 " and ONOS"
Jon Hall5cf14d52015-07-16 12:15:19 -07002171 topoResult = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002172 topoFailMsg = "ONOS topology don't match Mininet"
Jon Hall5cf14d52015-07-16 12:15:19 -07002173 elapsed = 0
2174 count = 0
Jon Halle9b1fa32015-12-08 15:32:21 -08002175 main.step( "Comparing ONOS topology to MN topology" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002176 startTime = time.time()
2177 # Give time for Gossip to work
Jon Halle9b1fa32015-12-08 15:32:21 -08002178 while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
Jon Hall96091e62015-09-21 17:34:17 -07002179 devicesResults = main.TRUE
2180 linksResults = main.TRUE
2181 hostsResults = main.TRUE
2182 hostAttachmentResults = True
Jon Hall5cf14d52015-07-16 12:15:19 -07002183 count += 1
2184 cliStart = time.time()
2185 devices = []
2186 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002187 for i in main.activeNodes:
2188 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002189 name="devices-" + str( i ),
Jon Halla440e872016-03-31 15:15:50 -07002190 args=[ main.CLIs[i].devices, [ None ] ],
2191 kwargs= { 'sleep': 5, 'attempts': 5,
2192 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002193 threads.append( t )
2194 t.start()
2195
2196 for t in threads:
2197 t.join()
2198 devices.append( t.result )
2199 hosts = []
2200 ipResult = main.TRUE
2201 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002202 for i in main.activeNodes:
Jon Halld8f6de82015-12-17 17:04:34 -08002203 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002204 name="hosts-" + str( i ),
Jon Halld8f6de82015-12-17 17:04:34 -08002205 args=[ main.CLIs[i].hosts, [ None ] ],
2206 kwargs= { 'sleep': 5, 'attempts': 5,
2207 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002208 threads.append( t )
2209 t.start()
2210
2211 for t in threads:
2212 t.join()
2213 try:
2214 hosts.append( json.loads( t.result ) )
2215 except ( ValueError, TypeError ):
2216 main.log.exception( "Error parsing hosts results" )
2217 main.log.error( repr( t.result ) )
Jon Hallf3d16e72015-12-16 17:45:08 -08002218 hosts.append( None )
Jon Hall5cf14d52015-07-16 12:15:19 -07002219 for controller in range( 0, len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07002220 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hallacd1b182015-12-17 11:43:20 -08002221 if hosts[ controller ]:
2222 for host in hosts[ controller ]:
2223 if host is None or host.get( 'ipAddresses', [] ) == []:
2224 main.log.error(
2225 "Error with host ipAddresses on controller" +
2226 controllerStr + ": " + str( host ) )
2227 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002228 ports = []
2229 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002230 for i in main.activeNodes:
2231 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002232 name="ports-" + str( i ),
Jon Halla440e872016-03-31 15:15:50 -07002233 args=[ main.CLIs[i].ports, [ None ] ],
2234 kwargs= { 'sleep': 5, 'attempts': 5,
2235 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002236 threads.append( t )
2237 t.start()
2238
2239 for t in threads:
2240 t.join()
2241 ports.append( t.result )
2242 links = []
2243 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002244 for i in main.activeNodes:
2245 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002246 name="links-" + str( i ),
Jon Halla440e872016-03-31 15:15:50 -07002247 args=[ main.CLIs[i].links, [ None ] ],
2248 kwargs= { 'sleep': 5, 'attempts': 5,
2249 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002250 threads.append( t )
2251 t.start()
2252
2253 for t in threads:
2254 t.join()
2255 links.append( t.result )
2256 clusters = []
2257 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002258 for i in main.activeNodes:
2259 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002260 name="clusters-" + str( i ),
Jon Halla440e872016-03-31 15:15:50 -07002261 args=[ main.CLIs[i].clusters, [ None ] ],
2262 kwargs= { 'sleep': 5, 'attempts': 5,
2263 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002264 threads.append( t )
2265 t.start()
2266
2267 for t in threads:
2268 t.join()
2269 clusters.append( t.result )
2270
2271 elapsed = time.time() - startTime
2272 cliTime = time.time() - cliStart
2273 print "Elapsed time: " + str( elapsed )
2274 print "CLI time: " + str( cliTime )
2275
Jon Halla440e872016-03-31 15:15:50 -07002276 if all( e is None for e in devices ) and\
2277 all( e is None for e in hosts ) and\
2278 all( e is None for e in ports ) and\
2279 all( e is None for e in links ) and\
2280 all( e is None for e in clusters ):
2281 topoFailMsg = "Could not get topology from ONOS"
2282 main.log.error( topoFailMsg )
2283 continue # Try again, No use trying to compare
2284
Jon Hall5cf14d52015-07-16 12:15:19 -07002285 mnSwitches = main.Mininet1.getSwitches()
2286 mnLinks = main.Mininet1.getLinks()
2287 mnHosts = main.Mininet1.getHosts()
Jon Halla440e872016-03-31 15:15:50 -07002288 for controller in range( len( main.activeNodes ) ):
2289 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002290 if devices[ controller ] and ports[ controller ] and\
2291 "Error" not in devices[ controller ] and\
2292 "Error" not in ports[ controller ]:
2293
Jon Hallc6793552016-01-19 14:18:37 -08002294 try:
2295 currentDevicesResult = main.Mininet1.compareSwitches(
2296 mnSwitches,
2297 json.loads( devices[ controller ] ),
2298 json.loads( ports[ controller ] ) )
2299 except ( TypeError, ValueError ) as e:
2300 main.log.exception( "Object not as expected; devices={!r}\nports={!r}".format(
2301 devices[ controller ], ports[ controller ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002302 else:
2303 currentDevicesResult = main.FALSE
2304 utilities.assert_equals( expect=main.TRUE,
2305 actual=currentDevicesResult,
2306 onpass="ONOS" + controllerStr +
2307 " Switches view is correct",
2308 onfail="ONOS" + controllerStr +
2309 " Switches view is incorrect" )
2310
2311 if links[ controller ] and "Error" not in links[ controller ]:
2312 currentLinksResult = main.Mininet1.compareLinks(
2313 mnSwitches, mnLinks,
2314 json.loads( links[ controller ] ) )
2315 else:
2316 currentLinksResult = main.FALSE
2317 utilities.assert_equals( expect=main.TRUE,
2318 actual=currentLinksResult,
2319 onpass="ONOS" + controllerStr +
2320 " links view is correct",
2321 onfail="ONOS" + controllerStr +
2322 " links view is incorrect" )
Jon Hall657cdf62015-12-17 14:40:51 -08002323 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002324 currentHostsResult = main.Mininet1.compareHosts(
2325 mnHosts,
2326 hosts[ controller ] )
Jon Hall13b446e2016-01-05 12:17:01 -08002327 elif hosts[ controller ] == []:
2328 currentHostsResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002329 else:
2330 currentHostsResult = main.FALSE
2331 utilities.assert_equals( expect=main.TRUE,
2332 actual=currentHostsResult,
2333 onpass="ONOS" + controllerStr +
2334 " hosts exist in Mininet",
2335 onfail="ONOS" + controllerStr +
2336 " hosts don't match Mininet" )
2337 # CHECKING HOST ATTACHMENT POINTS
2338 hostAttachment = True
2339 zeroHosts = False
2340 # FIXME: topo-HA/obelisk specific mappings:
2341 # key is mac and value is dpid
2342 mappings = {}
2343 for i in range( 1, 29 ): # hosts 1 through 28
2344 # set up correct variables:
2345 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2346 if i == 1:
2347 deviceId = "1000".zfill(16)
2348 elif i == 2:
2349 deviceId = "2000".zfill(16)
2350 elif i == 3:
2351 deviceId = "3000".zfill(16)
2352 elif i == 4:
2353 deviceId = "3004".zfill(16)
2354 elif i == 5:
2355 deviceId = "5000".zfill(16)
2356 elif i == 6:
2357 deviceId = "6000".zfill(16)
2358 elif i == 7:
2359 deviceId = "6007".zfill(16)
2360 elif i >= 8 and i <= 17:
2361 dpid = '3' + str( i ).zfill( 3 )
2362 deviceId = dpid.zfill(16)
2363 elif i >= 18 and i <= 27:
2364 dpid = '6' + str( i ).zfill( 3 )
2365 deviceId = dpid.zfill(16)
2366 elif i == 28:
2367 deviceId = "2800".zfill(16)
2368 mappings[ macId ] = deviceId
Jon Halld8f6de82015-12-17 17:04:34 -08002369 if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002370 if hosts[ controller ] == []:
2371 main.log.warn( "There are no hosts discovered" )
2372 zeroHosts = True
2373 else:
2374 for host in hosts[ controller ]:
2375 mac = None
2376 location = None
2377 device = None
2378 port = None
2379 try:
2380 mac = host.get( 'mac' )
2381 assert mac, "mac field could not be found for this host object"
2382
2383 location = host.get( 'location' )
2384 assert location, "location field could not be found for this host object"
2385
2386 # Trim the protocol identifier off deviceId
2387 device = str( location.get( 'elementId' ) ).split(':')[1]
2388 assert device, "elementId field could not be found for this host location object"
2389
2390 port = location.get( 'port' )
2391 assert port, "port field could not be found for this host location object"
2392
2393 # Now check if this matches where they should be
2394 if mac and device and port:
2395 if str( port ) != "1":
2396 main.log.error( "The attachment port is incorrect for " +
2397 "host " + str( mac ) +
2398 ". Expected: 1 Actual: " + str( port) )
2399 hostAttachment = False
2400 if device != mappings[ str( mac ) ]:
2401 main.log.error( "The attachment device is incorrect for " +
2402 "host " + str( mac ) +
2403 ". Expected: " + mappings[ str( mac ) ] +
2404 " Actual: " + device )
2405 hostAttachment = False
2406 else:
2407 hostAttachment = False
2408 except AssertionError:
2409 main.log.exception( "Json object not as expected" )
2410 main.log.error( repr( host ) )
2411 hostAttachment = False
2412 else:
2413 main.log.error( "No hosts json output or \"Error\"" +
2414 " in output. hosts = " +
2415 repr( hosts[ controller ] ) )
2416 if zeroHosts is False:
2417 hostAttachment = True
2418
2419 # END CHECKING HOST ATTACHMENT POINTS
2420 devicesResults = devicesResults and currentDevicesResult
2421 linksResults = linksResults and currentLinksResult
2422 hostsResults = hostsResults and currentHostsResult
2423 hostAttachmentResults = hostAttachmentResults and\
2424 hostAttachment
2425 topoResult = ( devicesResults and linksResults
2426 and hostsResults and ipResult and
2427 hostAttachmentResults )
Jon Halle9b1fa32015-12-08 15:32:21 -08002428 utilities.assert_equals( expect=True,
2429 actual=topoResult,
2430 onpass="ONOS topology matches Mininet",
Jon Halla440e872016-03-31 15:15:50 -07002431 onfail=topoFailMsg )
Jon Halle9b1fa32015-12-08 15:32:21 -08002432 # End of While loop to pull ONOS state
Jon Hall5cf14d52015-07-16 12:15:19 -07002433
2434 # Compare json objects for hosts and dataplane clusters
2435
2436 # hosts
2437 main.step( "Hosts view is consistent across all ONOS nodes" )
2438 consistentHostsResult = main.TRUE
2439 for controller in range( len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07002440 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall13b446e2016-01-05 12:17:01 -08002441 if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002442 if hosts[ controller ] == hosts[ 0 ]:
2443 continue
2444 else: # hosts not consistent
2445 main.log.error( "hosts from ONOS" + controllerStr +
2446 " is inconsistent with ONOS1" )
2447 main.log.warn( repr( hosts[ controller ] ) )
2448 consistentHostsResult = main.FALSE
2449
2450 else:
2451 main.log.error( "Error in getting ONOS hosts from ONOS" +
2452 controllerStr )
2453 consistentHostsResult = main.FALSE
2454 main.log.warn( "ONOS" + controllerStr +
2455 " hosts response: " +
2456 repr( hosts[ controller ] ) )
2457 utilities.assert_equals(
2458 expect=main.TRUE,
2459 actual=consistentHostsResult,
2460 onpass="Hosts view is consistent across all ONOS nodes",
2461 onfail="ONOS nodes have different views of hosts" )
2462
2463 main.step( "Hosts information is correct" )
2464 hostsResults = hostsResults and ipResult
2465 utilities.assert_equals(
2466 expect=main.TRUE,
2467 actual=hostsResults,
2468 onpass="Host information is correct",
2469 onfail="Host information is incorrect" )
2470
2471 main.step( "Host attachment points to the network" )
2472 utilities.assert_equals(
2473 expect=True,
2474 actual=hostAttachmentResults,
2475 onpass="Hosts are correctly attached to the network",
2476 onfail="ONOS did not correctly attach hosts to the network" )
2477
2478 # Strongly connected clusters of devices
2479 main.step( "Clusters view is consistent across all ONOS nodes" )
2480 consistentClustersResult = main.TRUE
2481 for controller in range( len( clusters ) ):
Jon Halla440e872016-03-31 15:15:50 -07002482 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002483 if "Error" not in clusters[ controller ]:
2484 if clusters[ controller ] == clusters[ 0 ]:
2485 continue
2486 else: # clusters not consistent
2487 main.log.error( "clusters from ONOS" +
2488 controllerStr +
2489 " is inconsistent with ONOS1" )
2490 consistentClustersResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002491 else:
2492 main.log.error( "Error in getting dataplane clusters " +
2493 "from ONOS" + controllerStr )
2494 consistentClustersResult = main.FALSE
2495 main.log.warn( "ONOS" + controllerStr +
2496 " clusters response: " +
2497 repr( clusters[ controller ] ) )
2498 utilities.assert_equals(
2499 expect=main.TRUE,
2500 actual=consistentClustersResult,
2501 onpass="Clusters view is consistent across all ONOS nodes",
2502 onfail="ONOS nodes have different views of clusters" )
2503
2504 main.step( "There is only one SCC" )
2505 # there should always only be one cluster
2506 try:
2507 numClusters = len( json.loads( clusters[ 0 ] ) )
2508 except ( ValueError, TypeError ):
2509 main.log.exception( "Error parsing clusters[0]: " +
2510 repr( clusters[0] ) )
Jon Halla440e872016-03-31 15:15:50 -07002511 numClusters = "ERROR"
Jon Hall5cf14d52015-07-16 12:15:19 -07002512 clusterResults = main.FALSE
2513 if numClusters == 1:
2514 clusterResults = main.TRUE
2515 utilities.assert_equals(
2516 expect=1,
2517 actual=numClusters,
2518 onpass="ONOS shows 1 SCC",
2519 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2520
2521 topoResult = ( devicesResults and linksResults
2522 and hostsResults and consistentHostsResult
2523 and consistentClustersResult and clusterResults
2524 and ipResult and hostAttachmentResults )
2525
2526 topoResult = topoResult and int( count <= 2 )
2527 note = "note it takes about " + str( int( cliTime ) ) + \
2528 " seconds for the test to make all the cli calls to fetch " +\
2529 "the topology from each ONOS instance"
2530 main.log.info(
2531 "Very crass estimate for topology discovery/convergence( " +
2532 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2533 str( count ) + " tries" )
2534
2535 main.step( "Device information is correct" )
2536 utilities.assert_equals(
2537 expect=main.TRUE,
2538 actual=devicesResults,
2539 onpass="Device information is correct",
2540 onfail="Device information is incorrect" )
2541
2542 main.step( "Links are correct" )
2543 utilities.assert_equals(
2544 expect=main.TRUE,
2545 actual=linksResults,
2546 onpass="Link are correct",
2547 onfail="Links are incorrect" )
2548
2549 main.step( "Hosts are correct" )
2550 utilities.assert_equals(
2551 expect=main.TRUE,
2552 actual=hostsResults,
2553 onpass="Hosts are correct",
2554 onfail="Hosts are incorrect" )
2555
2556 # FIXME: move this to an ONOS state case
2557 main.step( "Checking ONOS nodes" )
2558 nodesOutput = []
2559 nodeResults = main.TRUE
2560 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002561 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002562 t = main.Thread( target=main.CLIs[i].nodes,
Jon Hall5cf14d52015-07-16 12:15:19 -07002563 name="nodes-" + str( i ),
2564 args=[ ] )
2565 threads.append( t )
2566 t.start()
2567
2568 for t in threads:
2569 t.join()
2570 nodesOutput.append( t.result )
Jon Halla440e872016-03-31 15:15:50 -07002571 ips = [ main.nodes[node].ip_address for node in main.activeNodes ]
Jon Halle9b1fa32015-12-08 15:32:21 -08002572 ips.sort()
Jon Hall5cf14d52015-07-16 12:15:19 -07002573 for i in nodesOutput:
2574 try:
2575 current = json.loads( i )
Jon Halle9b1fa32015-12-08 15:32:21 -08002576 activeIps = []
2577 currentResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002578 for node in current:
Jon Hallbd182782016-03-28 16:42:22 -07002579 if node['state'] == 'READY':
Jon Halle9b1fa32015-12-08 15:32:21 -08002580 activeIps.append( node['ip'] )
2581 activeIps.sort()
2582 if ips == activeIps:
2583 currentResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002584 except ( ValueError, TypeError ):
2585 main.log.error( "Error parsing nodes output" )
2586 main.log.warn( repr( i ) )
Jon Halle9b1fa32015-12-08 15:32:21 -08002587 currentResult = main.FALSE
2588 nodeResults = nodeResults and currentResult
Jon Hall5cf14d52015-07-16 12:15:19 -07002589 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2590 onpass="Nodes check successful",
2591 onfail="Nodes check NOT successful" )
Jon Halla440e872016-03-31 15:15:50 -07002592 if not nodeResults:
2593 for cli in main.CLIs:
2594 main.log.debug( "{} components not ACTIVE: \n{}".format(
2595 cli.name,
2596 cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002597
2598 def CASE9( self, main ):
2599 """
2600 Link s3-s28 down
2601 """
2602 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002603 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002604 assert main, "main not defined"
2605 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002606 assert main.CLIs, "main.CLIs not defined"
2607 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002608 # NOTE: You should probably run a topology check after this
2609
2610 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2611
2612 description = "Turn off a link to ensure that Link Discovery " +\
2613 "is working properly"
2614 main.case( description )
2615
2616 main.step( "Kill Link between s3 and s28" )
2617 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
2618 main.log.info( "Waiting " + str( linkSleep ) +
2619 " seconds for link down to be discovered" )
2620 time.sleep( linkSleep )
2621 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
2622 onpass="Link down successful",
2623 onfail="Failed to bring link down" )
2624 # TODO do some sort of check here
2625
2626 def CASE10( self, main ):
2627 """
2628 Link s3-s28 up
2629 """
2630 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002631 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002632 assert main, "main not defined"
2633 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002634 assert main.CLIs, "main.CLIs not defined"
2635 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002636 # NOTE: You should probably run a topology check after this
2637
2638 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2639
2640 description = "Restore a link to ensure that Link Discovery is " + \
2641 "working properly"
2642 main.case( description )
2643
2644 main.step( "Bring link between s3 and s28 back up" )
2645 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
2646 main.log.info( "Waiting " + str( linkSleep ) +
2647 " seconds for link up to be discovered" )
2648 time.sleep( linkSleep )
2649 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
2650 onpass="Link up successful",
2651 onfail="Failed to bring link up" )
2652 # TODO do some sort of check here
2653
2654 def CASE11( self, main ):
2655 """
2656 Switch Down
2657 """
2658 # NOTE: You should probably run a topology check after this
2659 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002660 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002661 assert main, "main not defined"
2662 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002663 assert main.CLIs, "main.CLIs not defined"
2664 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002665
2666 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2667
2668 description = "Killing a switch to ensure it is discovered correctly"
Jon Halla440e872016-03-31 15:15:50 -07002669 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002670 main.case( description )
2671 switch = main.params[ 'kill' ][ 'switch' ]
2672 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2673
2674 # TODO: Make this switch parameterizable
2675 main.step( "Kill " + switch )
2676 main.log.info( "Deleting " + switch )
2677 main.Mininet1.delSwitch( switch )
2678 main.log.info( "Waiting " + str( switchSleep ) +
2679 " seconds for switch down to be discovered" )
2680 time.sleep( switchSleep )
Jon Halla440e872016-03-31 15:15:50 -07002681 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall5cf14d52015-07-16 12:15:19 -07002682 # Peek at the deleted switch
2683 main.log.warn( str( device ) )
2684 result = main.FALSE
2685 if device and device[ 'available' ] is False:
2686 result = main.TRUE
2687 utilities.assert_equals( expect=main.TRUE, actual=result,
2688 onpass="Kill switch successful",
2689 onfail="Failed to kill switch?" )
2690
2691 def CASE12( self, main ):
2692 """
2693 Switch Up
2694 """
2695 # NOTE: You should probably run a topology check after this
2696 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002697 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002698 assert main, "main not defined"
2699 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002700 assert main.CLIs, "main.CLIs not defined"
2701 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002702 assert ONOS1Port, "ONOS1Port not defined"
2703 assert ONOS2Port, "ONOS2Port not defined"
2704 assert ONOS3Port, "ONOS3Port not defined"
2705 assert ONOS4Port, "ONOS4Port not defined"
2706 assert ONOS5Port, "ONOS5Port not defined"
2707 assert ONOS6Port, "ONOS6Port not defined"
2708 assert ONOS7Port, "ONOS7Port not defined"
2709
2710 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2711 switch = main.params[ 'kill' ][ 'switch' ]
2712 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2713 links = main.params[ 'kill' ][ 'links' ].split()
Jon Halla440e872016-03-31 15:15:50 -07002714 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002715 description = "Adding a switch to ensure it is discovered correctly"
2716 main.case( description )
2717
2718 main.step( "Add back " + switch )
2719 main.Mininet1.addSwitch( switch, dpid=switchDPID )
2720 for peer in links:
2721 main.Mininet1.addLink( switch, peer )
Jon Halla440e872016-03-31 15:15:50 -07002722 ipList = [ node.ip_address for node in main.nodes ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002723 main.Mininet1.assignSwController( sw=switch, ip=ipList )
2724 main.log.info( "Waiting " + str( switchSleep ) +
2725 " seconds for switch up to be discovered" )
2726 time.sleep( switchSleep )
Jon Halla440e872016-03-31 15:15:50 -07002727 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall5cf14d52015-07-16 12:15:19 -07002728 # Peek at the deleted switch
2729 main.log.warn( str( device ) )
2730 result = main.FALSE
2731 if device and device[ 'available' ]:
2732 result = main.TRUE
2733 utilities.assert_equals( expect=main.TRUE, actual=result,
2734 onpass="add switch successful",
2735 onfail="Failed to add switch?" )
2736
2737 def CASE13( self, main ):
2738 """
2739 Clean up
2740 """
2741 import os
2742 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002743 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002744 assert main, "main not defined"
2745 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002746 assert main.CLIs, "main.CLIs not defined"
2747 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002748
2749 # printing colors to terminal
2750 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2751 'blue': '\033[94m', 'green': '\033[92m',
2752 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
2753 main.case( "Test Cleanup" )
2754 main.step( "Killing tcpdumps" )
2755 main.Mininet2.stopTcpdump()
2756
2757 testname = main.TEST
Jon Hall96091e62015-09-21 17:34:17 -07002758 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall5cf14d52015-07-16 12:15:19 -07002759 main.step( "Copying MN pcap and ONOS log files to test station" )
2760 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
2761 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
Jon Hall96091e62015-09-21 17:34:17 -07002762 # NOTE: MN Pcap file is being saved to logdir.
2763 # We scp this file as MN and TestON aren't necessarily the same vm
2764
2765 # FIXME: To be replaced with a Jenkin's post script
Jon Hall5cf14d52015-07-16 12:15:19 -07002766 # TODO: Load these from params
2767 # NOTE: must end in /
2768 logFolder = "/opt/onos/log/"
2769 logFiles = [ "karaf.log", "karaf.log.1" ]
2770 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002771 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002772 for node in main.nodes:
Jon Halla440e872016-03-31 15:15:50 -07002773 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002774 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2775 logFolder + f, dstName )
Jon Hall5cf14d52015-07-16 12:15:19 -07002776 # std*.log's
2777 # NOTE: must end in /
2778 logFolder = "/opt/onos/var/"
2779 logFiles = [ "stderr.log", "stdout.log" ]
2780 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002781 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002782 for node in main.nodes:
Jon Halla440e872016-03-31 15:15:50 -07002783 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002784 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2785 logFolder + f, dstName )
2786 else:
2787 main.log.debug( "skipping saving log files" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002788
2789 main.step( "Stopping Mininet" )
2790 mnResult = main.Mininet1.stopNet()
2791 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2792 onpass="Mininet stopped",
2793 onfail="MN cleanup NOT successful" )
2794
2795 main.step( "Checking ONOS Logs for errors" )
Jon Halle1a3b752015-07-22 13:02:46 -07002796 for node in main.nodes:
Jon Hall96091e62015-09-21 17:34:17 -07002797 main.log.debug( "Checking logs for errors on " + node.name + ":" )
2798 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002799
2800 try:
2801 timerLog = open( main.logdir + "/Timers.csv", 'w')
2802 # Overwrite with empty line and close
2803 labels = "Gossip Intents"
2804 data = str( gossipTime )
2805 timerLog.write( labels + "\n" + data )
2806 timerLog.close()
2807 except NameError, e:
2808 main.log.exception(e)
2809
2810 def CASE14( self, main ):
2811 """
2812 start election app on all onos nodes
2813 """
Jon Halle1a3b752015-07-22 13:02:46 -07002814 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002815 assert main, "main not defined"
2816 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002817 assert main.CLIs, "main.CLIs not defined"
2818 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002819
2820 main.case("Start Leadership Election app")
2821 main.step( "Install leadership election app" )
Jon Halla440e872016-03-31 15:15:50 -07002822 onosCli = main.CLIs[ main.activeNodes[0] ]
2823 appResult = onosCli.activateApp( "org.onosproject.election" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002824 utilities.assert_equals(
2825 expect=main.TRUE,
2826 actual=appResult,
2827 onpass="Election app installed",
2828 onfail="Something went wrong with installing Leadership election" )
2829
2830 main.step( "Run for election on each node" )
2831 leaderResult = main.TRUE
2832 leaders = []
Jon Halla440e872016-03-31 15:15:50 -07002833 for i in main.activeNodes:
2834 main.CLIs[i].electionTestRun()
2835 for i in main.activeNodes:
2836 cli = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07002837 leader = cli.electionTestLeader()
2838 if leader is None or leader == main.FALSE:
2839 main.log.error( cli.name + ": Leader for the election app " +
2840 "should be an ONOS node, instead got '" +
2841 str( leader ) + "'" )
2842 leaderResult = main.FALSE
2843 leaders.append( leader )
2844 utilities.assert_equals(
2845 expect=main.TRUE,
2846 actual=leaderResult,
2847 onpass="Successfully ran for leadership",
2848 onfail="Failed to run for leadership" )
2849
2850 main.step( "Check that each node shows the same leader" )
2851 sameLeader = main.TRUE
2852 if len( set( leaders ) ) != 1:
2853 sameLeader = main.FALSE
Jon Halle1a3b752015-07-22 13:02:46 -07002854 main.log.error( "Results of electionTestLeader is order of main.CLIs:" +
Jon Hall5cf14d52015-07-16 12:15:19 -07002855 str( leaders ) )
2856 utilities.assert_equals(
2857 expect=main.TRUE,
2858 actual=sameLeader,
2859 onpass="Leadership is consistent for the election topic",
2860 onfail="Nodes have different leaders" )
2861
2862 def CASE15( self, main ):
2863 """
2864 Check that Leadership Election is still functional
acsmars71adceb2015-08-31 15:09:26 -07002865 15.1 Run election on each node
2866 15.2 Check that each node has the same leaders and candidates
2867 15.3 Find current leader and withdraw
2868 15.4 Check that a new node was elected leader
2869 15.5 Check that that new leader was the candidate of old leader
2870 15.6 Run for election on old leader
2871 15.7 Check that oldLeader is a candidate, and leader if only 1 node
2872 15.8 Make sure that the old leader was added to the candidate list
2873
2874 old and new variable prefixes refer to data from before vs after
2875 withdrawl and later before withdrawl vs after re-election
Jon Hall5cf14d52015-07-16 12:15:19 -07002876 """
2877 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002878 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002879 assert main, "main not defined"
2880 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002881 assert main.CLIs, "main.CLIs not defined"
2882 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002883
Jon Halla440e872016-03-31 15:15:50 -07002884 description = "Check that Leadership Election is still functional"
Jon Hall5cf14d52015-07-16 12:15:19 -07002885 main.case( description )
Jon Halla440e872016-03-31 15:15:50 -07002886 # NOTE: Need to re-run after restarts since being a canidate is not persistant
Jon Hall5cf14d52015-07-16 12:15:19 -07002887
Jon Halla440e872016-03-31 15:15:50 -07002888 oldLeaders = [] # list of lists of each nodes' candidates before
2889 newLeaders = [] # list of lists of each nodes' candidates after
acsmars71adceb2015-08-31 15:09:26 -07002890 oldLeader = '' # the old leader from oldLeaders, None if not same
2891 newLeader = '' # the new leaders fron newLoeaders, None if not same
2892 oldLeaderCLI = None # the CLI of the old leader used for re-electing
2893 expectNoLeader = False # True when there is only one leader
2894 if main.numCtrls == 1:
2895 expectNoLeader = True
2896
2897 main.step( "Run for election on each node" )
2898 electionResult = main.TRUE
2899
Jon Halla440e872016-03-31 15:15:50 -07002900 for i in main.activeNodes: # run test election on each node
2901 if main.CLIs[i].electionTestRun() == main.FALSE:
acsmars71adceb2015-08-31 15:09:26 -07002902 electionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002903 utilities.assert_equals(
2904 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002905 actual=electionResult,
2906 onpass="All nodes successfully ran for leadership",
2907 onfail="At least one node failed to run for leadership" )
2908
acsmars3a72bde2015-09-02 14:16:22 -07002909 if electionResult == main.FALSE:
2910 main.log.error(
Jon Halla440e872016-03-31 15:15:50 -07002911 "Skipping Test Case because Election Test App isn't loaded" )
acsmars3a72bde2015-09-02 14:16:22 -07002912 main.skipCase()
2913
acsmars71adceb2015-08-31 15:09:26 -07002914 main.step( "Check that each node shows the same leader and candidates" )
Jon Halla440e872016-03-31 15:15:50 -07002915 failMessage = "Nodes have different leaderboards"
2916 def consistentLeaderboards( nodes ):
2917 TOPIC = 'org.onosproject.election'
2918 # FIXME: use threads
2919 #FIXME: should we retry outside the function?
2920 for n in range( 5 ): # Retry in case election is still happening
2921 leaderList = []
2922 # Get all leaderboards
2923 for cli in nodes:
2924 leaderList.append( cli.specificLeaderCandidate( TOPIC ) )
2925 # Compare leaderboards
2926 result = all( i == leaderList[0] for i in leaderList ) and\
2927 leaderList is not None
2928 main.log.debug( leaderList )
2929 main.log.warn( result )
2930 if result:
2931 return ( result, leaderList )
2932 time.sleep(5) #TODO: paramerterize
2933 main.log.error( "Inconsistent leaderboards:" + str( leaderList ) )
2934 activeCLIs = [ main.CLIs[i] for i in main.activeNodes ]
2935 sameResult, oldLeaders = consistentLeaderboards( activeCLIs )
2936 if sameResult:
2937 oldLeader = oldLeaders[ 0 ][ 0 ]
2938 main.log.warn( oldLeader )
acsmars71adceb2015-08-31 15:09:26 -07002939 else:
Jon Halla440e872016-03-31 15:15:50 -07002940 oldLeader = None
acsmars71adceb2015-08-31 15:09:26 -07002941 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07002942 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07002943 actual=sameResult,
Jon Halla440e872016-03-31 15:15:50 -07002944 onpass="Leaderboards are consistent for the election topic",
acsmars71adceb2015-08-31 15:09:26 -07002945 onfail=failMessage )
Jon Hall5cf14d52015-07-16 12:15:19 -07002946
2947 main.step( "Find current leader and withdraw" )
acsmars71adceb2015-08-31 15:09:26 -07002948 withdrawResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002949 # do some sanity checking on leader before using it
acsmars71adceb2015-08-31 15:09:26 -07002950 if oldLeader is None:
2951 main.log.error( "Leadership isn't consistent." )
2952 withdrawResult = main.FALSE
2953 # Get the CLI of the oldLeader
Jon Halla440e872016-03-31 15:15:50 -07002954 for i in main.activeNodes:
acsmars71adceb2015-08-31 15:09:26 -07002955 if oldLeader == main.nodes[ i ].ip_address:
2956 oldLeaderCLI = main.CLIs[ i ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002957 break
2958 else: # FOR/ELSE statement
2959 main.log.error( "Leader election, could not find current leader" )
2960 if oldLeader:
acsmars71adceb2015-08-31 15:09:26 -07002961 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall5cf14d52015-07-16 12:15:19 -07002962 utilities.assert_equals(
2963 expect=main.TRUE,
2964 actual=withdrawResult,
2965 onpass="Node was withdrawn from election",
2966 onfail="Node was not withdrawn from election" )
2967
acsmars71adceb2015-08-31 15:09:26 -07002968 main.step( "Check that a new node was elected leader" )
acsmars71adceb2015-08-31 15:09:26 -07002969 failMessage = "Nodes have different leaders"
acsmars71adceb2015-08-31 15:09:26 -07002970 # Get new leaders and candidates
Jon Halla440e872016-03-31 15:15:50 -07002971 newLeaderResult, newLeaders = consistentLeaderboards( activeCLIs )
2972 if newLeaders[ 0 ][ 0 ] == 'none':
2973 main.log.error( "No leader was elected on at least 1 node" )
2974 if not expectNoLeader:
2975 newLeaderResult = False
2976 if newLeaderResult:
2977 newLeader = newLeaders[ 0 ][ 0 ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002978 else:
Jon Halla440e872016-03-31 15:15:50 -07002979 newLeader = None
acsmars71adceb2015-08-31 15:09:26 -07002980
2981 # Check that the new leader is not the older leader, which was withdrawn
2982 if newLeader == oldLeader:
Jon Halla440e872016-03-31 15:15:50 -07002983 newLeaderResult = False
Jon Hall6e709752016-02-01 13:38:46 -08002984 main.log.error( "All nodes still see old leader: " + str( oldLeader ) +
acsmars71adceb2015-08-31 15:09:26 -07002985 " as the current leader" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002986 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07002987 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07002988 actual=newLeaderResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002989 onpass="Leadership election passed",
2990 onfail="Something went wrong with Leadership election" )
2991
Jon Halla440e872016-03-31 15:15:50 -07002992 main.step( "Check that that new leader was the candidate of old leader" )
2993 # candidates[ 2 ] should become the top candidate after withdrawl
acsmars71adceb2015-08-31 15:09:26 -07002994 correctCandidateResult = main.TRUE
2995 if expectNoLeader:
2996 if newLeader == 'none':
2997 main.log.info( "No leader expected. None found. Pass" )
2998 correctCandidateResult = main.TRUE
2999 else:
3000 main.log.info( "Expected no leader, got: " + str( newLeader ) )
3001 correctCandidateResult = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003002 elif len( oldLeaders[0] ) >= 3:
3003 if newLeader == oldLeaders[ 0 ][ 2 ]:
3004 # correct leader was elected
3005 correctCandidateResult = main.TRUE
3006 else:
3007 correctCandidateResult = main.FALSE
3008 main.log.error( "Candidate {} was elected. {} should have had priority.".format(
3009 newLeader, oldLeaders[ 0 ][ 2 ] ) )
3010 else:
3011 main.log.warn( "Could not determine who should be the correct leader" )
3012 main.log.debug( oldLeaders[ 0 ] )
acsmars71adceb2015-08-31 15:09:26 -07003013 correctCandidateResult = main.FALSE
acsmars71adceb2015-08-31 15:09:26 -07003014 utilities.assert_equals(
3015 expect=main.TRUE,
3016 actual=correctCandidateResult,
3017 onpass="Correct Candidate Elected",
3018 onfail="Incorrect Candidate Elected" )
3019
Jon Hall5cf14d52015-07-16 12:15:19 -07003020 main.step( "Run for election on old leader( just so everyone " +
3021 "is in the hat )" )
acsmars71adceb2015-08-31 15:09:26 -07003022 if oldLeaderCLI is not None:
3023 runResult = oldLeaderCLI.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07003024 else:
acsmars71adceb2015-08-31 15:09:26 -07003025 main.log.error( "No old leader to re-elect" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003026 runResult = main.FALSE
3027 utilities.assert_equals(
3028 expect=main.TRUE,
3029 actual=runResult,
3030 onpass="App re-ran for election",
3031 onfail="App failed to run for election" )
Jon Halla440e872016-03-31 15:15:50 -07003032
acsmars71adceb2015-08-31 15:09:26 -07003033 main.step(
3034 "Check that oldLeader is a candidate, and leader if only 1 node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003035 # verify leader didn't just change
Jon Halla440e872016-03-31 15:15:50 -07003036 # Get new leaders and candidates
3037 reRunLeaders = []
3038 time.sleep( 5 ) # Paremterize
3039 positionResult, reRunLeaders = consistentLeaderboards( activeCLIs )
acsmars71adceb2015-08-31 15:09:26 -07003040
3041 # Check that the re-elected node is last on the candidate List
Jon Halla440e872016-03-31 15:15:50 -07003042 if oldLeader != reRunLeaders[ 0 ][ -1 ]:
3043 main.log.error( "Old Leader ({}) not in the proper position: {} ".format( str( oldLeader),
3044 str( reRunLeaders[ 0 ] ) ) )
acsmars71adceb2015-08-31 15:09:26 -07003045 positionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07003046
3047 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07003048 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07003049 actual=positionResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07003050 onpass="Old leader successfully re-ran for election",
3051 onfail="Something went wrong with Leadership election after " +
3052 "the old leader re-ran for election" )
3053
3054 def CASE16( self, main ):
3055 """
3056 Install Distributed Primitives app
3057 """
3058 import time
Jon Halle1a3b752015-07-22 13:02:46 -07003059 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003060 assert main, "main not defined"
3061 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003062 assert main.CLIs, "main.CLIs not defined"
3063 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003064
3065 # Variables for the distributed primitives tests
3066 global pCounterName
Jon Hall5cf14d52015-07-16 12:15:19 -07003067 global pCounterValue
Jon Hall5cf14d52015-07-16 12:15:19 -07003068 global onosSet
3069 global onosSetName
3070 pCounterName = "TestON-Partitions"
Jon Hall5cf14d52015-07-16 12:15:19 -07003071 pCounterValue = 0
Jon Hall5cf14d52015-07-16 12:15:19 -07003072 onosSet = set([])
3073 onosSetName = "TestON-set"
3074
3075 description = "Install Primitives app"
3076 main.case( description )
3077 main.step( "Install Primitives app" )
3078 appName = "org.onosproject.distributedprimitives"
Jon Halla440e872016-03-31 15:15:50 -07003079 node = main.activeNodes[0]
3080 appResults = main.CLIs[node].activateApp( appName )
Jon Hall5cf14d52015-07-16 12:15:19 -07003081 utilities.assert_equals( expect=main.TRUE,
3082 actual=appResults,
3083 onpass="Primitives app activated",
3084 onfail="Primitives app not activated" )
3085 time.sleep( 5 ) # To allow all nodes to activate
3086
3087 def CASE17( self, main ):
3088 """
3089 Check for basic functionality with distributed primitives
3090 """
Jon Hall5cf14d52015-07-16 12:15:19 -07003091 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07003092 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003093 assert main, "main not defined"
3094 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003095 assert main.CLIs, "main.CLIs not defined"
3096 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003097 assert pCounterName, "pCounterName not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003098 assert onosSetName, "onosSetName not defined"
3099 # NOTE: assert fails if value is 0/None/Empty/False
3100 try:
3101 pCounterValue
3102 except NameError:
3103 main.log.error( "pCounterValue not defined, setting to 0" )
3104 pCounterValue = 0
3105 try:
Jon Hall5cf14d52015-07-16 12:15:19 -07003106 onosSet
3107 except NameError:
3108 main.log.error( "onosSet not defined, setting to empty Set" )
3109 onosSet = set([])
3110 # Variables for the distributed primitives tests. These are local only
3111 addValue = "a"
3112 addAllValue = "a b c d e f"
3113 retainValue = "c d e f"
3114
3115 description = "Check for basic functionality with distributed " +\
3116 "primitives"
3117 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07003118 main.caseExplanation = "Test the methods of the distributed " +\
3119 "primitives (counters and sets) throught the cli"
Jon Hall5cf14d52015-07-16 12:15:19 -07003120 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07003121 # Partitioned counters
3122 main.step( "Increment then get a default counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003123 pCounters = []
3124 threads = []
3125 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003126 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003127 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3128 name="counterAddAndGet-" + str( i ),
Jon Hall5cf14d52015-07-16 12:15:19 -07003129 args=[ pCounterName ] )
3130 pCounterValue += 1
3131 addedPValues.append( pCounterValue )
3132 threads.append( t )
3133 t.start()
3134
3135 for t in threads:
3136 t.join()
3137 pCounters.append( t.result )
3138 # Check that counter incremented numController times
3139 pCounterResults = True
3140 for i in addedPValues:
3141 tmpResult = i in pCounters
3142 pCounterResults = pCounterResults and tmpResult
3143 if not tmpResult:
3144 main.log.error( str( i ) + " is not in partitioned "
3145 "counter incremented results" )
3146 utilities.assert_equals( expect=True,
3147 actual=pCounterResults,
3148 onpass="Default counter incremented",
3149 onfail="Error incrementing default" +
3150 " counter" )
3151
Jon Halle1a3b752015-07-22 13:02:46 -07003152 main.step( "Get then Increment a default counter on each node" )
3153 pCounters = []
3154 threads = []
3155 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003156 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003157 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3158 name="counterGetAndAdd-" + str( i ),
3159 args=[ pCounterName ] )
3160 addedPValues.append( pCounterValue )
3161 pCounterValue += 1
3162 threads.append( t )
3163 t.start()
3164
3165 for t in threads:
3166 t.join()
3167 pCounters.append( t.result )
3168 # Check that counter incremented numController times
3169 pCounterResults = True
3170 for i in addedPValues:
3171 tmpResult = i in pCounters
3172 pCounterResults = pCounterResults and tmpResult
3173 if not tmpResult:
3174 main.log.error( str( i ) + " is not in partitioned "
3175 "counter incremented results" )
3176 utilities.assert_equals( expect=True,
3177 actual=pCounterResults,
3178 onpass="Default counter incremented",
3179 onfail="Error incrementing default" +
3180 " counter" )
3181
3182 main.step( "Counters we added have the correct values" )
3183 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3184 utilities.assert_equals( expect=main.TRUE,
3185 actual=incrementCheck,
3186 onpass="Added counters are correct",
3187 onfail="Added counters are incorrect" )
3188
3189 main.step( "Add -8 to then get a default counter on each node" )
3190 pCounters = []
3191 threads = []
3192 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003193 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003194 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3195 name="counterIncrement-" + str( i ),
3196 args=[ pCounterName ],
3197 kwargs={ "delta": -8 } )
3198 pCounterValue += -8
3199 addedPValues.append( pCounterValue )
3200 threads.append( t )
3201 t.start()
3202
3203 for t in threads:
3204 t.join()
3205 pCounters.append( t.result )
3206 # Check that counter incremented numController times
3207 pCounterResults = True
3208 for i in addedPValues:
3209 tmpResult = i in pCounters
3210 pCounterResults = pCounterResults and tmpResult
3211 if not tmpResult:
3212 main.log.error( str( i ) + " is not in partitioned "
3213 "counter incremented results" )
3214 utilities.assert_equals( expect=True,
3215 actual=pCounterResults,
3216 onpass="Default counter incremented",
3217 onfail="Error incrementing default" +
3218 " counter" )
3219
3220 main.step( "Add 5 to then get a default counter on each node" )
3221 pCounters = []
3222 threads = []
3223 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003224 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003225 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3226 name="counterIncrement-" + str( i ),
3227 args=[ pCounterName ],
3228 kwargs={ "delta": 5 } )
3229 pCounterValue += 5
3230 addedPValues.append( pCounterValue )
3231 threads.append( t )
3232 t.start()
3233
3234 for t in threads:
3235 t.join()
3236 pCounters.append( t.result )
3237 # Check that counter incremented numController times
3238 pCounterResults = True
3239 for i in addedPValues:
3240 tmpResult = i in pCounters
3241 pCounterResults = pCounterResults and tmpResult
3242 if not tmpResult:
3243 main.log.error( str( i ) + " is not in partitioned "
3244 "counter incremented results" )
3245 utilities.assert_equals( expect=True,
3246 actual=pCounterResults,
3247 onpass="Default counter incremented",
3248 onfail="Error incrementing default" +
3249 " counter" )
3250
3251 main.step( "Get then add 5 to a default counter on each node" )
3252 pCounters = []
3253 threads = []
3254 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003255 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003256 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3257 name="counterIncrement-" + str( i ),
3258 args=[ pCounterName ],
3259 kwargs={ "delta": 5 } )
3260 addedPValues.append( pCounterValue )
3261 pCounterValue += 5
3262 threads.append( t )
3263 t.start()
3264
3265 for t in threads:
3266 t.join()
3267 pCounters.append( t.result )
3268 # Check that counter incremented numController times
3269 pCounterResults = True
3270 for i in addedPValues:
3271 tmpResult = i in pCounters
3272 pCounterResults = pCounterResults and tmpResult
3273 if not tmpResult:
3274 main.log.error( str( i ) + " is not in partitioned "
3275 "counter incremented results" )
3276 utilities.assert_equals( expect=True,
3277 actual=pCounterResults,
3278 onpass="Default counter incremented",
3279 onfail="Error incrementing default" +
3280 " counter" )
3281
3282 main.step( "Counters we added have the correct values" )
3283 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3284 utilities.assert_equals( expect=main.TRUE,
3285 actual=incrementCheck,
3286 onpass="Added counters are correct",
3287 onfail="Added counters are incorrect" )
3288
Jon Hall5cf14d52015-07-16 12:15:19 -07003289 # DISTRIBUTED SETS
3290 main.step( "Distributed Set get" )
3291 size = len( onosSet )
3292 getResponses = []
3293 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003294 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003295 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003296 name="setTestGet-" + str( i ),
3297 args=[ onosSetName ] )
3298 threads.append( t )
3299 t.start()
3300 for t in threads:
3301 t.join()
3302 getResponses.append( t.result )
3303
3304 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003305 for i in range( len( main.activeNodes ) ):
3306 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003307 if isinstance( getResponses[ i ], list):
3308 current = set( getResponses[ i ] )
3309 if len( current ) == len( getResponses[ i ] ):
3310 # no repeats
3311 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07003312 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003313 " has incorrect view" +
3314 " of set " + onosSetName + ":\n" +
3315 str( getResponses[ i ] ) )
3316 main.log.debug( "Expected: " + str( onosSet ) )
3317 main.log.debug( "Actual: " + str( current ) )
3318 getResults = main.FALSE
3319 else:
3320 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003321 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003322 " has repeat elements in" +
3323 " set " + onosSetName + ":\n" +
3324 str( getResponses[ i ] ) )
3325 getResults = main.FALSE
3326 elif getResponses[ i ] == main.ERROR:
3327 getResults = main.FALSE
3328 utilities.assert_equals( expect=main.TRUE,
3329 actual=getResults,
3330 onpass="Set elements are correct",
3331 onfail="Set elements are incorrect" )
3332
3333 main.step( "Distributed Set size" )
3334 sizeResponses = []
3335 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003336 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003337 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003338 name="setTestSize-" + str( i ),
3339 args=[ onosSetName ] )
3340 threads.append( t )
3341 t.start()
3342 for t in threads:
3343 t.join()
3344 sizeResponses.append( t.result )
3345
3346 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003347 for i in range( len( main.activeNodes ) ):
3348 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003349 if size != sizeResponses[ i ]:
3350 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003351 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003352 " expected a size of " + str( size ) +
3353 " for set " + onosSetName +
3354 " but got " + str( sizeResponses[ i ] ) )
3355 utilities.assert_equals( expect=main.TRUE,
3356 actual=sizeResults,
3357 onpass="Set sizes are correct",
3358 onfail="Set sizes are incorrect" )
3359
3360 main.step( "Distributed Set add()" )
3361 onosSet.add( addValue )
3362 addResponses = []
3363 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003364 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003365 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003366 name="setTestAdd-" + str( i ),
3367 args=[ onosSetName, addValue ] )
3368 threads.append( t )
3369 t.start()
3370 for t in threads:
3371 t.join()
3372 addResponses.append( t.result )
3373
3374 # main.TRUE = successfully changed the set
3375 # main.FALSE = action resulted in no change in set
3376 # main.ERROR - Some error in executing the function
3377 addResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003378 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003379 if addResponses[ i ] == main.TRUE:
3380 # All is well
3381 pass
3382 elif addResponses[ i ] == main.FALSE:
3383 # Already in set, probably fine
3384 pass
3385 elif addResponses[ i ] == main.ERROR:
3386 # Error in execution
3387 addResults = main.FALSE
3388 else:
3389 # unexpected result
3390 addResults = main.FALSE
3391 if addResults != main.TRUE:
3392 main.log.error( "Error executing set add" )
3393
3394 # Check if set is still correct
3395 size = len( onosSet )
3396 getResponses = []
3397 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003398 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003399 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003400 name="setTestGet-" + str( i ),
3401 args=[ onosSetName ] )
3402 threads.append( t )
3403 t.start()
3404 for t in threads:
3405 t.join()
3406 getResponses.append( t.result )
3407 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003408 for i in range( len( main.activeNodes ) ):
3409 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003410 if isinstance( getResponses[ i ], list):
3411 current = set( getResponses[ i ] )
3412 if len( current ) == len( getResponses[ i ] ):
3413 # no repeats
3414 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07003415 main.log.error( "ONOS" + node + " has incorrect view" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003416 " of set " + onosSetName + ":\n" +
3417 str( getResponses[ i ] ) )
3418 main.log.debug( "Expected: " + str( onosSet ) )
3419 main.log.debug( "Actual: " + str( current ) )
3420 getResults = main.FALSE
3421 else:
3422 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003423 main.log.error( "ONOS" + node + " has repeat elements in" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003424 " set " + onosSetName + ":\n" +
3425 str( getResponses[ i ] ) )
3426 getResults = main.FALSE
3427 elif getResponses[ i ] == main.ERROR:
3428 getResults = main.FALSE
3429 sizeResponses = []
3430 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003431 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003432 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003433 name="setTestSize-" + str( i ),
3434 args=[ onosSetName ] )
3435 threads.append( t )
3436 t.start()
3437 for t in threads:
3438 t.join()
3439 sizeResponses.append( t.result )
3440 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003441 for i in range( len( main.activeNodes ) ):
3442 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003443 if size != sizeResponses[ i ]:
3444 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003445 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003446 " expected a size of " + str( size ) +
3447 " for set " + onosSetName +
3448 " but got " + str( sizeResponses[ i ] ) )
3449 addResults = addResults and getResults and sizeResults
3450 utilities.assert_equals( expect=main.TRUE,
3451 actual=addResults,
3452 onpass="Set add correct",
3453 onfail="Set add was incorrect" )
3454
3455 main.step( "Distributed Set addAll()" )
3456 onosSet.update( addAllValue.split() )
3457 addResponses = []
3458 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003459 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003460 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003461 name="setTestAddAll-" + str( i ),
3462 args=[ onosSetName, addAllValue ] )
3463 threads.append( t )
3464 t.start()
3465 for t in threads:
3466 t.join()
3467 addResponses.append( t.result )
3468
3469 # main.TRUE = successfully changed the set
3470 # main.FALSE = action resulted in no change in set
3471 # main.ERROR - Some error in executing the function
3472 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003473 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003474 if addResponses[ i ] == main.TRUE:
3475 # All is well
3476 pass
3477 elif addResponses[ i ] == main.FALSE:
3478 # Already in set, probably fine
3479 pass
3480 elif addResponses[ i ] == main.ERROR:
3481 # Error in execution
3482 addAllResults = main.FALSE
3483 else:
3484 # unexpected result
3485 addAllResults = main.FALSE
3486 if addAllResults != main.TRUE:
3487 main.log.error( "Error executing set addAll" )
3488
3489 # Check if set is still correct
3490 size = len( onosSet )
3491 getResponses = []
3492 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003493 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003494 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003495 name="setTestGet-" + str( i ),
3496 args=[ onosSetName ] )
3497 threads.append( t )
3498 t.start()
3499 for t in threads:
3500 t.join()
3501 getResponses.append( t.result )
3502 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003503 for i in range( len( main.activeNodes ) ):
3504 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003505 if isinstance( getResponses[ i ], list):
3506 current = set( getResponses[ i ] )
3507 if len( current ) == len( getResponses[ i ] ):
3508 # no repeats
3509 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07003510 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003511 " has incorrect view" +
3512 " of set " + onosSetName + ":\n" +
3513 str( getResponses[ i ] ) )
3514 main.log.debug( "Expected: " + str( onosSet ) )
3515 main.log.debug( "Actual: " + str( current ) )
3516 getResults = main.FALSE
3517 else:
3518 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003519 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003520 " has repeat elements in" +
3521 " set " + onosSetName + ":\n" +
3522 str( getResponses[ i ] ) )
3523 getResults = main.FALSE
3524 elif getResponses[ i ] == main.ERROR:
3525 getResults = main.FALSE
3526 sizeResponses = []
3527 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003528 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003529 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003530 name="setTestSize-" + str( i ),
3531 args=[ onosSetName ] )
3532 threads.append( t )
3533 t.start()
3534 for t in threads:
3535 t.join()
3536 sizeResponses.append( t.result )
3537 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003538 for i in range( len( main.activeNodes ) ):
3539 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003540 if size != sizeResponses[ i ]:
3541 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003542 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003543 " expected a size of " + str( size ) +
3544 " for set " + onosSetName +
3545 " but got " + str( sizeResponses[ i ] ) )
3546 addAllResults = addAllResults and getResults and sizeResults
3547 utilities.assert_equals( expect=main.TRUE,
3548 actual=addAllResults,
3549 onpass="Set addAll correct",
3550 onfail="Set addAll was incorrect" )
3551
3552 main.step( "Distributed Set contains()" )
3553 containsResponses = []
3554 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003555 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003556 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003557 name="setContains-" + str( i ),
3558 args=[ onosSetName ],
3559 kwargs={ "values": addValue } )
3560 threads.append( t )
3561 t.start()
3562 for t in threads:
3563 t.join()
3564 # NOTE: This is the tuple
3565 containsResponses.append( t.result )
3566
3567 containsResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003568 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003569 if containsResponses[ i ] == main.ERROR:
3570 containsResults = main.FALSE
3571 else:
3572 containsResults = containsResults and\
3573 containsResponses[ i ][ 1 ]
3574 utilities.assert_equals( expect=main.TRUE,
3575 actual=containsResults,
3576 onpass="Set contains is functional",
3577 onfail="Set contains failed" )
3578
3579 main.step( "Distributed Set containsAll()" )
3580 containsAllResponses = []
3581 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003582 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003583 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003584 name="setContainsAll-" + str( i ),
3585 args=[ onosSetName ],
3586 kwargs={ "values": addAllValue } )
3587 threads.append( t )
3588 t.start()
3589 for t in threads:
3590 t.join()
3591 # NOTE: This is the tuple
3592 containsAllResponses.append( t.result )
3593
3594 containsAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003595 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003596 if containsResponses[ i ] == main.ERROR:
3597 containsResults = main.FALSE
3598 else:
3599 containsResults = containsResults and\
3600 containsResponses[ i ][ 1 ]
3601 utilities.assert_equals( expect=main.TRUE,
3602 actual=containsAllResults,
3603 onpass="Set containsAll is functional",
3604 onfail="Set containsAll failed" )
3605
3606 main.step( "Distributed Set remove()" )
3607 onosSet.remove( addValue )
3608 removeResponses = []
3609 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003610 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003611 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003612 name="setTestRemove-" + str( i ),
3613 args=[ onosSetName, addValue ] )
3614 threads.append( t )
3615 t.start()
3616 for t in threads:
3617 t.join()
3618 removeResponses.append( t.result )
3619
3620 # main.TRUE = successfully changed the set
3621 # main.FALSE = action resulted in no change in set
3622 # main.ERROR - Some error in executing the function
3623 removeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003624 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003625 if removeResponses[ i ] == main.TRUE:
3626 # All is well
3627 pass
3628 elif removeResponses[ i ] == main.FALSE:
3629 # not in set, probably fine
3630 pass
3631 elif removeResponses[ i ] == main.ERROR:
3632 # Error in execution
3633 removeResults = main.FALSE
3634 else:
3635 # unexpected result
3636 removeResults = main.FALSE
3637 if removeResults != main.TRUE:
3638 main.log.error( "Error executing set remove" )
3639
3640 # Check if set is still correct
3641 size = len( onosSet )
3642 getResponses = []
3643 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003644 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003645 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003646 name="setTestGet-" + str( i ),
3647 args=[ onosSetName ] )
3648 threads.append( t )
3649 t.start()
3650 for t in threads:
3651 t.join()
3652 getResponses.append( t.result )
3653 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003654 for i in range( len( main.activeNodes ) ):
3655 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003656 if isinstance( getResponses[ i ], list):
3657 current = set( getResponses[ i ] )
3658 if len( current ) == len( getResponses[ i ] ):
3659 # no repeats
3660 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07003661 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003662 " has incorrect view" +
3663 " of set " + onosSetName + ":\n" +
3664 str( getResponses[ i ] ) )
3665 main.log.debug( "Expected: " + str( onosSet ) )
3666 main.log.debug( "Actual: " + str( current ) )
3667 getResults = main.FALSE
3668 else:
3669 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003670 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003671 " has repeat elements in" +
3672 " set " + onosSetName + ":\n" +
3673 str( getResponses[ i ] ) )
3674 getResults = main.FALSE
3675 elif getResponses[ i ] == main.ERROR:
3676 getResults = main.FALSE
3677 sizeResponses = []
3678 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003679 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003680 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003681 name="setTestSize-" + str( i ),
3682 args=[ onosSetName ] )
3683 threads.append( t )
3684 t.start()
3685 for t in threads:
3686 t.join()
3687 sizeResponses.append( t.result )
3688 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003689 for i in range( len( main.activeNodes ) ):
3690 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003691 if size != sizeResponses[ i ]:
3692 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003693 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003694 " expected a size of " + str( size ) +
3695 " for set " + onosSetName +
3696 " but got " + str( sizeResponses[ i ] ) )
3697 removeResults = removeResults and getResults and sizeResults
3698 utilities.assert_equals( expect=main.TRUE,
3699 actual=removeResults,
3700 onpass="Set remove correct",
3701 onfail="Set remove was incorrect" )
3702
3703 main.step( "Distributed Set removeAll()" )
3704 onosSet.difference_update( addAllValue.split() )
3705 removeAllResponses = []
3706 threads = []
3707 try:
Jon Halla440e872016-03-31 15:15:50 -07003708 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003709 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003710 name="setTestRemoveAll-" + str( i ),
3711 args=[ onosSetName, addAllValue ] )
3712 threads.append( t )
3713 t.start()
3714 for t in threads:
3715 t.join()
3716 removeAllResponses.append( t.result )
3717 except Exception, e:
3718 main.log.exception(e)
3719
3720 # main.TRUE = successfully changed the set
3721 # main.FALSE = action resulted in no change in set
3722 # main.ERROR - Some error in executing the function
3723 removeAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003724 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003725 if removeAllResponses[ i ] == main.TRUE:
3726 # All is well
3727 pass
3728 elif removeAllResponses[ i ] == main.FALSE:
3729 # not in set, probably fine
3730 pass
3731 elif removeAllResponses[ i ] == main.ERROR:
3732 # Error in execution
3733 removeAllResults = main.FALSE
3734 else:
3735 # unexpected result
3736 removeAllResults = main.FALSE
3737 if removeAllResults != main.TRUE:
3738 main.log.error( "Error executing set removeAll" )
3739
3740 # Check if set is still correct
3741 size = len( onosSet )
3742 getResponses = []
3743 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003744 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003745 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003746 name="setTestGet-" + str( i ),
3747 args=[ onosSetName ] )
3748 threads.append( t )
3749 t.start()
3750 for t in threads:
3751 t.join()
3752 getResponses.append( t.result )
3753 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003754 for i in range( len( main.activeNodes ) ):
3755 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003756 if isinstance( getResponses[ i ], list):
3757 current = set( getResponses[ i ] )
3758 if len( current ) == len( getResponses[ i ] ):
3759 # no repeats
3760 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07003761 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003762 " has incorrect view" +
3763 " of set " + onosSetName + ":\n" +
3764 str( getResponses[ i ] ) )
3765 main.log.debug( "Expected: " + str( onosSet ) )
3766 main.log.debug( "Actual: " + str( current ) )
3767 getResults = main.FALSE
3768 else:
3769 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003770 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003771 " has repeat elements in" +
3772 " set " + onosSetName + ":\n" +
3773 str( getResponses[ i ] ) )
3774 getResults = main.FALSE
3775 elif getResponses[ i ] == main.ERROR:
3776 getResults = main.FALSE
3777 sizeResponses = []
3778 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003779 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003780 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003781 name="setTestSize-" + str( i ),
3782 args=[ onosSetName ] )
3783 threads.append( t )
3784 t.start()
3785 for t in threads:
3786 t.join()
3787 sizeResponses.append( t.result )
3788 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003789 for i in range( len( main.activeNodes ) ):
3790 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003791 if size != sizeResponses[ i ]:
3792 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003793 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003794 " expected a size of " + str( size ) +
3795 " for set " + onosSetName +
3796 " but got " + str( sizeResponses[ i ] ) )
3797 removeAllResults = removeAllResults and getResults and sizeResults
3798 utilities.assert_equals( expect=main.TRUE,
3799 actual=removeAllResults,
3800 onpass="Set removeAll correct",
3801 onfail="Set removeAll was incorrect" )
3802
3803 main.step( "Distributed Set addAll()" )
3804 onosSet.update( addAllValue.split() )
3805 addResponses = []
3806 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003807 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003808 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003809 name="setTestAddAll-" + str( i ),
3810 args=[ onosSetName, addAllValue ] )
3811 threads.append( t )
3812 t.start()
3813 for t in threads:
3814 t.join()
3815 addResponses.append( t.result )
3816
3817 # main.TRUE = successfully changed the set
3818 # main.FALSE = action resulted in no change in set
3819 # main.ERROR - Some error in executing the function
3820 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003821 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003822 if addResponses[ i ] == main.TRUE:
3823 # All is well
3824 pass
3825 elif addResponses[ i ] == main.FALSE:
3826 # Already in set, probably fine
3827 pass
3828 elif addResponses[ i ] == main.ERROR:
3829 # Error in execution
3830 addAllResults = main.FALSE
3831 else:
3832 # unexpected result
3833 addAllResults = main.FALSE
3834 if addAllResults != main.TRUE:
3835 main.log.error( "Error executing set addAll" )
3836
3837 # Check if set is still correct
3838 size = len( onosSet )
3839 getResponses = []
3840 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003841 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003842 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003843 name="setTestGet-" + str( i ),
3844 args=[ onosSetName ] )
3845 threads.append( t )
3846 t.start()
3847 for t in threads:
3848 t.join()
3849 getResponses.append( t.result )
3850 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003851 for i in range( len( main.activeNodes ) ):
3852 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003853 if isinstance( getResponses[ i ], list):
3854 current = set( getResponses[ i ] )
3855 if len( current ) == len( getResponses[ i ] ):
3856 # no repeats
3857 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07003858 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003859 " has incorrect view" +
3860 " of set " + onosSetName + ":\n" +
3861 str( getResponses[ i ] ) )
3862 main.log.debug( "Expected: " + str( onosSet ) )
3863 main.log.debug( "Actual: " + str( current ) )
3864 getResults = main.FALSE
3865 else:
3866 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003867 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003868 " has repeat elements in" +
3869 " set " + onosSetName + ":\n" +
3870 str( getResponses[ i ] ) )
3871 getResults = main.FALSE
3872 elif getResponses[ i ] == main.ERROR:
3873 getResults = main.FALSE
3874 sizeResponses = []
3875 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003876 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003877 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003878 name="setTestSize-" + str( i ),
3879 args=[ onosSetName ] )
3880 threads.append( t )
3881 t.start()
3882 for t in threads:
3883 t.join()
3884 sizeResponses.append( t.result )
3885 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003886 for i in range( len( main.activeNodes ) ):
3887 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003888 if size != sizeResponses[ i ]:
3889 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003890 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003891 " expected a size of " + str( size ) +
3892 " for set " + onosSetName +
3893 " but got " + str( sizeResponses[ i ] ) )
3894 addAllResults = addAllResults and getResults and sizeResults
3895 utilities.assert_equals( expect=main.TRUE,
3896 actual=addAllResults,
3897 onpass="Set addAll correct",
3898 onfail="Set addAll was incorrect" )
3899
3900 main.step( "Distributed Set clear()" )
3901 onosSet.clear()
3902 clearResponses = []
3903 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003904 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003905 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003906 name="setTestClear-" + str( i ),
3907 args=[ onosSetName, " "], # Values doesn't matter
3908 kwargs={ "clear": True } )
3909 threads.append( t )
3910 t.start()
3911 for t in threads:
3912 t.join()
3913 clearResponses.append( t.result )
3914
3915 # main.TRUE = successfully changed the set
3916 # main.FALSE = action resulted in no change in set
3917 # main.ERROR - Some error in executing the function
3918 clearResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003919 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003920 if clearResponses[ i ] == main.TRUE:
3921 # All is well
3922 pass
3923 elif clearResponses[ i ] == main.FALSE:
3924 # Nothing set, probably fine
3925 pass
3926 elif clearResponses[ i ] == main.ERROR:
3927 # Error in execution
3928 clearResults = main.FALSE
3929 else:
3930 # unexpected result
3931 clearResults = main.FALSE
3932 if clearResults != main.TRUE:
3933 main.log.error( "Error executing set clear" )
3934
3935 # Check if set is still correct
3936 size = len( onosSet )
3937 getResponses = []
3938 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003939 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003940 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003941 name="setTestGet-" + str( i ),
3942 args=[ onosSetName ] )
3943 threads.append( t )
3944 t.start()
3945 for t in threads:
3946 t.join()
3947 getResponses.append( t.result )
3948 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003949 for i in range( len( main.activeNodes ) ):
3950 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003951 if isinstance( getResponses[ i ], list):
3952 current = set( getResponses[ i ] )
3953 if len( current ) == len( getResponses[ i ] ):
3954 # no repeats
3955 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07003956 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003957 " has incorrect view" +
3958 " of set " + onosSetName + ":\n" +
3959 str( getResponses[ i ] ) )
3960 main.log.debug( "Expected: " + str( onosSet ) )
3961 main.log.debug( "Actual: " + str( current ) )
3962 getResults = main.FALSE
3963 else:
3964 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003965 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003966 " has repeat elements in" +
3967 " set " + onosSetName + ":\n" +
3968 str( getResponses[ i ] ) )
3969 getResults = main.FALSE
3970 elif getResponses[ i ] == main.ERROR:
3971 getResults = main.FALSE
3972 sizeResponses = []
3973 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003974 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003975 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003976 name="setTestSize-" + str( i ),
3977 args=[ onosSetName ] )
3978 threads.append( t )
3979 t.start()
3980 for t in threads:
3981 t.join()
3982 sizeResponses.append( t.result )
3983 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003984 for i in range( len( main.activeNodes ) ):
3985 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003986 if size != sizeResponses[ i ]:
3987 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003988 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003989 " expected a size of " + str( size ) +
3990 " for set " + onosSetName +
3991 " but got " + str( sizeResponses[ i ] ) )
3992 clearResults = clearResults and getResults and sizeResults
3993 utilities.assert_equals( expect=main.TRUE,
3994 actual=clearResults,
3995 onpass="Set clear correct",
3996 onfail="Set clear was incorrect" )
3997
3998 main.step( "Distributed Set addAll()" )
3999 onosSet.update( addAllValue.split() )
4000 addResponses = []
4001 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004002 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004003 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004004 name="setTestAddAll-" + str( i ),
4005 args=[ onosSetName, addAllValue ] )
4006 threads.append( t )
4007 t.start()
4008 for t in threads:
4009 t.join()
4010 addResponses.append( t.result )
4011
4012 # main.TRUE = successfully changed the set
4013 # main.FALSE = action resulted in no change in set
4014 # main.ERROR - Some error in executing the function
4015 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004016 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004017 if addResponses[ i ] == main.TRUE:
4018 # All is well
4019 pass
4020 elif addResponses[ i ] == main.FALSE:
4021 # Already in set, probably fine
4022 pass
4023 elif addResponses[ i ] == main.ERROR:
4024 # Error in execution
4025 addAllResults = main.FALSE
4026 else:
4027 # unexpected result
4028 addAllResults = main.FALSE
4029 if addAllResults != main.TRUE:
4030 main.log.error( "Error executing set addAll" )
4031
4032 # Check if set is still correct
4033 size = len( onosSet )
4034 getResponses = []
4035 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004036 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004037 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004038 name="setTestGet-" + str( i ),
4039 args=[ onosSetName ] )
4040 threads.append( t )
4041 t.start()
4042 for t in threads:
4043 t.join()
4044 getResponses.append( t.result )
4045 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004046 for i in range( len( main.activeNodes ) ):
4047 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004048 if isinstance( getResponses[ i ], list):
4049 current = set( getResponses[ i ] )
4050 if len( current ) == len( getResponses[ i ] ):
4051 # no repeats
4052 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07004053 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004054 " has incorrect view" +
4055 " of set " + onosSetName + ":\n" +
4056 str( getResponses[ i ] ) )
4057 main.log.debug( "Expected: " + str( onosSet ) )
4058 main.log.debug( "Actual: " + str( current ) )
4059 getResults = main.FALSE
4060 else:
4061 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07004062 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004063 " has repeat elements in" +
4064 " set " + onosSetName + ":\n" +
4065 str( getResponses[ i ] ) )
4066 getResults = main.FALSE
4067 elif getResponses[ i ] == main.ERROR:
4068 getResults = main.FALSE
4069 sizeResponses = []
4070 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004071 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004072 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004073 name="setTestSize-" + str( i ),
4074 args=[ onosSetName ] )
4075 threads.append( t )
4076 t.start()
4077 for t in threads:
4078 t.join()
4079 sizeResponses.append( t.result )
4080 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004081 for i in range( len( main.activeNodes ) ):
4082 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004083 if size != sizeResponses[ i ]:
4084 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07004085 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004086 " expected a size of " + str( size ) +
4087 " for set " + onosSetName +
4088 " but got " + str( sizeResponses[ i ] ) )
4089 addAllResults = addAllResults and getResults and sizeResults
4090 utilities.assert_equals( expect=main.TRUE,
4091 actual=addAllResults,
4092 onpass="Set addAll correct",
4093 onfail="Set addAll was incorrect" )
4094
4095 main.step( "Distributed Set retain()" )
4096 onosSet.intersection_update( retainValue.split() )
4097 retainResponses = []
4098 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004099 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004100 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004101 name="setTestRetain-" + str( i ),
4102 args=[ onosSetName, retainValue ],
4103 kwargs={ "retain": True } )
4104 threads.append( t )
4105 t.start()
4106 for t in threads:
4107 t.join()
4108 retainResponses.append( t.result )
4109
4110 # main.TRUE = successfully changed the set
4111 # main.FALSE = action resulted in no change in set
4112 # main.ERROR - Some error in executing the function
4113 retainResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004114 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004115 if retainResponses[ i ] == main.TRUE:
4116 # All is well
4117 pass
4118 elif retainResponses[ i ] == main.FALSE:
4119 # Already in set, probably fine
4120 pass
4121 elif retainResponses[ i ] == main.ERROR:
4122 # Error in execution
4123 retainResults = main.FALSE
4124 else:
4125 # unexpected result
4126 retainResults = main.FALSE
4127 if retainResults != main.TRUE:
4128 main.log.error( "Error executing set retain" )
4129
4130 # Check if set is still correct
4131 size = len( onosSet )
4132 getResponses = []
4133 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004134 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004135 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004136 name="setTestGet-" + str( i ),
4137 args=[ onosSetName ] )
4138 threads.append( t )
4139 t.start()
4140 for t in threads:
4141 t.join()
4142 getResponses.append( t.result )
4143 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004144 for i in range( len( main.activeNodes ) ):
4145 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004146 if isinstance( getResponses[ i ], list):
4147 current = set( getResponses[ i ] )
4148 if len( current ) == len( getResponses[ i ] ):
4149 # no repeats
4150 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07004151 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004152 " has incorrect view" +
4153 " of set " + onosSetName + ":\n" +
4154 str( getResponses[ i ] ) )
4155 main.log.debug( "Expected: " + str( onosSet ) )
4156 main.log.debug( "Actual: " + str( current ) )
4157 getResults = main.FALSE
4158 else:
4159 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07004160 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004161 " has repeat elements in" +
4162 " set " + onosSetName + ":\n" +
4163 str( getResponses[ i ] ) )
4164 getResults = main.FALSE
4165 elif getResponses[ i ] == main.ERROR:
4166 getResults = main.FALSE
4167 sizeResponses = []
4168 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004169 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004170 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004171 name="setTestSize-" + str( i ),
4172 args=[ onosSetName ] )
4173 threads.append( t )
4174 t.start()
4175 for t in threads:
4176 t.join()
4177 sizeResponses.append( t.result )
4178 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004179 for i in range( len( main.activeNodes ) ):
4180 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004181 if size != sizeResponses[ i ]:
4182 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07004183 main.log.error( "ONOS" + node + " expected a size of " +
Jon Hall5cf14d52015-07-16 12:15:19 -07004184 str( size ) + " for set " + onosSetName +
4185 " but got " + str( sizeResponses[ i ] ) )
4186 retainResults = retainResults and getResults and sizeResults
4187 utilities.assert_equals( expect=main.TRUE,
4188 actual=retainResults,
4189 onpass="Set retain correct",
4190 onfail="Set retain was incorrect" )
4191
Jon Hall2a5002c2015-08-21 16:49:11 -07004192 # Transactional maps
4193 main.step( "Partitioned Transactional maps put" )
4194 tMapValue = "Testing"
4195 numKeys = 100
4196 putResult = True
Jon Halla440e872016-03-31 15:15:50 -07004197 node = main.activeNodes[0]
4198 putResponses = main.CLIs[node].transactionalMapPut( numKeys, tMapValue )
4199 if putResponses and len( putResponses ) == 100:
Jon Hall2a5002c2015-08-21 16:49:11 -07004200 for i in putResponses:
4201 if putResponses[ i ][ 'value' ] != tMapValue:
4202 putResult = False
4203 else:
4204 putResult = False
4205 if not putResult:
4206 main.log.debug( "Put response values: " + str( putResponses ) )
4207 utilities.assert_equals( expect=True,
4208 actual=putResult,
4209 onpass="Partitioned Transactional Map put successful",
4210 onfail="Partitioned Transactional Map put values are incorrect" )
4211
4212 main.step( "Partitioned Transactional maps get" )
4213 getCheck = True
4214 for n in range( 1, numKeys + 1 ):
4215 getResponses = []
4216 threads = []
4217 valueCheck = True
Jon Halla440e872016-03-31 15:15:50 -07004218 for i in main.activeNodes:
Jon Hall2a5002c2015-08-21 16:49:11 -07004219 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4220 name="TMap-get-" + str( i ),
Jon Halla440e872016-03-31 15:15:50 -07004221 args=[ "Key" + str( n ) ] )
Jon Hall2a5002c2015-08-21 16:49:11 -07004222 threads.append( t )
4223 t.start()
4224 for t in threads:
4225 t.join()
4226 getResponses.append( t.result )
4227 for node in getResponses:
4228 if node != tMapValue:
4229 valueCheck = False
4230 if not valueCheck:
4231 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4232 main.log.warn( getResponses )
4233 getCheck = getCheck and valueCheck
4234 utilities.assert_equals( expect=True,
4235 actual=getCheck,
4236 onpass="Partitioned Transactional Map get values were correct",
4237 onfail="Partitioned Transactional Map values incorrect" )