blob: 2d1eb2561854f40b3a621dac16fd8b9b3989f40f [file] [log] [blame]
Jon Hall5cf14d52015-07-16 12:15:19 -07001"""
2Description: This test is to determine if ONOS can handle
3 a minority of it's nodes restarting
4
5List of test cases:
6CASE1: Compile ONOS and push it to the test machines
7CASE2: Assign devices to controllers
8CASE21: Assign mastership to controllers
9CASE3: Assign intents
10CASE4: Ping across added host intents
11CASE5: Reading state of ONOS
Jon Hallb3ed8ed2015-10-28 16:43:55 -070012CASE61: The Failure inducing case.
13CASE62: The Failure recovery case.
Jon Hall5cf14d52015-07-16 12:15:19 -070014CASE7: 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
Jon Hallb3ed8ed2015-10-28 16:43:55 -070028class HAkillNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -070029
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 Hall3b489db2015-10-05 14:38:37 -070052 import pexpect
Jon Hall6e709752016-02-01 13:38:46 -080053 import time
Jon Halla440e872016-03-31 15:15:50 -070054 import json
Jon Hall6e709752016-02-01 13:38:46 -080055 main.log.info( "ONOS HA test: Restart a minority of ONOS nodes - " +
Jon Hall5cf14d52015-07-16 12:15:19 -070056 "initialization" )
57 main.case( "Setting up test environment" )
Jon Hall783bbf92015-07-23 14:33:19 -070058 main.caseExplanation = "Setup the test environment including " +\
Jon Hall5cf14d52015-07-16 12:15:19 -070059 "installing ONOS, starting Mininet and ONOS" +\
60 "cli sessions."
Jon Hall5cf14d52015-07-16 12:15:19 -070061
62 # load some variables from the params file
63 PULLCODE = False
64 if main.params[ 'Git' ] == 'True':
65 PULLCODE = True
66 gitBranch = main.params[ 'branch' ]
67 cellName = main.params[ 'ENV' ][ 'cellName' ]
68
Jon Halle1a3b752015-07-22 13:02:46 -070069 main.numCtrls = int( main.params[ 'num_controllers' ] )
Jon Hall5cf14d52015-07-16 12:15:19 -070070 if main.ONOSbench.maxNodes:
Jon Halle1a3b752015-07-22 13:02:46 -070071 if main.ONOSbench.maxNodes < main.numCtrls:
72 main.numCtrls = int( main.ONOSbench.maxNodes )
73 # set global variables
Jon Hall5cf14d52015-07-16 12:15:19 -070074 global ONOS1Port
75 global ONOS2Port
76 global ONOS3Port
77 global ONOS4Port
78 global ONOS5Port
79 global ONOS6Port
80 global ONOS7Port
Jon Halla440e872016-03-31 15:15:50 -070081 # These are for csv plotting in jenkins
82 global labels
83 global data
84 labels = []
85 data = []
Jon Hall5cf14d52015-07-16 12:15:19 -070086
87 # FIXME: just get controller port from params?
88 # TODO: do we really need all these?
89 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
90 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
91 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
92 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
93 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
94 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
95 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
96
Jon Halle1a3b752015-07-22 13:02:46 -070097 try:
Jon Halla440e872016-03-31 15:15:50 -070098 from tests.HAsanity.dependencies.Counters import Counters
99 main.Counters = Counters()
Jon Halle1a3b752015-07-22 13:02:46 -0700100 except Exception as e:
101 main.log.exception( e )
102 main.cleanup()
103 main.exit()
104
105 main.CLIs = []
106 main.nodes = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700107 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700108 for i in range( 1, main.numCtrls + 1 ):
109 try:
110 main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
111 main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
112 ipList.append( main.nodes[ -1 ].ip_address )
113 except AttributeError:
114 break
Jon Hall5cf14d52015-07-16 12:15:19 -0700115
116 main.step( "Create cell file" )
117 cellAppString = main.params[ 'ENV' ][ 'appString' ]
118 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
119 main.Mininet1.ip_address,
120 cellAppString, ipList )
121 main.step( "Applying cell variable to environment" )
122 cellResult = main.ONOSbench.setCell( cellName )
123 verifyResult = main.ONOSbench.verifyCell()
124
125 # FIXME:this is short term fix
126 main.log.info( "Removing raft logs" )
127 main.ONOSbench.onosRemoveRaftLogs()
128
129 main.log.info( "Uninstalling ONOS" )
Jon Halle1a3b752015-07-22 13:02:46 -0700130 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700131 main.ONOSbench.onosUninstall( node.ip_address )
132
133 # Make sure ONOS is DEAD
134 main.log.info( "Killing any ONOS processes" )
135 killResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700136 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700137 killed = main.ONOSbench.onosKill( node.ip_address )
138 killResults = killResults and killed
139
140 cleanInstallResult = main.TRUE
141 gitPullResult = main.TRUE
142
143 main.step( "Starting Mininet" )
144 # scp topo file to mininet
145 # TODO: move to params?
146 topoName = "obelisk.py"
147 filePath = main.ONOSbench.home + "/tools/test/topos/"
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700148 main.ONOSbench.scp( main.Mininet1,
149 filePath + topoName,
150 main.Mininet1.home,
151 direction="to" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700152 mnResult = main.Mininet1.startNet( )
153 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
154 onpass="Mininet Started",
155 onfail="Error starting Mininet" )
156
157 main.step( "Git checkout and pull " + gitBranch )
158 if PULLCODE:
159 main.ONOSbench.gitCheckout( gitBranch )
160 gitPullResult = main.ONOSbench.gitPull()
161 # values of 1 or 3 are good
162 utilities.assert_lesser( expect=0, actual=gitPullResult,
163 onpass="Git pull successful",
164 onfail="Git pull failed" )
165 main.ONOSbench.getVersion( report=True )
166
167 main.step( "Using mvn clean install" )
168 cleanInstallResult = main.TRUE
169 if PULLCODE and gitPullResult == main.TRUE:
170 cleanInstallResult = main.ONOSbench.cleanInstall()
171 else:
172 main.log.warn( "Did not pull new code so skipping mvn " +
173 "clean install" )
174 utilities.assert_equals( expect=main.TRUE,
175 actual=cleanInstallResult,
176 onpass="MCI successful",
177 onfail="MCI failed" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700178
179 main.step( "Make sure ONOS service doesn't automatically respawn" )
180 handle = main.ONOSbench.handle
181 handle.sendline( "sed -i -e 's/^respawn$/#respawn/g' tools/package/init/onos.conf" )
182 handle.expect( "\$" ) # $ from the command
183 handle.expect( "\$" ) # $ from the prompt
184
Jon Hall5cf14d52015-07-16 12:15:19 -0700185 # GRAPHS
186 # NOTE: important params here:
187 # job = name of Jenkins job
188 # Plot Name = Plot-HA, only can be used if multiple plots
189 # index = The number of the graph under plot name
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700190 job = "HAkillNodes"
Jon Hall5cf14d52015-07-16 12:15:19 -0700191 plotName = "Plot-HA"
Jon Hall843f8bc2016-03-18 14:28:13 -0700192 index = "2"
Jon Hall5cf14d52015-07-16 12:15:19 -0700193 graphs = '<ac:structured-macro ac:name="html">\n'
194 graphs += '<ac:plain-text-body><![CDATA[\n'
195 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
Jon Halla9845df2016-01-15 14:55:58 -0800196 '/plot/' + plotName + '/getPlot?index=' + index +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700197 '&width=500&height=300"' +\
198 'noborder="0" width="500" height="300" scrolling="yes" ' +\
199 'seamless="seamless"></iframe>\n'
200 graphs += ']]></ac:plain-text-body>\n'
201 graphs += '</ac:structured-macro>\n'
202 main.log.wiki(graphs)
203
204 main.step( "Creating ONOS package" )
Jon Hall3b489db2015-10-05 14:38:37 -0700205 # copy gen-partions file to ONOS
206 # NOTE: this assumes TestON and ONOS are on the same machine
207 srcFile = main.testDir + "/" + main.TEST + "/dependencies/onos-gen-partitions"
208 dstDir = main.ONOSbench.home + "/tools/test/bin/onos-gen-partitions"
209 cpResult = main.ONOSbench.secureCopy( main.ONOSbench.user_name,
210 main.ONOSbench.ip_address,
211 srcFile,
212 dstDir,
213 pwd=main.ONOSbench.pwd,
214 direction="from" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700215 packageResult = main.ONOSbench.onosPackage()
216 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
217 onpass="ONOS package successful",
218 onfail="ONOS package failed" )
219
220 main.step( "Installing ONOS package" )
221 onosInstallResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700222 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700223 tmpResult = main.ONOSbench.onosInstall( options="-f",
224 node=node.ip_address )
225 onosInstallResult = onosInstallResult and tmpResult
226 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
227 onpass="ONOS install successful",
228 onfail="ONOS install failed" )
Jon Hall3b489db2015-10-05 14:38:37 -0700229 # clean up gen-partitions file
230 try:
231 main.ONOSbench.handle.sendline( "cd " + main.ONOSbench.home )
232 main.ONOSbench.handle.expect( main.ONOSbench.home + "\$" )
233 main.ONOSbench.handle.sendline( "git checkout -- tools/test/bin/onos-gen-partitions" )
234 main.ONOSbench.handle.expect( main.ONOSbench.home + "\$" )
235 main.log.info( " Cleaning custom gen partitions file, response was: \n" +
236 str( main.ONOSbench.handle.before ) )
237 except ( pexpect.TIMEOUT, pexpect.EOF ):
238 main.log.exception( "ONOSbench: pexpect exception found:" +
239 main.ONOSbench.handle.before )
240 main.cleanup()
241 main.exit()
Jon Hall5cf14d52015-07-16 12:15:19 -0700242
243 main.step( "Checking if ONOS is up yet" )
244 for i in range( 2 ):
245 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700246 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700247 started = main.ONOSbench.isup( node.ip_address )
248 if not started:
Jon Hallc6793552016-01-19 14:18:37 -0800249 main.log.error( node.name + " hasn't started" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700250 onosIsupResult = onosIsupResult and started
251 if onosIsupResult == main.TRUE:
252 break
253 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
254 onpass="ONOS startup successful",
255 onfail="ONOS startup failed" )
256
257 main.log.step( "Starting ONOS CLI sessions" )
258 cliResults = main.TRUE
259 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700260 for i in range( main.numCtrls ):
261 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -0700262 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -0700263 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -0700264 threads.append( t )
265 t.start()
266
267 for t in threads:
268 t.join()
269 cliResults = cliResults and t.result
270 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
271 onpass="ONOS cli startup successful",
272 onfail="ONOS cli startup failed" )
273
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700274 # Create a list of active nodes for use when some nodes are stopped
275 main.activeNodes = [ i for i in range( 0, len( main.CLIs ) ) ]
276
Jon Hall5cf14d52015-07-16 12:15:19 -0700277 if main.params[ 'tcpdump' ].lower() == "true":
278 main.step( "Start Packet Capture MN" )
279 main.Mininet2.startTcpdump(
280 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
281 + "-MN.pcap",
282 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
283 port=main.params[ 'MNtcpdump' ][ 'port' ] )
284
285 main.step( "App Ids check" )
286 appCheck = main.TRUE
287 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700288 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -0700289 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700290 name="appToIDCheck-" + str( i ),
291 args=[] )
292 threads.append( t )
293 t.start()
294
295 for t in threads:
296 t.join()
297 appCheck = appCheck and t.result
298 if appCheck != main.TRUE:
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700299 node = main.activeNodes[0]
300 main.log.warn( main.CLIs[node].apps() )
301 main.log.warn( main.CLIs[node].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700302 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
303 onpass="App Ids seem to be correct",
304 onfail="Something is wrong with app Ids" )
305
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700306 main.step( "Clean up ONOS service changes" )
307 handle.sendline( "git checkout -- tools/package/init/onos.conf" )
308 handle.expect( "\$" )
309
Jon Halla440e872016-03-31 15:15:50 -0700310 main.step( "Checking ONOS nodes" )
311 nodesOutput = []
312 nodeResults = main.TRUE
313 threads = []
314 for i in main.activeNodes:
315 t = main.Thread( target=main.CLIs[i].nodes,
316 name="nodes-" + str( i ),
317 args=[ ] )
318 threads.append( t )
319 t.start()
320
321 for t in threads:
322 t.join()
323 nodesOutput.append( t.result )
324 ips = [ main.nodes[node].ip_address for node in main.activeNodes ]
325 ips.sort()
326 for i in nodesOutput:
327 try:
328 current = json.loads( i )
329 activeIps = []
330 currentResult = main.FALSE
331 for node in current:
332 if node['state'] == 'READY':
333 activeIps.append( node['ip'] )
334 activeIps.sort()
335 if ips == activeIps:
336 currentResult = main.TRUE
337 except ( ValueError, TypeError ):
338 main.log.error( "Error parsing nodes output" )
339 main.log.warn( repr( i ) )
340 currentResult = main.FALSE
341 nodeResults = nodeResults and currentResult
342 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
343 onpass="Nodes check successful",
344 onfail="Nodes check NOT successful" )
345
346 if not nodeResults:
347 for cli in main.CLIs:
348 main.log.debug( "{} components not ACTIVE: \n{}".format(
349 cli.name,
350 cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
351
Jon Hall5cf14d52015-07-16 12:15:19 -0700352 if cliResults == main.FALSE:
353 main.log.error( "Failed to start ONOS, stopping test" )
354 main.cleanup()
355 main.exit()
356
Jon Hall172b7ba2016-04-07 18:12:20 -0700357 main.step( "Activate apps defined in the params file" )
358 # get data from the params
359 apps = main.params.get( 'apps' )
360 if apps:
361 apps = apps.split(',')
362 main.log.warn( apps )
363 activateResult = True
364 for app in apps:
365 main.CLIs[ 0 ].app( app, "Activate" )
366 # TODO: check this worked
367 time.sleep( 10 ) # wait for apps to activate
368 for app in apps:
369 state = main.CLIs[ 0 ].appStatus( app )
370 if state == "ACTIVE":
371 activateResult = activeResult and True
372 else:
373 main.log.error( "{} is in {} state".format( app, state ) )
374 activeResult = False
375 utilities.assert_equals( expect=True,
376 actual=activateResult,
377 onpass="Successfully activated apps",
378 onfail="Failed to activate apps" )
379 else:
380 main.log.warn( "No apps were specified to be loaded after startup" )
381
382 main.step( "Set ONOS configurations" )
383 config = main.params.get( 'ONOS_Configuration' )
384 if config:
385 main.log.debug( config )
386 checkResult = main.TRUE
387 for component in config:
388 for setting in config[component]:
389 value = config[component][setting]
390 check = main.CLIs[ 0 ].setCfg( component, setting, value )
391 main.log.info( "Value was changed? {}".format( main.TRUE == check ) )
392 checkResult = check and checkResult
393 utilities.assert_equals( expect=main.TRUE,
394 actual=checkResult,
395 onpass="Successfully set config",
396 onfail="Failed to set config" )
397 else:
398 main.log.warn( "No configurations were specified to be changed after startup" )
399
Jon Hall5cf14d52015-07-16 12:15:19 -0700400 def CASE2( self, main ):
401 """
402 Assign devices to controllers
403 """
404 import re
Jon Halle1a3b752015-07-22 13:02:46 -0700405 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700406 assert main, "main not defined"
407 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700408 assert main.CLIs, "main.CLIs not defined"
409 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700410 assert ONOS1Port, "ONOS1Port not defined"
411 assert ONOS2Port, "ONOS2Port not defined"
412 assert ONOS3Port, "ONOS3Port not defined"
413 assert ONOS4Port, "ONOS4Port not defined"
414 assert ONOS5Port, "ONOS5Port not defined"
415 assert ONOS6Port, "ONOS6Port not defined"
416 assert ONOS7Port, "ONOS7Port not defined"
417
418 main.case( "Assigning devices to controllers" )
Jon Hall783bbf92015-07-23 14:33:19 -0700419 main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700420 "and check that an ONOS node becomes the " +\
421 "master of the device."
422 main.step( "Assign switches to controllers" )
423
424 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700425 for i in range( main.numCtrls ):
426 ipList.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -0700427 swList = []
428 for i in range( 1, 29 ):
429 swList.append( "s" + str( i ) )
430 main.Mininet1.assignSwController( sw=swList, ip=ipList )
431
432 mastershipCheck = main.TRUE
433 for i in range( 1, 29 ):
434 response = main.Mininet1.getSwController( "s" + str( i ) )
435 try:
436 main.log.info( str( response ) )
437 except Exception:
438 main.log.info( repr( response ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700439 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700440 if re.search( "tcp:" + node.ip_address, response ):
441 mastershipCheck = mastershipCheck and main.TRUE
442 else:
443 main.log.error( "Error, node " + node.ip_address + " is " +
444 "not in the list of controllers s" +
445 str( i ) + " is connecting to." )
446 mastershipCheck = main.FALSE
447 utilities.assert_equals(
448 expect=main.TRUE,
449 actual=mastershipCheck,
450 onpass="Switch mastership assigned correctly",
451 onfail="Switches not assigned correctly to controllers" )
452
453 def CASE21( self, main ):
454 """
455 Assign mastership to controllers
456 """
Jon Hall5cf14d52015-07-16 12:15:19 -0700457 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700458 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700459 assert main, "main not defined"
460 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700461 assert main.CLIs, "main.CLIs not defined"
462 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700463 assert ONOS1Port, "ONOS1Port not defined"
464 assert ONOS2Port, "ONOS2Port not defined"
465 assert ONOS3Port, "ONOS3Port not defined"
466 assert ONOS4Port, "ONOS4Port not defined"
467 assert ONOS5Port, "ONOS5Port not defined"
468 assert ONOS6Port, "ONOS6Port not defined"
469 assert ONOS7Port, "ONOS7Port not defined"
470
471 main.case( "Assigning Controller roles for switches" )
Jon Hall783bbf92015-07-23 14:33:19 -0700472 main.caseExplanation = "Check that ONOS is connected to each " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700473 "device. Then manually assign" +\
474 " mastership to specific ONOS nodes using" +\
475 " 'device-role'"
476 main.step( "Assign mastership of switches to specific controllers" )
477 # Manually assign mastership to the controller we want
478 roleCall = main.TRUE
479
480 ipList = [ ]
481 deviceList = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700482 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -0700483 try:
484 # Assign mastership to specific controllers. This assignment was
485 # determined for a 7 node cluser, but will work with any sized
486 # cluster
487 for i in range( 1, 29 ): # switches 1 through 28
488 # set up correct variables:
489 if i == 1:
490 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700491 ip = main.nodes[ c ].ip_address # ONOS1
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700492 deviceId = onosCli.getDevice( "1000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700493 elif i == 2:
Jon Halle1a3b752015-07-22 13:02:46 -0700494 c = 1 % main.numCtrls
495 ip = main.nodes[ c ].ip_address # ONOS2
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700496 deviceId = onosCli.getDevice( "2000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700497 elif i == 3:
Jon Halle1a3b752015-07-22 13:02:46 -0700498 c = 1 % main.numCtrls
499 ip = main.nodes[ c ].ip_address # ONOS2
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700500 deviceId = onosCli.getDevice( "3000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700501 elif i == 4:
Jon Halle1a3b752015-07-22 13:02:46 -0700502 c = 3 % main.numCtrls
503 ip = main.nodes[ c ].ip_address # ONOS4
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700504 deviceId = onosCli.getDevice( "3004" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700505 elif i == 5:
Jon Halle1a3b752015-07-22 13:02:46 -0700506 c = 2 % main.numCtrls
507 ip = main.nodes[ c ].ip_address # ONOS3
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700508 deviceId = onosCli.getDevice( "5000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700509 elif i == 6:
Jon Halle1a3b752015-07-22 13:02:46 -0700510 c = 2 % main.numCtrls
511 ip = main.nodes[ c ].ip_address # ONOS3
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700512 deviceId = onosCli.getDevice( "6000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700513 elif i == 7:
Jon Halle1a3b752015-07-22 13:02:46 -0700514 c = 5 % main.numCtrls
515 ip = main.nodes[ c ].ip_address # ONOS6
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700516 deviceId = onosCli.getDevice( "6007" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700517 elif i >= 8 and i <= 17:
Jon Halle1a3b752015-07-22 13:02:46 -0700518 c = 4 % main.numCtrls
519 ip = main.nodes[ c ].ip_address # ONOS5
Jon Hall5cf14d52015-07-16 12:15:19 -0700520 dpid = '3' + str( i ).zfill( 3 )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700521 deviceId = onosCli.getDevice( dpid ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700522 elif i >= 18 and i <= 27:
Jon Halle1a3b752015-07-22 13:02:46 -0700523 c = 6 % main.numCtrls
524 ip = main.nodes[ c ].ip_address # ONOS7
Jon Hall5cf14d52015-07-16 12:15:19 -0700525 dpid = '6' + str( i ).zfill( 3 )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700526 deviceId = onosCli.getDevice( dpid ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700527 elif i == 28:
528 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700529 ip = main.nodes[ c ].ip_address # ONOS1
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700530 deviceId = onosCli.getDevice( "2800" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700531 else:
532 main.log.error( "You didn't write an else statement for " +
533 "switch s" + str( i ) )
534 roleCall = main.FALSE
535 # Assign switch
536 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
537 # TODO: make this controller dynamic
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700538 roleCall = roleCall and onosCli.deviceRole( deviceId, ip )
Jon Hall5cf14d52015-07-16 12:15:19 -0700539 ipList.append( ip )
540 deviceList.append( deviceId )
541 except ( AttributeError, AssertionError ):
542 main.log.exception( "Something is wrong with ONOS device view" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700543 main.log.info( onosCli.devices() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700544 utilities.assert_equals(
545 expect=main.TRUE,
546 actual=roleCall,
547 onpass="Re-assigned switch mastership to designated controller",
548 onfail="Something wrong with deviceRole calls" )
549
550 main.step( "Check mastership was correctly assigned" )
551 roleCheck = main.TRUE
552 # NOTE: This is due to the fact that device mastership change is not
553 # atomic and is actually a multi step process
554 time.sleep( 5 )
555 for i in range( len( ipList ) ):
556 ip = ipList[i]
557 deviceId = deviceList[i]
558 # Check assignment
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700559 master = onosCli.getRole( deviceId ).get( 'master' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700560 if ip in master:
561 roleCheck = roleCheck and main.TRUE
562 else:
563 roleCheck = roleCheck and main.FALSE
564 main.log.error( "Error, controller " + ip + " is not" +
565 " master " + "of device " +
566 str( deviceId ) + ". Master is " +
567 repr( master ) + "." )
568 utilities.assert_equals(
569 expect=main.TRUE,
570 actual=roleCheck,
571 onpass="Switches were successfully reassigned to designated " +
572 "controller",
573 onfail="Switches were not successfully reassigned" )
574
575 def CASE3( self, main ):
576 """
577 Assign intents
578 """
579 import time
580 import json
Jon Halle1a3b752015-07-22 13:02:46 -0700581 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700582 assert main, "main not defined"
583 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700584 assert main.CLIs, "main.CLIs not defined"
585 assert main.nodes, "main.nodes not defined"
Jon Halla440e872016-03-31 15:15:50 -0700586 try:
587 labels
588 except NameError:
589 main.log.error( "labels not defined, setting to []" )
590 labels = []
591 try:
592 data
593 except NameError:
594 main.log.error( "data not defined, setting to []" )
595 data = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700596 main.case( "Adding host Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700597 main.caseExplanation = "Discover hosts by using pingall then " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700598 "assign predetermined host-to-host intents." +\
599 " After installation, check that the intent" +\
600 " is distributed to all nodes and the state" +\
601 " is INSTALLED"
602
603 # install onos-app-fwd
604 main.step( "Install reactive forwarding app" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700605 onosCli = main.CLIs[ main.activeNodes[0] ]
606 installResults = onosCli.activateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700607 utilities.assert_equals( expect=main.TRUE, actual=installResults,
608 onpass="Install fwd successful",
609 onfail="Install fwd failed" )
610
611 main.step( "Check app ids" )
612 appCheck = main.TRUE
613 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700614 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -0700615 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700616 name="appToIDCheck-" + str( i ),
617 args=[] )
618 threads.append( t )
619 t.start()
620
621 for t in threads:
622 t.join()
623 appCheck = appCheck and t.result
624 if appCheck != main.TRUE:
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700625 main.log.warn( onosCli.apps() )
626 main.log.warn( onosCli.appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700627 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
628 onpass="App Ids seem to be correct",
629 onfail="Something is wrong with app Ids" )
630
631 main.step( "Discovering Hosts( Via pingall for now )" )
632 # FIXME: Once we have a host discovery mechanism, use that instead
633 # REACTIVE FWD test
634 pingResult = main.FALSE
Jon Hall96091e62015-09-21 17:34:17 -0700635 passMsg = "Reactive Pingall test passed"
636 time1 = time.time()
637 pingResult = main.Mininet1.pingall()
638 time2 = time.time()
639 if not pingResult:
640 main.log.warn("First pingall failed. Trying again...")
Jon Hall5cf14d52015-07-16 12:15:19 -0700641 pingResult = main.Mininet1.pingall()
Jon Hall96091e62015-09-21 17:34:17 -0700642 passMsg += " on the second try"
643 utilities.assert_equals(
644 expect=main.TRUE,
645 actual=pingResult,
646 onpass= passMsg,
647 onfail="Reactive Pingall failed, " +
648 "one or more ping pairs failed" )
649 main.log.info( "Time for pingall: %2f seconds" %
650 ( time2 - time1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -0700651 # timeout for fwd flows
652 time.sleep( 11 )
653 # uninstall onos-app-fwd
654 main.step( "Uninstall reactive forwarding app" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700655 node = main.activeNodes[0]
656 uninstallResult = main.CLIs[node].deactivateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700657 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
658 onpass="Uninstall fwd successful",
659 onfail="Uninstall fwd failed" )
660
661 main.step( "Check app ids" )
662 threads = []
663 appCheck2 = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700664 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -0700665 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700666 name="appToIDCheck-" + str( i ),
667 args=[] )
668 threads.append( t )
669 t.start()
670
671 for t in threads:
672 t.join()
673 appCheck2 = appCheck2 and t.result
674 if appCheck2 != main.TRUE:
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700675 node = main.activeNodes[0]
676 main.log.warn( main.CLIs[node].apps() )
677 main.log.warn( main.CLIs[node].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700678 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
679 onpass="App Ids seem to be correct",
680 onfail="Something is wrong with app Ids" )
681
682 main.step( "Add host intents via cli" )
683 intentIds = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700684 # TODO: move the host numbers to params
685 # Maybe look at all the paths we ping?
Jon Hall5cf14d52015-07-16 12:15:19 -0700686 intentAddResult = True
687 hostResult = main.TRUE
688 for i in range( 8, 18 ):
689 main.log.info( "Adding host intent between h" + str( i ) +
690 " and h" + str( i + 10 ) )
691 host1 = "00:00:00:00:00:" + \
692 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
693 host2 = "00:00:00:00:00:" + \
694 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
695 # NOTE: getHost can return None
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700696 host1Dict = onosCli.getHost( host1 )
697 host2Dict = onosCli.getHost( host2 )
Jon Hall5cf14d52015-07-16 12:15:19 -0700698 host1Id = None
699 host2Id = None
700 if host1Dict and host2Dict:
701 host1Id = host1Dict.get( 'id', None )
702 host2Id = host2Dict.get( 'id', None )
703 if host1Id and host2Id:
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700704 nodeNum = ( i % len( main.activeNodes ) )
705 node = main.activeNodes[nodeNum]
706 tmpId = main.CLIs[node].addHostIntent( host1Id, host2Id )
Jon Hall5cf14d52015-07-16 12:15:19 -0700707 if tmpId:
708 main.log.info( "Added intent with id: " + tmpId )
709 intentIds.append( tmpId )
710 else:
711 main.log.error( "addHostIntent returned: " +
712 repr( tmpId ) )
713 else:
714 main.log.error( "Error, getHost() failed for h" + str( i ) +
715 " and/or h" + str( i + 10 ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700716 node = main.activeNodes[0]
717 hosts = main.CLIs[node].hosts()
Jon Hall5cf14d52015-07-16 12:15:19 -0700718 main.log.warn( "Hosts output: " )
719 try:
720 main.log.warn( json.dumps( json.loads( hosts ),
721 sort_keys=True,
722 indent=4,
723 separators=( ',', ': ' ) ) )
724 except ( ValueError, TypeError ):
725 main.log.warn( repr( hosts ) )
726 hostResult = main.FALSE
727 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
728 onpass="Found a host id for each host",
729 onfail="Error looking up host ids" )
730
731 intentStart = time.time()
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700732 onosIds = onosCli.getAllIntentsId()
Jon Hall5cf14d52015-07-16 12:15:19 -0700733 main.log.info( "Submitted intents: " + str( intentIds ) )
734 main.log.info( "Intents in ONOS: " + str( onosIds ) )
735 for intent in intentIds:
736 if intent in onosIds:
737 pass # intent submitted is in onos
738 else:
739 intentAddResult = False
740 if intentAddResult:
741 intentStop = time.time()
742 else:
743 intentStop = None
744 # Print the intent states
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700745 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700746 intentStates = []
747 installedCheck = True
748 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
749 count = 0
750 try:
751 for intent in json.loads( intents ):
752 state = intent.get( 'state', None )
753 if "INSTALLED" not in state:
754 installedCheck = False
755 intentId = intent.get( 'id', None )
756 intentStates.append( ( intentId, state ) )
757 except ( ValueError, TypeError ):
758 main.log.exception( "Error parsing intents" )
759 # add submitted intents not in the store
760 tmplist = [ i for i, s in intentStates ]
761 missingIntents = False
762 for i in intentIds:
763 if i not in tmplist:
764 intentStates.append( ( i, " - " ) )
765 missingIntents = True
766 intentStates.sort()
767 for i, s in intentStates:
768 count += 1
769 main.log.info( "%-6s%-15s%-15s" %
770 ( str( count ), str( i ), str( s ) ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700771 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -0700772 try:
773 missing = False
774 if leaders:
775 parsedLeaders = json.loads( leaders )
776 main.log.warn( json.dumps( parsedLeaders,
777 sort_keys=True,
778 indent=4,
779 separators=( ',', ': ' ) ) )
780 # check for all intent partitions
781 topics = []
782 for i in range( 14 ):
783 topics.append( "intent-partition-" + str( i ) )
784 main.log.debug( topics )
785 ONOStopics = [ j['topic'] for j in parsedLeaders ]
786 for topic in topics:
787 if topic not in ONOStopics:
788 main.log.error( "Error: " + topic +
789 " not in leaders" )
790 missing = True
791 else:
792 main.log.error( "leaders() returned None" )
793 except ( ValueError, TypeError ):
794 main.log.exception( "Error parsing leaders" )
795 main.log.error( repr( leaders ) )
796 # Check all nodes
797 if missing:
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700798 for i in main.activeNodes:
799 response = main.CLIs[i].leaders( jsonFormat=False)
800 main.log.warn( str( main.CLIs[i].name ) + " leaders output: \n" +
Jon Hall5cf14d52015-07-16 12:15:19 -0700801 str( response ) )
802
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700803 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -0700804 try:
805 if partitions :
806 parsedPartitions = json.loads( partitions )
807 main.log.warn( json.dumps( parsedPartitions,
808 sort_keys=True,
809 indent=4,
810 separators=( ',', ': ' ) ) )
811 # TODO check for a leader in all paritions
812 # TODO check for consistency among nodes
813 else:
814 main.log.error( "partitions() returned None" )
815 except ( ValueError, TypeError ):
816 main.log.exception( "Error parsing partitions" )
817 main.log.error( repr( partitions ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700818 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -0700819 try:
820 if pendingMap :
821 parsedPending = json.loads( pendingMap )
822 main.log.warn( json.dumps( parsedPending,
823 sort_keys=True,
824 indent=4,
825 separators=( ',', ': ' ) ) )
826 # TODO check something here?
827 else:
828 main.log.error( "pendingMap() returned None" )
829 except ( ValueError, TypeError ):
830 main.log.exception( "Error parsing pending map" )
831 main.log.error( repr( pendingMap ) )
832
833 intentAddResult = bool( intentAddResult and not missingIntents and
834 installedCheck )
835 if not intentAddResult:
836 main.log.error( "Error in pushing host intents to ONOS" )
837
838 main.step( "Intent Anti-Entropy dispersion" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700839 for j in range(100):
Jon Hall5cf14d52015-07-16 12:15:19 -0700840 correct = True
841 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700842 for i in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700843 onosIds = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700844 ids = main.CLIs[i].getAllIntentsId()
Jon Hall5cf14d52015-07-16 12:15:19 -0700845 onosIds.append( ids )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700846 main.log.debug( "Intents in " + main.CLIs[i].name + ": " +
Jon Hall5cf14d52015-07-16 12:15:19 -0700847 str( sorted( onosIds ) ) )
848 if sorted( ids ) != sorted( intentIds ):
849 main.log.warn( "Set of intent IDs doesn't match" )
850 correct = False
851 break
852 else:
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700853 intents = json.loads( main.CLIs[i].intents() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700854 for intent in intents:
855 if intent[ 'state' ] != "INSTALLED":
856 main.log.warn( "Intent " + intent[ 'id' ] +
857 " is " + intent[ 'state' ] )
858 correct = False
859 break
860 if correct:
861 break
862 else:
863 time.sleep(1)
864 if not intentStop:
865 intentStop = time.time()
866 global gossipTime
867 gossipTime = intentStop - intentStart
868 main.log.info( "It took about " + str( gossipTime ) +
869 " seconds for all intents to appear in each node" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700870 gossipPeriod = int( main.params['timers']['gossip'] )
871 maxGossipTime = gossipPeriod * len( main.activeNodes )
Jon Hall5cf14d52015-07-16 12:15:19 -0700872 utilities.assert_greater_equals(
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700873 expect=maxGossipTime, actual=gossipTime,
Jon Hall5cf14d52015-07-16 12:15:19 -0700874 onpass="ECM anti-entropy for intents worked within " +
875 "expected time",
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700876 onfail="Intent ECM anti-entropy took too long. " +
877 "Expected time:{}, Actual time:{}".format( maxGossipTime,
878 gossipTime ) )
879 if gossipTime <= maxGossipTime:
Jon Hall5cf14d52015-07-16 12:15:19 -0700880 intentAddResult = True
881
882 if not intentAddResult or "key" in pendingMap:
883 import time
884 installedCheck = True
885 main.log.info( "Sleeping 60 seconds to see if intents are found" )
886 time.sleep( 60 )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700887 onosIds = onosCli.getAllIntentsId()
Jon Hall5cf14d52015-07-16 12:15:19 -0700888 main.log.info( "Submitted intents: " + str( intentIds ) )
889 main.log.info( "Intents in ONOS: " + str( onosIds ) )
890 # Print the intent states
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700891 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700892 intentStates = []
893 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
894 count = 0
895 try:
896 for intent in json.loads( intents ):
897 # Iter through intents of a node
898 state = intent.get( 'state', None )
899 if "INSTALLED" not in state:
900 installedCheck = False
901 intentId = intent.get( 'id', None )
902 intentStates.append( ( intentId, state ) )
903 except ( ValueError, TypeError ):
904 main.log.exception( "Error parsing intents" )
905 # add submitted intents not in the store
906 tmplist = [ i for i, s in intentStates ]
907 for i in intentIds:
908 if i not in tmplist:
909 intentStates.append( ( i, " - " ) )
910 intentStates.sort()
911 for i, s in intentStates:
912 count += 1
913 main.log.info( "%-6s%-15s%-15s" %
914 ( str( count ), str( i ), str( s ) ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700915 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -0700916 try:
917 missing = False
918 if leaders:
919 parsedLeaders = json.loads( leaders )
920 main.log.warn( json.dumps( parsedLeaders,
921 sort_keys=True,
922 indent=4,
923 separators=( ',', ': ' ) ) )
924 # check for all intent partitions
925 # check for election
926 topics = []
927 for i in range( 14 ):
928 topics.append( "intent-partition-" + str( i ) )
929 # FIXME: this should only be after we start the app
930 topics.append( "org.onosproject.election" )
931 main.log.debug( topics )
932 ONOStopics = [ j['topic'] for j in parsedLeaders ]
933 for topic in topics:
934 if topic not in ONOStopics:
935 main.log.error( "Error: " + topic +
936 " not in leaders" )
937 missing = True
938 else:
939 main.log.error( "leaders() returned None" )
940 except ( ValueError, TypeError ):
941 main.log.exception( "Error parsing leaders" )
942 main.log.error( repr( leaders ) )
943 # Check all nodes
944 if missing:
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700945 for i in main.activeNodes:
946 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -0700947 response = node.leaders( jsonFormat=False)
948 main.log.warn( str( node.name ) + " leaders output: \n" +
949 str( response ) )
950
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700951 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -0700952 try:
953 if partitions :
954 parsedPartitions = json.loads( partitions )
955 main.log.warn( json.dumps( parsedPartitions,
956 sort_keys=True,
957 indent=4,
958 separators=( ',', ': ' ) ) )
959 # TODO check for a leader in all paritions
960 # TODO check for consistency among nodes
961 else:
962 main.log.error( "partitions() returned None" )
963 except ( ValueError, TypeError ):
964 main.log.exception( "Error parsing partitions" )
965 main.log.error( repr( partitions ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700966 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -0700967 try:
968 if pendingMap :
969 parsedPending = json.loads( pendingMap )
970 main.log.warn( json.dumps( parsedPending,
971 sort_keys=True,
972 indent=4,
973 separators=( ',', ': ' ) ) )
974 # TODO check something here?
975 else:
976 main.log.error( "pendingMap() returned None" )
977 except ( ValueError, TypeError ):
978 main.log.exception( "Error parsing pending map" )
979 main.log.error( repr( pendingMap ) )
980
981 def CASE4( self, main ):
982 """
983 Ping across added host intents
984 """
985 import json
986 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700987 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700988 assert main, "main not defined"
989 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700990 assert main.CLIs, "main.CLIs not defined"
991 assert main.nodes, "main.nodes not defined"
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700992 main.case( "Verify connectivity by sending traffic across Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700993 main.caseExplanation = "Ping across added host intents to check " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700994 "functionality and check the state of " +\
995 "the intent"
996 main.step( "Ping across added host intents" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700997 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -0700998 PingResult = main.TRUE
999 for i in range( 8, 18 ):
1000 ping = main.Mininet1.pingHost( src="h" + str( i ),
1001 target="h" + str( i + 10 ) )
1002 PingResult = PingResult and ping
1003 if ping == main.FALSE:
1004 main.log.warn( "Ping failed between h" + str( i ) +
1005 " and h" + str( i + 10 ) )
1006 elif ping == main.TRUE:
1007 main.log.info( "Ping test passed!" )
1008 # Don't set PingResult or you'd override failures
1009 if PingResult == main.FALSE:
1010 main.log.error(
1011 "Intents have not been installed correctly, pings failed." )
1012 # TODO: pretty print
1013 main.log.warn( "ONOS1 intents: " )
1014 try:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001015 tmpIntents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -07001016 main.log.warn( json.dumps( json.loads( tmpIntents ),
1017 sort_keys=True,
1018 indent=4,
1019 separators=( ',', ': ' ) ) )
1020 except ( ValueError, TypeError ):
1021 main.log.warn( repr( tmpIntents ) )
1022 utilities.assert_equals(
1023 expect=main.TRUE,
1024 actual=PingResult,
1025 onpass="Intents have been installed correctly and pings work",
1026 onfail="Intents have not been installed correctly, pings failed." )
1027
1028 main.step( "Check Intent state" )
1029 installedCheck = False
1030 loopCount = 0
1031 while not installedCheck and loopCount < 40:
1032 installedCheck = True
1033 # Print the intent states
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001034 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -07001035 intentStates = []
1036 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
1037 count = 0
1038 # Iter through intents of a node
1039 try:
1040 for intent in json.loads( intents ):
1041 state = intent.get( 'state', None )
1042 if "INSTALLED" not in state:
1043 installedCheck = False
1044 intentId = intent.get( 'id', None )
1045 intentStates.append( ( intentId, state ) )
1046 except ( ValueError, TypeError ):
1047 main.log.exception( "Error parsing intents." )
1048 # Print states
1049 intentStates.sort()
1050 for i, s in intentStates:
1051 count += 1
1052 main.log.info( "%-6s%-15s%-15s" %
1053 ( str( count ), str( i ), str( s ) ) )
1054 if not installedCheck:
1055 time.sleep( 1 )
1056 loopCount += 1
1057 utilities.assert_equals( expect=True, actual=installedCheck,
1058 onpass="Intents are all INSTALLED",
1059 onfail="Intents are not all in " +
1060 "INSTALLED state" )
1061
1062 main.step( "Check leadership of topics" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001063 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -07001064 topicCheck = main.TRUE
1065 try:
1066 if leaders:
1067 parsedLeaders = json.loads( leaders )
1068 main.log.warn( json.dumps( parsedLeaders,
1069 sort_keys=True,
1070 indent=4,
1071 separators=( ',', ': ' ) ) )
1072 # check for all intent partitions
1073 # check for election
1074 # TODO: Look at Devices as topics now that it uses this system
1075 topics = []
1076 for i in range( 14 ):
1077 topics.append( "intent-partition-" + str( i ) )
1078 # FIXME: this should only be after we start the app
1079 # FIXME: topics.append( "org.onosproject.election" )
1080 # Print leaders output
1081 main.log.debug( topics )
1082 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1083 for topic in topics:
1084 if topic not in ONOStopics:
1085 main.log.error( "Error: " + topic +
1086 " not in leaders" )
1087 topicCheck = main.FALSE
1088 else:
1089 main.log.error( "leaders() returned None" )
1090 topicCheck = main.FALSE
1091 except ( ValueError, TypeError ):
1092 topicCheck = main.FALSE
1093 main.log.exception( "Error parsing leaders" )
1094 main.log.error( repr( leaders ) )
1095 # TODO: Check for a leader of these topics
1096 # Check all nodes
1097 if topicCheck:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001098 for i in main.activeNodes:
1099 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07001100 response = node.leaders( jsonFormat=False)
1101 main.log.warn( str( node.name ) + " leaders output: \n" +
1102 str( response ) )
1103
1104 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
1105 onpass="intent Partitions is in leaders",
1106 onfail="Some topics were lost " )
1107 # Print partitions
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001108 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -07001109 try:
1110 if partitions :
1111 parsedPartitions = json.loads( partitions )
1112 main.log.warn( json.dumps( parsedPartitions,
1113 sort_keys=True,
1114 indent=4,
1115 separators=( ',', ': ' ) ) )
1116 # TODO check for a leader in all paritions
1117 # TODO check for consistency among nodes
1118 else:
1119 main.log.error( "partitions() returned None" )
1120 except ( ValueError, TypeError ):
1121 main.log.exception( "Error parsing partitions" )
1122 main.log.error( repr( partitions ) )
1123 # Print Pending Map
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001124 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -07001125 try:
1126 if pendingMap :
1127 parsedPending = json.loads( pendingMap )
1128 main.log.warn( json.dumps( parsedPending,
1129 sort_keys=True,
1130 indent=4,
1131 separators=( ',', ': ' ) ) )
1132 # TODO check something here?
1133 else:
1134 main.log.error( "pendingMap() returned None" )
1135 except ( ValueError, TypeError ):
1136 main.log.exception( "Error parsing pending map" )
1137 main.log.error( repr( pendingMap ) )
1138
1139 if not installedCheck:
1140 main.log.info( "Waiting 60 seconds to see if the state of " +
1141 "intents change" )
1142 time.sleep( 60 )
1143 # Print the intent states
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001144 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -07001145 intentStates = []
1146 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
1147 count = 0
1148 # Iter through intents of a node
1149 try:
1150 for intent in json.loads( intents ):
1151 state = intent.get( 'state', None )
1152 if "INSTALLED" not in state:
1153 installedCheck = False
1154 intentId = intent.get( 'id', None )
1155 intentStates.append( ( intentId, state ) )
1156 except ( ValueError, TypeError ):
1157 main.log.exception( "Error parsing intents." )
1158 intentStates.sort()
1159 for i, s in intentStates:
1160 count += 1
1161 main.log.info( "%-6s%-15s%-15s" %
1162 ( str( count ), str( i ), str( s ) ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001163 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -07001164 try:
1165 missing = False
1166 if leaders:
1167 parsedLeaders = json.loads( leaders )
1168 main.log.warn( json.dumps( parsedLeaders,
1169 sort_keys=True,
1170 indent=4,
1171 separators=( ',', ': ' ) ) )
1172 # check for all intent partitions
1173 # check for election
1174 topics = []
1175 for i in range( 14 ):
1176 topics.append( "intent-partition-" + str( i ) )
1177 # FIXME: this should only be after we start the app
1178 topics.append( "org.onosproject.election" )
1179 main.log.debug( topics )
1180 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1181 for topic in topics:
1182 if topic not in ONOStopics:
1183 main.log.error( "Error: " + topic +
1184 " not in leaders" )
1185 missing = True
1186 else:
1187 main.log.error( "leaders() returned None" )
1188 except ( ValueError, TypeError ):
1189 main.log.exception( "Error parsing leaders" )
1190 main.log.error( repr( leaders ) )
1191 if missing:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001192 for i in main.activeNodes:
1193 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07001194 response = node.leaders( jsonFormat=False)
1195 main.log.warn( str( node.name ) + " leaders output: \n" +
1196 str( response ) )
1197
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001198 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -07001199 try:
1200 if partitions :
1201 parsedPartitions = json.loads( partitions )
1202 main.log.warn( json.dumps( parsedPartitions,
1203 sort_keys=True,
1204 indent=4,
1205 separators=( ',', ': ' ) ) )
1206 # TODO check for a leader in all paritions
1207 # TODO check for consistency among nodes
1208 else:
1209 main.log.error( "partitions() returned None" )
1210 except ( ValueError, TypeError ):
1211 main.log.exception( "Error parsing partitions" )
1212 main.log.error( repr( partitions ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001213 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -07001214 try:
1215 if pendingMap :
1216 parsedPending = json.loads( pendingMap )
1217 main.log.warn( json.dumps( parsedPending,
1218 sort_keys=True,
1219 indent=4,
1220 separators=( ',', ': ' ) ) )
1221 # TODO check something here?
1222 else:
1223 main.log.error( "pendingMap() returned None" )
1224 except ( ValueError, TypeError ):
1225 main.log.exception( "Error parsing pending map" )
1226 main.log.error( repr( pendingMap ) )
1227 # Print flowrules
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001228 node = main.activeNodes[0]
1229 main.log.debug( main.CLIs[node].flows( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001230 main.step( "Wait a minute then ping again" )
1231 # the wait is above
1232 PingResult = main.TRUE
1233 for i in range( 8, 18 ):
1234 ping = main.Mininet1.pingHost( src="h" + str( i ),
1235 target="h" + str( i + 10 ) )
1236 PingResult = PingResult and ping
1237 if ping == main.FALSE:
1238 main.log.warn( "Ping failed between h" + str( i ) +
1239 " and h" + str( i + 10 ) )
1240 elif ping == main.TRUE:
1241 main.log.info( "Ping test passed!" )
1242 # Don't set PingResult or you'd override failures
1243 if PingResult == main.FALSE:
1244 main.log.error(
1245 "Intents have not been installed correctly, pings failed." )
1246 # TODO: pretty print
1247 main.log.warn( "ONOS1 intents: " )
1248 try:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001249 tmpIntents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -07001250 main.log.warn( json.dumps( json.loads( tmpIntents ),
1251 sort_keys=True,
1252 indent=4,
1253 separators=( ',', ': ' ) ) )
1254 except ( ValueError, TypeError ):
1255 main.log.warn( repr( tmpIntents ) )
1256 utilities.assert_equals(
1257 expect=main.TRUE,
1258 actual=PingResult,
1259 onpass="Intents have been installed correctly and pings work",
1260 onfail="Intents have not been installed correctly, pings failed." )
1261
1262 def CASE5( self, main ):
1263 """
1264 Reading state of ONOS
1265 """
1266 import json
1267 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001268 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001269 assert main, "main not defined"
1270 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001271 assert main.CLIs, "main.CLIs not defined"
1272 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001273
1274 main.case( "Setting up and gathering data for current state" )
1275 # The general idea for this test case is to pull the state of
1276 # ( intents,flows, topology,... ) from each ONOS node
1277 # We can then compare them with each other and also with past states
1278
1279 main.step( "Check that each switch has a master" )
1280 global mastershipState
1281 mastershipState = '[]'
1282
1283 # Assert that each device has a master
1284 rolesNotNull = main.TRUE
1285 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001286 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001287 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001288 name="rolesNotNull-" + str( i ),
1289 args=[] )
1290 threads.append( t )
1291 t.start()
1292
1293 for t in threads:
1294 t.join()
1295 rolesNotNull = rolesNotNull and t.result
1296 utilities.assert_equals(
1297 expect=main.TRUE,
1298 actual=rolesNotNull,
1299 onpass="Each device has a master",
1300 onfail="Some devices don't have a master assigned" )
1301
1302 main.step( "Get the Mastership of each switch from each controller" )
1303 ONOSMastership = []
1304 mastershipCheck = main.FALSE
1305 consistentMastership = True
1306 rolesResults = True
1307 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001308 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001309 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001310 name="roles-" + str( i ),
1311 args=[] )
1312 threads.append( t )
1313 t.start()
1314
1315 for t in threads:
1316 t.join()
1317 ONOSMastership.append( t.result )
1318
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001319 for i in range( len( ONOSMastership ) ):
1320 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001321 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001322 main.log.error( "Error in getting ONOS" + node + " roles" )
1323 main.log.warn( "ONOS" + node + " mastership response: " +
1324 repr( ONOSMastership[i] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001325 rolesResults = False
1326 utilities.assert_equals(
1327 expect=True,
1328 actual=rolesResults,
1329 onpass="No error in reading roles output",
1330 onfail="Error in reading roles from ONOS" )
1331
1332 main.step( "Check for consistency in roles from each controller" )
1333 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1334 main.log.info(
1335 "Switch roles are consistent across all ONOS nodes" )
1336 else:
1337 consistentMastership = False
1338 utilities.assert_equals(
1339 expect=True,
1340 actual=consistentMastership,
1341 onpass="Switch roles are consistent across all ONOS nodes",
1342 onfail="ONOS nodes have different views of switch roles" )
1343
1344 if rolesResults and not consistentMastership:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001345 for i in range( len( main.activeNodes ) ):
1346 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001347 try:
1348 main.log.warn(
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001349 "ONOS" + node + " roles: ",
Jon Hall5cf14d52015-07-16 12:15:19 -07001350 json.dumps(
1351 json.loads( ONOSMastership[ i ] ),
1352 sort_keys=True,
1353 indent=4,
1354 separators=( ',', ': ' ) ) )
1355 except ( ValueError, TypeError ):
1356 main.log.warn( repr( ONOSMastership[ i ] ) )
1357 elif rolesResults and consistentMastership:
1358 mastershipCheck = main.TRUE
1359 mastershipState = ONOSMastership[ 0 ]
1360
1361 main.step( "Get the intents from each controller" )
1362 global intentState
1363 intentState = []
1364 ONOSIntents = []
1365 intentCheck = main.FALSE
1366 consistentIntents = True
1367 intentsResults = True
1368 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001369 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001370 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001371 name="intents-" + str( i ),
1372 args=[],
1373 kwargs={ 'jsonFormat': True } )
1374 threads.append( t )
1375 t.start()
1376
1377 for t in threads:
1378 t.join()
1379 ONOSIntents.append( t.result )
1380
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001381 for i in range( len( ONOSIntents ) ):
1382 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001383 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001384 main.log.error( "Error in getting ONOS" + node + " intents" )
1385 main.log.warn( "ONOS" + node + " intents response: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07001386 repr( ONOSIntents[ i ] ) )
1387 intentsResults = False
1388 utilities.assert_equals(
1389 expect=True,
1390 actual=intentsResults,
1391 onpass="No error in reading intents output",
1392 onfail="Error in reading intents from ONOS" )
1393
1394 main.step( "Check for consistency in Intents from each controller" )
1395 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1396 main.log.info( "Intents are consistent across all ONOS " +
1397 "nodes" )
1398 else:
1399 consistentIntents = False
1400 main.log.error( "Intents not consistent" )
1401 utilities.assert_equals(
1402 expect=True,
1403 actual=consistentIntents,
1404 onpass="Intents are consistent across all ONOS nodes",
1405 onfail="ONOS nodes have different views of intents" )
1406
1407 if intentsResults:
1408 # Try to make it easy to figure out what is happening
1409 #
1410 # Intent ONOS1 ONOS2 ...
1411 # 0x01 INSTALLED INSTALLING
1412 # ... ... ...
1413 # ... ... ...
1414 title = " Id"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001415 for n in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001416 title += " " * 10 + "ONOS" + str( n + 1 )
1417 main.log.warn( title )
1418 # get all intent keys in the cluster
1419 keys = []
Jon Halla440e872016-03-31 15:15:50 -07001420 try:
1421 # Get the set of all intent keys
Jon Hall5cf14d52015-07-16 12:15:19 -07001422 for nodeStr in ONOSIntents:
1423 node = json.loads( nodeStr )
1424 for intent in node:
Jon Halla440e872016-03-31 15:15:50 -07001425 keys.append( intent.get( 'id' ) )
1426 keys = set( keys )
1427 # For each intent key, print the state on each node
1428 for key in keys:
1429 row = "%-13s" % key
1430 for nodeStr in ONOSIntents:
1431 node = json.loads( nodeStr )
1432 for intent in node:
1433 if intent.get( 'id', "Error" ) == key:
1434 row += "%-15s" % intent.get( 'state' )
1435 main.log.warn( row )
1436 # End of intent state table
1437 except ValueError as e:
1438 main.log.exception( e )
1439 main.log.debug( "nodeStr was: " + repr( nodeStr ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001440
1441 if intentsResults and not consistentIntents:
1442 # print the json objects
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001443 n = str( main.activeNodes[-1] + 1 )
1444 main.log.debug( "ONOS" + n + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07001445 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1446 sort_keys=True,
1447 indent=4,
1448 separators=( ',', ': ' ) ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001449 for i in range( len( ONOSIntents ) ):
1450 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001451 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001452 main.log.debug( "ONOS" + node + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07001453 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1454 sort_keys=True,
1455 indent=4,
1456 separators=( ',', ': ' ) ) )
1457 else:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001458 main.log.debug( "ONOS" + node + " intents match ONOS" +
1459 n + " intents" )
Jon Hall5cf14d52015-07-16 12:15:19 -07001460 elif intentsResults and consistentIntents:
1461 intentCheck = main.TRUE
1462 intentState = ONOSIntents[ 0 ]
1463
1464 main.step( "Get the flows from each controller" )
1465 global flowState
1466 flowState = []
1467 ONOSFlows = []
1468 ONOSFlowsJson = []
1469 flowCheck = main.FALSE
1470 consistentFlows = True
1471 flowsResults = True
1472 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001473 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001474 t = main.Thread( target=main.CLIs[i].flows,
Jon Hall5cf14d52015-07-16 12:15:19 -07001475 name="flows-" + str( i ),
1476 args=[],
1477 kwargs={ 'jsonFormat': True } )
1478 threads.append( t )
1479 t.start()
1480
1481 # NOTE: Flows command can take some time to run
1482 time.sleep(30)
1483 for t in threads:
1484 t.join()
1485 result = t.result
1486 ONOSFlows.append( result )
1487
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001488 for i in range( len( ONOSFlows ) ):
1489 num = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001490 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1491 main.log.error( "Error in getting ONOS" + num + " flows" )
1492 main.log.warn( "ONOS" + num + " flows response: " +
1493 repr( ONOSFlows[ i ] ) )
1494 flowsResults = False
1495 ONOSFlowsJson.append( None )
1496 else:
1497 try:
1498 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1499 except ( ValueError, TypeError ):
1500 # FIXME: change this to log.error?
1501 main.log.exception( "Error in parsing ONOS" + num +
1502 " response as json." )
1503 main.log.error( repr( ONOSFlows[ i ] ) )
1504 ONOSFlowsJson.append( None )
1505 flowsResults = False
1506 utilities.assert_equals(
1507 expect=True,
1508 actual=flowsResults,
1509 onpass="No error in reading flows output",
1510 onfail="Error in reading flows from ONOS" )
1511
1512 main.step( "Check for consistency in Flows from each controller" )
1513 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1514 if all( tmp ):
1515 main.log.info( "Flow count is consistent across all ONOS nodes" )
1516 else:
1517 consistentFlows = False
1518 utilities.assert_equals(
1519 expect=True,
1520 actual=consistentFlows,
1521 onpass="The flow count is consistent across all ONOS nodes",
1522 onfail="ONOS nodes have different flow counts" )
1523
1524 if flowsResults and not consistentFlows:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001525 for i in range( len( ONOSFlows ) ):
1526 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001527 try:
1528 main.log.warn(
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001529 "ONOS" + node + " flows: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07001530 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1531 indent=4, separators=( ',', ': ' ) ) )
1532 except ( ValueError, TypeError ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001533 main.log.warn( "ONOS" + node + " flows: " +
1534 repr( ONOSFlows[ i ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001535 elif flowsResults and consistentFlows:
1536 flowCheck = main.TRUE
1537 flowState = ONOSFlows[ 0 ]
1538
1539 main.step( "Get the OF Table entries" )
1540 global flows
1541 flows = []
1542 for i in range( 1, 29 ):
GlennRC68467eb2015-11-16 18:01:01 -08001543 flows.append( main.Mininet1.getFlowTable( "s" + str( i ), version="1.3", debug=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001544 if flowCheck == main.FALSE:
1545 for table in flows:
1546 main.log.warn( table )
1547 # TODO: Compare switch flow tables with ONOS flow tables
1548
1549 main.step( "Start continuous pings" )
1550 main.Mininet2.pingLong(
1551 src=main.params[ 'PING' ][ 'source1' ],
1552 target=main.params[ 'PING' ][ 'target1' ],
1553 pingTime=500 )
1554 main.Mininet2.pingLong(
1555 src=main.params[ 'PING' ][ 'source2' ],
1556 target=main.params[ 'PING' ][ 'target2' ],
1557 pingTime=500 )
1558 main.Mininet2.pingLong(
1559 src=main.params[ 'PING' ][ 'source3' ],
1560 target=main.params[ 'PING' ][ 'target3' ],
1561 pingTime=500 )
1562 main.Mininet2.pingLong(
1563 src=main.params[ 'PING' ][ 'source4' ],
1564 target=main.params[ 'PING' ][ 'target4' ],
1565 pingTime=500 )
1566 main.Mininet2.pingLong(
1567 src=main.params[ 'PING' ][ 'source5' ],
1568 target=main.params[ 'PING' ][ 'target5' ],
1569 pingTime=500 )
1570 main.Mininet2.pingLong(
1571 src=main.params[ 'PING' ][ 'source6' ],
1572 target=main.params[ 'PING' ][ 'target6' ],
1573 pingTime=500 )
1574 main.Mininet2.pingLong(
1575 src=main.params[ 'PING' ][ 'source7' ],
1576 target=main.params[ 'PING' ][ 'target7' ],
1577 pingTime=500 )
1578 main.Mininet2.pingLong(
1579 src=main.params[ 'PING' ][ 'source8' ],
1580 target=main.params[ 'PING' ][ 'target8' ],
1581 pingTime=500 )
1582 main.Mininet2.pingLong(
1583 src=main.params[ 'PING' ][ 'source9' ],
1584 target=main.params[ 'PING' ][ 'target9' ],
1585 pingTime=500 )
1586 main.Mininet2.pingLong(
1587 src=main.params[ 'PING' ][ 'source10' ],
1588 target=main.params[ 'PING' ][ 'target10' ],
1589 pingTime=500 )
1590
1591 main.step( "Collecting topology information from ONOS" )
1592 devices = []
1593 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001594 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001595 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07001596 name="devices-" + str( i ),
1597 args=[ ] )
1598 threads.append( t )
1599 t.start()
1600
1601 for t in threads:
1602 t.join()
1603 devices.append( t.result )
1604 hosts = []
1605 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001606 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001607 t = main.Thread( target=main.CLIs[i].hosts,
Jon Hall5cf14d52015-07-16 12:15:19 -07001608 name="hosts-" + str( i ),
1609 args=[ ] )
1610 threads.append( t )
1611 t.start()
1612
1613 for t in threads:
1614 t.join()
1615 try:
1616 hosts.append( json.loads( t.result ) )
1617 except ( ValueError, TypeError ):
1618 # FIXME: better handling of this, print which node
1619 # Maybe use thread name?
1620 main.log.exception( "Error parsing json output of hosts" )
Jon Hallf3d16e72015-12-16 17:45:08 -08001621 main.log.warn( repr( t.result ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001622 hosts.append( None )
1623
1624 ports = []
1625 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001626 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001627 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07001628 name="ports-" + str( i ),
1629 args=[ ] )
1630 threads.append( t )
1631 t.start()
1632
1633 for t in threads:
1634 t.join()
1635 ports.append( t.result )
1636 links = []
1637 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001638 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001639 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07001640 name="links-" + str( i ),
1641 args=[ ] )
1642 threads.append( t )
1643 t.start()
1644
1645 for t in threads:
1646 t.join()
1647 links.append( t.result )
1648 clusters = []
1649 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001650 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001651 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07001652 name="clusters-" + str( i ),
1653 args=[ ] )
1654 threads.append( t )
1655 t.start()
1656
1657 for t in threads:
1658 t.join()
1659 clusters.append( t.result )
1660 # Compare json objects for hosts and dataplane clusters
1661
1662 # hosts
1663 main.step( "Host view is consistent across ONOS nodes" )
1664 consistentHostsResult = main.TRUE
1665 for controller in range( len( hosts ) ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001666 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hallf3d16e72015-12-16 17:45:08 -08001667 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001668 if hosts[ controller ] == hosts[ 0 ]:
1669 continue
1670 else: # hosts not consistent
1671 main.log.error( "hosts from ONOS" +
1672 controllerStr +
1673 " is inconsistent with ONOS1" )
1674 main.log.warn( repr( hosts[ controller ] ) )
1675 consistentHostsResult = main.FALSE
1676
1677 else:
1678 main.log.error( "Error in getting ONOS hosts from ONOS" +
1679 controllerStr )
1680 consistentHostsResult = main.FALSE
1681 main.log.warn( "ONOS" + controllerStr +
1682 " hosts response: " +
1683 repr( hosts[ controller ] ) )
1684 utilities.assert_equals(
1685 expect=main.TRUE,
1686 actual=consistentHostsResult,
1687 onpass="Hosts view is consistent across all ONOS nodes",
1688 onfail="ONOS nodes have different views of hosts" )
1689
1690 main.step( "Each host has an IP address" )
1691 ipResult = main.TRUE
1692 for controller in range( 0, len( hosts ) ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001693 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hallf3d16e72015-12-16 17:45:08 -08001694 if hosts[ controller ]:
1695 for host in hosts[ controller ]:
1696 if not host.get( 'ipAddresses', [ ] ):
1697 main.log.error( "Error with host ips on controller" +
1698 controllerStr + ": " + str( host ) )
1699 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07001700 utilities.assert_equals(
1701 expect=main.TRUE,
1702 actual=ipResult,
1703 onpass="The ips of the hosts aren't empty",
1704 onfail="The ip of at least one host is missing" )
1705
1706 # Strongly connected clusters of devices
1707 main.step( "Cluster view is consistent across ONOS nodes" )
1708 consistentClustersResult = main.TRUE
1709 for controller in range( len( clusters ) ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001710 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001711 if "Error" not in clusters[ controller ]:
1712 if clusters[ controller ] == clusters[ 0 ]:
1713 continue
1714 else: # clusters not consistent
1715 main.log.error( "clusters from ONOS" + controllerStr +
1716 " is inconsistent with ONOS1" )
1717 consistentClustersResult = main.FALSE
1718
1719 else:
1720 main.log.error( "Error in getting dataplane clusters " +
1721 "from ONOS" + controllerStr )
1722 consistentClustersResult = main.FALSE
1723 main.log.warn( "ONOS" + controllerStr +
1724 " clusters response: " +
1725 repr( clusters[ controller ] ) )
1726 utilities.assert_equals(
1727 expect=main.TRUE,
1728 actual=consistentClustersResult,
1729 onpass="Clusters view is consistent across all ONOS nodes",
1730 onfail="ONOS nodes have different views of clusters" )
Jon Hall172b7ba2016-04-07 18:12:20 -07001731 if consistentClustersResult != main.TRUE:
1732 main.log.debug( clusters )
Jon Hall5cf14d52015-07-16 12:15:19 -07001733 # there should always only be one cluster
1734 main.step( "Cluster view correct across ONOS nodes" )
1735 try:
1736 numClusters = len( json.loads( clusters[ 0 ] ) )
1737 except ( ValueError, TypeError ):
1738 main.log.exception( "Error parsing clusters[0]: " +
1739 repr( clusters[ 0 ] ) )
Jon Hall6e709752016-02-01 13:38:46 -08001740 numClusters = "ERROR"
Jon Hall5cf14d52015-07-16 12:15:19 -07001741 clusterResults = main.FALSE
1742 if numClusters == 1:
1743 clusterResults = main.TRUE
1744 utilities.assert_equals(
1745 expect=1,
1746 actual=numClusters,
1747 onpass="ONOS shows 1 SCC",
1748 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1749
1750 main.step( "Comparing ONOS topology to MN" )
1751 devicesResults = main.TRUE
1752 linksResults = main.TRUE
1753 hostsResults = main.TRUE
1754 mnSwitches = main.Mininet1.getSwitches()
1755 mnLinks = main.Mininet1.getLinks()
1756 mnHosts = main.Mininet1.getHosts()
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001757 for controller in main.activeNodes:
1758 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001759 if devices[ controller ] and ports[ controller ] and\
1760 "Error" not in devices[ controller ] and\
1761 "Error" not in ports[ controller ]:
Jon Hall6e709752016-02-01 13:38:46 -08001762 currentDevicesResult = main.Mininet1.compareSwitches(
1763 mnSwitches,
1764 json.loads( devices[ controller ] ),
1765 json.loads( ports[ controller ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001766 else:
1767 currentDevicesResult = main.FALSE
1768 utilities.assert_equals( expect=main.TRUE,
1769 actual=currentDevicesResult,
1770 onpass="ONOS" + controllerStr +
1771 " Switches view is correct",
1772 onfail="ONOS" + controllerStr +
1773 " Switches view is incorrect" )
1774 if links[ controller ] and "Error" not in links[ controller ]:
1775 currentLinksResult = main.Mininet1.compareLinks(
1776 mnSwitches, mnLinks,
1777 json.loads( links[ controller ] ) )
1778 else:
1779 currentLinksResult = main.FALSE
1780 utilities.assert_equals( expect=main.TRUE,
1781 actual=currentLinksResult,
1782 onpass="ONOS" + controllerStr +
1783 " links view is correct",
1784 onfail="ONOS" + controllerStr +
1785 " links view is incorrect" )
1786
Jon Hall657cdf62015-12-17 14:40:51 -08001787 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001788 currentHostsResult = main.Mininet1.compareHosts(
1789 mnHosts,
1790 hosts[ controller ] )
1791 else:
1792 currentHostsResult = main.FALSE
1793 utilities.assert_equals( expect=main.TRUE,
1794 actual=currentHostsResult,
1795 onpass="ONOS" + controllerStr +
1796 " hosts exist in Mininet",
1797 onfail="ONOS" + controllerStr +
1798 " hosts don't match Mininet" )
1799
1800 devicesResults = devicesResults and currentDevicesResult
1801 linksResults = linksResults and currentLinksResult
1802 hostsResults = hostsResults and currentHostsResult
1803
1804 main.step( "Device information is correct" )
1805 utilities.assert_equals(
1806 expect=main.TRUE,
1807 actual=devicesResults,
1808 onpass="Device information is correct",
1809 onfail="Device information is incorrect" )
1810
1811 main.step( "Links are correct" )
1812 utilities.assert_equals(
1813 expect=main.TRUE,
1814 actual=linksResults,
1815 onpass="Link are correct",
1816 onfail="Links are incorrect" )
1817
1818 main.step( "Hosts are correct" )
1819 utilities.assert_equals(
1820 expect=main.TRUE,
1821 actual=hostsResults,
1822 onpass="Hosts are correct",
1823 onfail="Hosts are incorrect" )
1824
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001825 def CASE61( self, main ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001826 """
1827 The Failure case.
1828 """
Jon Halle1a3b752015-07-22 13:02:46 -07001829 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001830 assert main, "main not defined"
1831 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001832 assert main.CLIs, "main.CLIs not defined"
1833 assert main.nodes, "main.nodes not defined"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001834 main.case( "Kill minority of ONOS nodes" )
Jon Hall96091e62015-09-21 17:34:17 -07001835
1836 main.step( "Checking ONOS Logs for errors" )
1837 for node in main.nodes:
1838 main.log.debug( "Checking logs for errors on " + node.name + ":" )
1839 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
1840
Jon Hall3b489db2015-10-05 14:38:37 -07001841 n = len( main.nodes ) # Number of nodes
1842 p = ( ( n + 1 ) / 2 ) + 1 # Number of partitions
1843 main.kill = [ 0 ] # ONOS node to kill, listed by index in main.nodes
1844 if n > 3:
1845 main.kill.append( p - 1 )
1846 # NOTE: This only works for cluster sizes of 3,5, or 7.
1847
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001848 main.step( "Kill " + str( len( main.kill ) ) + " ONOS nodes" )
Jon Hall3b489db2015-10-05 14:38:37 -07001849 killResults = main.TRUE
1850 for i in main.kill:
1851 killResults = killResults and\
1852 main.ONOSbench.onosKill( main.nodes[i].ip_address )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001853 main.activeNodes.remove( i )
Jon Hall5cf14d52015-07-16 12:15:19 -07001854 utilities.assert_equals( expect=main.TRUE, actual=killResults,
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001855 onpass="ONOS nodes killed successfully",
1856 onfail="ONOS nodes NOT successfully killed" )
1857
1858 def CASE62( self, main ):
1859 """
1860 The bring up stopped nodes
1861 """
1862 import time
1863 assert main.numCtrls, "main.numCtrls not defined"
1864 assert main, "main not defined"
1865 assert utilities.assert_equals, "utilities.assert_equals not defined"
1866 assert main.CLIs, "main.CLIs not defined"
1867 assert main.nodes, "main.nodes not defined"
1868 assert main.kill, "main.kill not defined"
1869 main.case( "Restart minority of ONOS nodes" )
1870
1871 main.step( "Restarting " + str( len( main.kill ) ) + " ONOS nodes" )
1872 startResults = main.TRUE
1873 restartTime = time.time()
1874 for i in main.kill:
1875 startResults = startResults and\
1876 main.ONOSbench.onosStart( main.nodes[i].ip_address )
1877 utilities.assert_equals( expect=main.TRUE, actual=startResults,
1878 onpass="ONOS nodes started successfully",
1879 onfail="ONOS nodes NOT successfully started" )
Jon Hall5cf14d52015-07-16 12:15:19 -07001880
1881 main.step( "Checking if ONOS is up yet" )
1882 count = 0
1883 onosIsupResult = main.FALSE
1884 while onosIsupResult == main.FALSE and count < 10:
Jon Hall3b489db2015-10-05 14:38:37 -07001885 onosIsupResult = main.TRUE
1886 for i in main.kill:
1887 onosIsupResult = onosIsupResult and\
1888 main.ONOSbench.isup( main.nodes[i].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -07001889 count = count + 1
Jon Hall5cf14d52015-07-16 12:15:19 -07001890 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1891 onpass="ONOS restarted successfully",
1892 onfail="ONOS restart NOT successful" )
1893
Jon Halle1a3b752015-07-22 13:02:46 -07001894 main.step( "Restarting ONOS main.CLIs" )
Jon Hall3b489db2015-10-05 14:38:37 -07001895 cliResults = main.TRUE
1896 for i in main.kill:
1897 cliResults = cliResults and\
1898 main.CLIs[i].startOnosCli( main.nodes[i].ip_address )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001899 main.activeNodes.append( i )
Jon Hall5cf14d52015-07-16 12:15:19 -07001900 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1901 onpass="ONOS cli restarted",
1902 onfail="ONOS cli did not restart" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001903 main.activeNodes.sort()
1904 try:
1905 assert list( set( main.activeNodes ) ) == main.activeNodes,\
1906 "List of active nodes has duplicates, this likely indicates something was run out of order"
1907 except AssertionError:
1908 main.log.exception( "" )
1909 main.cleanup()
1910 main.exit()
Jon Hall5cf14d52015-07-16 12:15:19 -07001911
1912 # Grab the time of restart so we chan check how long the gossip
1913 # protocol has had time to work
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001914 main.restartTime = time.time() - restartTime
Jon Hall5cf14d52015-07-16 12:15:19 -07001915 main.log.debug( "Restart time: " + str( main.restartTime ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001916 # TODO: MAke this configurable. Also, we are breaking the above timer
1917 time.sleep( 60 )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001918 node = main.activeNodes[0]
1919 main.log.debug( main.CLIs[node].nodes( jsonFormat=False ) )
1920 main.log.debug( main.CLIs[node].leaders( jsonFormat=False ) )
1921 main.log.debug( main.CLIs[node].partitions( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001922
Jon Halla440e872016-03-31 15:15:50 -07001923 main.step( "Rerun for election on the node(s) that were killed" )
1924 runResults = main.TRUE
1925 for i in main.kill:
1926 runResults = runResults and\
1927 main.CLIs[i].electionTestRun()
1928 utilities.assert_equals( expect=main.TRUE, actual=runResults,
1929 onpass="ONOS nodes reran for election topic",
1930 onfail="Errror rerunning for election" )
1931
Jon Hall5cf14d52015-07-16 12:15:19 -07001932 def CASE7( self, main ):
1933 """
1934 Check state after ONOS failure
1935 """
1936 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001937 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001938 assert main, "main not defined"
1939 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001940 assert main.CLIs, "main.CLIs not defined"
1941 assert main.nodes, "main.nodes not defined"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001942 try:
1943 main.kill
1944 except AttributeError:
1945 main.kill = []
1946
Jon Hall5cf14d52015-07-16 12:15:19 -07001947 main.case( "Running ONOS Constant State Tests" )
1948
1949 main.step( "Check that each switch has a master" )
1950 # Assert that each device has a master
1951 rolesNotNull = main.TRUE
1952 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001953 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001954 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001955 name="rolesNotNull-" + str( i ),
1956 args=[ ] )
1957 threads.append( t )
1958 t.start()
1959
1960 for t in threads:
1961 t.join()
1962 rolesNotNull = rolesNotNull and t.result
1963 utilities.assert_equals(
1964 expect=main.TRUE,
1965 actual=rolesNotNull,
1966 onpass="Each device has a master",
1967 onfail="Some devices don't have a master assigned" )
1968
1969 main.step( "Read device roles from ONOS" )
1970 ONOSMastership = []
Jon Halla440e872016-03-31 15:15:50 -07001971 mastershipCheck = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07001972 consistentMastership = True
1973 rolesResults = True
1974 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001975 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001976 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001977 name="roles-" + str( i ),
1978 args=[] )
1979 threads.append( t )
1980 t.start()
1981
1982 for t in threads:
1983 t.join()
1984 ONOSMastership.append( t.result )
1985
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001986 for i in range( len( ONOSMastership ) ):
1987 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001988 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001989 main.log.error( "Error in getting ONOS" + node + " roles" )
1990 main.log.warn( "ONOS" + node + " mastership response: " +
1991 repr( ONOSMastership[i] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001992 rolesResults = False
1993 utilities.assert_equals(
1994 expect=True,
1995 actual=rolesResults,
1996 onpass="No error in reading roles output",
1997 onfail="Error in reading roles from ONOS" )
1998
1999 main.step( "Check for consistency in roles from each controller" )
2000 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
2001 main.log.info(
2002 "Switch roles are consistent across all ONOS nodes" )
2003 else:
2004 consistentMastership = False
2005 utilities.assert_equals(
2006 expect=True,
2007 actual=consistentMastership,
2008 onpass="Switch roles are consistent across all ONOS nodes",
2009 onfail="ONOS nodes have different views of switch roles" )
2010
2011 if rolesResults and not consistentMastership:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002012 for i in range( len( ONOSMastership ) ):
2013 node = str( main.activeNodes[i] + 1 )
2014 main.log.warn( "ONOS" + node + " roles: ",
2015 json.dumps( json.loads( ONOSMastership[ i ] ),
2016 sort_keys=True,
2017 indent=4,
2018 separators=( ',', ': ' ) ) )
Jon Halla440e872016-03-31 15:15:50 -07002019 elif rolesResults and consistentMastership:
2020 mastershipCheck = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002021
2022 # NOTE: we expect mastership to change on controller failure
Jon Hall5cf14d52015-07-16 12:15:19 -07002023
2024 main.step( "Get the intents and compare across all nodes" )
2025 ONOSIntents = []
2026 intentCheck = main.FALSE
2027 consistentIntents = True
2028 intentsResults = True
2029 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002030 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002031 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07002032 name="intents-" + str( i ),
2033 args=[],
2034 kwargs={ 'jsonFormat': True } )
2035 threads.append( t )
2036 t.start()
2037
2038 for t in threads:
2039 t.join()
2040 ONOSIntents.append( t.result )
2041
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002042 for i in range( len( ONOSIntents) ):
2043 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002044 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002045 main.log.error( "Error in getting ONOS" + node + " intents" )
2046 main.log.warn( "ONOS" + node + " intents response: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07002047 repr( ONOSIntents[ i ] ) )
2048 intentsResults = False
2049 utilities.assert_equals(
2050 expect=True,
2051 actual=intentsResults,
2052 onpass="No error in reading intents output",
2053 onfail="Error in reading intents from ONOS" )
2054
2055 main.step( "Check for consistency in Intents from each controller" )
2056 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
2057 main.log.info( "Intents are consistent across all ONOS " +
2058 "nodes" )
2059 else:
2060 consistentIntents = False
2061
2062 # Try to make it easy to figure out what is happening
2063 #
2064 # Intent ONOS1 ONOS2 ...
2065 # 0x01 INSTALLED INSTALLING
2066 # ... ... ...
2067 # ... ... ...
2068 title = " ID"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002069 for n in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07002070 title += " " * 10 + "ONOS" + str( n + 1 )
2071 main.log.warn( title )
2072 # get all intent keys in the cluster
2073 keys = []
2074 for nodeStr in ONOSIntents:
2075 node = json.loads( nodeStr )
2076 for intent in node:
2077 keys.append( intent.get( 'id' ) )
2078 keys = set( keys )
2079 for key in keys:
2080 row = "%-13s" % key
2081 for nodeStr in ONOSIntents:
2082 node = json.loads( nodeStr )
2083 for intent in node:
2084 if intent.get( 'id' ) == key:
2085 row += "%-15s" % intent.get( 'state' )
2086 main.log.warn( row )
2087 # End table view
2088
2089 utilities.assert_equals(
2090 expect=True,
2091 actual=consistentIntents,
2092 onpass="Intents are consistent across all ONOS nodes",
2093 onfail="ONOS nodes have different views of intents" )
2094 intentStates = []
2095 for node in ONOSIntents: # Iter through ONOS nodes
2096 nodeStates = []
2097 # Iter through intents of a node
2098 try:
2099 for intent in json.loads( node ):
2100 nodeStates.append( intent[ 'state' ] )
2101 except ( ValueError, TypeError ):
2102 main.log.exception( "Error in parsing intents" )
2103 main.log.error( repr( node ) )
2104 intentStates.append( nodeStates )
2105 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
2106 main.log.info( dict( out ) )
2107
2108 if intentsResults and not consistentIntents:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002109 for i in range( len( main.activeNodes ) ):
2110 node = str( main.activeNodes[i] + 1 )
2111 main.log.warn( "ONOS" + node + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07002112 main.log.warn( json.dumps(
2113 json.loads( ONOSIntents[ i ] ),
2114 sort_keys=True,
2115 indent=4,
2116 separators=( ',', ': ' ) ) )
2117 elif intentsResults and consistentIntents:
2118 intentCheck = main.TRUE
2119
2120 # NOTE: Store has no durability, so intents are lost across system
2121 # restarts
2122 main.step( "Compare current intents with intents before the failure" )
2123 # NOTE: this requires case 5 to pass for intentState to be set.
2124 # maybe we should stop the test if that fails?
2125 sameIntents = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002126 try:
2127 intentState
2128 except NameError:
2129 main.log.warn( "No previous intent state was saved" )
2130 else:
2131 if intentState and intentState == ONOSIntents[ 0 ]:
2132 sameIntents = main.TRUE
2133 main.log.info( "Intents are consistent with before failure" )
2134 # TODO: possibly the states have changed? we may need to figure out
2135 # what the acceptable states are
2136 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
2137 sameIntents = main.TRUE
2138 try:
2139 before = json.loads( intentState )
2140 after = json.loads( ONOSIntents[ 0 ] )
2141 for intent in before:
2142 if intent not in after:
2143 sameIntents = main.FALSE
2144 main.log.debug( "Intent is not currently in ONOS " +
2145 "(at least in the same form):" )
2146 main.log.debug( json.dumps( intent ) )
2147 except ( ValueError, TypeError ):
2148 main.log.exception( "Exception printing intents" )
2149 main.log.debug( repr( ONOSIntents[0] ) )
2150 main.log.debug( repr( intentState ) )
2151 if sameIntents == main.FALSE:
2152 try:
2153 main.log.debug( "ONOS intents before: " )
2154 main.log.debug( json.dumps( json.loads( intentState ),
2155 sort_keys=True, indent=4,
2156 separators=( ',', ': ' ) ) )
2157 main.log.debug( "Current ONOS intents: " )
2158 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
2159 sort_keys=True, indent=4,
2160 separators=( ',', ': ' ) ) )
2161 except ( ValueError, TypeError ):
2162 main.log.exception( "Exception printing intents" )
2163 main.log.debug( repr( ONOSIntents[0] ) )
2164 main.log.debug( repr( intentState ) )
2165 utilities.assert_equals(
2166 expect=main.TRUE,
2167 actual=sameIntents,
2168 onpass="Intents are consistent with before failure",
2169 onfail="The Intents changed during failure" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002170 intentCheck = intentCheck and sameIntents
2171
2172 main.step( "Get the OF Table entries and compare to before " +
2173 "component failure" )
2174 FlowTables = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002175 for i in range( 28 ):
2176 main.log.info( "Checking flow table on s" + str( i + 1 ) )
GlennRC68467eb2015-11-16 18:01:01 -08002177 tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
2178 FlowTables = FlowTables and main.Mininet1.flowTableComp( flows[i], tmpFlows )
Jon Hall5cf14d52015-07-16 12:15:19 -07002179 if FlowTables == main.FALSE:
GlennRC68467eb2015-11-16 18:01:01 -08002180 main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002181 utilities.assert_equals(
2182 expect=main.TRUE,
2183 actual=FlowTables,
2184 onpass="No changes were found in the flow tables",
2185 onfail="Changes were found in the flow tables" )
2186
2187 main.Mininet2.pingLongKill()
2188 '''
2189 main.step( "Check the continuous pings to ensure that no packets " +
2190 "were dropped during component failure" )
2191 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
2192 main.params[ 'TESTONIP' ] )
2193 LossInPings = main.FALSE
2194 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
2195 for i in range( 8, 18 ):
2196 main.log.info(
2197 "Checking for a loss in pings along flow from s" +
2198 str( i ) )
2199 LossInPings = main.Mininet2.checkForLoss(
2200 "/tmp/ping.h" +
2201 str( i ) ) or LossInPings
2202 if LossInPings == main.TRUE:
2203 main.log.info( "Loss in ping detected" )
2204 elif LossInPings == main.ERROR:
2205 main.log.info( "There are multiple mininet process running" )
2206 elif LossInPings == main.FALSE:
2207 main.log.info( "No Loss in the pings" )
2208 main.log.info( "No loss of dataplane connectivity" )
2209 utilities.assert_equals(
2210 expect=main.FALSE,
2211 actual=LossInPings,
2212 onpass="No Loss of connectivity",
2213 onfail="Loss of dataplane connectivity detected" )
2214 '''
2215
2216 main.step( "Leadership Election is still functional" )
2217 # Test of LeadershipElection
2218 leaderList = []
Jon Hall5cf14d52015-07-16 12:15:19 -07002219
Jon Hall3b489db2015-10-05 14:38:37 -07002220 restarted = []
2221 for i in main.kill:
2222 restarted.append( main.nodes[i].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -07002223 leaderResult = main.TRUE
Jon Hall3b489db2015-10-05 14:38:37 -07002224
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002225 for i in main.activeNodes:
2226 cli = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07002227 leaderN = cli.electionTestLeader()
2228 leaderList.append( leaderN )
2229 if leaderN == main.FALSE:
2230 # error in response
2231 main.log.error( "Something is wrong with " +
2232 "electionTestLeader function, check the" +
2233 " error logs" )
2234 leaderResult = main.FALSE
2235 elif leaderN is None:
2236 main.log.error( cli.name +
2237 " shows no leader for the election-app was" +
2238 " elected after the old one died" )
2239 leaderResult = main.FALSE
2240 elif leaderN in restarted:
2241 main.log.error( cli.name + " shows " + str( leaderN ) +
2242 " as leader for the election-app, but it " +
2243 "was restarted" )
2244 leaderResult = main.FALSE
2245 if len( set( leaderList ) ) != 1:
2246 leaderResult = main.FALSE
2247 main.log.error(
2248 "Inconsistent view of leader for the election test app" )
2249 # TODO: print the list
2250 utilities.assert_equals(
2251 expect=main.TRUE,
2252 actual=leaderResult,
2253 onpass="Leadership election passed",
2254 onfail="Something went wrong with Leadership election" )
2255
2256 def CASE8( self, main ):
2257 """
2258 Compare topo
2259 """
2260 import json
2261 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002262 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002263 assert main, "main not defined"
2264 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002265 assert main.CLIs, "main.CLIs not defined"
2266 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002267
2268 main.case( "Compare ONOS Topology view to Mininet topology" )
Jon Hall783bbf92015-07-23 14:33:19 -07002269 main.caseExplanation = "Compare topology objects between Mininet" +\
Jon Hall5cf14d52015-07-16 12:15:19 -07002270 " and ONOS"
Jon Hall5cf14d52015-07-16 12:15:19 -07002271 topoResult = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08002272 topoFailMsg = "ONOS topology don't match Mininet"
Jon Hall5cf14d52015-07-16 12:15:19 -07002273 elapsed = 0
2274 count = 0
Jon Halle9b1fa32015-12-08 15:32:21 -08002275 main.step( "Comparing ONOS topology to MN topology" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002276 startTime = time.time()
2277 # Give time for Gossip to work
Jon Halle9b1fa32015-12-08 15:32:21 -08002278 while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
Jon Hall96091e62015-09-21 17:34:17 -07002279 devicesResults = main.TRUE
2280 linksResults = main.TRUE
2281 hostsResults = main.TRUE
2282 hostAttachmentResults = True
Jon Hall5cf14d52015-07-16 12:15:19 -07002283 count += 1
2284 cliStart = time.time()
2285 devices = []
2286 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002287 for i in main.activeNodes:
Jon Hall6e709752016-02-01 13:38:46 -08002288 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002289 name="devices-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08002290 args=[ main.CLIs[i].devices, [ None ] ],
2291 kwargs= { 'sleep': 5, 'attempts': 5,
2292 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002293 threads.append( t )
2294 t.start()
2295
2296 for t in threads:
2297 t.join()
2298 devices.append( t.result )
2299 hosts = []
2300 ipResult = main.TRUE
2301 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002302 for i in main.activeNodes:
Jon Halld8f6de82015-12-17 17:04:34 -08002303 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002304 name="hosts-" + str( i ),
Jon Halld8f6de82015-12-17 17:04:34 -08002305 args=[ main.CLIs[i].hosts, [ None ] ],
2306 kwargs= { 'sleep': 5, 'attempts': 5,
2307 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002308 threads.append( t )
2309 t.start()
2310
2311 for t in threads:
2312 t.join()
2313 try:
2314 hosts.append( json.loads( t.result ) )
2315 except ( ValueError, TypeError ):
2316 main.log.exception( "Error parsing hosts results" )
2317 main.log.error( repr( t.result ) )
Jon Hallf3d16e72015-12-16 17:45:08 -08002318 hosts.append( None )
Jon Hall5cf14d52015-07-16 12:15:19 -07002319 for controller in range( 0, len( hosts ) ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002320 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hallacd1b182015-12-17 11:43:20 -08002321 if hosts[ controller ]:
2322 for host in hosts[ controller ]:
2323 if host is None or host.get( 'ipAddresses', [] ) == []:
2324 main.log.error(
2325 "Error with host ipAddresses on controller" +
2326 controllerStr + ": " + str( host ) )
2327 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002328 ports = []
2329 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002330 for i in main.activeNodes:
Jon Hall6e709752016-02-01 13:38:46 -08002331 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002332 name="ports-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08002333 args=[ main.CLIs[i].ports, [ None ] ],
2334 kwargs= { 'sleep': 5, 'attempts': 5,
2335 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002336 threads.append( t )
2337 t.start()
2338
2339 for t in threads:
2340 t.join()
2341 ports.append( t.result )
2342 links = []
2343 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002344 for i in main.activeNodes:
Jon Hall6e709752016-02-01 13:38:46 -08002345 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002346 name="links-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08002347 args=[ main.CLIs[i].links, [ None ] ],
2348 kwargs= { 'sleep': 5, 'attempts': 5,
2349 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002350 threads.append( t )
2351 t.start()
2352
2353 for t in threads:
2354 t.join()
2355 links.append( t.result )
2356 clusters = []
2357 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002358 for i in main.activeNodes:
Jon Hall6e709752016-02-01 13:38:46 -08002359 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002360 name="clusters-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08002361 args=[ main.CLIs[i].clusters, [ None ] ],
2362 kwargs= { 'sleep': 5, 'attempts': 5,
2363 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002364 threads.append( t )
2365 t.start()
2366
2367 for t in threads:
2368 t.join()
2369 clusters.append( t.result )
2370
2371 elapsed = time.time() - startTime
2372 cliTime = time.time() - cliStart
2373 print "Elapsed time: " + str( elapsed )
2374 print "CLI time: " + str( cliTime )
2375
Jon Hall6e709752016-02-01 13:38:46 -08002376 if all( e is None for e in devices ) and\
2377 all( e is None for e in hosts ) and\
2378 all( e is None for e in ports ) and\
2379 all( e is None for e in links ) and\
2380 all( e is None for e in clusters ):
2381 topoFailMsg = "Could not get topology from ONOS"
2382 main.log.error( topoFailMsg )
2383 continue # Try again, No use trying to compare
2384
Jon Hall5cf14d52015-07-16 12:15:19 -07002385 mnSwitches = main.Mininet1.getSwitches()
2386 mnLinks = main.Mininet1.getLinks()
2387 mnHosts = main.Mininet1.getHosts()
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002388 for controller in range( len( main.activeNodes ) ):
2389 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002390 if devices[ controller ] and ports[ controller ] and\
2391 "Error" not in devices[ controller ] and\
2392 "Error" not in ports[ controller ]:
2393
Jon Hallc6793552016-01-19 14:18:37 -08002394 try:
2395 currentDevicesResult = main.Mininet1.compareSwitches(
2396 mnSwitches,
2397 json.loads( devices[ controller ] ),
2398 json.loads( ports[ controller ] ) )
2399 except ( TypeError, ValueError ) as e:
2400 main.log.exception( "Object not as expected; devices={!r}\nports={!r}".format(
2401 devices[ controller ], ports[ controller ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002402 else:
2403 currentDevicesResult = main.FALSE
2404 utilities.assert_equals( expect=main.TRUE,
2405 actual=currentDevicesResult,
2406 onpass="ONOS" + controllerStr +
2407 " Switches view is correct",
2408 onfail="ONOS" + controllerStr +
2409 " Switches view is incorrect" )
2410
2411 if links[ controller ] and "Error" not in links[ controller ]:
2412 currentLinksResult = main.Mininet1.compareLinks(
2413 mnSwitches, mnLinks,
2414 json.loads( links[ controller ] ) )
2415 else:
2416 currentLinksResult = main.FALSE
2417 utilities.assert_equals( expect=main.TRUE,
2418 actual=currentLinksResult,
2419 onpass="ONOS" + controllerStr +
2420 " links view is correct",
2421 onfail="ONOS" + controllerStr +
2422 " links view is incorrect" )
Jon Hall657cdf62015-12-17 14:40:51 -08002423 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002424 currentHostsResult = main.Mininet1.compareHosts(
2425 mnHosts,
2426 hosts[ controller ] )
Jon Hall13b446e2016-01-05 12:17:01 -08002427 elif hosts[ controller ] == []:
2428 currentHostsResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002429 else:
2430 currentHostsResult = main.FALSE
2431 utilities.assert_equals( expect=main.TRUE,
2432 actual=currentHostsResult,
2433 onpass="ONOS" + controllerStr +
2434 " hosts exist in Mininet",
2435 onfail="ONOS" + controllerStr +
2436 " hosts don't match Mininet" )
2437 # CHECKING HOST ATTACHMENT POINTS
2438 hostAttachment = True
2439 zeroHosts = False
2440 # FIXME: topo-HA/obelisk specific mappings:
2441 # key is mac and value is dpid
2442 mappings = {}
2443 for i in range( 1, 29 ): # hosts 1 through 28
2444 # set up correct variables:
2445 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2446 if i == 1:
2447 deviceId = "1000".zfill(16)
2448 elif i == 2:
2449 deviceId = "2000".zfill(16)
2450 elif i == 3:
2451 deviceId = "3000".zfill(16)
2452 elif i == 4:
2453 deviceId = "3004".zfill(16)
2454 elif i == 5:
2455 deviceId = "5000".zfill(16)
2456 elif i == 6:
2457 deviceId = "6000".zfill(16)
2458 elif i == 7:
2459 deviceId = "6007".zfill(16)
2460 elif i >= 8 and i <= 17:
2461 dpid = '3' + str( i ).zfill( 3 )
2462 deviceId = dpid.zfill(16)
2463 elif i >= 18 and i <= 27:
2464 dpid = '6' + str( i ).zfill( 3 )
2465 deviceId = dpid.zfill(16)
2466 elif i == 28:
2467 deviceId = "2800".zfill(16)
2468 mappings[ macId ] = deviceId
Jon Halld8f6de82015-12-17 17:04:34 -08002469 if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002470 if hosts[ controller ] == []:
2471 main.log.warn( "There are no hosts discovered" )
2472 zeroHosts = True
2473 else:
2474 for host in hosts[ controller ]:
2475 mac = None
2476 location = None
2477 device = None
2478 port = None
2479 try:
2480 mac = host.get( 'mac' )
2481 assert mac, "mac field could not be found for this host object"
2482
2483 location = host.get( 'location' )
2484 assert location, "location field could not be found for this host object"
2485
2486 # Trim the protocol identifier off deviceId
2487 device = str( location.get( 'elementId' ) ).split(':')[1]
2488 assert device, "elementId field could not be found for this host location object"
2489
2490 port = location.get( 'port' )
2491 assert port, "port field could not be found for this host location object"
2492
2493 # Now check if this matches where they should be
2494 if mac and device and port:
2495 if str( port ) != "1":
2496 main.log.error( "The attachment port is incorrect for " +
2497 "host " + str( mac ) +
2498 ". Expected: 1 Actual: " + str( port) )
2499 hostAttachment = False
2500 if device != mappings[ str( mac ) ]:
2501 main.log.error( "The attachment device is incorrect for " +
2502 "host " + str( mac ) +
2503 ". Expected: " + mappings[ str( mac ) ] +
2504 " Actual: " + device )
2505 hostAttachment = False
2506 else:
2507 hostAttachment = False
2508 except AssertionError:
2509 main.log.exception( "Json object not as expected" )
2510 main.log.error( repr( host ) )
2511 hostAttachment = False
2512 else:
2513 main.log.error( "No hosts json output or \"Error\"" +
2514 " in output. hosts = " +
2515 repr( hosts[ controller ] ) )
2516 if zeroHosts is False:
2517 hostAttachment = True
2518
2519 # END CHECKING HOST ATTACHMENT POINTS
2520 devicesResults = devicesResults and currentDevicesResult
2521 linksResults = linksResults and currentLinksResult
2522 hostsResults = hostsResults and currentHostsResult
2523 hostAttachmentResults = hostAttachmentResults and\
2524 hostAttachment
Jon Halla440e872016-03-31 15:15:50 -07002525 topoResult = ( devicesResults and linksResults
2526 and hostsResults and ipResult and
2527 hostAttachmentResults )
Jon Halle9b1fa32015-12-08 15:32:21 -08002528 utilities.assert_equals( expect=True,
2529 actual=topoResult,
2530 onpass="ONOS topology matches Mininet",
Jon Hall6e709752016-02-01 13:38:46 -08002531 onfail=topoFailMsg )
Jon Halle9b1fa32015-12-08 15:32:21 -08002532 # End of While loop to pull ONOS state
Jon Hall5cf14d52015-07-16 12:15:19 -07002533
2534 # Compare json objects for hosts and dataplane clusters
2535
2536 # hosts
2537 main.step( "Hosts view is consistent across all ONOS nodes" )
2538 consistentHostsResult = main.TRUE
2539 for controller in range( len( hosts ) ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002540 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall13b446e2016-01-05 12:17:01 -08002541 if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002542 if hosts[ controller ] == hosts[ 0 ]:
2543 continue
2544 else: # hosts not consistent
2545 main.log.error( "hosts from ONOS" + controllerStr +
2546 " is inconsistent with ONOS1" )
2547 main.log.warn( repr( hosts[ controller ] ) )
2548 consistentHostsResult = main.FALSE
2549
2550 else:
2551 main.log.error( "Error in getting ONOS hosts from ONOS" +
2552 controllerStr )
2553 consistentHostsResult = main.FALSE
2554 main.log.warn( "ONOS" + controllerStr +
2555 " hosts response: " +
2556 repr( hosts[ controller ] ) )
2557 utilities.assert_equals(
2558 expect=main.TRUE,
2559 actual=consistentHostsResult,
2560 onpass="Hosts view is consistent across all ONOS nodes",
2561 onfail="ONOS nodes have different views of hosts" )
2562
2563 main.step( "Hosts information is correct" )
2564 hostsResults = hostsResults and ipResult
2565 utilities.assert_equals(
2566 expect=main.TRUE,
2567 actual=hostsResults,
2568 onpass="Host information is correct",
2569 onfail="Host information is incorrect" )
2570
2571 main.step( "Host attachment points to the network" )
2572 utilities.assert_equals(
2573 expect=True,
2574 actual=hostAttachmentResults,
2575 onpass="Hosts are correctly attached to the network",
2576 onfail="ONOS did not correctly attach hosts to the network" )
2577
2578 # Strongly connected clusters of devices
2579 main.step( "Clusters view is consistent across all ONOS nodes" )
2580 consistentClustersResult = main.TRUE
2581 for controller in range( len( clusters ) ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002582 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002583 if "Error" not in clusters[ controller ]:
2584 if clusters[ controller ] == clusters[ 0 ]:
2585 continue
2586 else: # clusters not consistent
2587 main.log.error( "clusters from ONOS" +
2588 controllerStr +
2589 " is inconsistent with ONOS1" )
2590 consistentClustersResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002591 else:
2592 main.log.error( "Error in getting dataplane clusters " +
2593 "from ONOS" + controllerStr )
2594 consistentClustersResult = main.FALSE
2595 main.log.warn( "ONOS" + controllerStr +
2596 " clusters response: " +
2597 repr( clusters[ controller ] ) )
2598 utilities.assert_equals(
2599 expect=main.TRUE,
2600 actual=consistentClustersResult,
2601 onpass="Clusters view is consistent across all ONOS nodes",
2602 onfail="ONOS nodes have different views of clusters" )
2603
2604 main.step( "There is only one SCC" )
2605 # there should always only be one cluster
2606 try:
2607 numClusters = len( json.loads( clusters[ 0 ] ) )
2608 except ( ValueError, TypeError ):
2609 main.log.exception( "Error parsing clusters[0]: " +
2610 repr( clusters[0] ) )
Jon Halla440e872016-03-31 15:15:50 -07002611 numClusters = "ERROR"
Jon Hall5cf14d52015-07-16 12:15:19 -07002612 clusterResults = main.FALSE
2613 if numClusters == 1:
2614 clusterResults = main.TRUE
2615 utilities.assert_equals(
2616 expect=1,
2617 actual=numClusters,
2618 onpass="ONOS shows 1 SCC",
2619 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2620
2621 topoResult = ( devicesResults and linksResults
2622 and hostsResults and consistentHostsResult
2623 and consistentClustersResult and clusterResults
2624 and ipResult and hostAttachmentResults )
2625
2626 topoResult = topoResult and int( count <= 2 )
2627 note = "note it takes about " + str( int( cliTime ) ) + \
2628 " seconds for the test to make all the cli calls to fetch " +\
2629 "the topology from each ONOS instance"
2630 main.log.info(
2631 "Very crass estimate for topology discovery/convergence( " +
2632 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2633 str( count ) + " tries" )
2634
2635 main.step( "Device information is correct" )
2636 utilities.assert_equals(
2637 expect=main.TRUE,
2638 actual=devicesResults,
2639 onpass="Device information is correct",
2640 onfail="Device information is incorrect" )
2641
2642 main.step( "Links are correct" )
2643 utilities.assert_equals(
2644 expect=main.TRUE,
2645 actual=linksResults,
2646 onpass="Link are correct",
2647 onfail="Links are incorrect" )
2648
Jon Halla440e872016-03-31 15:15:50 -07002649 main.step( "Hosts are correct" )
2650 utilities.assert_equals(
2651 expect=main.TRUE,
2652 actual=hostsResults,
2653 onpass="Hosts are correct",
2654 onfail="Hosts are incorrect" )
2655
Jon Hall5cf14d52015-07-16 12:15:19 -07002656 # FIXME: move this to an ONOS state case
2657 main.step( "Checking ONOS nodes" )
2658 nodesOutput = []
2659 nodeResults = main.TRUE
2660 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002661 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002662 t = main.Thread( target=main.CLIs[i].nodes,
Jon Hall5cf14d52015-07-16 12:15:19 -07002663 name="nodes-" + str( i ),
2664 args=[ ] )
2665 threads.append( t )
2666 t.start()
2667
2668 for t in threads:
2669 t.join()
2670 nodesOutput.append( t.result )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002671 ips = [ main.nodes[node].ip_address for node in main.activeNodes ]
Jon Halle9b1fa32015-12-08 15:32:21 -08002672 ips.sort()
Jon Hall5cf14d52015-07-16 12:15:19 -07002673 for i in nodesOutput:
2674 try:
2675 current = json.loads( i )
Jon Halle9b1fa32015-12-08 15:32:21 -08002676 activeIps = []
2677 currentResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002678 for node in current:
Jon Hallbd182782016-03-28 16:42:22 -07002679 if node['state'] == 'READY':
Jon Halle9b1fa32015-12-08 15:32:21 -08002680 activeIps.append( node['ip'] )
2681 activeIps.sort()
2682 if ips == activeIps:
2683 currentResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002684 except ( ValueError, TypeError ):
2685 main.log.error( "Error parsing nodes output" )
2686 main.log.warn( repr( i ) )
Jon Halle9b1fa32015-12-08 15:32:21 -08002687 currentResult = main.FALSE
2688 nodeResults = nodeResults and currentResult
Jon Hall5cf14d52015-07-16 12:15:19 -07002689 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2690 onpass="Nodes check successful",
2691 onfail="Nodes check NOT successful" )
Jon Halla440e872016-03-31 15:15:50 -07002692 if not nodeResults:
2693 for cli in main.CLIs:
2694 main.log.debug( "{} components not ACTIVE: \n{}".format(
2695 cli.name,
2696 cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002697
2698 def CASE9( self, main ):
2699 """
2700 Link s3-s28 down
2701 """
2702 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002703 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002704 assert main, "main not defined"
2705 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002706 assert main.CLIs, "main.CLIs not defined"
2707 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002708 # NOTE: You should probably run a topology check after this
2709
2710 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2711
2712 description = "Turn off a link to ensure that Link Discovery " +\
2713 "is working properly"
2714 main.case( description )
2715
2716 main.step( "Kill Link between s3 and s28" )
2717 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
2718 main.log.info( "Waiting " + str( linkSleep ) +
2719 " seconds for link down to be discovered" )
2720 time.sleep( linkSleep )
2721 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
2722 onpass="Link down successful",
2723 onfail="Failed to bring link down" )
2724 # TODO do some sort of check here
2725
2726 def CASE10( self, main ):
2727 """
2728 Link s3-s28 up
2729 """
2730 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002731 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002732 assert main, "main not defined"
2733 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002734 assert main.CLIs, "main.CLIs not defined"
2735 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002736 # NOTE: You should probably run a topology check after this
2737
2738 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2739
2740 description = "Restore a link to ensure that Link Discovery is " + \
2741 "working properly"
2742 main.case( description )
2743
2744 main.step( "Bring link between s3 and s28 back up" )
2745 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
2746 main.log.info( "Waiting " + str( linkSleep ) +
2747 " seconds for link up to be discovered" )
2748 time.sleep( linkSleep )
2749 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
2750 onpass="Link up successful",
2751 onfail="Failed to bring link up" )
2752 # TODO do some sort of check here
2753
2754 def CASE11( self, main ):
2755 """
2756 Switch Down
2757 """
2758 # NOTE: You should probably run a topology check after this
2759 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002760 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002761 assert main, "main not defined"
2762 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002763 assert main.CLIs, "main.CLIs not defined"
2764 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002765
2766 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2767
2768 description = "Killing a switch to ensure it is discovered correctly"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002769 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002770 main.case( description )
2771 switch = main.params[ 'kill' ][ 'switch' ]
2772 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2773
2774 # TODO: Make this switch parameterizable
2775 main.step( "Kill " + switch )
2776 main.log.info( "Deleting " + switch )
2777 main.Mininet1.delSwitch( switch )
2778 main.log.info( "Waiting " + str( switchSleep ) +
2779 " seconds for switch down to be discovered" )
2780 time.sleep( switchSleep )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002781 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall5cf14d52015-07-16 12:15:19 -07002782 # Peek at the deleted switch
2783 main.log.warn( str( device ) )
2784 result = main.FALSE
2785 if device and device[ 'available' ] is False:
2786 result = main.TRUE
2787 utilities.assert_equals( expect=main.TRUE, actual=result,
2788 onpass="Kill switch successful",
2789 onfail="Failed to kill switch?" )
2790
2791 def CASE12( self, main ):
2792 """
2793 Switch Up
2794 """
2795 # NOTE: You should probably run a topology check after this
2796 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002797 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002798 assert main, "main not defined"
2799 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002800 assert main.CLIs, "main.CLIs not defined"
2801 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002802 assert ONOS1Port, "ONOS1Port not defined"
2803 assert ONOS2Port, "ONOS2Port not defined"
2804 assert ONOS3Port, "ONOS3Port not defined"
2805 assert ONOS4Port, "ONOS4Port not defined"
2806 assert ONOS5Port, "ONOS5Port not defined"
2807 assert ONOS6Port, "ONOS6Port not defined"
2808 assert ONOS7Port, "ONOS7Port not defined"
2809
2810 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2811 switch = main.params[ 'kill' ][ 'switch' ]
2812 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2813 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002814 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002815 description = "Adding a switch to ensure it is discovered correctly"
2816 main.case( description )
2817
2818 main.step( "Add back " + switch )
2819 main.Mininet1.addSwitch( switch, dpid=switchDPID )
2820 for peer in links:
2821 main.Mininet1.addLink( switch, peer )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002822 ipList = [ node.ip_address for node in main.nodes ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002823 main.Mininet1.assignSwController( sw=switch, ip=ipList )
2824 main.log.info( "Waiting " + str( switchSleep ) +
2825 " seconds for switch up to be discovered" )
2826 time.sleep( switchSleep )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002827 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall5cf14d52015-07-16 12:15:19 -07002828 # Peek at the deleted switch
2829 main.log.warn( str( device ) )
2830 result = main.FALSE
2831 if device and device[ 'available' ]:
2832 result = main.TRUE
2833 utilities.assert_equals( expect=main.TRUE, actual=result,
2834 onpass="add switch successful",
2835 onfail="Failed to add switch?" )
2836
2837 def CASE13( self, main ):
2838 """
2839 Clean up
2840 """
2841 import os
2842 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002843 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002844 assert main, "main not defined"
2845 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002846 assert main.CLIs, "main.CLIs not defined"
2847 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002848
2849 # printing colors to terminal
2850 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2851 'blue': '\033[94m', 'green': '\033[92m',
2852 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
2853 main.case( "Test Cleanup" )
2854 main.step( "Killing tcpdumps" )
2855 main.Mininet2.stopTcpdump()
2856
2857 testname = main.TEST
Jon Hall96091e62015-09-21 17:34:17 -07002858 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall5cf14d52015-07-16 12:15:19 -07002859 main.step( "Copying MN pcap and ONOS log files to test station" )
2860 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
2861 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
Jon Hall96091e62015-09-21 17:34:17 -07002862 # NOTE: MN Pcap file is being saved to logdir.
2863 # We scp this file as MN and TestON aren't necessarily the same vm
2864
2865 # FIXME: To be replaced with a Jenkin's post script
Jon Hall5cf14d52015-07-16 12:15:19 -07002866 # TODO: Load these from params
2867 # NOTE: must end in /
2868 logFolder = "/opt/onos/log/"
2869 logFiles = [ "karaf.log", "karaf.log.1" ]
2870 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002871 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002872 for node in main.nodes:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002873 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002874 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2875 logFolder + f, dstName )
Jon Hall5cf14d52015-07-16 12:15:19 -07002876 # std*.log's
2877 # NOTE: must end in /
2878 logFolder = "/opt/onos/var/"
2879 logFiles = [ "stderr.log", "stdout.log" ]
2880 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002881 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002882 for node in main.nodes:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002883 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002884 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2885 logFolder + f, dstName )
2886 else:
2887 main.log.debug( "skipping saving log files" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002888
2889 main.step( "Stopping Mininet" )
2890 mnResult = main.Mininet1.stopNet()
2891 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2892 onpass="Mininet stopped",
2893 onfail="MN cleanup NOT successful" )
2894
2895 main.step( "Checking ONOS Logs for errors" )
Jon Halle1a3b752015-07-22 13:02:46 -07002896 for node in main.nodes:
Jon Hall96091e62015-09-21 17:34:17 -07002897 main.log.debug( "Checking logs for errors on " + node.name + ":" )
2898 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002899
2900 try:
2901 timerLog = open( main.logdir + "/Timers.csv", 'w')
2902 # Overwrite with empty line and close
2903 labels = "Gossip Intents, Restart"
2904 data = str( gossipTime ) + ", " + str( main.restartTime )
2905 timerLog.write( labels + "\n" + data )
2906 timerLog.close()
2907 except NameError, e:
2908 main.log.exception(e)
2909
2910 def CASE14( self, main ):
2911 """
2912 start election app on all onos nodes
2913 """
Jon Halle1a3b752015-07-22 13:02:46 -07002914 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002915 assert main, "main not defined"
2916 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002917 assert main.CLIs, "main.CLIs not defined"
2918 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002919
2920 main.case("Start Leadership Election app")
2921 main.step( "Install leadership election app" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002922 onosCli = main.CLIs[ main.activeNodes[0] ]
2923 appResult = onosCli.activateApp( "org.onosproject.election" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002924 utilities.assert_equals(
2925 expect=main.TRUE,
2926 actual=appResult,
2927 onpass="Election app installed",
2928 onfail="Something went wrong with installing Leadership election" )
2929
2930 main.step( "Run for election on each node" )
2931 leaderResult = main.TRUE
2932 leaders = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002933 for i in main.activeNodes:
2934 main.CLIs[i].electionTestRun()
2935 for i in main.activeNodes:
2936 cli = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07002937 leader = cli.electionTestLeader()
2938 if leader is None or leader == main.FALSE:
2939 main.log.error( cli.name + ": Leader for the election app " +
2940 "should be an ONOS node, instead got '" +
2941 str( leader ) + "'" )
2942 leaderResult = main.FALSE
2943 leaders.append( leader )
2944 utilities.assert_equals(
2945 expect=main.TRUE,
2946 actual=leaderResult,
2947 onpass="Successfully ran for leadership",
2948 onfail="Failed to run for leadership" )
2949
2950 main.step( "Check that each node shows the same leader" )
2951 sameLeader = main.TRUE
2952 if len( set( leaders ) ) != 1:
2953 sameLeader = main.FALSE
Jon Halle1a3b752015-07-22 13:02:46 -07002954 main.log.error( "Results of electionTestLeader is order of main.CLIs:" +
Jon Hall5cf14d52015-07-16 12:15:19 -07002955 str( leaders ) )
2956 utilities.assert_equals(
2957 expect=main.TRUE,
2958 actual=sameLeader,
2959 onpass="Leadership is consistent for the election topic",
2960 onfail="Nodes have different leaders" )
2961
2962 def CASE15( self, main ):
2963 """
2964 Check that Leadership Election is still functional
acsmars71adceb2015-08-31 15:09:26 -07002965 15.1 Run election on each node
2966 15.2 Check that each node has the same leaders and candidates
2967 15.3 Find current leader and withdraw
2968 15.4 Check that a new node was elected leader
2969 15.5 Check that that new leader was the candidate of old leader
2970 15.6 Run for election on old leader
2971 15.7 Check that oldLeader is a candidate, and leader if only 1 node
2972 15.8 Make sure that the old leader was added to the candidate list
2973
2974 old and new variable prefixes refer to data from before vs after
2975 withdrawl and later before withdrawl vs after re-election
Jon Hall5cf14d52015-07-16 12:15:19 -07002976 """
2977 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002978 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002979 assert main, "main not defined"
2980 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002981 assert main.CLIs, "main.CLIs not defined"
2982 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002983
Jon Hall5cf14d52015-07-16 12:15:19 -07002984 description = "Check that Leadership Election is still functional"
2985 main.case( description )
Jon Halla440e872016-03-31 15:15:50 -07002986 # NOTE: Need to re-run after restarts since being a canidate is not persistant
Jon Hall5cf14d52015-07-16 12:15:19 -07002987
Jon Halla440e872016-03-31 15:15:50 -07002988 oldLeaders = [] # list of lists of each nodes' candidates before
2989 newLeaders = [] # list of lists of each nodes' candidates after
acsmars71adceb2015-08-31 15:09:26 -07002990 oldLeader = '' # the old leader from oldLeaders, None if not same
2991 newLeader = '' # the new leaders fron newLoeaders, None if not same
2992 oldLeaderCLI = None # the CLI of the old leader used for re-electing
2993 expectNoLeader = False # True when there is only one leader
2994 if main.numCtrls == 1:
2995 expectNoLeader = True
2996
2997 main.step( "Run for election on each node" )
2998 electionResult = main.TRUE
2999
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003000 for i in main.activeNodes: # run test election on each node
3001 if main.CLIs[i].electionTestRun() == main.FALSE:
acsmars71adceb2015-08-31 15:09:26 -07003002 electionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07003003 utilities.assert_equals(
3004 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07003005 actual=electionResult,
3006 onpass="All nodes successfully ran for leadership",
3007 onfail="At least one node failed to run for leadership" )
3008
acsmars3a72bde2015-09-02 14:16:22 -07003009 if electionResult == main.FALSE:
3010 main.log.error(
3011 "Skipping Test Case because Election Test App isn't loaded" )
3012 main.skipCase()
3013
acsmars71adceb2015-08-31 15:09:26 -07003014 main.step( "Check that each node shows the same leader and candidates" )
Jon Halla440e872016-03-31 15:15:50 -07003015 failMessage = "Nodes have different leaderboards"
3016 def consistentLeaderboards( nodes ):
3017 TOPIC = 'org.onosproject.election'
3018 # FIXME: use threads
3019 #FIXME: should we retry outside the function?
3020 for n in range( 5 ): # Retry in case election is still happening
3021 leaderList = []
3022 # Get all leaderboards
3023 for cli in nodes:
3024 leaderList.append( cli.specificLeaderCandidate( TOPIC ) )
3025 # Compare leaderboards
3026 result = all( i == leaderList[0] for i in leaderList ) and\
3027 leaderList is not None
3028 main.log.debug( leaderList )
3029 main.log.warn( result )
3030 if result:
3031 return ( result, leaderList )
3032 time.sleep(5) #TODO: paramerterize
3033 main.log.error( "Inconsistent leaderboards:" + str( leaderList ) )
3034 activeCLIs = [ main.CLIs[i] for i in main.activeNodes ]
3035 sameResult, oldLeaders = consistentLeaderboards( activeCLIs )
3036 if sameResult:
3037 oldLeader = oldLeaders[ 0 ][ 0 ]
3038 main.log.warn( oldLeader )
acsmars71adceb2015-08-31 15:09:26 -07003039 else:
Jon Halla440e872016-03-31 15:15:50 -07003040 oldLeader = None
acsmars71adceb2015-08-31 15:09:26 -07003041 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07003042 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07003043 actual=sameResult,
Jon Halla440e872016-03-31 15:15:50 -07003044 onpass="Leaderboards are consistent for the election topic",
acsmars71adceb2015-08-31 15:09:26 -07003045 onfail=failMessage )
Jon Hall5cf14d52015-07-16 12:15:19 -07003046
3047 main.step( "Find current leader and withdraw" )
acsmars71adceb2015-08-31 15:09:26 -07003048 withdrawResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07003049 # do some sanity checking on leader before using it
acsmars71adceb2015-08-31 15:09:26 -07003050 if oldLeader is None:
3051 main.log.error( "Leadership isn't consistent." )
3052 withdrawResult = main.FALSE
3053 # Get the CLI of the oldLeader
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003054 for i in main.activeNodes:
acsmars71adceb2015-08-31 15:09:26 -07003055 if oldLeader == main.nodes[ i ].ip_address:
3056 oldLeaderCLI = main.CLIs[ i ]
Jon Hall5cf14d52015-07-16 12:15:19 -07003057 break
3058 else: # FOR/ELSE statement
3059 main.log.error( "Leader election, could not find current leader" )
3060 if oldLeader:
acsmars71adceb2015-08-31 15:09:26 -07003061 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall5cf14d52015-07-16 12:15:19 -07003062 utilities.assert_equals(
3063 expect=main.TRUE,
3064 actual=withdrawResult,
3065 onpass="Node was withdrawn from election",
3066 onfail="Node was not withdrawn from election" )
3067
acsmars71adceb2015-08-31 15:09:26 -07003068 main.step( "Check that a new node was elected leader" )
acsmars71adceb2015-08-31 15:09:26 -07003069 failMessage = "Nodes have different leaders"
acsmars71adceb2015-08-31 15:09:26 -07003070 # Get new leaders and candidates
Jon Halla440e872016-03-31 15:15:50 -07003071 newLeaderResult, newLeaders = consistentLeaderboards( activeCLIs )
3072 if newLeaders[ 0 ][ 0 ] == 'none':
3073 main.log.error( "No leader was elected on at least 1 node" )
3074 if not expectNoLeader:
3075 newLeaderResult = False
3076 if newLeaderResult:
3077 newLeader = newLeaders[ 0 ][ 0 ]
Jon Hall5cf14d52015-07-16 12:15:19 -07003078 else:
Jon Halla440e872016-03-31 15:15:50 -07003079 newLeader = None
acsmars71adceb2015-08-31 15:09:26 -07003080
3081 # Check that the new leader is not the older leader, which was withdrawn
3082 if newLeader == oldLeader:
Jon Halla440e872016-03-31 15:15:50 -07003083 newLeaderResult = False
Jon Hall6e709752016-02-01 13:38:46 -08003084 main.log.error( "All nodes still see old leader: " + str( oldLeader ) +
acsmars71adceb2015-08-31 15:09:26 -07003085 " as the current leader" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003086 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07003087 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07003088 actual=newLeaderResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07003089 onpass="Leadership election passed",
3090 onfail="Something went wrong with Leadership election" )
3091
Jon Halla440e872016-03-31 15:15:50 -07003092 main.step( "Check that that new leader was the candidate of old leader" )
Jon Hall6e709752016-02-01 13:38:46 -08003093 # candidates[ 2 ] should become the top candidate after withdrawl
acsmars71adceb2015-08-31 15:09:26 -07003094 correctCandidateResult = main.TRUE
3095 if expectNoLeader:
3096 if newLeader == 'none':
3097 main.log.info( "No leader expected. None found. Pass" )
3098 correctCandidateResult = main.TRUE
3099 else:
3100 main.log.info( "Expected no leader, got: " + str( newLeader ) )
3101 correctCandidateResult = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003102 elif len( oldLeaders[0] ) >= 3:
3103 if newLeader == oldLeaders[ 0 ][ 2 ]:
3104 # correct leader was elected
3105 correctCandidateResult = main.TRUE
3106 else:
3107 correctCandidateResult = main.FALSE
3108 main.log.error( "Candidate {} was elected. {} should have had priority.".format(
3109 newLeader, oldLeaders[ 0 ][ 2 ] ) )
Jon Hall6e709752016-02-01 13:38:46 -08003110 else:
3111 main.log.warn( "Could not determine who should be the correct leader" )
Jon Halla440e872016-03-31 15:15:50 -07003112 main.log.debug( oldLeaders[ 0 ] )
Jon Hall6e709752016-02-01 13:38:46 -08003113 correctCandidateResult = main.FALSE
acsmars71adceb2015-08-31 15:09:26 -07003114 utilities.assert_equals(
3115 expect=main.TRUE,
3116 actual=correctCandidateResult,
3117 onpass="Correct Candidate Elected",
3118 onfail="Incorrect Candidate Elected" )
3119
Jon Hall5cf14d52015-07-16 12:15:19 -07003120 main.step( "Run for election on old leader( just so everyone " +
3121 "is in the hat )" )
acsmars71adceb2015-08-31 15:09:26 -07003122 if oldLeaderCLI is not None:
3123 runResult = oldLeaderCLI.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07003124 else:
acsmars71adceb2015-08-31 15:09:26 -07003125 main.log.error( "No old leader to re-elect" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003126 runResult = main.FALSE
3127 utilities.assert_equals(
3128 expect=main.TRUE,
3129 actual=runResult,
3130 onpass="App re-ran for election",
3131 onfail="App failed to run for election" )
Jon Halla440e872016-03-31 15:15:50 -07003132
acsmars71adceb2015-08-31 15:09:26 -07003133 main.step(
3134 "Check that oldLeader is a candidate, and leader if only 1 node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003135 # verify leader didn't just change
Jon Halla440e872016-03-31 15:15:50 -07003136 # Get new leaders and candidates
3137 reRunLeaders = []
3138 time.sleep( 5 ) # Paremterize
3139 positionResult, reRunLeaders = consistentLeaderboards( activeCLIs )
acsmars71adceb2015-08-31 15:09:26 -07003140
3141 # Check that the re-elected node is last on the candidate List
Jon Halla440e872016-03-31 15:15:50 -07003142 if oldLeader != reRunLeaders[ 0 ][ -1 ]:
3143 main.log.error( "Old Leader ({}) not in the proper position: {} ".format( str( oldLeader),
3144 str( reRunLeaders[ 0 ] ) ) )
acsmars71adceb2015-08-31 15:09:26 -07003145 positionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07003146
3147 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07003148 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07003149 actual=positionResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07003150 onpass="Old leader successfully re-ran for election",
3151 onfail="Something went wrong with Leadership election after " +
3152 "the old leader re-ran for election" )
3153
3154 def CASE16( self, main ):
3155 """
3156 Install Distributed Primitives app
3157 """
3158 import time
Jon Halle1a3b752015-07-22 13:02:46 -07003159 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003160 assert main, "main not defined"
3161 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003162 assert main.CLIs, "main.CLIs not defined"
3163 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003164
3165 # Variables for the distributed primitives tests
3166 global pCounterName
Jon Hall5cf14d52015-07-16 12:15:19 -07003167 global pCounterValue
Jon Hall5cf14d52015-07-16 12:15:19 -07003168 global onosSet
3169 global onosSetName
3170 pCounterName = "TestON-Partitions"
Jon Hall5cf14d52015-07-16 12:15:19 -07003171 pCounterValue = 0
Jon Hall5cf14d52015-07-16 12:15:19 -07003172 onosSet = set([])
3173 onosSetName = "TestON-set"
3174
3175 description = "Install Primitives app"
3176 main.case( description )
3177 main.step( "Install Primitives app" )
3178 appName = "org.onosproject.distributedprimitives"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003179 node = main.activeNodes[0]
3180 appResults = main.CLIs[node].activateApp( appName )
Jon Hall5cf14d52015-07-16 12:15:19 -07003181 utilities.assert_equals( expect=main.TRUE,
3182 actual=appResults,
3183 onpass="Primitives app activated",
3184 onfail="Primitives app not activated" )
3185 time.sleep( 5 ) # To allow all nodes to activate
3186
3187 def CASE17( self, main ):
3188 """
3189 Check for basic functionality with distributed primitives
3190 """
Jon Hall5cf14d52015-07-16 12:15:19 -07003191 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07003192 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003193 assert main, "main not defined"
3194 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003195 assert main.CLIs, "main.CLIs not defined"
3196 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003197 assert pCounterName, "pCounterName not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003198 assert onosSetName, "onosSetName not defined"
3199 # NOTE: assert fails if value is 0/None/Empty/False
3200 try:
3201 pCounterValue
3202 except NameError:
3203 main.log.error( "pCounterValue not defined, setting to 0" )
3204 pCounterValue = 0
3205 try:
Jon Hall5cf14d52015-07-16 12:15:19 -07003206 onosSet
3207 except NameError:
3208 main.log.error( "onosSet not defined, setting to empty Set" )
3209 onosSet = set([])
3210 # Variables for the distributed primitives tests. These are local only
3211 addValue = "a"
3212 addAllValue = "a b c d e f"
3213 retainValue = "c d e f"
3214
3215 description = "Check for basic functionality with distributed " +\
3216 "primitives"
3217 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07003218 main.caseExplanation = "Test the methods of the distributed " +\
3219 "primitives (counters and sets) throught the cli"
Jon Hall5cf14d52015-07-16 12:15:19 -07003220 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07003221 # Partitioned counters
3222 main.step( "Increment then get a default counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003223 pCounters = []
3224 threads = []
3225 addedPValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003226 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003227 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3228 name="counterAddAndGet-" + str( i ),
Jon Hall5cf14d52015-07-16 12:15:19 -07003229 args=[ pCounterName ] )
3230 pCounterValue += 1
3231 addedPValues.append( pCounterValue )
3232 threads.append( t )
3233 t.start()
3234
3235 for t in threads:
3236 t.join()
3237 pCounters.append( t.result )
3238 # Check that counter incremented numController times
3239 pCounterResults = True
3240 for i in addedPValues:
3241 tmpResult = i in pCounters
3242 pCounterResults = pCounterResults and tmpResult
3243 if not tmpResult:
3244 main.log.error( str( i ) + " is not in partitioned "
3245 "counter incremented results" )
3246 utilities.assert_equals( expect=True,
3247 actual=pCounterResults,
3248 onpass="Default counter incremented",
3249 onfail="Error incrementing default" +
3250 " counter" )
3251
Jon Halle1a3b752015-07-22 13:02:46 -07003252 main.step( "Get then Increment a default counter on each node" )
3253 pCounters = []
3254 threads = []
3255 addedPValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003256 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003257 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3258 name="counterGetAndAdd-" + str( i ),
3259 args=[ pCounterName ] )
3260 addedPValues.append( pCounterValue )
3261 pCounterValue += 1
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
3289 main.step( "Add -8 to then get a default counter on each node" )
3290 pCounters = []
3291 threads = []
3292 addedPValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003293 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003294 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3295 name="counterIncrement-" + str( i ),
3296 args=[ pCounterName ],
3297 kwargs={ "delta": -8 } )
3298 pCounterValue += -8
3299 addedPValues.append( pCounterValue )
3300 threads.append( t )
3301 t.start()
3302
3303 for t in threads:
3304 t.join()
3305 pCounters.append( t.result )
3306 # Check that counter incremented numController times
3307 pCounterResults = True
3308 for i in addedPValues:
3309 tmpResult = i in pCounters
3310 pCounterResults = pCounterResults and tmpResult
3311 if not tmpResult:
3312 main.log.error( str( i ) + " is not in partitioned "
3313 "counter incremented results" )
3314 utilities.assert_equals( expect=True,
3315 actual=pCounterResults,
3316 onpass="Default counter incremented",
3317 onfail="Error incrementing default" +
3318 " counter" )
3319
3320 main.step( "Add 5 to then get a default counter on each node" )
3321 pCounters = []
3322 threads = []
3323 addedPValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003324 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003325 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3326 name="counterIncrement-" + str( i ),
3327 args=[ pCounterName ],
3328 kwargs={ "delta": 5 } )
3329 pCounterValue += 5
3330 addedPValues.append( pCounterValue )
3331 threads.append( t )
3332 t.start()
3333
3334 for t in threads:
3335 t.join()
3336 pCounters.append( t.result )
3337 # Check that counter incremented numController times
3338 pCounterResults = True
3339 for i in addedPValues:
3340 tmpResult = i in pCounters
3341 pCounterResults = pCounterResults and tmpResult
3342 if not tmpResult:
3343 main.log.error( str( i ) + " is not in partitioned "
3344 "counter incremented results" )
3345 utilities.assert_equals( expect=True,
3346 actual=pCounterResults,
3347 onpass="Default counter incremented",
3348 onfail="Error incrementing default" +
3349 " counter" )
3350
3351 main.step( "Get then add 5 to a default counter on each node" )
3352 pCounters = []
3353 threads = []
3354 addedPValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003355 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003356 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3357 name="counterIncrement-" + str( i ),
3358 args=[ pCounterName ],
3359 kwargs={ "delta": 5 } )
3360 addedPValues.append( pCounterValue )
3361 pCounterValue += 5
3362 threads.append( t )
3363 t.start()
3364
3365 for t in threads:
3366 t.join()
3367 pCounters.append( t.result )
3368 # Check that counter incremented numController times
3369 pCounterResults = True
3370 for i in addedPValues:
3371 tmpResult = i in pCounters
3372 pCounterResults = pCounterResults and tmpResult
3373 if not tmpResult:
3374 main.log.error( str( i ) + " is not in partitioned "
3375 "counter incremented results" )
3376 utilities.assert_equals( expect=True,
3377 actual=pCounterResults,
3378 onpass="Default counter incremented",
3379 onfail="Error incrementing default" +
3380 " counter" )
3381
3382 main.step( "Counters we added have the correct values" )
3383 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3384 utilities.assert_equals( expect=main.TRUE,
3385 actual=incrementCheck,
3386 onpass="Added counters are correct",
3387 onfail="Added counters are incorrect" )
3388
Jon Hall5cf14d52015-07-16 12:15:19 -07003389 # DISTRIBUTED SETS
3390 main.step( "Distributed Set get" )
3391 size = len( onosSet )
3392 getResponses = []
3393 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003394 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003395 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003396 name="setTestGet-" + str( i ),
3397 args=[ onosSetName ] )
3398 threads.append( t )
3399 t.start()
3400 for t in threads:
3401 t.join()
3402 getResponses.append( t.result )
3403
3404 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003405 for i in range( len( main.activeNodes ) ):
3406 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003407 if isinstance( getResponses[ i ], list):
3408 current = set( getResponses[ i ] )
3409 if len( current ) == len( getResponses[ i ] ):
3410 # no repeats
3411 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003412 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003413 " has incorrect view" +
3414 " of set " + onosSetName + ":\n" +
3415 str( getResponses[ i ] ) )
3416 main.log.debug( "Expected: " + str( onosSet ) )
3417 main.log.debug( "Actual: " + str( current ) )
3418 getResults = main.FALSE
3419 else:
3420 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003421 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003422 " has repeat elements in" +
3423 " set " + onosSetName + ":\n" +
3424 str( getResponses[ i ] ) )
3425 getResults = main.FALSE
3426 elif getResponses[ i ] == main.ERROR:
3427 getResults = main.FALSE
3428 utilities.assert_equals( expect=main.TRUE,
3429 actual=getResults,
3430 onpass="Set elements are correct",
3431 onfail="Set elements are incorrect" )
3432
3433 main.step( "Distributed Set size" )
3434 sizeResponses = []
3435 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003436 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003437 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003438 name="setTestSize-" + str( i ),
3439 args=[ onosSetName ] )
3440 threads.append( t )
3441 t.start()
3442 for t in threads:
3443 t.join()
3444 sizeResponses.append( t.result )
3445
3446 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003447 for i in range( len( main.activeNodes ) ):
3448 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003449 if size != sizeResponses[ i ]:
3450 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003451 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003452 " expected a size of " + str( size ) +
3453 " for set " + onosSetName +
3454 " but got " + str( sizeResponses[ i ] ) )
3455 utilities.assert_equals( expect=main.TRUE,
3456 actual=sizeResults,
3457 onpass="Set sizes are correct",
3458 onfail="Set sizes are incorrect" )
3459
3460 main.step( "Distributed Set add()" )
3461 onosSet.add( addValue )
3462 addResponses = []
3463 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003464 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003465 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003466 name="setTestAdd-" + str( i ),
3467 args=[ onosSetName, addValue ] )
3468 threads.append( t )
3469 t.start()
3470 for t in threads:
3471 t.join()
3472 addResponses.append( t.result )
3473
3474 # main.TRUE = successfully changed the set
3475 # main.FALSE = action resulted in no change in set
3476 # main.ERROR - Some error in executing the function
3477 addResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003478 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003479 if addResponses[ i ] == main.TRUE:
3480 # All is well
3481 pass
3482 elif addResponses[ i ] == main.FALSE:
3483 # Already in set, probably fine
3484 pass
3485 elif addResponses[ i ] == main.ERROR:
3486 # Error in execution
3487 addResults = main.FALSE
3488 else:
3489 # unexpected result
3490 addResults = main.FALSE
3491 if addResults != main.TRUE:
3492 main.log.error( "Error executing set add" )
3493
3494 # Check if set is still correct
3495 size = len( onosSet )
3496 getResponses = []
3497 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003498 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003499 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003500 name="setTestGet-" + str( i ),
3501 args=[ onosSetName ] )
3502 threads.append( t )
3503 t.start()
3504 for t in threads:
3505 t.join()
3506 getResponses.append( t.result )
3507 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003508 for i in range( len( main.activeNodes ) ):
3509 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003510 if isinstance( getResponses[ i ], list):
3511 current = set( getResponses[ i ] )
3512 if len( current ) == len( getResponses[ i ] ):
3513 # no repeats
3514 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003515 main.log.error( "ONOS" + node + " has incorrect view" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003516 " of set " + onosSetName + ":\n" +
3517 str( getResponses[ i ] ) )
3518 main.log.debug( "Expected: " + str( onosSet ) )
3519 main.log.debug( "Actual: " + str( current ) )
3520 getResults = main.FALSE
3521 else:
3522 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003523 main.log.error( "ONOS" + node + " has repeat elements in" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003524 " set " + onosSetName + ":\n" +
3525 str( getResponses[ i ] ) )
3526 getResults = main.FALSE
3527 elif getResponses[ i ] == main.ERROR:
3528 getResults = main.FALSE
3529 sizeResponses = []
3530 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003531 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003532 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003533 name="setTestSize-" + str( i ),
3534 args=[ onosSetName ] )
3535 threads.append( t )
3536 t.start()
3537 for t in threads:
3538 t.join()
3539 sizeResponses.append( t.result )
3540 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003541 for i in range( len( main.activeNodes ) ):
3542 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003543 if size != sizeResponses[ i ]:
3544 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003545 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003546 " expected a size of " + str( size ) +
3547 " for set " + onosSetName +
3548 " but got " + str( sizeResponses[ i ] ) )
3549 addResults = addResults and getResults and sizeResults
3550 utilities.assert_equals( expect=main.TRUE,
3551 actual=addResults,
3552 onpass="Set add correct",
3553 onfail="Set add was incorrect" )
3554
3555 main.step( "Distributed Set addAll()" )
3556 onosSet.update( addAllValue.split() )
3557 addResponses = []
3558 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003559 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003560 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003561 name="setTestAddAll-" + str( i ),
3562 args=[ onosSetName, addAllValue ] )
3563 threads.append( t )
3564 t.start()
3565 for t in threads:
3566 t.join()
3567 addResponses.append( t.result )
3568
3569 # main.TRUE = successfully changed the set
3570 # main.FALSE = action resulted in no change in set
3571 # main.ERROR - Some error in executing the function
3572 addAllResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003573 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003574 if addResponses[ i ] == main.TRUE:
3575 # All is well
3576 pass
3577 elif addResponses[ i ] == main.FALSE:
3578 # Already in set, probably fine
3579 pass
3580 elif addResponses[ i ] == main.ERROR:
3581 # Error in execution
3582 addAllResults = main.FALSE
3583 else:
3584 # unexpected result
3585 addAllResults = main.FALSE
3586 if addAllResults != main.TRUE:
3587 main.log.error( "Error executing set addAll" )
3588
3589 # Check if set is still correct
3590 size = len( onosSet )
3591 getResponses = []
3592 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003593 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003594 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003595 name="setTestGet-" + str( i ),
3596 args=[ onosSetName ] )
3597 threads.append( t )
3598 t.start()
3599 for t in threads:
3600 t.join()
3601 getResponses.append( t.result )
3602 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003603 for i in range( len( main.activeNodes ) ):
3604 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003605 if isinstance( getResponses[ i ], list):
3606 current = set( getResponses[ i ] )
3607 if len( current ) == len( getResponses[ i ] ):
3608 # no repeats
3609 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003610 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003611 " has incorrect view" +
3612 " of set " + onosSetName + ":\n" +
3613 str( getResponses[ i ] ) )
3614 main.log.debug( "Expected: " + str( onosSet ) )
3615 main.log.debug( "Actual: " + str( current ) )
3616 getResults = main.FALSE
3617 else:
3618 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003619 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003620 " has repeat elements in" +
3621 " set " + onosSetName + ":\n" +
3622 str( getResponses[ i ] ) )
3623 getResults = main.FALSE
3624 elif getResponses[ i ] == main.ERROR:
3625 getResults = main.FALSE
3626 sizeResponses = []
3627 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003628 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003629 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003630 name="setTestSize-" + str( i ),
3631 args=[ onosSetName ] )
3632 threads.append( t )
3633 t.start()
3634 for t in threads:
3635 t.join()
3636 sizeResponses.append( t.result )
3637 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003638 for i in range( len( main.activeNodes ) ):
3639 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003640 if size != sizeResponses[ i ]:
3641 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003642 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003643 " expected a size of " + str( size ) +
3644 " for set " + onosSetName +
3645 " but got " + str( sizeResponses[ i ] ) )
3646 addAllResults = addAllResults and getResults and sizeResults
3647 utilities.assert_equals( expect=main.TRUE,
3648 actual=addAllResults,
3649 onpass="Set addAll correct",
3650 onfail="Set addAll was incorrect" )
3651
3652 main.step( "Distributed Set contains()" )
3653 containsResponses = []
3654 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003655 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003656 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003657 name="setContains-" + str( i ),
3658 args=[ onosSetName ],
3659 kwargs={ "values": addValue } )
3660 threads.append( t )
3661 t.start()
3662 for t in threads:
3663 t.join()
3664 # NOTE: This is the tuple
3665 containsResponses.append( t.result )
3666
3667 containsResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003668 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003669 if containsResponses[ i ] == main.ERROR:
3670 containsResults = main.FALSE
3671 else:
3672 containsResults = containsResults and\
3673 containsResponses[ i ][ 1 ]
3674 utilities.assert_equals( expect=main.TRUE,
3675 actual=containsResults,
3676 onpass="Set contains is functional",
3677 onfail="Set contains failed" )
3678
3679 main.step( "Distributed Set containsAll()" )
3680 containsAllResponses = []
3681 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003682 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003683 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003684 name="setContainsAll-" + str( i ),
3685 args=[ onosSetName ],
3686 kwargs={ "values": addAllValue } )
3687 threads.append( t )
3688 t.start()
3689 for t in threads:
3690 t.join()
3691 # NOTE: This is the tuple
3692 containsAllResponses.append( t.result )
3693
3694 containsAllResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003695 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003696 if containsResponses[ i ] == main.ERROR:
3697 containsResults = main.FALSE
3698 else:
3699 containsResults = containsResults and\
3700 containsResponses[ i ][ 1 ]
3701 utilities.assert_equals( expect=main.TRUE,
3702 actual=containsAllResults,
3703 onpass="Set containsAll is functional",
3704 onfail="Set containsAll failed" )
3705
3706 main.step( "Distributed Set remove()" )
3707 onosSet.remove( addValue )
3708 removeResponses = []
3709 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003710 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003711 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003712 name="setTestRemove-" + str( i ),
3713 args=[ onosSetName, addValue ] )
3714 threads.append( t )
3715 t.start()
3716 for t in threads:
3717 t.join()
3718 removeResponses.append( t.result )
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 removeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003724 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003725 if removeResponses[ i ] == main.TRUE:
3726 # All is well
3727 pass
3728 elif removeResponses[ i ] == main.FALSE:
3729 # not in set, probably fine
3730 pass
3731 elif removeResponses[ i ] == main.ERROR:
3732 # Error in execution
3733 removeResults = main.FALSE
3734 else:
3735 # unexpected result
3736 removeResults = main.FALSE
3737 if removeResults != main.TRUE:
3738 main.log.error( "Error executing set remove" )
3739
3740 # Check if set is still correct
3741 size = len( onosSet )
3742 getResponses = []
3743 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -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 Hallb3ed8ed2015-10-28 16:43:55 -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 Hallb3ed8ed2015-10-28 16:43:55 -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 Hallb3ed8ed2015-10-28 16:43:55 -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 Hallb3ed8ed2015-10-28 16:43:55 -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 Hallb3ed8ed2015-10-28 16:43:55 -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 Hallb3ed8ed2015-10-28 16:43:55 -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 removeResults = removeResults and getResults and sizeResults
3798 utilities.assert_equals( expect=main.TRUE,
3799 actual=removeResults,
3800 onpass="Set remove correct",
3801 onfail="Set remove was incorrect" )
3802
3803 main.step( "Distributed Set removeAll()" )
3804 onosSet.difference_update( addAllValue.split() )
3805 removeAllResponses = []
3806 threads = []
3807 try:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003808 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003809 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003810 name="setTestRemoveAll-" + str( i ),
3811 args=[ onosSetName, addAllValue ] )
3812 threads.append( t )
3813 t.start()
3814 for t in threads:
3815 t.join()
3816 removeAllResponses.append( t.result )
3817 except Exception, e:
3818 main.log.exception(e)
3819
3820 # main.TRUE = successfully changed the set
3821 # main.FALSE = action resulted in no change in set
3822 # main.ERROR - Some error in executing the function
3823 removeAllResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003824 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003825 if removeAllResponses[ i ] == main.TRUE:
3826 # All is well
3827 pass
3828 elif removeAllResponses[ i ] == main.FALSE:
3829 # not in set, probably fine
3830 pass
3831 elif removeAllResponses[ i ] == main.ERROR:
3832 # Error in execution
3833 removeAllResults = main.FALSE
3834 else:
3835 # unexpected result
3836 removeAllResults = main.FALSE
3837 if removeAllResults != main.TRUE:
3838 main.log.error( "Error executing set removeAll" )
3839
3840 # Check if set is still correct
3841 size = len( onosSet )
3842 getResponses = []
3843 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003844 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003845 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003846 name="setTestGet-" + str( i ),
3847 args=[ onosSetName ] )
3848 threads.append( t )
3849 t.start()
3850 for t in threads:
3851 t.join()
3852 getResponses.append( t.result )
3853 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003854 for i in range( len( main.activeNodes ) ):
3855 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003856 if isinstance( getResponses[ i ], list):
3857 current = set( getResponses[ i ] )
3858 if len( current ) == len( getResponses[ i ] ):
3859 # no repeats
3860 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003861 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003862 " has incorrect view" +
3863 " of set " + onosSetName + ":\n" +
3864 str( getResponses[ i ] ) )
3865 main.log.debug( "Expected: " + str( onosSet ) )
3866 main.log.debug( "Actual: " + str( current ) )
3867 getResults = main.FALSE
3868 else:
3869 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003870 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003871 " has repeat elements in" +
3872 " set " + onosSetName + ":\n" +
3873 str( getResponses[ i ] ) )
3874 getResults = main.FALSE
3875 elif getResponses[ i ] == main.ERROR:
3876 getResults = main.FALSE
3877 sizeResponses = []
3878 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003879 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003880 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003881 name="setTestSize-" + str( i ),
3882 args=[ onosSetName ] )
3883 threads.append( t )
3884 t.start()
3885 for t in threads:
3886 t.join()
3887 sizeResponses.append( t.result )
3888 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003889 for i in range( len( main.activeNodes ) ):
3890 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003891 if size != sizeResponses[ i ]:
3892 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003893 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003894 " expected a size of " + str( size ) +
3895 " for set " + onosSetName +
3896 " but got " + str( sizeResponses[ i ] ) )
3897 removeAllResults = removeAllResults and getResults and sizeResults
3898 utilities.assert_equals( expect=main.TRUE,
3899 actual=removeAllResults,
3900 onpass="Set removeAll correct",
3901 onfail="Set removeAll was incorrect" )
3902
3903 main.step( "Distributed Set addAll()" )
3904 onosSet.update( addAllValue.split() )
3905 addResponses = []
3906 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003907 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003908 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003909 name="setTestAddAll-" + str( i ),
3910 args=[ onosSetName, addAllValue ] )
3911 threads.append( t )
3912 t.start()
3913 for t in threads:
3914 t.join()
3915 addResponses.append( t.result )
3916
3917 # main.TRUE = successfully changed the set
3918 # main.FALSE = action resulted in no change in set
3919 # main.ERROR - Some error in executing the function
3920 addAllResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003921 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003922 if addResponses[ i ] == main.TRUE:
3923 # All is well
3924 pass
3925 elif addResponses[ i ] == main.FALSE:
3926 # Already in set, probably fine
3927 pass
3928 elif addResponses[ i ] == main.ERROR:
3929 # Error in execution
3930 addAllResults = main.FALSE
3931 else:
3932 # unexpected result
3933 addAllResults = main.FALSE
3934 if addAllResults != main.TRUE:
3935 main.log.error( "Error executing set addAll" )
3936
3937 # Check if set is still correct
3938 size = len( onosSet )
3939 getResponses = []
3940 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003941 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003942 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003943 name="setTestGet-" + str( i ),
3944 args=[ onosSetName ] )
3945 threads.append( t )
3946 t.start()
3947 for t in threads:
3948 t.join()
3949 getResponses.append( t.result )
3950 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003951 for i in range( len( main.activeNodes ) ):
3952 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003953 if isinstance( getResponses[ i ], list):
3954 current = set( getResponses[ i ] )
3955 if len( current ) == len( getResponses[ i ] ):
3956 # no repeats
3957 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003958 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003959 " has incorrect view" +
3960 " of set " + onosSetName + ":\n" +
3961 str( getResponses[ i ] ) )
3962 main.log.debug( "Expected: " + str( onosSet ) )
3963 main.log.debug( "Actual: " + str( current ) )
3964 getResults = main.FALSE
3965 else:
3966 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003967 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003968 " has repeat elements in" +
3969 " set " + onosSetName + ":\n" +
3970 str( getResponses[ i ] ) )
3971 getResults = main.FALSE
3972 elif getResponses[ i ] == main.ERROR:
3973 getResults = main.FALSE
3974 sizeResponses = []
3975 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003976 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003977 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003978 name="setTestSize-" + str( i ),
3979 args=[ onosSetName ] )
3980 threads.append( t )
3981 t.start()
3982 for t in threads:
3983 t.join()
3984 sizeResponses.append( t.result )
3985 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003986 for i in range( len( main.activeNodes ) ):
3987 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003988 if size != sizeResponses[ i ]:
3989 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003990 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003991 " expected a size of " + str( size ) +
3992 " for set " + onosSetName +
3993 " but got " + str( sizeResponses[ i ] ) )
3994 addAllResults = addAllResults and getResults and sizeResults
3995 utilities.assert_equals( expect=main.TRUE,
3996 actual=addAllResults,
3997 onpass="Set addAll correct",
3998 onfail="Set addAll was incorrect" )
3999
4000 main.step( "Distributed Set clear()" )
4001 onosSet.clear()
4002 clearResponses = []
4003 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004004 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004005 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004006 name="setTestClear-" + str( i ),
4007 args=[ onosSetName, " "], # Values doesn't matter
4008 kwargs={ "clear": True } )
4009 threads.append( t )
4010 t.start()
4011 for t in threads:
4012 t.join()
4013 clearResponses.append( t.result )
4014
4015 # main.TRUE = successfully changed the set
4016 # main.FALSE = action resulted in no change in set
4017 # main.ERROR - Some error in executing the function
4018 clearResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004019 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004020 if clearResponses[ i ] == main.TRUE:
4021 # All is well
4022 pass
4023 elif clearResponses[ i ] == main.FALSE:
4024 # Nothing set, probably fine
4025 pass
4026 elif clearResponses[ i ] == main.ERROR:
4027 # Error in execution
4028 clearResults = main.FALSE
4029 else:
4030 # unexpected result
4031 clearResults = main.FALSE
4032 if clearResults != main.TRUE:
4033 main.log.error( "Error executing set clear" )
4034
4035 # Check if set is still correct
4036 size = len( onosSet )
4037 getResponses = []
4038 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004039 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004040 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004041 name="setTestGet-" + str( i ),
4042 args=[ onosSetName ] )
4043 threads.append( t )
4044 t.start()
4045 for t in threads:
4046 t.join()
4047 getResponses.append( t.result )
4048 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004049 for i in range( len( main.activeNodes ) ):
4050 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004051 if isinstance( getResponses[ i ], list):
4052 current = set( getResponses[ i ] )
4053 if len( current ) == len( getResponses[ i ] ):
4054 # no repeats
4055 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004056 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004057 " has incorrect view" +
4058 " of set " + onosSetName + ":\n" +
4059 str( getResponses[ i ] ) )
4060 main.log.debug( "Expected: " + str( onosSet ) )
4061 main.log.debug( "Actual: " + str( current ) )
4062 getResults = main.FALSE
4063 else:
4064 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004065 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004066 " has repeat elements in" +
4067 " set " + onosSetName + ":\n" +
4068 str( getResponses[ i ] ) )
4069 getResults = main.FALSE
4070 elif getResponses[ i ] == main.ERROR:
4071 getResults = main.FALSE
4072 sizeResponses = []
4073 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004074 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004075 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004076 name="setTestSize-" + str( i ),
4077 args=[ onosSetName ] )
4078 threads.append( t )
4079 t.start()
4080 for t in threads:
4081 t.join()
4082 sizeResponses.append( t.result )
4083 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004084 for i in range( len( main.activeNodes ) ):
4085 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004086 if size != sizeResponses[ i ]:
4087 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004088 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004089 " expected a size of " + str( size ) +
4090 " for set " + onosSetName +
4091 " but got " + str( sizeResponses[ i ] ) )
4092 clearResults = clearResults and getResults and sizeResults
4093 utilities.assert_equals( expect=main.TRUE,
4094 actual=clearResults,
4095 onpass="Set clear correct",
4096 onfail="Set clear was incorrect" )
4097
4098 main.step( "Distributed Set addAll()" )
4099 onosSet.update( addAllValue.split() )
4100 addResponses = []
4101 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004102 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004103 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004104 name="setTestAddAll-" + str( i ),
4105 args=[ onosSetName, addAllValue ] )
4106 threads.append( t )
4107 t.start()
4108 for t in threads:
4109 t.join()
4110 addResponses.append( t.result )
4111
4112 # main.TRUE = successfully changed the set
4113 # main.FALSE = action resulted in no change in set
4114 # main.ERROR - Some error in executing the function
4115 addAllResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004116 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004117 if addResponses[ i ] == main.TRUE:
4118 # All is well
4119 pass
4120 elif addResponses[ i ] == main.FALSE:
4121 # Already in set, probably fine
4122 pass
4123 elif addResponses[ i ] == main.ERROR:
4124 # Error in execution
4125 addAllResults = main.FALSE
4126 else:
4127 # unexpected result
4128 addAllResults = main.FALSE
4129 if addAllResults != main.TRUE:
4130 main.log.error( "Error executing set addAll" )
4131
4132 # Check if set is still correct
4133 size = len( onosSet )
4134 getResponses = []
4135 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004136 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004137 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004138 name="setTestGet-" + str( i ),
4139 args=[ onosSetName ] )
4140 threads.append( t )
4141 t.start()
4142 for t in threads:
4143 t.join()
4144 getResponses.append( t.result )
4145 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004146 for i in range( len( main.activeNodes ) ):
4147 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004148 if isinstance( getResponses[ i ], list):
4149 current = set( getResponses[ i ] )
4150 if len( current ) == len( getResponses[ i ] ):
4151 # no repeats
4152 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004153 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004154 " has incorrect view" +
4155 " of set " + onosSetName + ":\n" +
4156 str( getResponses[ i ] ) )
4157 main.log.debug( "Expected: " + str( onosSet ) )
4158 main.log.debug( "Actual: " + str( current ) )
4159 getResults = main.FALSE
4160 else:
4161 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004162 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004163 " has repeat elements in" +
4164 " set " + onosSetName + ":\n" +
4165 str( getResponses[ i ] ) )
4166 getResults = main.FALSE
4167 elif getResponses[ i ] == main.ERROR:
4168 getResults = main.FALSE
4169 sizeResponses = []
4170 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004171 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004172 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004173 name="setTestSize-" + str( i ),
4174 args=[ onosSetName ] )
4175 threads.append( t )
4176 t.start()
4177 for t in threads:
4178 t.join()
4179 sizeResponses.append( t.result )
4180 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004181 for i in range( len( main.activeNodes ) ):
4182 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004183 if size != sizeResponses[ i ]:
4184 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004185 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004186 " expected a size of " + str( size ) +
4187 " for set " + onosSetName +
4188 " but got " + str( sizeResponses[ i ] ) )
4189 addAllResults = addAllResults and getResults and sizeResults
4190 utilities.assert_equals( expect=main.TRUE,
4191 actual=addAllResults,
4192 onpass="Set addAll correct",
4193 onfail="Set addAll was incorrect" )
4194
4195 main.step( "Distributed Set retain()" )
4196 onosSet.intersection_update( retainValue.split() )
4197 retainResponses = []
4198 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004199 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004200 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004201 name="setTestRetain-" + str( i ),
4202 args=[ onosSetName, retainValue ],
4203 kwargs={ "retain": True } )
4204 threads.append( t )
4205 t.start()
4206 for t in threads:
4207 t.join()
4208 retainResponses.append( t.result )
4209
4210 # main.TRUE = successfully changed the set
4211 # main.FALSE = action resulted in no change in set
4212 # main.ERROR - Some error in executing the function
4213 retainResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004214 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004215 if retainResponses[ i ] == main.TRUE:
4216 # All is well
4217 pass
4218 elif retainResponses[ i ] == main.FALSE:
4219 # Already in set, probably fine
4220 pass
4221 elif retainResponses[ i ] == main.ERROR:
4222 # Error in execution
4223 retainResults = main.FALSE
4224 else:
4225 # unexpected result
4226 retainResults = main.FALSE
4227 if retainResults != main.TRUE:
4228 main.log.error( "Error executing set retain" )
4229
4230 # Check if set is still correct
4231 size = len( onosSet )
4232 getResponses = []
4233 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004234 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004235 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004236 name="setTestGet-" + str( i ),
4237 args=[ onosSetName ] )
4238 threads.append( t )
4239 t.start()
4240 for t in threads:
4241 t.join()
4242 getResponses.append( t.result )
4243 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004244 for i in range( len( main.activeNodes ) ):
4245 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004246 if isinstance( getResponses[ i ], list):
4247 current = set( getResponses[ i ] )
4248 if len( current ) == len( getResponses[ i ] ):
4249 # no repeats
4250 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004251 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004252 " has incorrect view" +
4253 " of set " + onosSetName + ":\n" +
4254 str( getResponses[ i ] ) )
4255 main.log.debug( "Expected: " + str( onosSet ) )
4256 main.log.debug( "Actual: " + str( current ) )
4257 getResults = main.FALSE
4258 else:
4259 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004260 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004261 " has repeat elements in" +
4262 " set " + onosSetName + ":\n" +
4263 str( getResponses[ i ] ) )
4264 getResults = main.FALSE
4265 elif getResponses[ i ] == main.ERROR:
4266 getResults = main.FALSE
4267 sizeResponses = []
4268 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004269 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004270 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004271 name="setTestSize-" + str( i ),
4272 args=[ onosSetName ] )
4273 threads.append( t )
4274 t.start()
4275 for t in threads:
4276 t.join()
4277 sizeResponses.append( t.result )
4278 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004279 for i in range( len( main.activeNodes ) ):
4280 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004281 if size != sizeResponses[ i ]:
4282 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004283 main.log.error( "ONOS" + node + " expected a size of " +
Jon Hall5cf14d52015-07-16 12:15:19 -07004284 str( size ) + " for set " + onosSetName +
4285 " but got " + str( sizeResponses[ i ] ) )
4286 retainResults = retainResults and getResults and sizeResults
4287 utilities.assert_equals( expect=main.TRUE,
4288 actual=retainResults,
4289 onpass="Set retain correct",
4290 onfail="Set retain was incorrect" )
4291
Jon Hall2a5002c2015-08-21 16:49:11 -07004292 # Transactional maps
4293 main.step( "Partitioned Transactional maps put" )
4294 tMapValue = "Testing"
4295 numKeys = 100
4296 putResult = True
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004297 node = main.activeNodes[0]
4298 putResponses = main.CLIs[node].transactionalMapPut( numKeys, tMapValue )
Jon Hall6e709752016-02-01 13:38:46 -08004299 if putResponses and len( putResponses ) == 100:
Jon Hall2a5002c2015-08-21 16:49:11 -07004300 for i in putResponses:
4301 if putResponses[ i ][ 'value' ] != tMapValue:
4302 putResult = False
4303 else:
4304 putResult = False
4305 if not putResult:
4306 main.log.debug( "Put response values: " + str( putResponses ) )
4307 utilities.assert_equals( expect=True,
4308 actual=putResult,
4309 onpass="Partitioned Transactional Map put successful",
4310 onfail="Partitioned Transactional Map put values are incorrect" )
4311
4312 main.step( "Partitioned Transactional maps get" )
4313 getCheck = True
4314 for n in range( 1, numKeys + 1 ):
4315 getResponses = []
4316 threads = []
4317 valueCheck = True
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004318 for i in main.activeNodes:
Jon Hall2a5002c2015-08-21 16:49:11 -07004319 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4320 name="TMap-get-" + str( i ),
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004321 args=[ "Key" + str( n ) ] )
Jon Hall2a5002c2015-08-21 16:49:11 -07004322 threads.append( t )
4323 t.start()
4324 for t in threads:
4325 t.join()
4326 getResponses.append( t.result )
4327 for node in getResponses:
4328 if node != tMapValue:
4329 valueCheck = False
4330 if not valueCheck:
4331 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4332 main.log.warn( getResponses )
4333 getCheck = getCheck and valueCheck
4334 utilities.assert_equals( expect=True,
4335 actual=getCheck,
4336 onpass="Partitioned Transactional Map get values were correct",
4337 onfail="Partitioned Transactional Map values incorrect" )