blob: 6622075e03641d91aaee69115064bf630eff2aab [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 HAstopNodes:
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 Hallf3d16e72015-12-16 17:45:08 -080053 import time
Jon Halla440e872016-03-31 15:15:50 -070054 import json
Jon Hallb3ed8ed2015-10-28 16:43:55 -070055 main.log.info( "ONOS HA test: Stop 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" )
178 # GRAPHS
179 # NOTE: important params here:
180 # job = name of Jenkins job
181 # Plot Name = Plot-HA, only can be used if multiple plots
182 # index = The number of the graph under plot name
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700183 job = "HAstopNodes"
Jon Hall5cf14d52015-07-16 12:15:19 -0700184 plotName = "Plot-HA"
Jon Hall843f8bc2016-03-18 14:28:13 -0700185 index = "2"
Jon Hall5cf14d52015-07-16 12:15:19 -0700186 graphs = '<ac:structured-macro ac:name="html">\n'
187 graphs += '<ac:plain-text-body><![CDATA[\n'
188 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
Jon Halla9845df2016-01-15 14:55:58 -0800189 '/plot/' + plotName + '/getPlot?index=' + index +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700190 '&width=500&height=300"' +\
191 'noborder="0" width="500" height="300" scrolling="yes" ' +\
192 'seamless="seamless"></iframe>\n'
193 graphs += ']]></ac:plain-text-body>\n'
194 graphs += '</ac:structured-macro>\n'
195 main.log.wiki(graphs)
196
197 main.step( "Creating ONOS package" )
Jon Hall3b489db2015-10-05 14:38:37 -0700198 # copy gen-partions file to ONOS
199 # NOTE: this assumes TestON and ONOS are on the same machine
200 srcFile = main.testDir + "/" + main.TEST + "/dependencies/onos-gen-partitions"
201 dstDir = main.ONOSbench.home + "/tools/test/bin/onos-gen-partitions"
202 cpResult = main.ONOSbench.secureCopy( main.ONOSbench.user_name,
203 main.ONOSbench.ip_address,
204 srcFile,
205 dstDir,
206 pwd=main.ONOSbench.pwd,
207 direction="from" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700208 packageResult = main.ONOSbench.onosPackage()
209 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
210 onpass="ONOS package successful",
211 onfail="ONOS package failed" )
212
213 main.step( "Installing ONOS package" )
214 onosInstallResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700215 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700216 tmpResult = main.ONOSbench.onosInstall( options="-f",
217 node=node.ip_address )
218 onosInstallResult = onosInstallResult and tmpResult
219 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
220 onpass="ONOS install successful",
221 onfail="ONOS install failed" )
Jon Hall3b489db2015-10-05 14:38:37 -0700222 # clean up gen-partitions file
223 try:
224 main.ONOSbench.handle.sendline( "cd " + main.ONOSbench.home )
225 main.ONOSbench.handle.expect( main.ONOSbench.home + "\$" )
226 main.ONOSbench.handle.sendline( "git checkout -- tools/test/bin/onos-gen-partitions" )
227 main.ONOSbench.handle.expect( main.ONOSbench.home + "\$" )
228 main.log.info( " Cleaning custom gen partitions file, response was: \n" +
229 str( main.ONOSbench.handle.before ) )
230 except ( pexpect.TIMEOUT, pexpect.EOF ):
231 main.log.exception( "ONOSbench: pexpect exception found:" +
232 main.ONOSbench.handle.before )
233 main.cleanup()
234 main.exit()
Jon Hall5cf14d52015-07-16 12:15:19 -0700235
236 main.step( "Checking if ONOS is up yet" )
237 for i in range( 2 ):
238 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700239 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700240 started = main.ONOSbench.isup( node.ip_address )
241 if not started:
Jon Hallc6793552016-01-19 14:18:37 -0800242 main.log.error( node.name + " hasn't started" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700243 onosIsupResult = onosIsupResult and started
244 if onosIsupResult == main.TRUE:
245 break
246 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
247 onpass="ONOS startup successful",
248 onfail="ONOS startup failed" )
249
250 main.log.step( "Starting ONOS CLI sessions" )
251 cliResults = main.TRUE
252 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700253 for i in range( main.numCtrls ):
254 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -0700255 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -0700256 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -0700257 threads.append( t )
258 t.start()
259
260 for t in threads:
261 t.join()
262 cliResults = cliResults and t.result
263 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
264 onpass="ONOS cli startup successful",
265 onfail="ONOS cli startup failed" )
266
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700267 # Create a list of active nodes for use when some nodes are stopped
268 main.activeNodes = [ i for i in range( 0, len( main.CLIs ) ) ]
269
Jon Hall5cf14d52015-07-16 12:15:19 -0700270 if main.params[ 'tcpdump' ].lower() == "true":
271 main.step( "Start Packet Capture MN" )
272 main.Mininet2.startTcpdump(
273 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
274 + "-MN.pcap",
275 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
276 port=main.params[ 'MNtcpdump' ][ 'port' ] )
277
278 main.step( "App Ids check" )
279 appCheck = main.TRUE
280 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700281 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -0700282 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700283 name="appToIDCheck-" + str( i ),
284 args=[] )
285 threads.append( t )
286 t.start()
287
288 for t in threads:
289 t.join()
290 appCheck = appCheck and t.result
291 if appCheck != main.TRUE:
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700292 node = main.activeNodes[0]
293 main.log.warn( main.CLIs[node].apps() )
294 main.log.warn( main.CLIs[node].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700295 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
296 onpass="App Ids seem to be correct",
297 onfail="Something is wrong with app Ids" )
298
Jon Halla440e872016-03-31 15:15:50 -0700299 main.step( "Checking ONOS nodes" )
300 nodesOutput = []
301 nodeResults = main.TRUE
302 threads = []
303 for i in main.activeNodes:
304 t = main.Thread( target=main.CLIs[i].nodes,
305 name="nodes-" + str( i ),
306 args=[ ] )
307 threads.append( t )
308 t.start()
309
310 for t in threads:
311 t.join()
312 nodesOutput.append( t.result )
313 ips = [ main.nodes[node].ip_address for node in main.activeNodes ]
314 ips.sort()
315 for i in nodesOutput:
316 try:
317 current = json.loads( i )
318 activeIps = []
319 currentResult = main.FALSE
320 for node in current:
321 if node['state'] == 'READY':
322 activeIps.append( node['ip'] )
323 activeIps.sort()
324 if ips == activeIps:
325 currentResult = main.TRUE
326 except ( ValueError, TypeError ):
327 main.log.error( "Error parsing nodes output" )
328 main.log.warn( repr( i ) )
329 currentResult = main.FALSE
330 nodeResults = nodeResults and currentResult
331 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
332 onpass="Nodes check successful",
333 onfail="Nodes check NOT successful" )
334
335 if not nodeResults:
336 for cli in main.CLIs:
337 main.log.debug( "{} components not ACTIVE: \n{}".format(
338 cli.name,
339 cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
340
Jon Hall5cf14d52015-07-16 12:15:19 -0700341 if cliResults == main.FALSE:
342 main.log.error( "Failed to start ONOS, stopping test" )
343 main.cleanup()
344 main.exit()
345
Jon Hall172b7ba2016-04-07 18:12:20 -0700346 main.step( "Activate apps defined in the params file" )
347 # get data from the params
348 apps = main.params.get( 'apps' )
349 if apps:
350 apps = apps.split(',')
351 main.log.warn( apps )
352 activateResult = True
353 for app in apps:
354 main.CLIs[ 0 ].app( app, "Activate" )
355 # TODO: check this worked
356 time.sleep( 10 ) # wait for apps to activate
357 for app in apps:
358 state = main.CLIs[ 0 ].appStatus( app )
359 if state == "ACTIVE":
360 activateResult = activeResult and True
361 else:
362 main.log.error( "{} is in {} state".format( app, state ) )
363 activeResult = False
364 utilities.assert_equals( expect=True,
365 actual=activateResult,
366 onpass="Successfully activated apps",
367 onfail="Failed to activate apps" )
368 else:
369 main.log.warn( "No apps were specified to be loaded after startup" )
370
371 main.step( "Set ONOS configurations" )
372 config = main.params.get( 'ONOS_Configuration' )
373 if config:
374 main.log.debug( config )
375 checkResult = main.TRUE
376 for component in config:
377 for setting in config[component]:
378 value = config[component][setting]
379 check = main.CLIs[ 0 ].setCfg( component, setting, value )
380 main.log.info( "Value was changed? {}".format( main.TRUE == check ) )
381 checkResult = check and checkResult
382 utilities.assert_equals( expect=main.TRUE,
383 actual=checkResult,
384 onpass="Successfully set config",
385 onfail="Failed to set config" )
386 else:
387 main.log.warn( "No configurations were specified to be changed after startup" )
388
Jon Hall5cf14d52015-07-16 12:15:19 -0700389 def CASE2( self, main ):
390 """
391 Assign devices to controllers
392 """
393 import re
Jon Halle1a3b752015-07-22 13:02:46 -0700394 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700395 assert main, "main not defined"
396 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700397 assert main.CLIs, "main.CLIs not defined"
398 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700399 assert ONOS1Port, "ONOS1Port not defined"
400 assert ONOS2Port, "ONOS2Port not defined"
401 assert ONOS3Port, "ONOS3Port not defined"
402 assert ONOS4Port, "ONOS4Port not defined"
403 assert ONOS5Port, "ONOS5Port not defined"
404 assert ONOS6Port, "ONOS6Port not defined"
405 assert ONOS7Port, "ONOS7Port not defined"
406
407 main.case( "Assigning devices to controllers" )
Jon Hall783bbf92015-07-23 14:33:19 -0700408 main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700409 "and check that an ONOS node becomes the " +\
410 "master of the device."
411 main.step( "Assign switches to controllers" )
412
413 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700414 for i in range( main.numCtrls ):
415 ipList.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -0700416 swList = []
417 for i in range( 1, 29 ):
418 swList.append( "s" + str( i ) )
419 main.Mininet1.assignSwController( sw=swList, ip=ipList )
420
421 mastershipCheck = main.TRUE
422 for i in range( 1, 29 ):
423 response = main.Mininet1.getSwController( "s" + str( i ) )
424 try:
425 main.log.info( str( response ) )
426 except Exception:
427 main.log.info( repr( response ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700428 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700429 if re.search( "tcp:" + node.ip_address, response ):
430 mastershipCheck = mastershipCheck and main.TRUE
431 else:
432 main.log.error( "Error, node " + node.ip_address + " is " +
433 "not in the list of controllers s" +
434 str( i ) + " is connecting to." )
435 mastershipCheck = main.FALSE
436 utilities.assert_equals(
437 expect=main.TRUE,
438 actual=mastershipCheck,
439 onpass="Switch mastership assigned correctly",
440 onfail="Switches not assigned correctly to controllers" )
441
442 def CASE21( self, main ):
443 """
444 Assign mastership to controllers
445 """
Jon Hall5cf14d52015-07-16 12:15:19 -0700446 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700447 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700448 assert main, "main not defined"
449 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700450 assert main.CLIs, "main.CLIs not defined"
451 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700452 assert ONOS1Port, "ONOS1Port not defined"
453 assert ONOS2Port, "ONOS2Port not defined"
454 assert ONOS3Port, "ONOS3Port not defined"
455 assert ONOS4Port, "ONOS4Port not defined"
456 assert ONOS5Port, "ONOS5Port not defined"
457 assert ONOS6Port, "ONOS6Port not defined"
458 assert ONOS7Port, "ONOS7Port not defined"
459
460 main.case( "Assigning Controller roles for switches" )
Jon Hall783bbf92015-07-23 14:33:19 -0700461 main.caseExplanation = "Check that ONOS is connected to each " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700462 "device. Then manually assign" +\
463 " mastership to specific ONOS nodes using" +\
464 " 'device-role'"
465 main.step( "Assign mastership of switches to specific controllers" )
466 # Manually assign mastership to the controller we want
467 roleCall = main.TRUE
468
469 ipList = [ ]
470 deviceList = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700471 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -0700472 try:
473 # Assign mastership to specific controllers. This assignment was
474 # determined for a 7 node cluser, but will work with any sized
475 # cluster
476 for i in range( 1, 29 ): # switches 1 through 28
477 # set up correct variables:
478 if i == 1:
479 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700480 ip = main.nodes[ c ].ip_address # ONOS1
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700481 deviceId = onosCli.getDevice( "1000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700482 elif i == 2:
Jon Halle1a3b752015-07-22 13:02:46 -0700483 c = 1 % main.numCtrls
484 ip = main.nodes[ c ].ip_address # ONOS2
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700485 deviceId = onosCli.getDevice( "2000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700486 elif i == 3:
Jon Halle1a3b752015-07-22 13:02:46 -0700487 c = 1 % main.numCtrls
488 ip = main.nodes[ c ].ip_address # ONOS2
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700489 deviceId = onosCli.getDevice( "3000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700490 elif i == 4:
Jon Halle1a3b752015-07-22 13:02:46 -0700491 c = 3 % main.numCtrls
492 ip = main.nodes[ c ].ip_address # ONOS4
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700493 deviceId = onosCli.getDevice( "3004" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700494 elif i == 5:
Jon Halle1a3b752015-07-22 13:02:46 -0700495 c = 2 % main.numCtrls
496 ip = main.nodes[ c ].ip_address # ONOS3
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700497 deviceId = onosCli.getDevice( "5000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700498 elif i == 6:
Jon Halle1a3b752015-07-22 13:02:46 -0700499 c = 2 % main.numCtrls
500 ip = main.nodes[ c ].ip_address # ONOS3
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700501 deviceId = onosCli.getDevice( "6000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700502 elif i == 7:
Jon Halle1a3b752015-07-22 13:02:46 -0700503 c = 5 % main.numCtrls
504 ip = main.nodes[ c ].ip_address # ONOS6
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700505 deviceId = onosCli.getDevice( "6007" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700506 elif i >= 8 and i <= 17:
Jon Halle1a3b752015-07-22 13:02:46 -0700507 c = 4 % main.numCtrls
508 ip = main.nodes[ c ].ip_address # ONOS5
Jon Hall5cf14d52015-07-16 12:15:19 -0700509 dpid = '3' + str( i ).zfill( 3 )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700510 deviceId = onosCli.getDevice( dpid ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700511 elif i >= 18 and i <= 27:
Jon Halle1a3b752015-07-22 13:02:46 -0700512 c = 6 % main.numCtrls
513 ip = main.nodes[ c ].ip_address # ONOS7
Jon Hall5cf14d52015-07-16 12:15:19 -0700514 dpid = '6' + str( i ).zfill( 3 )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700515 deviceId = onosCli.getDevice( dpid ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700516 elif i == 28:
517 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700518 ip = main.nodes[ c ].ip_address # ONOS1
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700519 deviceId = onosCli.getDevice( "2800" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700520 else:
521 main.log.error( "You didn't write an else statement for " +
522 "switch s" + str( i ) )
523 roleCall = main.FALSE
524 # Assign switch
525 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
526 # TODO: make this controller dynamic
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700527 roleCall = roleCall and onosCli.deviceRole( deviceId, ip )
Jon Hall5cf14d52015-07-16 12:15:19 -0700528 ipList.append( ip )
529 deviceList.append( deviceId )
530 except ( AttributeError, AssertionError ):
531 main.log.exception( "Something is wrong with ONOS device view" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700532 main.log.info( onosCli.devices() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700533 utilities.assert_equals(
534 expect=main.TRUE,
535 actual=roleCall,
536 onpass="Re-assigned switch mastership to designated controller",
537 onfail="Something wrong with deviceRole calls" )
538
539 main.step( "Check mastership was correctly assigned" )
540 roleCheck = main.TRUE
541 # NOTE: This is due to the fact that device mastership change is not
542 # atomic and is actually a multi step process
543 time.sleep( 5 )
544 for i in range( len( ipList ) ):
545 ip = ipList[i]
546 deviceId = deviceList[i]
547 # Check assignment
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700548 master = onosCli.getRole( deviceId ).get( 'master' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700549 if ip in master:
550 roleCheck = roleCheck and main.TRUE
551 else:
552 roleCheck = roleCheck and main.FALSE
553 main.log.error( "Error, controller " + ip + " is not" +
554 " master " + "of device " +
555 str( deviceId ) + ". Master is " +
556 repr( master ) + "." )
557 utilities.assert_equals(
558 expect=main.TRUE,
559 actual=roleCheck,
560 onpass="Switches were successfully reassigned to designated " +
561 "controller",
562 onfail="Switches were not successfully reassigned" )
563
564 def CASE3( self, main ):
565 """
566 Assign intents
567 """
568 import time
569 import json
Jon Halle1a3b752015-07-22 13:02:46 -0700570 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700571 assert main, "main not defined"
572 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700573 assert main.CLIs, "main.CLIs not defined"
574 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700575 main.case( "Adding host Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700576 main.caseExplanation = "Discover hosts by using pingall then " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700577 "assign predetermined host-to-host intents." +\
578 " After installation, check that the intent" +\
579 " is distributed to all nodes and the state" +\
580 " is INSTALLED"
581
582 # install onos-app-fwd
583 main.step( "Install reactive forwarding app" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700584 onosCli = main.CLIs[ main.activeNodes[0] ]
585 installResults = onosCli.activateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700586 utilities.assert_equals( expect=main.TRUE, actual=installResults,
587 onpass="Install fwd successful",
588 onfail="Install fwd failed" )
589
590 main.step( "Check app ids" )
591 appCheck = main.TRUE
592 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700593 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -0700594 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700595 name="appToIDCheck-" + str( i ),
596 args=[] )
597 threads.append( t )
598 t.start()
599
600 for t in threads:
601 t.join()
602 appCheck = appCheck and t.result
603 if appCheck != main.TRUE:
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700604 main.log.warn( onosCli.apps() )
605 main.log.warn( onosCli.appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700606 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
607 onpass="App Ids seem to be correct",
608 onfail="Something is wrong with app Ids" )
609
610 main.step( "Discovering Hosts( Via pingall for now )" )
611 # FIXME: Once we have a host discovery mechanism, use that instead
612 # REACTIVE FWD test
613 pingResult = main.FALSE
Jon Hall96091e62015-09-21 17:34:17 -0700614 passMsg = "Reactive Pingall test passed"
615 time1 = time.time()
616 pingResult = main.Mininet1.pingall()
617 time2 = time.time()
618 if not pingResult:
619 main.log.warn("First pingall failed. Trying again...")
Jon Hall5cf14d52015-07-16 12:15:19 -0700620 pingResult = main.Mininet1.pingall()
Jon Hall96091e62015-09-21 17:34:17 -0700621 passMsg += " on the second try"
622 utilities.assert_equals(
623 expect=main.TRUE,
624 actual=pingResult,
625 onpass= passMsg,
626 onfail="Reactive Pingall failed, " +
627 "one or more ping pairs failed" )
628 main.log.info( "Time for pingall: %2f seconds" %
629 ( time2 - time1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -0700630 # timeout for fwd flows
631 time.sleep( 11 )
632 # uninstall onos-app-fwd
633 main.step( "Uninstall reactive forwarding app" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700634 node = main.activeNodes[0]
635 uninstallResult = main.CLIs[node].deactivateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700636 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
637 onpass="Uninstall fwd successful",
638 onfail="Uninstall fwd failed" )
639
640 main.step( "Check app ids" )
641 threads = []
642 appCheck2 = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700643 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -0700644 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700645 name="appToIDCheck-" + str( i ),
646 args=[] )
647 threads.append( t )
648 t.start()
649
650 for t in threads:
651 t.join()
652 appCheck2 = appCheck2 and t.result
653 if appCheck2 != main.TRUE:
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700654 node = main.activeNodes[0]
655 main.log.warn( main.CLIs[node].apps() )
656 main.log.warn( main.CLIs[node].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700657 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
658 onpass="App Ids seem to be correct",
659 onfail="Something is wrong with app Ids" )
660
661 main.step( "Add host intents via cli" )
662 intentIds = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700663 # TODO: move the host numbers to params
664 # Maybe look at all the paths we ping?
Jon Hall5cf14d52015-07-16 12:15:19 -0700665 intentAddResult = True
666 hostResult = main.TRUE
667 for i in range( 8, 18 ):
668 main.log.info( "Adding host intent between h" + str( i ) +
669 " and h" + str( i + 10 ) )
670 host1 = "00:00:00:00:00:" + \
671 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
672 host2 = "00:00:00:00:00:" + \
673 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
674 # NOTE: getHost can return None
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700675 host1Dict = onosCli.getHost( host1 )
676 host2Dict = onosCli.getHost( host2 )
Jon Hall5cf14d52015-07-16 12:15:19 -0700677 host1Id = None
678 host2Id = None
679 if host1Dict and host2Dict:
680 host1Id = host1Dict.get( 'id', None )
681 host2Id = host2Dict.get( 'id', None )
682 if host1Id and host2Id:
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700683 nodeNum = ( i % len( main.activeNodes ) )
684 node = main.activeNodes[nodeNum]
685 tmpId = main.CLIs[node].addHostIntent( host1Id, host2Id )
Jon Hall5cf14d52015-07-16 12:15:19 -0700686 if tmpId:
687 main.log.info( "Added intent with id: " + tmpId )
688 intentIds.append( tmpId )
689 else:
690 main.log.error( "addHostIntent returned: " +
691 repr( tmpId ) )
692 else:
693 main.log.error( "Error, getHost() failed for h" + str( i ) +
694 " and/or h" + str( i + 10 ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700695 node = main.activeNodes[0]
696 hosts = main.CLIs[node].hosts()
Jon Hall5cf14d52015-07-16 12:15:19 -0700697 main.log.warn( "Hosts output: " )
698 try:
699 main.log.warn( json.dumps( json.loads( hosts ),
700 sort_keys=True,
701 indent=4,
702 separators=( ',', ': ' ) ) )
703 except ( ValueError, TypeError ):
704 main.log.warn( repr( hosts ) )
705 hostResult = main.FALSE
706 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
707 onpass="Found a host id for each host",
708 onfail="Error looking up host ids" )
709
710 intentStart = time.time()
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700711 onosIds = onosCli.getAllIntentsId()
Jon Hall5cf14d52015-07-16 12:15:19 -0700712 main.log.info( "Submitted intents: " + str( intentIds ) )
713 main.log.info( "Intents in ONOS: " + str( onosIds ) )
714 for intent in intentIds:
715 if intent in onosIds:
716 pass # intent submitted is in onos
717 else:
718 intentAddResult = False
719 if intentAddResult:
720 intentStop = time.time()
721 else:
722 intentStop = None
723 # Print the intent states
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700724 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700725 intentStates = []
726 installedCheck = True
727 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
728 count = 0
729 try:
730 for intent in json.loads( intents ):
731 state = intent.get( 'state', None )
732 if "INSTALLED" not in state:
733 installedCheck = False
734 intentId = intent.get( 'id', None )
735 intentStates.append( ( intentId, state ) )
736 except ( ValueError, TypeError ):
737 main.log.exception( "Error parsing intents" )
738 # add submitted intents not in the store
739 tmplist = [ i for i, s in intentStates ]
740 missingIntents = False
741 for i in intentIds:
742 if i not in tmplist:
743 intentStates.append( ( i, " - " ) )
744 missingIntents = True
745 intentStates.sort()
746 for i, s in intentStates:
747 count += 1
748 main.log.info( "%-6s%-15s%-15s" %
749 ( str( count ), str( i ), str( s ) ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700750 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -0700751 try:
752 missing = False
753 if leaders:
754 parsedLeaders = json.loads( leaders )
755 main.log.warn( json.dumps( parsedLeaders,
756 sort_keys=True,
757 indent=4,
758 separators=( ',', ': ' ) ) )
759 # check for all intent partitions
760 topics = []
761 for i in range( 14 ):
762 topics.append( "intent-partition-" + str( i ) )
763 main.log.debug( topics )
764 ONOStopics = [ j['topic'] for j in parsedLeaders ]
765 for topic in topics:
766 if topic not in ONOStopics:
767 main.log.error( "Error: " + topic +
768 " not in leaders" )
769 missing = True
770 else:
771 main.log.error( "leaders() returned None" )
772 except ( ValueError, TypeError ):
773 main.log.exception( "Error parsing leaders" )
774 main.log.error( repr( leaders ) )
775 # Check all nodes
776 if missing:
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700777 for i in main.activeNodes:
778 response = main.CLIs[i].leaders( jsonFormat=False)
779 main.log.warn( str( main.CLIs[i].name ) + " leaders output: \n" +
Jon Hall5cf14d52015-07-16 12:15:19 -0700780 str( response ) )
781
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700782 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -0700783 try:
784 if partitions :
785 parsedPartitions = json.loads( partitions )
786 main.log.warn( json.dumps( parsedPartitions,
787 sort_keys=True,
788 indent=4,
789 separators=( ',', ': ' ) ) )
790 # TODO check for a leader in all paritions
791 # TODO check for consistency among nodes
792 else:
793 main.log.error( "partitions() returned None" )
794 except ( ValueError, TypeError ):
795 main.log.exception( "Error parsing partitions" )
796 main.log.error( repr( partitions ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700797 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -0700798 try:
799 if pendingMap :
800 parsedPending = json.loads( pendingMap )
801 main.log.warn( json.dumps( parsedPending,
802 sort_keys=True,
803 indent=4,
804 separators=( ',', ': ' ) ) )
805 # TODO check something here?
806 else:
807 main.log.error( "pendingMap() returned None" )
808 except ( ValueError, TypeError ):
809 main.log.exception( "Error parsing pending map" )
810 main.log.error( repr( pendingMap ) )
811
812 intentAddResult = bool( intentAddResult and not missingIntents and
813 installedCheck )
814 if not intentAddResult:
815 main.log.error( "Error in pushing host intents to ONOS" )
816
817 main.step( "Intent Anti-Entropy dispersion" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700818 for j in range(100):
Jon Hall5cf14d52015-07-16 12:15:19 -0700819 correct = True
820 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700821 for i in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700822 onosIds = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700823 ids = main.CLIs[i].getAllIntentsId()
Jon Hall5cf14d52015-07-16 12:15:19 -0700824 onosIds.append( ids )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700825 main.log.debug( "Intents in " + main.CLIs[i].name + ": " +
Jon Hall5cf14d52015-07-16 12:15:19 -0700826 str( sorted( onosIds ) ) )
827 if sorted( ids ) != sorted( intentIds ):
828 main.log.warn( "Set of intent IDs doesn't match" )
829 correct = False
830 break
831 else:
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700832 intents = json.loads( main.CLIs[i].intents() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700833 for intent in intents:
834 if intent[ 'state' ] != "INSTALLED":
835 main.log.warn( "Intent " + intent[ 'id' ] +
836 " is " + intent[ 'state' ] )
837 correct = False
838 break
839 if correct:
840 break
841 else:
842 time.sleep(1)
843 if not intentStop:
844 intentStop = time.time()
845 global gossipTime
846 gossipTime = intentStop - intentStart
847 main.log.info( "It took about " + str( gossipTime ) +
848 " seconds for all intents to appear in each node" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700849 gossipPeriod = int( main.params['timers']['gossip'] )
850 maxGossipTime = gossipPeriod * len( main.activeNodes )
Jon Hall5cf14d52015-07-16 12:15:19 -0700851 utilities.assert_greater_equals(
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700852 expect=maxGossipTime, actual=gossipTime,
Jon Hall5cf14d52015-07-16 12:15:19 -0700853 onpass="ECM anti-entropy for intents worked within " +
854 "expected time",
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700855 onfail="Intent ECM anti-entropy took too long. " +
856 "Expected time:{}, Actual time:{}".format( maxGossipTime,
857 gossipTime ) )
858 if gossipTime <= maxGossipTime:
Jon Hall5cf14d52015-07-16 12:15:19 -0700859 intentAddResult = True
860
861 if not intentAddResult or "key" in pendingMap:
862 import time
863 installedCheck = True
864 main.log.info( "Sleeping 60 seconds to see if intents are found" )
865 time.sleep( 60 )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700866 onosIds = onosCli.getAllIntentsId()
Jon Hall5cf14d52015-07-16 12:15:19 -0700867 main.log.info( "Submitted intents: " + str( intentIds ) )
868 main.log.info( "Intents in ONOS: " + str( onosIds ) )
869 # Print the intent states
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700870 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700871 intentStates = []
872 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
873 count = 0
874 try:
875 for intent in json.loads( intents ):
876 # Iter through intents of a node
877 state = intent.get( 'state', None )
878 if "INSTALLED" not in state:
879 installedCheck = False
880 intentId = intent.get( 'id', None )
881 intentStates.append( ( intentId, state ) )
882 except ( ValueError, TypeError ):
883 main.log.exception( "Error parsing intents" )
884 # add submitted intents not in the store
885 tmplist = [ i for i, s in intentStates ]
886 for i in intentIds:
887 if i not in tmplist:
888 intentStates.append( ( i, " - " ) )
889 intentStates.sort()
890 for i, s in intentStates:
891 count += 1
892 main.log.info( "%-6s%-15s%-15s" %
893 ( str( count ), str( i ), str( s ) ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700894 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -0700895 try:
896 missing = False
897 if leaders:
898 parsedLeaders = json.loads( leaders )
899 main.log.warn( json.dumps( parsedLeaders,
900 sort_keys=True,
901 indent=4,
902 separators=( ',', ': ' ) ) )
903 # check for all intent partitions
904 # check for election
905 topics = []
906 for i in range( 14 ):
907 topics.append( "intent-partition-" + str( i ) )
908 # FIXME: this should only be after we start the app
909 topics.append( "org.onosproject.election" )
910 main.log.debug( topics )
911 ONOStopics = [ j['topic'] for j in parsedLeaders ]
912 for topic in topics:
913 if topic not in ONOStopics:
914 main.log.error( "Error: " + topic +
915 " not in leaders" )
916 missing = True
917 else:
918 main.log.error( "leaders() returned None" )
919 except ( ValueError, TypeError ):
920 main.log.exception( "Error parsing leaders" )
921 main.log.error( repr( leaders ) )
922 # Check all nodes
923 if missing:
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700924 for i in main.activeNodes:
925 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -0700926 response = node.leaders( jsonFormat=False)
927 main.log.warn( str( node.name ) + " leaders output: \n" +
928 str( response ) )
929
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700930 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -0700931 try:
932 if partitions :
933 parsedPartitions = json.loads( partitions )
934 main.log.warn( json.dumps( parsedPartitions,
935 sort_keys=True,
936 indent=4,
937 separators=( ',', ': ' ) ) )
938 # TODO check for a leader in all paritions
939 # TODO check for consistency among nodes
940 else:
941 main.log.error( "partitions() returned None" )
942 except ( ValueError, TypeError ):
943 main.log.exception( "Error parsing partitions" )
944 main.log.error( repr( partitions ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700945 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -0700946 try:
947 if pendingMap :
948 parsedPending = json.loads( pendingMap )
949 main.log.warn( json.dumps( parsedPending,
950 sort_keys=True,
951 indent=4,
952 separators=( ',', ': ' ) ) )
953 # TODO check something here?
954 else:
955 main.log.error( "pendingMap() returned None" )
956 except ( ValueError, TypeError ):
957 main.log.exception( "Error parsing pending map" )
958 main.log.error( repr( pendingMap ) )
959
960 def CASE4( self, main ):
961 """
962 Ping across added host intents
963 """
964 import json
965 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700966 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700967 assert main, "main not defined"
968 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700969 assert main.CLIs, "main.CLIs not defined"
970 assert main.nodes, "main.nodes not defined"
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700971 main.case( "Verify connectivity by sending traffic across Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700972 main.caseExplanation = "Ping across added host intents to check " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700973 "functionality and check the state of " +\
974 "the intent"
975 main.step( "Ping across added host intents" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700976 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -0700977 PingResult = main.TRUE
978 for i in range( 8, 18 ):
979 ping = main.Mininet1.pingHost( src="h" + str( i ),
980 target="h" + str( i + 10 ) )
981 PingResult = PingResult and ping
982 if ping == main.FALSE:
983 main.log.warn( "Ping failed between h" + str( i ) +
984 " and h" + str( i + 10 ) )
985 elif ping == main.TRUE:
986 main.log.info( "Ping test passed!" )
987 # Don't set PingResult or you'd override failures
988 if PingResult == main.FALSE:
989 main.log.error(
990 "Intents have not been installed correctly, pings failed." )
991 # TODO: pretty print
992 main.log.warn( "ONOS1 intents: " )
993 try:
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700994 tmpIntents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700995 main.log.warn( json.dumps( json.loads( tmpIntents ),
996 sort_keys=True,
997 indent=4,
998 separators=( ',', ': ' ) ) )
999 except ( ValueError, TypeError ):
1000 main.log.warn( repr( tmpIntents ) )
1001 utilities.assert_equals(
1002 expect=main.TRUE,
1003 actual=PingResult,
1004 onpass="Intents have been installed correctly and pings work",
1005 onfail="Intents have not been installed correctly, pings failed." )
1006
1007 main.step( "Check Intent state" )
1008 installedCheck = False
1009 loopCount = 0
1010 while not installedCheck and loopCount < 40:
1011 installedCheck = True
1012 # Print the intent states
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001013 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -07001014 intentStates = []
1015 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
1016 count = 0
1017 # Iter through intents of a node
1018 try:
1019 for intent in json.loads( intents ):
1020 state = intent.get( 'state', None )
1021 if "INSTALLED" not in state:
1022 installedCheck = False
1023 intentId = intent.get( 'id', None )
1024 intentStates.append( ( intentId, state ) )
1025 except ( ValueError, TypeError ):
1026 main.log.exception( "Error parsing intents." )
1027 # Print states
1028 intentStates.sort()
1029 for i, s in intentStates:
1030 count += 1
1031 main.log.info( "%-6s%-15s%-15s" %
1032 ( str( count ), str( i ), str( s ) ) )
1033 if not installedCheck:
1034 time.sleep( 1 )
1035 loopCount += 1
1036 utilities.assert_equals( expect=True, actual=installedCheck,
1037 onpass="Intents are all INSTALLED",
1038 onfail="Intents are not all in " +
1039 "INSTALLED state" )
1040
1041 main.step( "Check leadership of topics" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001042 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -07001043 topicCheck = main.TRUE
1044 try:
1045 if leaders:
1046 parsedLeaders = json.loads( leaders )
1047 main.log.warn( json.dumps( parsedLeaders,
1048 sort_keys=True,
1049 indent=4,
1050 separators=( ',', ': ' ) ) )
1051 # check for all intent partitions
1052 # check for election
1053 # TODO: Look at Devices as topics now that it uses this system
1054 topics = []
1055 for i in range( 14 ):
1056 topics.append( "intent-partition-" + str( i ) )
1057 # FIXME: this should only be after we start the app
1058 # FIXME: topics.append( "org.onosproject.election" )
1059 # Print leaders output
1060 main.log.debug( topics )
1061 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1062 for topic in topics:
1063 if topic not in ONOStopics:
1064 main.log.error( "Error: " + topic +
1065 " not in leaders" )
1066 topicCheck = main.FALSE
1067 else:
1068 main.log.error( "leaders() returned None" )
1069 topicCheck = main.FALSE
1070 except ( ValueError, TypeError ):
1071 topicCheck = main.FALSE
1072 main.log.exception( "Error parsing leaders" )
1073 main.log.error( repr( leaders ) )
1074 # TODO: Check for a leader of these topics
1075 # Check all nodes
1076 if topicCheck:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001077 for i in main.activeNodes:
1078 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07001079 response = node.leaders( jsonFormat=False)
1080 main.log.warn( str( node.name ) + " leaders output: \n" +
1081 str( response ) )
1082
1083 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
1084 onpass="intent Partitions is in leaders",
1085 onfail="Some topics were lost " )
1086 # Print partitions
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001087 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -07001088 try:
1089 if partitions :
1090 parsedPartitions = json.loads( partitions )
1091 main.log.warn( json.dumps( parsedPartitions,
1092 sort_keys=True,
1093 indent=4,
1094 separators=( ',', ': ' ) ) )
1095 # TODO check for a leader in all paritions
1096 # TODO check for consistency among nodes
1097 else:
1098 main.log.error( "partitions() returned None" )
1099 except ( ValueError, TypeError ):
1100 main.log.exception( "Error parsing partitions" )
1101 main.log.error( repr( partitions ) )
1102 # Print Pending Map
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001103 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -07001104 try:
1105 if pendingMap :
1106 parsedPending = json.loads( pendingMap )
1107 main.log.warn( json.dumps( parsedPending,
1108 sort_keys=True,
1109 indent=4,
1110 separators=( ',', ': ' ) ) )
1111 # TODO check something here?
1112 else:
1113 main.log.error( "pendingMap() returned None" )
1114 except ( ValueError, TypeError ):
1115 main.log.exception( "Error parsing pending map" )
1116 main.log.error( repr( pendingMap ) )
1117
1118 if not installedCheck:
1119 main.log.info( "Waiting 60 seconds to see if the state of " +
1120 "intents change" )
1121 time.sleep( 60 )
1122 # Print the intent states
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001123 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -07001124 intentStates = []
1125 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
1126 count = 0
1127 # Iter through intents of a node
1128 try:
1129 for intent in json.loads( intents ):
1130 state = intent.get( 'state', None )
1131 if "INSTALLED" not in state:
1132 installedCheck = False
1133 intentId = intent.get( 'id', None )
1134 intentStates.append( ( intentId, state ) )
1135 except ( ValueError, TypeError ):
1136 main.log.exception( "Error parsing intents." )
1137 intentStates.sort()
1138 for i, s in intentStates:
1139 count += 1
1140 main.log.info( "%-6s%-15s%-15s" %
1141 ( str( count ), str( i ), str( s ) ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001142 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -07001143 try:
1144 missing = False
1145 if leaders:
1146 parsedLeaders = json.loads( leaders )
1147 main.log.warn( json.dumps( parsedLeaders,
1148 sort_keys=True,
1149 indent=4,
1150 separators=( ',', ': ' ) ) )
1151 # check for all intent partitions
1152 # check for election
1153 topics = []
1154 for i in range( 14 ):
1155 topics.append( "intent-partition-" + str( i ) )
1156 # FIXME: this should only be after we start the app
1157 topics.append( "org.onosproject.election" )
1158 main.log.debug( topics )
1159 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1160 for topic in topics:
1161 if topic not in ONOStopics:
1162 main.log.error( "Error: " + topic +
1163 " not in leaders" )
1164 missing = True
1165 else:
1166 main.log.error( "leaders() returned None" )
1167 except ( ValueError, TypeError ):
1168 main.log.exception( "Error parsing leaders" )
1169 main.log.error( repr( leaders ) )
1170 if missing:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001171 for i in main.activeNodes:
1172 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07001173 response = node.leaders( jsonFormat=False)
1174 main.log.warn( str( node.name ) + " leaders output: \n" +
1175 str( response ) )
1176
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001177 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -07001178 try:
1179 if partitions :
1180 parsedPartitions = json.loads( partitions )
1181 main.log.warn( json.dumps( parsedPartitions,
1182 sort_keys=True,
1183 indent=4,
1184 separators=( ',', ': ' ) ) )
1185 # TODO check for a leader in all paritions
1186 # TODO check for consistency among nodes
1187 else:
1188 main.log.error( "partitions() returned None" )
1189 except ( ValueError, TypeError ):
1190 main.log.exception( "Error parsing partitions" )
1191 main.log.error( repr( partitions ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001192 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -07001193 try:
1194 if pendingMap :
1195 parsedPending = json.loads( pendingMap )
1196 main.log.warn( json.dumps( parsedPending,
1197 sort_keys=True,
1198 indent=4,
1199 separators=( ',', ': ' ) ) )
1200 # TODO check something here?
1201 else:
1202 main.log.error( "pendingMap() returned None" )
1203 except ( ValueError, TypeError ):
1204 main.log.exception( "Error parsing pending map" )
1205 main.log.error( repr( pendingMap ) )
1206 # Print flowrules
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001207 node = main.activeNodes[0]
1208 main.log.debug( main.CLIs[node].flows( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001209 main.step( "Wait a minute then ping again" )
1210 # the wait is above
1211 PingResult = main.TRUE
1212 for i in range( 8, 18 ):
1213 ping = main.Mininet1.pingHost( src="h" + str( i ),
1214 target="h" + str( i + 10 ) )
1215 PingResult = PingResult and ping
1216 if ping == main.FALSE:
1217 main.log.warn( "Ping failed between h" + str( i ) +
1218 " and h" + str( i + 10 ) )
1219 elif ping == main.TRUE:
1220 main.log.info( "Ping test passed!" )
1221 # Don't set PingResult or you'd override failures
1222 if PingResult == main.FALSE:
1223 main.log.error(
1224 "Intents have not been installed correctly, pings failed." )
1225 # TODO: pretty print
1226 main.log.warn( "ONOS1 intents: " )
1227 try:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001228 tmpIntents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -07001229 main.log.warn( json.dumps( json.loads( tmpIntents ),
1230 sort_keys=True,
1231 indent=4,
1232 separators=( ',', ': ' ) ) )
1233 except ( ValueError, TypeError ):
1234 main.log.warn( repr( tmpIntents ) )
1235 utilities.assert_equals(
1236 expect=main.TRUE,
1237 actual=PingResult,
1238 onpass="Intents have been installed correctly and pings work",
1239 onfail="Intents have not been installed correctly, pings failed." )
1240
1241 def CASE5( self, main ):
1242 """
1243 Reading state of ONOS
1244 """
1245 import json
1246 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001247 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001248 assert main, "main not defined"
1249 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001250 assert main.CLIs, "main.CLIs not defined"
1251 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001252
1253 main.case( "Setting up and gathering data for current state" )
1254 # The general idea for this test case is to pull the state of
1255 # ( intents,flows, topology,... ) from each ONOS node
1256 # We can then compare them with each other and also with past states
1257
1258 main.step( "Check that each switch has a master" )
1259 global mastershipState
1260 mastershipState = '[]'
1261
1262 # Assert that each device has a master
1263 rolesNotNull = main.TRUE
1264 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001265 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001266 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001267 name="rolesNotNull-" + str( i ),
1268 args=[] )
1269 threads.append( t )
1270 t.start()
1271
1272 for t in threads:
1273 t.join()
1274 rolesNotNull = rolesNotNull and t.result
1275 utilities.assert_equals(
1276 expect=main.TRUE,
1277 actual=rolesNotNull,
1278 onpass="Each device has a master",
1279 onfail="Some devices don't have a master assigned" )
1280
1281 main.step( "Get the Mastership of each switch from each controller" )
1282 ONOSMastership = []
1283 mastershipCheck = main.FALSE
1284 consistentMastership = True
1285 rolesResults = True
1286 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001287 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001288 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001289 name="roles-" + str( i ),
1290 args=[] )
1291 threads.append( t )
1292 t.start()
1293
1294 for t in threads:
1295 t.join()
1296 ONOSMastership.append( t.result )
1297
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001298 for i in range( len( ONOSMastership ) ):
1299 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001300 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001301 main.log.error( "Error in getting ONOS" + node + " roles" )
1302 main.log.warn( "ONOS" + node + " mastership response: " +
1303 repr( ONOSMastership[i] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001304 rolesResults = False
1305 utilities.assert_equals(
1306 expect=True,
1307 actual=rolesResults,
1308 onpass="No error in reading roles output",
1309 onfail="Error in reading roles from ONOS" )
1310
1311 main.step( "Check for consistency in roles from each controller" )
1312 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1313 main.log.info(
1314 "Switch roles are consistent across all ONOS nodes" )
1315 else:
1316 consistentMastership = False
1317 utilities.assert_equals(
1318 expect=True,
1319 actual=consistentMastership,
1320 onpass="Switch roles are consistent across all ONOS nodes",
1321 onfail="ONOS nodes have different views of switch roles" )
1322
1323 if rolesResults and not consistentMastership:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001324 for i in range( len( main.activeNodes ) ):
1325 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001326 try:
1327 main.log.warn(
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001328 "ONOS" + node + " roles: ",
Jon Hall5cf14d52015-07-16 12:15:19 -07001329 json.dumps(
1330 json.loads( ONOSMastership[ i ] ),
1331 sort_keys=True,
1332 indent=4,
1333 separators=( ',', ': ' ) ) )
1334 except ( ValueError, TypeError ):
1335 main.log.warn( repr( ONOSMastership[ i ] ) )
1336 elif rolesResults and consistentMastership:
1337 mastershipCheck = main.TRUE
1338 mastershipState = ONOSMastership[ 0 ]
1339
1340 main.step( "Get the intents from each controller" )
1341 global intentState
1342 intentState = []
1343 ONOSIntents = []
1344 intentCheck = main.FALSE
1345 consistentIntents = True
1346 intentsResults = True
1347 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001348 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001349 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001350 name="intents-" + str( i ),
1351 args=[],
1352 kwargs={ 'jsonFormat': True } )
1353 threads.append( t )
1354 t.start()
1355
1356 for t in threads:
1357 t.join()
1358 ONOSIntents.append( t.result )
1359
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001360 for i in range( len( ONOSIntents ) ):
1361 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001362 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001363 main.log.error( "Error in getting ONOS" + node + " intents" )
1364 main.log.warn( "ONOS" + node + " intents response: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07001365 repr( ONOSIntents[ i ] ) )
1366 intentsResults = False
1367 utilities.assert_equals(
1368 expect=True,
1369 actual=intentsResults,
1370 onpass="No error in reading intents output",
1371 onfail="Error in reading intents from ONOS" )
1372
1373 main.step( "Check for consistency in Intents from each controller" )
1374 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1375 main.log.info( "Intents are consistent across all ONOS " +
1376 "nodes" )
1377 else:
1378 consistentIntents = False
1379 main.log.error( "Intents not consistent" )
1380 utilities.assert_equals(
1381 expect=True,
1382 actual=consistentIntents,
1383 onpass="Intents are consistent across all ONOS nodes",
1384 onfail="ONOS nodes have different views of intents" )
1385
1386 if intentsResults:
1387 # Try to make it easy to figure out what is happening
1388 #
1389 # Intent ONOS1 ONOS2 ...
1390 # 0x01 INSTALLED INSTALLING
1391 # ... ... ...
1392 # ... ... ...
1393 title = " Id"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001394 for n in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001395 title += " " * 10 + "ONOS" + str( n + 1 )
1396 main.log.warn( title )
1397 # get all intent keys in the cluster
1398 keys = []
Jon Halla440e872016-03-31 15:15:50 -07001399 try:
1400 # Get the set of all intent keys
Jon Hall5cf14d52015-07-16 12:15:19 -07001401 for nodeStr in ONOSIntents:
1402 node = json.loads( nodeStr )
1403 for intent in node:
Jon Halla440e872016-03-31 15:15:50 -07001404 keys.append( intent.get( 'id' ) )
1405 keys = set( keys )
1406 # For each intent key, print the state on each node
1407 for key in keys:
1408 row = "%-13s" % key
1409 for nodeStr in ONOSIntents:
1410 node = json.loads( nodeStr )
1411 for intent in node:
1412 if intent.get( 'id', "Error" ) == key:
1413 row += "%-15s" % intent.get( 'state' )
1414 main.log.warn( row )
1415 # End of intent state table
1416 except ValueError as e:
1417 main.log.exception( e )
1418 main.log.debug( "nodeStr was: " + repr( nodeStr ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001419
1420 if intentsResults and not consistentIntents:
1421 # print the json objects
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001422 n = str( main.activeNodes[-1] + 1 )
1423 main.log.debug( "ONOS" + n + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07001424 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1425 sort_keys=True,
1426 indent=4,
1427 separators=( ',', ': ' ) ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001428 for i in range( len( ONOSIntents ) ):
1429 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001430 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001431 main.log.debug( "ONOS" + node + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07001432 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1433 sort_keys=True,
1434 indent=4,
1435 separators=( ',', ': ' ) ) )
1436 else:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001437 main.log.debug( "ONOS" + node + " intents match ONOS" +
1438 n + " intents" )
Jon Hall5cf14d52015-07-16 12:15:19 -07001439 elif intentsResults and consistentIntents:
1440 intentCheck = main.TRUE
1441 intentState = ONOSIntents[ 0 ]
1442
1443 main.step( "Get the flows from each controller" )
1444 global flowState
1445 flowState = []
1446 ONOSFlows = []
1447 ONOSFlowsJson = []
1448 flowCheck = main.FALSE
1449 consistentFlows = True
1450 flowsResults = True
1451 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001452 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001453 t = main.Thread( target=main.CLIs[i].flows,
Jon Hall5cf14d52015-07-16 12:15:19 -07001454 name="flows-" + str( i ),
1455 args=[],
1456 kwargs={ 'jsonFormat': True } )
1457 threads.append( t )
1458 t.start()
1459
1460 # NOTE: Flows command can take some time to run
1461 time.sleep(30)
1462 for t in threads:
1463 t.join()
1464 result = t.result
1465 ONOSFlows.append( result )
1466
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001467 for i in range( len( ONOSFlows ) ):
1468 num = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001469 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1470 main.log.error( "Error in getting ONOS" + num + " flows" )
1471 main.log.warn( "ONOS" + num + " flows response: " +
1472 repr( ONOSFlows[ i ] ) )
1473 flowsResults = False
1474 ONOSFlowsJson.append( None )
1475 else:
1476 try:
1477 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1478 except ( ValueError, TypeError ):
1479 # FIXME: change this to log.error?
1480 main.log.exception( "Error in parsing ONOS" + num +
1481 " response as json." )
1482 main.log.error( repr( ONOSFlows[ i ] ) )
1483 ONOSFlowsJson.append( None )
1484 flowsResults = False
1485 utilities.assert_equals(
1486 expect=True,
1487 actual=flowsResults,
1488 onpass="No error in reading flows output",
1489 onfail="Error in reading flows from ONOS" )
1490
1491 main.step( "Check for consistency in Flows from each controller" )
1492 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1493 if all( tmp ):
1494 main.log.info( "Flow count is consistent across all ONOS nodes" )
1495 else:
1496 consistentFlows = False
1497 utilities.assert_equals(
1498 expect=True,
1499 actual=consistentFlows,
1500 onpass="The flow count is consistent across all ONOS nodes",
1501 onfail="ONOS nodes have different flow counts" )
1502
1503 if flowsResults and not consistentFlows:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001504 for i in range( len( ONOSFlows ) ):
1505 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001506 try:
1507 main.log.warn(
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001508 "ONOS" + node + " flows: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07001509 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1510 indent=4, separators=( ',', ': ' ) ) )
1511 except ( ValueError, TypeError ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001512 main.log.warn( "ONOS" + node + " flows: " +
1513 repr( ONOSFlows[ i ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001514 elif flowsResults and consistentFlows:
1515 flowCheck = main.TRUE
1516 flowState = ONOSFlows[ 0 ]
1517
1518 main.step( "Get the OF Table entries" )
1519 global flows
1520 flows = []
1521 for i in range( 1, 29 ):
GlennRC68467eb2015-11-16 18:01:01 -08001522 flows.append( main.Mininet1.getFlowTable( "s" + str( i ), version="1.3", debug=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001523 if flowCheck == main.FALSE:
1524 for table in flows:
1525 main.log.warn( table )
1526 # TODO: Compare switch flow tables with ONOS flow tables
1527
1528 main.step( "Start continuous pings" )
1529 main.Mininet2.pingLong(
1530 src=main.params[ 'PING' ][ 'source1' ],
1531 target=main.params[ 'PING' ][ 'target1' ],
1532 pingTime=500 )
1533 main.Mininet2.pingLong(
1534 src=main.params[ 'PING' ][ 'source2' ],
1535 target=main.params[ 'PING' ][ 'target2' ],
1536 pingTime=500 )
1537 main.Mininet2.pingLong(
1538 src=main.params[ 'PING' ][ 'source3' ],
1539 target=main.params[ 'PING' ][ 'target3' ],
1540 pingTime=500 )
1541 main.Mininet2.pingLong(
1542 src=main.params[ 'PING' ][ 'source4' ],
1543 target=main.params[ 'PING' ][ 'target4' ],
1544 pingTime=500 )
1545 main.Mininet2.pingLong(
1546 src=main.params[ 'PING' ][ 'source5' ],
1547 target=main.params[ 'PING' ][ 'target5' ],
1548 pingTime=500 )
1549 main.Mininet2.pingLong(
1550 src=main.params[ 'PING' ][ 'source6' ],
1551 target=main.params[ 'PING' ][ 'target6' ],
1552 pingTime=500 )
1553 main.Mininet2.pingLong(
1554 src=main.params[ 'PING' ][ 'source7' ],
1555 target=main.params[ 'PING' ][ 'target7' ],
1556 pingTime=500 )
1557 main.Mininet2.pingLong(
1558 src=main.params[ 'PING' ][ 'source8' ],
1559 target=main.params[ 'PING' ][ 'target8' ],
1560 pingTime=500 )
1561 main.Mininet2.pingLong(
1562 src=main.params[ 'PING' ][ 'source9' ],
1563 target=main.params[ 'PING' ][ 'target9' ],
1564 pingTime=500 )
1565 main.Mininet2.pingLong(
1566 src=main.params[ 'PING' ][ 'source10' ],
1567 target=main.params[ 'PING' ][ 'target10' ],
1568 pingTime=500 )
1569
1570 main.step( "Collecting topology information from ONOS" )
1571 devices = []
1572 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001573 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001574 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07001575 name="devices-" + str( i ),
1576 args=[ ] )
1577 threads.append( t )
1578 t.start()
1579
1580 for t in threads:
1581 t.join()
1582 devices.append( t.result )
1583 hosts = []
1584 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001585 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001586 t = main.Thread( target=main.CLIs[i].hosts,
Jon Hall5cf14d52015-07-16 12:15:19 -07001587 name="hosts-" + str( i ),
1588 args=[ ] )
1589 threads.append( t )
1590 t.start()
1591
1592 for t in threads:
1593 t.join()
1594 try:
1595 hosts.append( json.loads( t.result ) )
1596 except ( ValueError, TypeError ):
1597 # FIXME: better handling of this, print which node
1598 # Maybe use thread name?
1599 main.log.exception( "Error parsing json output of hosts" )
Jon Hallf3d16e72015-12-16 17:45:08 -08001600 main.log.warn( repr( t.result ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001601 hosts.append( None )
1602
1603 ports = []
1604 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001605 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001606 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07001607 name="ports-" + str( i ),
1608 args=[ ] )
1609 threads.append( t )
1610 t.start()
1611
1612 for t in threads:
1613 t.join()
1614 ports.append( t.result )
1615 links = []
1616 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001617 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001618 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07001619 name="links-" + str( i ),
1620 args=[ ] )
1621 threads.append( t )
1622 t.start()
1623
1624 for t in threads:
1625 t.join()
1626 links.append( t.result )
1627 clusters = []
1628 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001629 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001630 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07001631 name="clusters-" + str( i ),
1632 args=[ ] )
1633 threads.append( t )
1634 t.start()
1635
1636 for t in threads:
1637 t.join()
1638 clusters.append( t.result )
1639 # Compare json objects for hosts and dataplane clusters
1640
1641 # hosts
1642 main.step( "Host view is consistent across ONOS nodes" )
1643 consistentHostsResult = main.TRUE
1644 for controller in range( len( hosts ) ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001645 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hallf3d16e72015-12-16 17:45:08 -08001646 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001647 if hosts[ controller ] == hosts[ 0 ]:
1648 continue
1649 else: # hosts not consistent
1650 main.log.error( "hosts from ONOS" +
1651 controllerStr +
1652 " is inconsistent with ONOS1" )
1653 main.log.warn( repr( hosts[ controller ] ) )
1654 consistentHostsResult = main.FALSE
1655
1656 else:
1657 main.log.error( "Error in getting ONOS hosts from ONOS" +
1658 controllerStr )
1659 consistentHostsResult = main.FALSE
1660 main.log.warn( "ONOS" + controllerStr +
1661 " hosts response: " +
1662 repr( hosts[ controller ] ) )
1663 utilities.assert_equals(
1664 expect=main.TRUE,
1665 actual=consistentHostsResult,
1666 onpass="Hosts view is consistent across all ONOS nodes",
1667 onfail="ONOS nodes have different views of hosts" )
1668
1669 main.step( "Each host has an IP address" )
1670 ipResult = main.TRUE
1671 for controller in range( 0, len( hosts ) ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001672 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hallf3d16e72015-12-16 17:45:08 -08001673 if hosts[ controller ]:
1674 for host in hosts[ controller ]:
1675 if not host.get( 'ipAddresses', [ ] ):
1676 main.log.error( "Error with host ips on controller" +
1677 controllerStr + ": " + str( host ) )
1678 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07001679 utilities.assert_equals(
1680 expect=main.TRUE,
1681 actual=ipResult,
1682 onpass="The ips of the hosts aren't empty",
1683 onfail="The ip of at least one host is missing" )
1684
1685 # Strongly connected clusters of devices
1686 main.step( "Cluster view is consistent across ONOS nodes" )
1687 consistentClustersResult = main.TRUE
1688 for controller in range( len( clusters ) ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001689 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001690 if "Error" not in clusters[ controller ]:
1691 if clusters[ controller ] == clusters[ 0 ]:
1692 continue
1693 else: # clusters not consistent
1694 main.log.error( "clusters from ONOS" + controllerStr +
1695 " is inconsistent with ONOS1" )
1696 consistentClustersResult = main.FALSE
1697
1698 else:
1699 main.log.error( "Error in getting dataplane clusters " +
1700 "from ONOS" + controllerStr )
1701 consistentClustersResult = main.FALSE
1702 main.log.warn( "ONOS" + controllerStr +
1703 " clusters response: " +
1704 repr( clusters[ controller ] ) )
1705 utilities.assert_equals(
1706 expect=main.TRUE,
1707 actual=consistentClustersResult,
1708 onpass="Clusters view is consistent across all ONOS nodes",
1709 onfail="ONOS nodes have different views of clusters" )
Jon Hall172b7ba2016-04-07 18:12:20 -07001710 if consistentClustersResult != main.TRUE:
1711 main.log.debug( clusters )
Jon Hall5cf14d52015-07-16 12:15:19 -07001712 # there should always only be one cluster
1713 main.step( "Cluster view correct across ONOS nodes" )
1714 try:
1715 numClusters = len( json.loads( clusters[ 0 ] ) )
1716 except ( ValueError, TypeError ):
1717 main.log.exception( "Error parsing clusters[0]: " +
1718 repr( clusters[ 0 ] ) )
Jon Hall6e709752016-02-01 13:38:46 -08001719 numClusters = "ERROR"
Jon Hall5cf14d52015-07-16 12:15:19 -07001720 clusterResults = main.FALSE
1721 if numClusters == 1:
1722 clusterResults = main.TRUE
1723 utilities.assert_equals(
1724 expect=1,
1725 actual=numClusters,
1726 onpass="ONOS shows 1 SCC",
1727 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1728
1729 main.step( "Comparing ONOS topology to MN" )
1730 devicesResults = main.TRUE
1731 linksResults = main.TRUE
1732 hostsResults = main.TRUE
1733 mnSwitches = main.Mininet1.getSwitches()
1734 mnLinks = main.Mininet1.getLinks()
1735 mnHosts = main.Mininet1.getHosts()
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001736 for controller in main.activeNodes:
1737 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001738 if devices[ controller ] and ports[ controller ] and\
1739 "Error" not in devices[ controller ] and\
1740 "Error" not in ports[ controller ]:
Jon Hall6e709752016-02-01 13:38:46 -08001741 currentDevicesResult = main.Mininet1.compareSwitches(
1742 mnSwitches,
1743 json.loads( devices[ controller ] ),
1744 json.loads( ports[ controller ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001745 else:
1746 currentDevicesResult = main.FALSE
1747 utilities.assert_equals( expect=main.TRUE,
1748 actual=currentDevicesResult,
1749 onpass="ONOS" + controllerStr +
1750 " Switches view is correct",
1751 onfail="ONOS" + controllerStr +
1752 " Switches view is incorrect" )
1753 if links[ controller ] and "Error" not in links[ controller ]:
1754 currentLinksResult = main.Mininet1.compareLinks(
1755 mnSwitches, mnLinks,
1756 json.loads( links[ controller ] ) )
1757 else:
1758 currentLinksResult = main.FALSE
1759 utilities.assert_equals( expect=main.TRUE,
1760 actual=currentLinksResult,
1761 onpass="ONOS" + controllerStr +
1762 " links view is correct",
1763 onfail="ONOS" + controllerStr +
1764 " links view is incorrect" )
1765
Jon Hall657cdf62015-12-17 14:40:51 -08001766 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001767 currentHostsResult = main.Mininet1.compareHosts(
1768 mnHosts,
1769 hosts[ controller ] )
1770 else:
1771 currentHostsResult = main.FALSE
1772 utilities.assert_equals( expect=main.TRUE,
1773 actual=currentHostsResult,
1774 onpass="ONOS" + controllerStr +
1775 " hosts exist in Mininet",
1776 onfail="ONOS" + controllerStr +
1777 " hosts don't match Mininet" )
1778
1779 devicesResults = devicesResults and currentDevicesResult
1780 linksResults = linksResults and currentLinksResult
1781 hostsResults = hostsResults and currentHostsResult
1782
1783 main.step( "Device information is correct" )
1784 utilities.assert_equals(
1785 expect=main.TRUE,
1786 actual=devicesResults,
1787 onpass="Device information is correct",
1788 onfail="Device information is incorrect" )
1789
1790 main.step( "Links are correct" )
1791 utilities.assert_equals(
1792 expect=main.TRUE,
1793 actual=linksResults,
1794 onpass="Link are correct",
1795 onfail="Links are incorrect" )
1796
1797 main.step( "Hosts are correct" )
1798 utilities.assert_equals(
1799 expect=main.TRUE,
1800 actual=hostsResults,
1801 onpass="Hosts are correct",
1802 onfail="Hosts are incorrect" )
1803
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001804 def CASE61( self, main ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001805 """
1806 The Failure case.
1807 """
Jon Halle1a3b752015-07-22 13:02:46 -07001808 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001809 assert main, "main not defined"
1810 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001811 assert main.CLIs, "main.CLIs not defined"
1812 assert main.nodes, "main.nodes not defined"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001813 main.case( "Stop minority of ONOS nodes" )
Jon Hall96091e62015-09-21 17:34:17 -07001814
1815 main.step( "Checking ONOS Logs for errors" )
1816 for node in main.nodes:
1817 main.log.debug( "Checking logs for errors on " + node.name + ":" )
1818 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
1819
Jon Hall3b489db2015-10-05 14:38:37 -07001820 n = len( main.nodes ) # Number of nodes
1821 p = ( ( n + 1 ) / 2 ) + 1 # Number of partitions
1822 main.kill = [ 0 ] # ONOS node to kill, listed by index in main.nodes
1823 if n > 3:
1824 main.kill.append( p - 1 )
1825 # NOTE: This only works for cluster sizes of 3,5, or 7.
1826
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001827 main.step( "Stopping " + str( len( main.kill ) ) + " ONOS nodes" )
Jon Hall3b489db2015-10-05 14:38:37 -07001828 killResults = main.TRUE
1829 for i in main.kill:
1830 killResults = killResults and\
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001831 main.ONOSbench.onosStop( main.nodes[i].ip_address )
1832 main.activeNodes.remove( i )
Jon Hall5cf14d52015-07-16 12:15:19 -07001833 utilities.assert_equals( expect=main.TRUE, actual=killResults,
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001834 onpass="ONOS nodes stopped successfully",
1835 onfail="ONOS nodes NOT successfully stopped" )
1836
1837 def CASE62( self, main ):
1838 """
1839 The bring up stopped nodes
1840 """
1841 import time
1842 assert main.numCtrls, "main.numCtrls not defined"
1843 assert main, "main not defined"
1844 assert utilities.assert_equals, "utilities.assert_equals not defined"
1845 assert main.CLIs, "main.CLIs not defined"
1846 assert main.nodes, "main.nodes not defined"
1847 assert main.kill, "main.kill not defined"
1848 main.case( "Restart minority of ONOS nodes" )
1849
1850 main.step( "Restarting " + str( len( main.kill ) ) + " ONOS nodes" )
1851 startResults = main.TRUE
1852 restartTime = time.time()
1853 for i in main.kill:
1854 startResults = startResults and\
1855 main.ONOSbench.onosStart( main.nodes[i].ip_address )
1856 utilities.assert_equals( expect=main.TRUE, actual=startResults,
1857 onpass="ONOS nodes started successfully",
1858 onfail="ONOS nodes NOT successfully started" )
Jon Hall5cf14d52015-07-16 12:15:19 -07001859
1860 main.step( "Checking if ONOS is up yet" )
1861 count = 0
1862 onosIsupResult = main.FALSE
1863 while onosIsupResult == main.FALSE and count < 10:
Jon Hall3b489db2015-10-05 14:38:37 -07001864 onosIsupResult = main.TRUE
1865 for i in main.kill:
1866 onosIsupResult = onosIsupResult and\
1867 main.ONOSbench.isup( main.nodes[i].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -07001868 count = count + 1
Jon Hall5cf14d52015-07-16 12:15:19 -07001869 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1870 onpass="ONOS restarted successfully",
1871 onfail="ONOS restart NOT successful" )
1872
Jon Halle1a3b752015-07-22 13:02:46 -07001873 main.step( "Restarting ONOS main.CLIs" )
Jon Hall3b489db2015-10-05 14:38:37 -07001874 cliResults = main.TRUE
1875 for i in main.kill:
1876 cliResults = cliResults and\
1877 main.CLIs[i].startOnosCli( main.nodes[i].ip_address )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001878 main.activeNodes.append( i )
Jon Hall5cf14d52015-07-16 12:15:19 -07001879 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1880 onpass="ONOS cli restarted",
1881 onfail="ONOS cli did not restart" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001882 main.activeNodes.sort()
1883 try:
1884 assert list( set( main.activeNodes ) ) == main.activeNodes,\
1885 "List of active nodes has duplicates, this likely indicates something was run out of order"
1886 except AssertionError:
1887 main.log.exception( "" )
1888 main.cleanup()
1889 main.exit()
Jon Hall5cf14d52015-07-16 12:15:19 -07001890
1891 # Grab the time of restart so we chan check how long the gossip
1892 # protocol has had time to work
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001893 main.restartTime = time.time() - restartTime
Jon Hall5cf14d52015-07-16 12:15:19 -07001894 main.log.debug( "Restart time: " + str( main.restartTime ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001895 # TODO: MAke this configurable. Also, we are breaking the above timer
1896 time.sleep( 60 )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001897 node = main.activeNodes[0]
1898 main.log.debug( main.CLIs[node].nodes( jsonFormat=False ) )
1899 main.log.debug( main.CLIs[node].leaders( jsonFormat=False ) )
1900 main.log.debug( main.CLIs[node].partitions( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001901
Jon Halla440e872016-03-31 15:15:50 -07001902 main.step( "Rerun for election on the node(s) that were killed" )
1903 runResults = main.TRUE
1904 for i in main.kill:
1905 runResults = runResults and\
1906 main.CLIs[i].electionTestRun()
1907 utilities.assert_equals( expect=main.TRUE, actual=runResults,
1908 onpass="ONOS nodes reran for election topic",
1909 onfail="Errror rerunning for election" )
1910
Jon Hall5cf14d52015-07-16 12:15:19 -07001911 def CASE7( self, main ):
1912 """
1913 Check state after ONOS failure
1914 """
1915 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001916 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001917 assert main, "main not defined"
1918 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001919 assert main.CLIs, "main.CLIs not defined"
1920 assert main.nodes, "main.nodes not defined"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001921 try:
1922 main.kill
1923 except AttributeError:
1924 main.kill = []
1925
Jon Hall5cf14d52015-07-16 12:15:19 -07001926 main.case( "Running ONOS Constant State Tests" )
1927
1928 main.step( "Check that each switch has a master" )
1929 # Assert that each device has a master
1930 rolesNotNull = main.TRUE
1931 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001932 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001933 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001934 name="rolesNotNull-" + str( i ),
1935 args=[ ] )
1936 threads.append( t )
1937 t.start()
1938
1939 for t in threads:
1940 t.join()
1941 rolesNotNull = rolesNotNull and t.result
1942 utilities.assert_equals(
1943 expect=main.TRUE,
1944 actual=rolesNotNull,
1945 onpass="Each device has a master",
1946 onfail="Some devices don't have a master assigned" )
1947
1948 main.step( "Read device roles from ONOS" )
1949 ONOSMastership = []
Jon Halla440e872016-03-31 15:15:50 -07001950 mastershipCheck = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07001951 consistentMastership = True
1952 rolesResults = True
1953 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001954 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001955 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001956 name="roles-" + str( i ),
1957 args=[] )
1958 threads.append( t )
1959 t.start()
1960
1961 for t in threads:
1962 t.join()
1963 ONOSMastership.append( t.result )
1964
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001965 for i in range( len( ONOSMastership ) ):
1966 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001967 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001968 main.log.error( "Error in getting ONOS" + node + " roles" )
1969 main.log.warn( "ONOS" + node + " mastership response: " +
1970 repr( ONOSMastership[i] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001971 rolesResults = False
1972 utilities.assert_equals(
1973 expect=True,
1974 actual=rolesResults,
1975 onpass="No error in reading roles output",
1976 onfail="Error in reading roles from ONOS" )
1977
1978 main.step( "Check for consistency in roles from each controller" )
1979 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1980 main.log.info(
1981 "Switch roles are consistent across all ONOS nodes" )
1982 else:
1983 consistentMastership = False
1984 utilities.assert_equals(
1985 expect=True,
1986 actual=consistentMastership,
1987 onpass="Switch roles are consistent across all ONOS nodes",
1988 onfail="ONOS nodes have different views of switch roles" )
1989
1990 if rolesResults and not consistentMastership:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001991 for i in range( len( ONOSMastership ) ):
1992 node = str( main.activeNodes[i] + 1 )
1993 main.log.warn( "ONOS" + node + " roles: ",
1994 json.dumps( json.loads( ONOSMastership[ i ] ),
1995 sort_keys=True,
1996 indent=4,
1997 separators=( ',', ': ' ) ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001998
1999 # NOTE: we expect mastership to change on controller failure
Jon Hall5cf14d52015-07-16 12:15:19 -07002000
2001 main.step( "Get the intents and compare across all nodes" )
2002 ONOSIntents = []
2003 intentCheck = main.FALSE
2004 consistentIntents = True
2005 intentsResults = True
2006 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002007 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002008 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07002009 name="intents-" + str( i ),
2010 args=[],
2011 kwargs={ 'jsonFormat': True } )
2012 threads.append( t )
2013 t.start()
2014
2015 for t in threads:
2016 t.join()
2017 ONOSIntents.append( t.result )
2018
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002019 for i in range( len( ONOSIntents) ):
2020 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002021 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002022 main.log.error( "Error in getting ONOS" + node + " intents" )
2023 main.log.warn( "ONOS" + node + " intents response: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07002024 repr( ONOSIntents[ i ] ) )
2025 intentsResults = False
2026 utilities.assert_equals(
2027 expect=True,
2028 actual=intentsResults,
2029 onpass="No error in reading intents output",
2030 onfail="Error in reading intents from ONOS" )
2031
2032 main.step( "Check for consistency in Intents from each controller" )
2033 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
2034 main.log.info( "Intents are consistent across all ONOS " +
2035 "nodes" )
2036 else:
2037 consistentIntents = False
2038
2039 # Try to make it easy to figure out what is happening
2040 #
2041 # Intent ONOS1 ONOS2 ...
2042 # 0x01 INSTALLED INSTALLING
2043 # ... ... ...
2044 # ... ... ...
2045 title = " ID"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002046 for n in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07002047 title += " " * 10 + "ONOS" + str( n + 1 )
2048 main.log.warn( title )
2049 # get all intent keys in the cluster
2050 keys = []
2051 for nodeStr in ONOSIntents:
2052 node = json.loads( nodeStr )
2053 for intent in node:
2054 keys.append( intent.get( 'id' ) )
2055 keys = set( keys )
2056 for key in keys:
2057 row = "%-13s" % key
2058 for nodeStr in ONOSIntents:
2059 node = json.loads( nodeStr )
2060 for intent in node:
2061 if intent.get( 'id' ) == key:
2062 row += "%-15s" % intent.get( 'state' )
2063 main.log.warn( row )
2064 # End table view
2065
2066 utilities.assert_equals(
2067 expect=True,
2068 actual=consistentIntents,
2069 onpass="Intents are consistent across all ONOS nodes",
2070 onfail="ONOS nodes have different views of intents" )
2071 intentStates = []
2072 for node in ONOSIntents: # Iter through ONOS nodes
2073 nodeStates = []
2074 # Iter through intents of a node
2075 try:
2076 for intent in json.loads( node ):
2077 nodeStates.append( intent[ 'state' ] )
2078 except ( ValueError, TypeError ):
2079 main.log.exception( "Error in parsing intents" )
2080 main.log.error( repr( node ) )
2081 intentStates.append( nodeStates )
2082 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
2083 main.log.info( dict( out ) )
2084
2085 if intentsResults and not consistentIntents:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002086 for i in range( len( main.activeNodes ) ):
2087 node = str( main.activeNodes[i] + 1 )
2088 main.log.warn( "ONOS" + node + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07002089 main.log.warn( json.dumps(
2090 json.loads( ONOSIntents[ i ] ),
2091 sort_keys=True,
2092 indent=4,
2093 separators=( ',', ': ' ) ) )
2094 elif intentsResults and consistentIntents:
2095 intentCheck = main.TRUE
2096
2097 # NOTE: Store has no durability, so intents are lost across system
2098 # restarts
2099 main.step( "Compare current intents with intents before the failure" )
2100 # NOTE: this requires case 5 to pass for intentState to be set.
2101 # maybe we should stop the test if that fails?
2102 sameIntents = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002103 try:
2104 intentState
2105 except NameError:
2106 main.log.warn( "No previous intent state was saved" )
2107 else:
2108 if intentState and intentState == ONOSIntents[ 0 ]:
2109 sameIntents = main.TRUE
2110 main.log.info( "Intents are consistent with before failure" )
2111 # TODO: possibly the states have changed? we may need to figure out
2112 # what the acceptable states are
2113 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
2114 sameIntents = main.TRUE
2115 try:
2116 before = json.loads( intentState )
2117 after = json.loads( ONOSIntents[ 0 ] )
2118 for intent in before:
2119 if intent not in after:
2120 sameIntents = main.FALSE
2121 main.log.debug( "Intent is not currently in ONOS " +
2122 "(at least in the same form):" )
2123 main.log.debug( json.dumps( intent ) )
2124 except ( ValueError, TypeError ):
2125 main.log.exception( "Exception printing intents" )
2126 main.log.debug( repr( ONOSIntents[0] ) )
2127 main.log.debug( repr( intentState ) )
2128 if sameIntents == main.FALSE:
2129 try:
2130 main.log.debug( "ONOS intents before: " )
2131 main.log.debug( json.dumps( json.loads( intentState ),
2132 sort_keys=True, indent=4,
2133 separators=( ',', ': ' ) ) )
2134 main.log.debug( "Current ONOS intents: " )
2135 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
2136 sort_keys=True, indent=4,
2137 separators=( ',', ': ' ) ) )
2138 except ( ValueError, TypeError ):
2139 main.log.exception( "Exception printing intents" )
2140 main.log.debug( repr( ONOSIntents[0] ) )
2141 main.log.debug( repr( intentState ) )
2142 utilities.assert_equals(
2143 expect=main.TRUE,
2144 actual=sameIntents,
2145 onpass="Intents are consistent with before failure",
2146 onfail="The Intents changed during failure" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002147 intentCheck = intentCheck and sameIntents
2148
2149 main.step( "Get the OF Table entries and compare to before " +
2150 "component failure" )
2151 FlowTables = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002152 for i in range( 28 ):
2153 main.log.info( "Checking flow table on s" + str( i + 1 ) )
GlennRC68467eb2015-11-16 18:01:01 -08002154 tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
2155 FlowTables = FlowTables and main.Mininet1.flowTableComp( flows[i], tmpFlows )
Jon Hall5cf14d52015-07-16 12:15:19 -07002156 if FlowTables == main.FALSE:
GlennRC68467eb2015-11-16 18:01:01 -08002157 main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002158 utilities.assert_equals(
2159 expect=main.TRUE,
2160 actual=FlowTables,
2161 onpass="No changes were found in the flow tables",
2162 onfail="Changes were found in the flow tables" )
2163
2164 main.Mininet2.pingLongKill()
2165 '''
2166 main.step( "Check the continuous pings to ensure that no packets " +
2167 "were dropped during component failure" )
2168 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
2169 main.params[ 'TESTONIP' ] )
2170 LossInPings = main.FALSE
2171 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
2172 for i in range( 8, 18 ):
2173 main.log.info(
2174 "Checking for a loss in pings along flow from s" +
2175 str( i ) )
2176 LossInPings = main.Mininet2.checkForLoss(
2177 "/tmp/ping.h" +
2178 str( i ) ) or LossInPings
2179 if LossInPings == main.TRUE:
2180 main.log.info( "Loss in ping detected" )
2181 elif LossInPings == main.ERROR:
2182 main.log.info( "There are multiple mininet process running" )
2183 elif LossInPings == main.FALSE:
2184 main.log.info( "No Loss in the pings" )
2185 main.log.info( "No loss of dataplane connectivity" )
2186 utilities.assert_equals(
2187 expect=main.FALSE,
2188 actual=LossInPings,
2189 onpass="No Loss of connectivity",
2190 onfail="Loss of dataplane connectivity detected" )
2191 '''
2192
2193 main.step( "Leadership Election is still functional" )
2194 # Test of LeadershipElection
2195 leaderList = []
Jon Hall5cf14d52015-07-16 12:15:19 -07002196
Jon Hall3b489db2015-10-05 14:38:37 -07002197 restarted = []
2198 for i in main.kill:
2199 restarted.append( main.nodes[i].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -07002200 leaderResult = main.TRUE
Jon Hall3b489db2015-10-05 14:38:37 -07002201
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002202 for i in main.activeNodes:
2203 cli = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07002204 leaderN = cli.electionTestLeader()
2205 leaderList.append( leaderN )
2206 if leaderN == main.FALSE:
2207 # error in response
2208 main.log.error( "Something is wrong with " +
2209 "electionTestLeader function, check the" +
2210 " error logs" )
2211 leaderResult = main.FALSE
2212 elif leaderN is None:
2213 main.log.error( cli.name +
2214 " shows no leader for the election-app was" +
2215 " elected after the old one died" )
2216 leaderResult = main.FALSE
2217 elif leaderN in restarted:
2218 main.log.error( cli.name + " shows " + str( leaderN ) +
2219 " as leader for the election-app, but it " +
2220 "was restarted" )
2221 leaderResult = main.FALSE
2222 if len( set( leaderList ) ) != 1:
2223 leaderResult = main.FALSE
2224 main.log.error(
2225 "Inconsistent view of leader for the election test app" )
2226 # TODO: print the list
2227 utilities.assert_equals(
2228 expect=main.TRUE,
2229 actual=leaderResult,
2230 onpass="Leadership election passed",
2231 onfail="Something went wrong with Leadership election" )
2232
2233 def CASE8( self, main ):
2234 """
2235 Compare topo
2236 """
2237 import json
2238 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002239 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002240 assert main, "main not defined"
2241 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002242 assert main.CLIs, "main.CLIs not defined"
2243 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002244
2245 main.case( "Compare ONOS Topology view to Mininet topology" )
Jon Hall783bbf92015-07-23 14:33:19 -07002246 main.caseExplanation = "Compare topology objects between Mininet" +\
Jon Hall5cf14d52015-07-16 12:15:19 -07002247 " and ONOS"
Jon Hall5cf14d52015-07-16 12:15:19 -07002248 topoResult = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08002249 topoFailMsg = "ONOS topology don't match Mininet"
Jon Hall5cf14d52015-07-16 12:15:19 -07002250 elapsed = 0
2251 count = 0
Jon Halle9b1fa32015-12-08 15:32:21 -08002252 main.step( "Comparing ONOS topology to MN topology" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002253 startTime = time.time()
2254 # Give time for Gossip to work
Jon Halle9b1fa32015-12-08 15:32:21 -08002255 while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
Jon Hall96091e62015-09-21 17:34:17 -07002256 devicesResults = main.TRUE
2257 linksResults = main.TRUE
2258 hostsResults = main.TRUE
2259 hostAttachmentResults = True
Jon Hall5cf14d52015-07-16 12:15:19 -07002260 count += 1
2261 cliStart = time.time()
2262 devices = []
2263 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002264 for i in main.activeNodes:
Jon Hall6e709752016-02-01 13:38:46 -08002265 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002266 name="devices-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08002267 args=[ main.CLIs[i].devices, [ None ] ],
2268 kwargs= { 'sleep': 5, 'attempts': 5,
2269 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002270 threads.append( t )
2271 t.start()
2272
2273 for t in threads:
2274 t.join()
2275 devices.append( t.result )
2276 hosts = []
2277 ipResult = main.TRUE
2278 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002279 for i in main.activeNodes:
Jon Halld8f6de82015-12-17 17:04:34 -08002280 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002281 name="hosts-" + str( i ),
Jon Halld8f6de82015-12-17 17:04:34 -08002282 args=[ main.CLIs[i].hosts, [ None ] ],
2283 kwargs= { 'sleep': 5, 'attempts': 5,
2284 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002285 threads.append( t )
2286 t.start()
2287
2288 for t in threads:
2289 t.join()
2290 try:
2291 hosts.append( json.loads( t.result ) )
2292 except ( ValueError, TypeError ):
2293 main.log.exception( "Error parsing hosts results" )
2294 main.log.error( repr( t.result ) )
Jon Hallf3d16e72015-12-16 17:45:08 -08002295 hosts.append( None )
Jon Hall5cf14d52015-07-16 12:15:19 -07002296 for controller in range( 0, len( hosts ) ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002297 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hallacd1b182015-12-17 11:43:20 -08002298 if hosts[ controller ]:
2299 for host in hosts[ controller ]:
2300 if host is None or host.get( 'ipAddresses', [] ) == []:
2301 main.log.error(
2302 "Error with host ipAddresses on controller" +
2303 controllerStr + ": " + str( host ) )
2304 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002305 ports = []
2306 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002307 for i in main.activeNodes:
Jon Hall6e709752016-02-01 13:38:46 -08002308 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002309 name="ports-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08002310 args=[ main.CLIs[i].ports, [ None ] ],
2311 kwargs= { 'sleep': 5, 'attempts': 5,
2312 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002313 threads.append( t )
2314 t.start()
2315
2316 for t in threads:
2317 t.join()
2318 ports.append( t.result )
2319 links = []
2320 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002321 for i in main.activeNodes:
Jon Hall6e709752016-02-01 13:38:46 -08002322 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002323 name="links-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08002324 args=[ main.CLIs[i].links, [ None ] ],
2325 kwargs= { 'sleep': 5, 'attempts': 5,
2326 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002327 threads.append( t )
2328 t.start()
2329
2330 for t in threads:
2331 t.join()
2332 links.append( t.result )
2333 clusters = []
2334 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002335 for i in main.activeNodes:
Jon Hall6e709752016-02-01 13:38:46 -08002336 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002337 name="clusters-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08002338 args=[ main.CLIs[i].clusters, [ None ] ],
2339 kwargs= { 'sleep': 5, 'attempts': 5,
2340 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002341 threads.append( t )
2342 t.start()
2343
2344 for t in threads:
2345 t.join()
2346 clusters.append( t.result )
2347
2348 elapsed = time.time() - startTime
2349 cliTime = time.time() - cliStart
2350 print "Elapsed time: " + str( elapsed )
2351 print "CLI time: " + str( cliTime )
2352
Jon Hall6e709752016-02-01 13:38:46 -08002353 if all( e is None for e in devices ) and\
2354 all( e is None for e in hosts ) and\
2355 all( e is None for e in ports ) and\
2356 all( e is None for e in links ) and\
2357 all( e is None for e in clusters ):
2358 topoFailMsg = "Could not get topology from ONOS"
2359 main.log.error( topoFailMsg )
2360 continue # Try again, No use trying to compare
2361
Jon Hall5cf14d52015-07-16 12:15:19 -07002362 mnSwitches = main.Mininet1.getSwitches()
2363 mnLinks = main.Mininet1.getLinks()
2364 mnHosts = main.Mininet1.getHosts()
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002365 for controller in range( len( main.activeNodes ) ):
2366 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002367 if devices[ controller ] and ports[ controller ] and\
2368 "Error" not in devices[ controller ] and\
2369 "Error" not in ports[ controller ]:
2370
Jon Hallc6793552016-01-19 14:18:37 -08002371 try:
2372 currentDevicesResult = main.Mininet1.compareSwitches(
2373 mnSwitches,
2374 json.loads( devices[ controller ] ),
2375 json.loads( ports[ controller ] ) )
2376 except ( TypeError, ValueError ) as e:
2377 main.log.exception( "Object not as expected; devices={!r}\nports={!r}".format(
2378 devices[ controller ], ports[ controller ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002379 else:
2380 currentDevicesResult = main.FALSE
2381 utilities.assert_equals( expect=main.TRUE,
2382 actual=currentDevicesResult,
2383 onpass="ONOS" + controllerStr +
2384 " Switches view is correct",
2385 onfail="ONOS" + controllerStr +
2386 " Switches view is incorrect" )
2387
2388 if links[ controller ] and "Error" not in links[ controller ]:
2389 currentLinksResult = main.Mininet1.compareLinks(
2390 mnSwitches, mnLinks,
2391 json.loads( links[ controller ] ) )
2392 else:
2393 currentLinksResult = main.FALSE
2394 utilities.assert_equals( expect=main.TRUE,
2395 actual=currentLinksResult,
2396 onpass="ONOS" + controllerStr +
2397 " links view is correct",
2398 onfail="ONOS" + controllerStr +
2399 " links view is incorrect" )
Jon Hall657cdf62015-12-17 14:40:51 -08002400 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002401 currentHostsResult = main.Mininet1.compareHosts(
2402 mnHosts,
2403 hosts[ controller ] )
Jon Hall13b446e2016-01-05 12:17:01 -08002404 elif hosts[ controller ] == []:
2405 currentHostsResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002406 else:
2407 currentHostsResult = main.FALSE
2408 utilities.assert_equals( expect=main.TRUE,
2409 actual=currentHostsResult,
2410 onpass="ONOS" + controllerStr +
2411 " hosts exist in Mininet",
2412 onfail="ONOS" + controllerStr +
2413 " hosts don't match Mininet" )
2414 # CHECKING HOST ATTACHMENT POINTS
2415 hostAttachment = True
2416 zeroHosts = False
2417 # FIXME: topo-HA/obelisk specific mappings:
2418 # key is mac and value is dpid
2419 mappings = {}
2420 for i in range( 1, 29 ): # hosts 1 through 28
2421 # set up correct variables:
2422 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2423 if i == 1:
2424 deviceId = "1000".zfill(16)
2425 elif i == 2:
2426 deviceId = "2000".zfill(16)
2427 elif i == 3:
2428 deviceId = "3000".zfill(16)
2429 elif i == 4:
2430 deviceId = "3004".zfill(16)
2431 elif i == 5:
2432 deviceId = "5000".zfill(16)
2433 elif i == 6:
2434 deviceId = "6000".zfill(16)
2435 elif i == 7:
2436 deviceId = "6007".zfill(16)
2437 elif i >= 8 and i <= 17:
2438 dpid = '3' + str( i ).zfill( 3 )
2439 deviceId = dpid.zfill(16)
2440 elif i >= 18 and i <= 27:
2441 dpid = '6' + str( i ).zfill( 3 )
2442 deviceId = dpid.zfill(16)
2443 elif i == 28:
2444 deviceId = "2800".zfill(16)
2445 mappings[ macId ] = deviceId
Jon Halld8f6de82015-12-17 17:04:34 -08002446 if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002447 if hosts[ controller ] == []:
2448 main.log.warn( "There are no hosts discovered" )
2449 zeroHosts = True
2450 else:
2451 for host in hosts[ controller ]:
2452 mac = None
2453 location = None
2454 device = None
2455 port = None
2456 try:
2457 mac = host.get( 'mac' )
2458 assert mac, "mac field could not be found for this host object"
2459
2460 location = host.get( 'location' )
2461 assert location, "location field could not be found for this host object"
2462
2463 # Trim the protocol identifier off deviceId
2464 device = str( location.get( 'elementId' ) ).split(':')[1]
2465 assert device, "elementId field could not be found for this host location object"
2466
2467 port = location.get( 'port' )
2468 assert port, "port field could not be found for this host location object"
2469
2470 # Now check if this matches where they should be
2471 if mac and device and port:
2472 if str( port ) != "1":
2473 main.log.error( "The attachment port is incorrect for " +
2474 "host " + str( mac ) +
2475 ". Expected: 1 Actual: " + str( port) )
2476 hostAttachment = False
2477 if device != mappings[ str( mac ) ]:
2478 main.log.error( "The attachment device is incorrect for " +
2479 "host " + str( mac ) +
2480 ". Expected: " + mappings[ str( mac ) ] +
2481 " Actual: " + device )
2482 hostAttachment = False
2483 else:
2484 hostAttachment = False
2485 except AssertionError:
2486 main.log.exception( "Json object not as expected" )
2487 main.log.error( repr( host ) )
2488 hostAttachment = False
2489 else:
2490 main.log.error( "No hosts json output or \"Error\"" +
2491 " in output. hosts = " +
2492 repr( hosts[ controller ] ) )
2493 if zeroHosts is False:
2494 hostAttachment = True
2495
2496 # END CHECKING HOST ATTACHMENT POINTS
2497 devicesResults = devicesResults and currentDevicesResult
2498 linksResults = linksResults and currentLinksResult
2499 hostsResults = hostsResults and currentHostsResult
2500 hostAttachmentResults = hostAttachmentResults and\
2501 hostAttachment
Jon Halla440e872016-03-31 15:15:50 -07002502 topoResult = ( devicesResults and linksResults
2503 and hostsResults and ipResult and
2504 hostAttachmentResults )
Jon Halle9b1fa32015-12-08 15:32:21 -08002505 utilities.assert_equals( expect=True,
2506 actual=topoResult,
2507 onpass="ONOS topology matches Mininet",
Jon Hall6e709752016-02-01 13:38:46 -08002508 onfail=topoFailMsg )
Jon Halle9b1fa32015-12-08 15:32:21 -08002509 # End of While loop to pull ONOS state
Jon Hall5cf14d52015-07-16 12:15:19 -07002510
2511 # Compare json objects for hosts and dataplane clusters
2512
2513 # hosts
2514 main.step( "Hosts view is consistent across all ONOS nodes" )
2515 consistentHostsResult = main.TRUE
2516 for controller in range( len( hosts ) ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002517 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall13b446e2016-01-05 12:17:01 -08002518 if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002519 if hosts[ controller ] == hosts[ 0 ]:
2520 continue
2521 else: # hosts not consistent
2522 main.log.error( "hosts from ONOS" + controllerStr +
2523 " is inconsistent with ONOS1" )
2524 main.log.warn( repr( hosts[ controller ] ) )
2525 consistentHostsResult = main.FALSE
2526
2527 else:
2528 main.log.error( "Error in getting ONOS hosts from ONOS" +
2529 controllerStr )
2530 consistentHostsResult = main.FALSE
2531 main.log.warn( "ONOS" + controllerStr +
2532 " hosts response: " +
2533 repr( hosts[ controller ] ) )
2534 utilities.assert_equals(
2535 expect=main.TRUE,
2536 actual=consistentHostsResult,
2537 onpass="Hosts view is consistent across all ONOS nodes",
2538 onfail="ONOS nodes have different views of hosts" )
2539
2540 main.step( "Hosts information is correct" )
2541 hostsResults = hostsResults and ipResult
2542 utilities.assert_equals(
2543 expect=main.TRUE,
2544 actual=hostsResults,
2545 onpass="Host information is correct",
2546 onfail="Host information is incorrect" )
2547
2548 main.step( "Host attachment points to the network" )
2549 utilities.assert_equals(
2550 expect=True,
2551 actual=hostAttachmentResults,
2552 onpass="Hosts are correctly attached to the network",
2553 onfail="ONOS did not correctly attach hosts to the network" )
2554
2555 # Strongly connected clusters of devices
2556 main.step( "Clusters view is consistent across all ONOS nodes" )
2557 consistentClustersResult = main.TRUE
2558 for controller in range( len( clusters ) ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002559 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002560 if "Error" not in clusters[ controller ]:
2561 if clusters[ controller ] == clusters[ 0 ]:
2562 continue
2563 else: # clusters not consistent
2564 main.log.error( "clusters from ONOS" +
2565 controllerStr +
2566 " is inconsistent with ONOS1" )
2567 consistentClustersResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002568 else:
2569 main.log.error( "Error in getting dataplane clusters " +
2570 "from ONOS" + controllerStr )
2571 consistentClustersResult = main.FALSE
2572 main.log.warn( "ONOS" + controllerStr +
2573 " clusters response: " +
2574 repr( clusters[ controller ] ) )
2575 utilities.assert_equals(
2576 expect=main.TRUE,
2577 actual=consistentClustersResult,
2578 onpass="Clusters view is consistent across all ONOS nodes",
2579 onfail="ONOS nodes have different views of clusters" )
2580
2581 main.step( "There is only one SCC" )
2582 # there should always only be one cluster
2583 try:
2584 numClusters = len( json.loads( clusters[ 0 ] ) )
2585 except ( ValueError, TypeError ):
2586 main.log.exception( "Error parsing clusters[0]: " +
2587 repr( clusters[0] ) )
Jon Halla440e872016-03-31 15:15:50 -07002588 numClusters = "ERROR"
Jon Hall5cf14d52015-07-16 12:15:19 -07002589 clusterResults = main.FALSE
2590 if numClusters == 1:
2591 clusterResults = main.TRUE
2592 utilities.assert_equals(
2593 expect=1,
2594 actual=numClusters,
2595 onpass="ONOS shows 1 SCC",
2596 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2597
2598 topoResult = ( devicesResults and linksResults
2599 and hostsResults and consistentHostsResult
2600 and consistentClustersResult and clusterResults
2601 and ipResult and hostAttachmentResults )
2602
2603 topoResult = topoResult and int( count <= 2 )
2604 note = "note it takes about " + str( int( cliTime ) ) + \
2605 " seconds for the test to make all the cli calls to fetch " +\
2606 "the topology from each ONOS instance"
2607 main.log.info(
2608 "Very crass estimate for topology discovery/convergence( " +
2609 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2610 str( count ) + " tries" )
2611
2612 main.step( "Device information is correct" )
2613 utilities.assert_equals(
2614 expect=main.TRUE,
2615 actual=devicesResults,
2616 onpass="Device information is correct",
2617 onfail="Device information is incorrect" )
2618
2619 main.step( "Links are correct" )
2620 utilities.assert_equals(
2621 expect=main.TRUE,
2622 actual=linksResults,
2623 onpass="Link are correct",
2624 onfail="Links are incorrect" )
2625
Jon Halla440e872016-03-31 15:15:50 -07002626 main.step( "Hosts are correct" )
2627 utilities.assert_equals(
2628 expect=main.TRUE,
2629 actual=hostsResults,
2630 onpass="Hosts are correct",
2631 onfail="Hosts are incorrect" )
2632
Jon Hall5cf14d52015-07-16 12:15:19 -07002633 # FIXME: move this to an ONOS state case
2634 main.step( "Checking ONOS nodes" )
2635 nodesOutput = []
2636 nodeResults = main.TRUE
2637 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002638 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002639 t = main.Thread( target=main.CLIs[i].nodes,
Jon Hall5cf14d52015-07-16 12:15:19 -07002640 name="nodes-" + str( i ),
2641 args=[ ] )
2642 threads.append( t )
2643 t.start()
2644
2645 for t in threads:
2646 t.join()
2647 nodesOutput.append( t.result )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002648 ips = [ main.nodes[node].ip_address for node in main.activeNodes ]
Jon Halle9b1fa32015-12-08 15:32:21 -08002649 ips.sort()
Jon Hall5cf14d52015-07-16 12:15:19 -07002650 for i in nodesOutput:
2651 try:
2652 current = json.loads( i )
Jon Halle9b1fa32015-12-08 15:32:21 -08002653 activeIps = []
2654 currentResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002655 for node in current:
Jon Hallbd182782016-03-28 16:42:22 -07002656 if node['state'] == 'READY':
Jon Halle9b1fa32015-12-08 15:32:21 -08002657 activeIps.append( node['ip'] )
2658 activeIps.sort()
2659 if ips == activeIps:
2660 currentResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002661 except ( ValueError, TypeError ):
2662 main.log.error( "Error parsing nodes output" )
2663 main.log.warn( repr( i ) )
Jon Halle9b1fa32015-12-08 15:32:21 -08002664 currentResult = main.FALSE
2665 nodeResults = nodeResults and currentResult
Jon Hall5cf14d52015-07-16 12:15:19 -07002666 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2667 onpass="Nodes check successful",
2668 onfail="Nodes check NOT successful" )
Jon Halla440e872016-03-31 15:15:50 -07002669 if not nodeResults:
2670 for cli in main.CLIs:
2671 main.log.debug( "{} components not ACTIVE: \n{}".format(
2672 cli.name,
2673 cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002674
2675 def CASE9( self, main ):
2676 """
2677 Link s3-s28 down
2678 """
2679 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002680 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002681 assert main, "main not defined"
2682 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002683 assert main.CLIs, "main.CLIs not defined"
2684 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002685 # NOTE: You should probably run a topology check after this
2686
2687 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2688
2689 description = "Turn off a link to ensure that Link Discovery " +\
2690 "is working properly"
2691 main.case( description )
2692
2693 main.step( "Kill Link between s3 and s28" )
2694 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
2695 main.log.info( "Waiting " + str( linkSleep ) +
2696 " seconds for link down to be discovered" )
2697 time.sleep( linkSleep )
2698 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
2699 onpass="Link down successful",
2700 onfail="Failed to bring link down" )
2701 # TODO do some sort of check here
2702
2703 def CASE10( self, main ):
2704 """
2705 Link s3-s28 up
2706 """
2707 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002708 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002709 assert main, "main not defined"
2710 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002711 assert main.CLIs, "main.CLIs not defined"
2712 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002713 # NOTE: You should probably run a topology check after this
2714
2715 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2716
2717 description = "Restore a link to ensure that Link Discovery is " + \
2718 "working properly"
2719 main.case( description )
2720
2721 main.step( "Bring link between s3 and s28 back up" )
2722 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
2723 main.log.info( "Waiting " + str( linkSleep ) +
2724 " seconds for link up to be discovered" )
2725 time.sleep( linkSleep )
2726 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
2727 onpass="Link up successful",
2728 onfail="Failed to bring link up" )
2729 # TODO do some sort of check here
2730
2731 def CASE11( self, main ):
2732 """
2733 Switch Down
2734 """
2735 # NOTE: You should probably run a topology check after this
2736 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002737 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002738 assert main, "main not defined"
2739 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002740 assert main.CLIs, "main.CLIs not defined"
2741 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002742
2743 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2744
2745 description = "Killing a switch to ensure it is discovered correctly"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002746 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002747 main.case( description )
2748 switch = main.params[ 'kill' ][ 'switch' ]
2749 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2750
2751 # TODO: Make this switch parameterizable
2752 main.step( "Kill " + switch )
2753 main.log.info( "Deleting " + switch )
2754 main.Mininet1.delSwitch( switch )
2755 main.log.info( "Waiting " + str( switchSleep ) +
2756 " seconds for switch down to be discovered" )
2757 time.sleep( switchSleep )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002758 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall5cf14d52015-07-16 12:15:19 -07002759 # Peek at the deleted switch
2760 main.log.warn( str( device ) )
2761 result = main.FALSE
2762 if device and device[ 'available' ] is False:
2763 result = main.TRUE
2764 utilities.assert_equals( expect=main.TRUE, actual=result,
2765 onpass="Kill switch successful",
2766 onfail="Failed to kill switch?" )
2767
2768 def CASE12( self, main ):
2769 """
2770 Switch Up
2771 """
2772 # NOTE: You should probably run a topology check after this
2773 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002774 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002775 assert main, "main not defined"
2776 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002777 assert main.CLIs, "main.CLIs not defined"
2778 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002779 assert ONOS1Port, "ONOS1Port not defined"
2780 assert ONOS2Port, "ONOS2Port not defined"
2781 assert ONOS3Port, "ONOS3Port not defined"
2782 assert ONOS4Port, "ONOS4Port not defined"
2783 assert ONOS5Port, "ONOS5Port not defined"
2784 assert ONOS6Port, "ONOS6Port not defined"
2785 assert ONOS7Port, "ONOS7Port not defined"
2786
2787 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2788 switch = main.params[ 'kill' ][ 'switch' ]
2789 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2790 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002791 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002792 description = "Adding a switch to ensure it is discovered correctly"
2793 main.case( description )
2794
2795 main.step( "Add back " + switch )
2796 main.Mininet1.addSwitch( switch, dpid=switchDPID )
2797 for peer in links:
2798 main.Mininet1.addLink( switch, peer )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002799 ipList = [ node.ip_address for node in main.nodes ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002800 main.Mininet1.assignSwController( sw=switch, ip=ipList )
2801 main.log.info( "Waiting " + str( switchSleep ) +
2802 " seconds for switch up to be discovered" )
2803 time.sleep( switchSleep )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002804 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall5cf14d52015-07-16 12:15:19 -07002805 # Peek at the deleted switch
2806 main.log.warn( str( device ) )
2807 result = main.FALSE
2808 if device and device[ 'available' ]:
2809 result = main.TRUE
2810 utilities.assert_equals( expect=main.TRUE, actual=result,
2811 onpass="add switch successful",
2812 onfail="Failed to add switch?" )
2813
2814 def CASE13( self, main ):
2815 """
2816 Clean up
2817 """
2818 import os
2819 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002820 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002821 assert main, "main not defined"
2822 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002823 assert main.CLIs, "main.CLIs not defined"
2824 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002825
2826 # printing colors to terminal
2827 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2828 'blue': '\033[94m', 'green': '\033[92m',
2829 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
2830 main.case( "Test Cleanup" )
2831 main.step( "Killing tcpdumps" )
2832 main.Mininet2.stopTcpdump()
2833
2834 testname = main.TEST
Jon Hall96091e62015-09-21 17:34:17 -07002835 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall5cf14d52015-07-16 12:15:19 -07002836 main.step( "Copying MN pcap and ONOS log files to test station" )
2837 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
2838 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
Jon Hall96091e62015-09-21 17:34:17 -07002839 # NOTE: MN Pcap file is being saved to logdir.
2840 # We scp this file as MN and TestON aren't necessarily the same vm
2841
2842 # FIXME: To be replaced with a Jenkin's post script
Jon Hall5cf14d52015-07-16 12:15:19 -07002843 # TODO: Load these from params
2844 # NOTE: must end in /
2845 logFolder = "/opt/onos/log/"
2846 logFiles = [ "karaf.log", "karaf.log.1" ]
2847 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002848 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002849 for node in main.nodes:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002850 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002851 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2852 logFolder + f, dstName )
Jon Hall5cf14d52015-07-16 12:15:19 -07002853 # std*.log's
2854 # NOTE: must end in /
2855 logFolder = "/opt/onos/var/"
2856 logFiles = [ "stderr.log", "stdout.log" ]
2857 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002858 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002859 for node in main.nodes:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002860 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002861 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2862 logFolder + f, dstName )
2863 else:
2864 main.log.debug( "skipping saving log files" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002865
2866 main.step( "Stopping Mininet" )
2867 mnResult = main.Mininet1.stopNet()
2868 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2869 onpass="Mininet stopped",
2870 onfail="MN cleanup NOT successful" )
2871
2872 main.step( "Checking ONOS Logs for errors" )
Jon Halle1a3b752015-07-22 13:02:46 -07002873 for node in main.nodes:
Jon Hall96091e62015-09-21 17:34:17 -07002874 main.log.debug( "Checking logs for errors on " + node.name + ":" )
2875 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002876
2877 try:
2878 timerLog = open( main.logdir + "/Timers.csv", 'w')
2879 # Overwrite with empty line and close
2880 labels = "Gossip Intents, Restart"
2881 data = str( gossipTime ) + ", " + str( main.restartTime )
2882 timerLog.write( labels + "\n" + data )
2883 timerLog.close()
2884 except NameError, e:
2885 main.log.exception(e)
2886
2887 def CASE14( self, main ):
2888 """
2889 start election app on all onos nodes
2890 """
Jon Halle1a3b752015-07-22 13:02:46 -07002891 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002892 assert main, "main not defined"
2893 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002894 assert main.CLIs, "main.CLIs not defined"
2895 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002896
2897 main.case("Start Leadership Election app")
2898 main.step( "Install leadership election app" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002899 onosCli = main.CLIs[ main.activeNodes[0] ]
2900 appResult = onosCli.activateApp( "org.onosproject.election" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002901 utilities.assert_equals(
2902 expect=main.TRUE,
2903 actual=appResult,
2904 onpass="Election app installed",
2905 onfail="Something went wrong with installing Leadership election" )
2906
2907 main.step( "Run for election on each node" )
2908 leaderResult = main.TRUE
2909 leaders = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002910 for i in main.activeNodes:
2911 main.CLIs[i].electionTestRun()
2912 for i in main.activeNodes:
2913 cli = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07002914 leader = cli.electionTestLeader()
2915 if leader is None or leader == main.FALSE:
2916 main.log.error( cli.name + ": Leader for the election app " +
2917 "should be an ONOS node, instead got '" +
2918 str( leader ) + "'" )
2919 leaderResult = main.FALSE
2920 leaders.append( leader )
2921 utilities.assert_equals(
2922 expect=main.TRUE,
2923 actual=leaderResult,
2924 onpass="Successfully ran for leadership",
2925 onfail="Failed to run for leadership" )
2926
2927 main.step( "Check that each node shows the same leader" )
2928 sameLeader = main.TRUE
2929 if len( set( leaders ) ) != 1:
2930 sameLeader = main.FALSE
Jon Halle1a3b752015-07-22 13:02:46 -07002931 main.log.error( "Results of electionTestLeader is order of main.CLIs:" +
Jon Hall5cf14d52015-07-16 12:15:19 -07002932 str( leaders ) )
2933 utilities.assert_equals(
2934 expect=main.TRUE,
2935 actual=sameLeader,
2936 onpass="Leadership is consistent for the election topic",
2937 onfail="Nodes have different leaders" )
2938
2939 def CASE15( self, main ):
2940 """
2941 Check that Leadership Election is still functional
acsmars71adceb2015-08-31 15:09:26 -07002942 15.1 Run election on each node
2943 15.2 Check that each node has the same leaders and candidates
2944 15.3 Find current leader and withdraw
2945 15.4 Check that a new node was elected leader
2946 15.5 Check that that new leader was the candidate of old leader
2947 15.6 Run for election on old leader
2948 15.7 Check that oldLeader is a candidate, and leader if only 1 node
2949 15.8 Make sure that the old leader was added to the candidate list
2950
2951 old and new variable prefixes refer to data from before vs after
2952 withdrawl and later before withdrawl vs after re-election
Jon Hall5cf14d52015-07-16 12:15:19 -07002953 """
2954 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002955 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002956 assert main, "main not defined"
2957 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002958 assert main.CLIs, "main.CLIs not defined"
2959 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002960
Jon Hall5cf14d52015-07-16 12:15:19 -07002961 description = "Check that Leadership Election is still functional"
2962 main.case( description )
Jon Halla440e872016-03-31 15:15:50 -07002963 # NOTE: Need to re-run after restarts since being a canidate is not persistant
Jon Hall5cf14d52015-07-16 12:15:19 -07002964
Jon Halla440e872016-03-31 15:15:50 -07002965 oldLeaders = [] # list of lists of each nodes' candidates before
2966 newLeaders = [] # list of lists of each nodes' candidates after
acsmars71adceb2015-08-31 15:09:26 -07002967 oldLeader = '' # the old leader from oldLeaders, None if not same
2968 newLeader = '' # the new leaders fron newLoeaders, None if not same
2969 oldLeaderCLI = None # the CLI of the old leader used for re-electing
2970 expectNoLeader = False # True when there is only one leader
2971 if main.numCtrls == 1:
2972 expectNoLeader = True
2973
2974 main.step( "Run for election on each node" )
2975 electionResult = main.TRUE
2976
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002977 for i in main.activeNodes: # run test election on each node
2978 if main.CLIs[i].electionTestRun() == main.FALSE:
acsmars71adceb2015-08-31 15:09:26 -07002979 electionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002980 utilities.assert_equals(
2981 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002982 actual=electionResult,
2983 onpass="All nodes successfully ran for leadership",
2984 onfail="At least one node failed to run for leadership" )
2985
acsmars3a72bde2015-09-02 14:16:22 -07002986 if electionResult == main.FALSE:
2987 main.log.error(
2988 "Skipping Test Case because Election Test App isn't loaded" )
2989 main.skipCase()
2990
acsmars71adceb2015-08-31 15:09:26 -07002991 main.step( "Check that each node shows the same leader and candidates" )
Jon Halla440e872016-03-31 15:15:50 -07002992 failMessage = "Nodes have different leaderboards"
2993 def consistentLeaderboards( nodes ):
2994 TOPIC = 'org.onosproject.election'
2995 # FIXME: use threads
2996 #FIXME: should we retry outside the function?
2997 for n in range( 5 ): # Retry in case election is still happening
2998 leaderList = []
2999 # Get all leaderboards
3000 for cli in nodes:
3001 leaderList.append( cli.specificLeaderCandidate( TOPIC ) )
3002 # Compare leaderboards
3003 result = all( i == leaderList[0] for i in leaderList ) and\
3004 leaderList is not None
3005 main.log.debug( leaderList )
3006 main.log.warn( result )
3007 if result:
3008 return ( result, leaderList )
3009 time.sleep(5) #TODO: paramerterize
3010 main.log.error( "Inconsistent leaderboards:" + str( leaderList ) )
3011 activeCLIs = [ main.CLIs[i] for i in main.activeNodes ]
3012 sameResult, oldLeaders = consistentLeaderboards( activeCLIs )
3013 if sameResult:
3014 oldLeader = oldLeaders[ 0 ][ 0 ]
3015 main.log.warn( oldLeader )
acsmars71adceb2015-08-31 15:09:26 -07003016 else:
Jon Halla440e872016-03-31 15:15:50 -07003017 oldLeader = None
acsmars71adceb2015-08-31 15:09:26 -07003018 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07003019 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07003020 actual=sameResult,
Jon Halla440e872016-03-31 15:15:50 -07003021 onpass="Leaderboards are consistent for the election topic",
acsmars71adceb2015-08-31 15:09:26 -07003022 onfail=failMessage )
Jon Hall5cf14d52015-07-16 12:15:19 -07003023
3024 main.step( "Find current leader and withdraw" )
acsmars71adceb2015-08-31 15:09:26 -07003025 withdrawResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07003026 # do some sanity checking on leader before using it
acsmars71adceb2015-08-31 15:09:26 -07003027 if oldLeader is None:
3028 main.log.error( "Leadership isn't consistent." )
3029 withdrawResult = main.FALSE
3030 # Get the CLI of the oldLeader
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003031 for i in main.activeNodes:
acsmars71adceb2015-08-31 15:09:26 -07003032 if oldLeader == main.nodes[ i ].ip_address:
3033 oldLeaderCLI = main.CLIs[ i ]
Jon Hall5cf14d52015-07-16 12:15:19 -07003034 break
3035 else: # FOR/ELSE statement
3036 main.log.error( "Leader election, could not find current leader" )
3037 if oldLeader:
acsmars71adceb2015-08-31 15:09:26 -07003038 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall5cf14d52015-07-16 12:15:19 -07003039 utilities.assert_equals(
3040 expect=main.TRUE,
3041 actual=withdrawResult,
3042 onpass="Node was withdrawn from election",
3043 onfail="Node was not withdrawn from election" )
3044
acsmars71adceb2015-08-31 15:09:26 -07003045 main.step( "Check that a new node was elected leader" )
acsmars71adceb2015-08-31 15:09:26 -07003046 failMessage = "Nodes have different leaders"
acsmars71adceb2015-08-31 15:09:26 -07003047 # Get new leaders and candidates
Jon Halla440e872016-03-31 15:15:50 -07003048 newLeaderResult, newLeaders = consistentLeaderboards( activeCLIs )
3049 if newLeaders[ 0 ][ 0 ] == 'none':
3050 main.log.error( "No leader was elected on at least 1 node" )
3051 if not expectNoLeader:
3052 newLeaderResult = False
3053 if newLeaderResult:
3054 newLeader = newLeaders[ 0 ][ 0 ]
Jon Hall5cf14d52015-07-16 12:15:19 -07003055 else:
Jon Halla440e872016-03-31 15:15:50 -07003056 newLeader = None
acsmars71adceb2015-08-31 15:09:26 -07003057
3058 # Check that the new leader is not the older leader, which was withdrawn
3059 if newLeader == oldLeader:
Jon Halla440e872016-03-31 15:15:50 -07003060 newLeaderResult = False
Jon Hall6e709752016-02-01 13:38:46 -08003061 main.log.error( "All nodes still see old leader: " + str( oldLeader ) +
acsmars71adceb2015-08-31 15:09:26 -07003062 " as the current leader" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003063 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07003064 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07003065 actual=newLeaderResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07003066 onpass="Leadership election passed",
3067 onfail="Something went wrong with Leadership election" )
3068
Jon Halla440e872016-03-31 15:15:50 -07003069 main.step( "Check that that new leader was the candidate of old leader" )
Jon Hall6e709752016-02-01 13:38:46 -08003070 # candidates[ 2 ] should become the top candidate after withdrawl
acsmars71adceb2015-08-31 15:09:26 -07003071 correctCandidateResult = main.TRUE
3072 if expectNoLeader:
3073 if newLeader == 'none':
3074 main.log.info( "No leader expected. None found. Pass" )
3075 correctCandidateResult = main.TRUE
3076 else:
3077 main.log.info( "Expected no leader, got: " + str( newLeader ) )
3078 correctCandidateResult = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003079 elif len( oldLeaders[0] ) >= 3:
3080 if newLeader == oldLeaders[ 0 ][ 2 ]:
3081 # correct leader was elected
3082 correctCandidateResult = main.TRUE
3083 else:
3084 correctCandidateResult = main.FALSE
3085 main.log.error( "Candidate {} was elected. {} should have had priority.".format(
3086 newLeader, oldLeaders[ 0 ][ 2 ] ) )
Jon Hall6e709752016-02-01 13:38:46 -08003087 else:
3088 main.log.warn( "Could not determine who should be the correct leader" )
Jon Halla440e872016-03-31 15:15:50 -07003089 main.log.debug( oldLeaders[ 0 ] )
Jon Hall6e709752016-02-01 13:38:46 -08003090 correctCandidateResult = main.FALSE
acsmars71adceb2015-08-31 15:09:26 -07003091 utilities.assert_equals(
3092 expect=main.TRUE,
3093 actual=correctCandidateResult,
3094 onpass="Correct Candidate Elected",
3095 onfail="Incorrect Candidate Elected" )
3096
Jon Hall5cf14d52015-07-16 12:15:19 -07003097 main.step( "Run for election on old leader( just so everyone " +
3098 "is in the hat )" )
acsmars71adceb2015-08-31 15:09:26 -07003099 if oldLeaderCLI is not None:
3100 runResult = oldLeaderCLI.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07003101 else:
acsmars71adceb2015-08-31 15:09:26 -07003102 main.log.error( "No old leader to re-elect" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003103 runResult = main.FALSE
3104 utilities.assert_equals(
3105 expect=main.TRUE,
3106 actual=runResult,
3107 onpass="App re-ran for election",
3108 onfail="App failed to run for election" )
Jon Halla440e872016-03-31 15:15:50 -07003109
acsmars71adceb2015-08-31 15:09:26 -07003110 main.step(
3111 "Check that oldLeader is a candidate, and leader if only 1 node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003112 # verify leader didn't just change
Jon Halla440e872016-03-31 15:15:50 -07003113 # Get new leaders and candidates
3114 reRunLeaders = []
3115 time.sleep( 5 ) # Paremterize
3116 positionResult, reRunLeaders = consistentLeaderboards( activeCLIs )
acsmars71adceb2015-08-31 15:09:26 -07003117
3118 # Check that the re-elected node is last on the candidate List
Jon Halla440e872016-03-31 15:15:50 -07003119 if oldLeader != reRunLeaders[ 0 ][ -1 ]:
3120 main.log.error( "Old Leader ({}) not in the proper position: {} ".format( str( oldLeader),
3121 str( reRunLeaders[ 0 ] ) ) )
acsmars71adceb2015-08-31 15:09:26 -07003122 positionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07003123
3124 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07003125 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07003126 actual=positionResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07003127 onpass="Old leader successfully re-ran for election",
3128 onfail="Something went wrong with Leadership election after " +
3129 "the old leader re-ran for election" )
3130
3131 def CASE16( self, main ):
3132 """
3133 Install Distributed Primitives app
3134 """
3135 import time
Jon Halle1a3b752015-07-22 13:02:46 -07003136 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003137 assert main, "main not defined"
3138 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003139 assert main.CLIs, "main.CLIs not defined"
3140 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003141
3142 # Variables for the distributed primitives tests
3143 global pCounterName
Jon Hall5cf14d52015-07-16 12:15:19 -07003144 global pCounterValue
Jon Hall5cf14d52015-07-16 12:15:19 -07003145 global onosSet
3146 global onosSetName
3147 pCounterName = "TestON-Partitions"
Jon Hall5cf14d52015-07-16 12:15:19 -07003148 pCounterValue = 0
Jon Hall5cf14d52015-07-16 12:15:19 -07003149 onosSet = set([])
3150 onosSetName = "TestON-set"
3151
3152 description = "Install Primitives app"
3153 main.case( description )
3154 main.step( "Install Primitives app" )
3155 appName = "org.onosproject.distributedprimitives"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003156 node = main.activeNodes[0]
3157 appResults = main.CLIs[node].activateApp( appName )
Jon Hall5cf14d52015-07-16 12:15:19 -07003158 utilities.assert_equals( expect=main.TRUE,
3159 actual=appResults,
3160 onpass="Primitives app activated",
3161 onfail="Primitives app not activated" )
3162 time.sleep( 5 ) # To allow all nodes to activate
3163
3164 def CASE17( self, main ):
3165 """
3166 Check for basic functionality with distributed primitives
3167 """
Jon Hall5cf14d52015-07-16 12:15:19 -07003168 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07003169 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003170 assert main, "main not defined"
3171 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003172 assert main.CLIs, "main.CLIs not defined"
3173 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003174 assert pCounterName, "pCounterName not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003175 assert onosSetName, "onosSetName not defined"
3176 # NOTE: assert fails if value is 0/None/Empty/False
3177 try:
3178 pCounterValue
3179 except NameError:
3180 main.log.error( "pCounterValue not defined, setting to 0" )
3181 pCounterValue = 0
3182 try:
Jon Hall5cf14d52015-07-16 12:15:19 -07003183 onosSet
3184 except NameError:
3185 main.log.error( "onosSet not defined, setting to empty Set" )
3186 onosSet = set([])
3187 # Variables for the distributed primitives tests. These are local only
3188 addValue = "a"
3189 addAllValue = "a b c d e f"
3190 retainValue = "c d e f"
3191
3192 description = "Check for basic functionality with distributed " +\
3193 "primitives"
3194 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07003195 main.caseExplanation = "Test the methods of the distributed " +\
3196 "primitives (counters and sets) throught the cli"
Jon Hall5cf14d52015-07-16 12:15:19 -07003197 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07003198 # Partitioned counters
3199 main.step( "Increment then get a default counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003200 pCounters = []
3201 threads = []
3202 addedPValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003203 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003204 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3205 name="counterAddAndGet-" + str( i ),
Jon Hall5cf14d52015-07-16 12:15:19 -07003206 args=[ pCounterName ] )
3207 pCounterValue += 1
3208 addedPValues.append( pCounterValue )
3209 threads.append( t )
3210 t.start()
3211
3212 for t in threads:
3213 t.join()
3214 pCounters.append( t.result )
3215 # Check that counter incremented numController times
3216 pCounterResults = True
3217 for i in addedPValues:
3218 tmpResult = i in pCounters
3219 pCounterResults = pCounterResults and tmpResult
3220 if not tmpResult:
3221 main.log.error( str( i ) + " is not in partitioned "
3222 "counter incremented results" )
3223 utilities.assert_equals( expect=True,
3224 actual=pCounterResults,
3225 onpass="Default counter incremented",
3226 onfail="Error incrementing default" +
3227 " counter" )
3228
Jon Halle1a3b752015-07-22 13:02:46 -07003229 main.step( "Get then Increment a default counter on each node" )
3230 pCounters = []
3231 threads = []
3232 addedPValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003233 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003234 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3235 name="counterGetAndAdd-" + str( i ),
3236 args=[ pCounterName ] )
3237 addedPValues.append( pCounterValue )
3238 pCounterValue += 1
3239 threads.append( t )
3240 t.start()
3241
3242 for t in threads:
3243 t.join()
3244 pCounters.append( t.result )
3245 # Check that counter incremented numController times
3246 pCounterResults = True
3247 for i in addedPValues:
3248 tmpResult = i in pCounters
3249 pCounterResults = pCounterResults and tmpResult
3250 if not tmpResult:
3251 main.log.error( str( i ) + " is not in partitioned "
3252 "counter incremented results" )
3253 utilities.assert_equals( expect=True,
3254 actual=pCounterResults,
3255 onpass="Default counter incremented",
3256 onfail="Error incrementing default" +
3257 " counter" )
3258
3259 main.step( "Counters we added have the correct values" )
3260 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3261 utilities.assert_equals( expect=main.TRUE,
3262 actual=incrementCheck,
3263 onpass="Added counters are correct",
3264 onfail="Added counters are incorrect" )
3265
3266 main.step( "Add -8 to then get a default counter on each node" )
3267 pCounters = []
3268 threads = []
3269 addedPValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003270 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003271 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3272 name="counterIncrement-" + str( i ),
3273 args=[ pCounterName ],
3274 kwargs={ "delta": -8 } )
3275 pCounterValue += -8
3276 addedPValues.append( pCounterValue )
3277 threads.append( t )
3278 t.start()
3279
3280 for t in threads:
3281 t.join()
3282 pCounters.append( t.result )
3283 # Check that counter incremented numController times
3284 pCounterResults = True
3285 for i in addedPValues:
3286 tmpResult = i in pCounters
3287 pCounterResults = pCounterResults and tmpResult
3288 if not tmpResult:
3289 main.log.error( str( i ) + " is not in partitioned "
3290 "counter incremented results" )
3291 utilities.assert_equals( expect=True,
3292 actual=pCounterResults,
3293 onpass="Default counter incremented",
3294 onfail="Error incrementing default" +
3295 " counter" )
3296
3297 main.step( "Add 5 to then get a default counter on each node" )
3298 pCounters = []
3299 threads = []
3300 addedPValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003301 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003302 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3303 name="counterIncrement-" + str( i ),
3304 args=[ pCounterName ],
3305 kwargs={ "delta": 5 } )
3306 pCounterValue += 5
3307 addedPValues.append( pCounterValue )
3308 threads.append( t )
3309 t.start()
3310
3311 for t in threads:
3312 t.join()
3313 pCounters.append( t.result )
3314 # Check that counter incremented numController times
3315 pCounterResults = True
3316 for i in addedPValues:
3317 tmpResult = i in pCounters
3318 pCounterResults = pCounterResults and tmpResult
3319 if not tmpResult:
3320 main.log.error( str( i ) + " is not in partitioned "
3321 "counter incremented results" )
3322 utilities.assert_equals( expect=True,
3323 actual=pCounterResults,
3324 onpass="Default counter incremented",
3325 onfail="Error incrementing default" +
3326 " counter" )
3327
3328 main.step( "Get then add 5 to a default counter on each node" )
3329 pCounters = []
3330 threads = []
3331 addedPValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003332 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003333 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3334 name="counterIncrement-" + str( i ),
3335 args=[ pCounterName ],
3336 kwargs={ "delta": 5 } )
3337 addedPValues.append( pCounterValue )
3338 pCounterValue += 5
3339 threads.append( t )
3340 t.start()
3341
3342 for t in threads:
3343 t.join()
3344 pCounters.append( t.result )
3345 # Check that counter incremented numController times
3346 pCounterResults = True
3347 for i in addedPValues:
3348 tmpResult = i in pCounters
3349 pCounterResults = pCounterResults and tmpResult
3350 if not tmpResult:
3351 main.log.error( str( i ) + " is not in partitioned "
3352 "counter incremented results" )
3353 utilities.assert_equals( expect=True,
3354 actual=pCounterResults,
3355 onpass="Default counter incremented",
3356 onfail="Error incrementing default" +
3357 " counter" )
3358
3359 main.step( "Counters we added have the correct values" )
3360 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3361 utilities.assert_equals( expect=main.TRUE,
3362 actual=incrementCheck,
3363 onpass="Added counters are correct",
3364 onfail="Added counters are incorrect" )
3365
Jon Hall5cf14d52015-07-16 12:15:19 -07003366 # DISTRIBUTED SETS
3367 main.step( "Distributed Set get" )
3368 size = len( onosSet )
3369 getResponses = []
3370 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003371 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003372 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003373 name="setTestGet-" + str( i ),
3374 args=[ onosSetName ] )
3375 threads.append( t )
3376 t.start()
3377 for t in threads:
3378 t.join()
3379 getResponses.append( t.result )
3380
3381 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003382 for i in range( len( main.activeNodes ) ):
3383 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003384 if isinstance( getResponses[ i ], list):
3385 current = set( getResponses[ i ] )
3386 if len( current ) == len( getResponses[ i ] ):
3387 # no repeats
3388 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003389 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003390 " has incorrect view" +
3391 " of set " + onosSetName + ":\n" +
3392 str( getResponses[ i ] ) )
3393 main.log.debug( "Expected: " + str( onosSet ) )
3394 main.log.debug( "Actual: " + str( current ) )
3395 getResults = main.FALSE
3396 else:
3397 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003398 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003399 " has repeat elements in" +
3400 " set " + onosSetName + ":\n" +
3401 str( getResponses[ i ] ) )
3402 getResults = main.FALSE
3403 elif getResponses[ i ] == main.ERROR:
3404 getResults = main.FALSE
3405 utilities.assert_equals( expect=main.TRUE,
3406 actual=getResults,
3407 onpass="Set elements are correct",
3408 onfail="Set elements are incorrect" )
3409
3410 main.step( "Distributed Set size" )
3411 sizeResponses = []
3412 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003413 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003414 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003415 name="setTestSize-" + str( i ),
3416 args=[ onosSetName ] )
3417 threads.append( t )
3418 t.start()
3419 for t in threads:
3420 t.join()
3421 sizeResponses.append( t.result )
3422
3423 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003424 for i in range( len( main.activeNodes ) ):
3425 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003426 if size != sizeResponses[ i ]:
3427 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003428 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003429 " expected a size of " + str( size ) +
3430 " for set " + onosSetName +
3431 " but got " + str( sizeResponses[ i ] ) )
3432 utilities.assert_equals( expect=main.TRUE,
3433 actual=sizeResults,
3434 onpass="Set sizes are correct",
3435 onfail="Set sizes are incorrect" )
3436
3437 main.step( "Distributed Set add()" )
3438 onosSet.add( addValue )
3439 addResponses = []
3440 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003441 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003442 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003443 name="setTestAdd-" + str( i ),
3444 args=[ onosSetName, addValue ] )
3445 threads.append( t )
3446 t.start()
3447 for t in threads:
3448 t.join()
3449 addResponses.append( t.result )
3450
3451 # main.TRUE = successfully changed the set
3452 # main.FALSE = action resulted in no change in set
3453 # main.ERROR - Some error in executing the function
3454 addResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003455 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003456 if addResponses[ i ] == main.TRUE:
3457 # All is well
3458 pass
3459 elif addResponses[ i ] == main.FALSE:
3460 # Already in set, probably fine
3461 pass
3462 elif addResponses[ i ] == main.ERROR:
3463 # Error in execution
3464 addResults = main.FALSE
3465 else:
3466 # unexpected result
3467 addResults = main.FALSE
3468 if addResults != main.TRUE:
3469 main.log.error( "Error executing set add" )
3470
3471 # Check if set is still correct
3472 size = len( onosSet )
3473 getResponses = []
3474 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003475 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003476 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003477 name="setTestGet-" + str( i ),
3478 args=[ onosSetName ] )
3479 threads.append( t )
3480 t.start()
3481 for t in threads:
3482 t.join()
3483 getResponses.append( t.result )
3484 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003485 for i in range( len( main.activeNodes ) ):
3486 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003487 if isinstance( getResponses[ i ], list):
3488 current = set( getResponses[ i ] )
3489 if len( current ) == len( getResponses[ i ] ):
3490 # no repeats
3491 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003492 main.log.error( "ONOS" + node + " has incorrect view" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003493 " of set " + onosSetName + ":\n" +
3494 str( getResponses[ i ] ) )
3495 main.log.debug( "Expected: " + str( onosSet ) )
3496 main.log.debug( "Actual: " + str( current ) )
3497 getResults = main.FALSE
3498 else:
3499 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003500 main.log.error( "ONOS" + node + " has repeat elements in" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003501 " set " + onosSetName + ":\n" +
3502 str( getResponses[ i ] ) )
3503 getResults = main.FALSE
3504 elif getResponses[ i ] == main.ERROR:
3505 getResults = main.FALSE
3506 sizeResponses = []
3507 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003508 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003509 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003510 name="setTestSize-" + str( i ),
3511 args=[ onosSetName ] )
3512 threads.append( t )
3513 t.start()
3514 for t in threads:
3515 t.join()
3516 sizeResponses.append( t.result )
3517 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003518 for i in range( len( main.activeNodes ) ):
3519 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003520 if size != sizeResponses[ i ]:
3521 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003522 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003523 " expected a size of " + str( size ) +
3524 " for set " + onosSetName +
3525 " but got " + str( sizeResponses[ i ] ) )
3526 addResults = addResults and getResults and sizeResults
3527 utilities.assert_equals( expect=main.TRUE,
3528 actual=addResults,
3529 onpass="Set add correct",
3530 onfail="Set add was incorrect" )
3531
3532 main.step( "Distributed Set addAll()" )
3533 onosSet.update( addAllValue.split() )
3534 addResponses = []
3535 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003536 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003537 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003538 name="setTestAddAll-" + str( i ),
3539 args=[ onosSetName, addAllValue ] )
3540 threads.append( t )
3541 t.start()
3542 for t in threads:
3543 t.join()
3544 addResponses.append( t.result )
3545
3546 # main.TRUE = successfully changed the set
3547 # main.FALSE = action resulted in no change in set
3548 # main.ERROR - Some error in executing the function
3549 addAllResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003550 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003551 if addResponses[ i ] == main.TRUE:
3552 # All is well
3553 pass
3554 elif addResponses[ i ] == main.FALSE:
3555 # Already in set, probably fine
3556 pass
3557 elif addResponses[ i ] == main.ERROR:
3558 # Error in execution
3559 addAllResults = main.FALSE
3560 else:
3561 # unexpected result
3562 addAllResults = main.FALSE
3563 if addAllResults != main.TRUE:
3564 main.log.error( "Error executing set addAll" )
3565
3566 # Check if set is still correct
3567 size = len( onosSet )
3568 getResponses = []
3569 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003570 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003571 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003572 name="setTestGet-" + str( i ),
3573 args=[ onosSetName ] )
3574 threads.append( t )
3575 t.start()
3576 for t in threads:
3577 t.join()
3578 getResponses.append( t.result )
3579 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003580 for i in range( len( main.activeNodes ) ):
3581 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003582 if isinstance( getResponses[ i ], list):
3583 current = set( getResponses[ i ] )
3584 if len( current ) == len( getResponses[ i ] ):
3585 # no repeats
3586 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003587 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003588 " has incorrect view" +
3589 " of set " + onosSetName + ":\n" +
3590 str( getResponses[ i ] ) )
3591 main.log.debug( "Expected: " + str( onosSet ) )
3592 main.log.debug( "Actual: " + str( current ) )
3593 getResults = main.FALSE
3594 else:
3595 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003596 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003597 " has repeat elements in" +
3598 " set " + onosSetName + ":\n" +
3599 str( getResponses[ i ] ) )
3600 getResults = main.FALSE
3601 elif getResponses[ i ] == main.ERROR:
3602 getResults = main.FALSE
3603 sizeResponses = []
3604 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003605 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003606 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003607 name="setTestSize-" + str( i ),
3608 args=[ onosSetName ] )
3609 threads.append( t )
3610 t.start()
3611 for t in threads:
3612 t.join()
3613 sizeResponses.append( t.result )
3614 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003615 for i in range( len( main.activeNodes ) ):
3616 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003617 if size != sizeResponses[ i ]:
3618 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003619 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003620 " expected a size of " + str( size ) +
3621 " for set " + onosSetName +
3622 " but got " + str( sizeResponses[ i ] ) )
3623 addAllResults = addAllResults and getResults and sizeResults
3624 utilities.assert_equals( expect=main.TRUE,
3625 actual=addAllResults,
3626 onpass="Set addAll correct",
3627 onfail="Set addAll was incorrect" )
3628
3629 main.step( "Distributed Set contains()" )
3630 containsResponses = []
3631 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003632 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003633 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003634 name="setContains-" + str( i ),
3635 args=[ onosSetName ],
3636 kwargs={ "values": addValue } )
3637 threads.append( t )
3638 t.start()
3639 for t in threads:
3640 t.join()
3641 # NOTE: This is the tuple
3642 containsResponses.append( t.result )
3643
3644 containsResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003645 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003646 if containsResponses[ i ] == main.ERROR:
3647 containsResults = main.FALSE
3648 else:
3649 containsResults = containsResults and\
3650 containsResponses[ i ][ 1 ]
3651 utilities.assert_equals( expect=main.TRUE,
3652 actual=containsResults,
3653 onpass="Set contains is functional",
3654 onfail="Set contains failed" )
3655
3656 main.step( "Distributed Set containsAll()" )
3657 containsAllResponses = []
3658 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003659 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003660 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003661 name="setContainsAll-" + str( i ),
3662 args=[ onosSetName ],
3663 kwargs={ "values": addAllValue } )
3664 threads.append( t )
3665 t.start()
3666 for t in threads:
3667 t.join()
3668 # NOTE: This is the tuple
3669 containsAllResponses.append( t.result )
3670
3671 containsAllResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003672 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003673 if containsResponses[ i ] == main.ERROR:
3674 containsResults = main.FALSE
3675 else:
3676 containsResults = containsResults and\
3677 containsResponses[ i ][ 1 ]
3678 utilities.assert_equals( expect=main.TRUE,
3679 actual=containsAllResults,
3680 onpass="Set containsAll is functional",
3681 onfail="Set containsAll failed" )
3682
3683 main.step( "Distributed Set remove()" )
3684 onosSet.remove( addValue )
3685 removeResponses = []
3686 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003687 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003688 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003689 name="setTestRemove-" + str( i ),
3690 args=[ onosSetName, addValue ] )
3691 threads.append( t )
3692 t.start()
3693 for t in threads:
3694 t.join()
3695 removeResponses.append( t.result )
3696
3697 # main.TRUE = successfully changed the set
3698 # main.FALSE = action resulted in no change in set
3699 # main.ERROR - Some error in executing the function
3700 removeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003701 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003702 if removeResponses[ i ] == main.TRUE:
3703 # All is well
3704 pass
3705 elif removeResponses[ i ] == main.FALSE:
3706 # not in set, probably fine
3707 pass
3708 elif removeResponses[ i ] == main.ERROR:
3709 # Error in execution
3710 removeResults = main.FALSE
3711 else:
3712 # unexpected result
3713 removeResults = main.FALSE
3714 if removeResults != main.TRUE:
3715 main.log.error( "Error executing set remove" )
3716
3717 # Check if set is still correct
3718 size = len( onosSet )
3719 getResponses = []
3720 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003721 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003722 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003723 name="setTestGet-" + str( i ),
3724 args=[ onosSetName ] )
3725 threads.append( t )
3726 t.start()
3727 for t in threads:
3728 t.join()
3729 getResponses.append( t.result )
3730 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003731 for i in range( len( main.activeNodes ) ):
3732 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003733 if isinstance( getResponses[ i ], list):
3734 current = set( getResponses[ i ] )
3735 if len( current ) == len( getResponses[ i ] ):
3736 # no repeats
3737 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003738 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003739 " has incorrect view" +
3740 " of set " + onosSetName + ":\n" +
3741 str( getResponses[ i ] ) )
3742 main.log.debug( "Expected: " + str( onosSet ) )
3743 main.log.debug( "Actual: " + str( current ) )
3744 getResults = main.FALSE
3745 else:
3746 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003747 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003748 " has repeat elements in" +
3749 " set " + onosSetName + ":\n" +
3750 str( getResponses[ i ] ) )
3751 getResults = main.FALSE
3752 elif getResponses[ i ] == main.ERROR:
3753 getResults = main.FALSE
3754 sizeResponses = []
3755 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003756 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003757 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003758 name="setTestSize-" + str( i ),
3759 args=[ onosSetName ] )
3760 threads.append( t )
3761 t.start()
3762 for t in threads:
3763 t.join()
3764 sizeResponses.append( t.result )
3765 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003766 for i in range( len( main.activeNodes ) ):
3767 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003768 if size != sizeResponses[ i ]:
3769 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003770 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003771 " expected a size of " + str( size ) +
3772 " for set " + onosSetName +
3773 " but got " + str( sizeResponses[ i ] ) )
3774 removeResults = removeResults and getResults and sizeResults
3775 utilities.assert_equals( expect=main.TRUE,
3776 actual=removeResults,
3777 onpass="Set remove correct",
3778 onfail="Set remove was incorrect" )
3779
3780 main.step( "Distributed Set removeAll()" )
3781 onosSet.difference_update( addAllValue.split() )
3782 removeAllResponses = []
3783 threads = []
3784 try:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003785 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003786 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003787 name="setTestRemoveAll-" + str( i ),
3788 args=[ onosSetName, addAllValue ] )
3789 threads.append( t )
3790 t.start()
3791 for t in threads:
3792 t.join()
3793 removeAllResponses.append( t.result )
3794 except Exception, e:
3795 main.log.exception(e)
3796
3797 # main.TRUE = successfully changed the set
3798 # main.FALSE = action resulted in no change in set
3799 # main.ERROR - Some error in executing the function
3800 removeAllResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003801 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003802 if removeAllResponses[ i ] == main.TRUE:
3803 # All is well
3804 pass
3805 elif removeAllResponses[ i ] == main.FALSE:
3806 # not in set, probably fine
3807 pass
3808 elif removeAllResponses[ i ] == main.ERROR:
3809 # Error in execution
3810 removeAllResults = main.FALSE
3811 else:
3812 # unexpected result
3813 removeAllResults = main.FALSE
3814 if removeAllResults != main.TRUE:
3815 main.log.error( "Error executing set removeAll" )
3816
3817 # Check if set is still correct
3818 size = len( onosSet )
3819 getResponses = []
3820 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003821 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003822 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003823 name="setTestGet-" + str( i ),
3824 args=[ onosSetName ] )
3825 threads.append( t )
3826 t.start()
3827 for t in threads:
3828 t.join()
3829 getResponses.append( t.result )
3830 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003831 for i in range( len( main.activeNodes ) ):
3832 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003833 if isinstance( getResponses[ i ], list):
3834 current = set( getResponses[ i ] )
3835 if len( current ) == len( getResponses[ i ] ):
3836 # no repeats
3837 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003838 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003839 " has incorrect view" +
3840 " of set " + onosSetName + ":\n" +
3841 str( getResponses[ i ] ) )
3842 main.log.debug( "Expected: " + str( onosSet ) )
3843 main.log.debug( "Actual: " + str( current ) )
3844 getResults = main.FALSE
3845 else:
3846 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003847 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003848 " has repeat elements in" +
3849 " set " + onosSetName + ":\n" +
3850 str( getResponses[ i ] ) )
3851 getResults = main.FALSE
3852 elif getResponses[ i ] == main.ERROR:
3853 getResults = main.FALSE
3854 sizeResponses = []
3855 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003856 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003857 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003858 name="setTestSize-" + str( i ),
3859 args=[ onosSetName ] )
3860 threads.append( t )
3861 t.start()
3862 for t in threads:
3863 t.join()
3864 sizeResponses.append( t.result )
3865 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003866 for i in range( len( main.activeNodes ) ):
3867 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003868 if size != sizeResponses[ i ]:
3869 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003870 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003871 " expected a size of " + str( size ) +
3872 " for set " + onosSetName +
3873 " but got " + str( sizeResponses[ i ] ) )
3874 removeAllResults = removeAllResults and getResults and sizeResults
3875 utilities.assert_equals( expect=main.TRUE,
3876 actual=removeAllResults,
3877 onpass="Set removeAll correct",
3878 onfail="Set removeAll was incorrect" )
3879
3880 main.step( "Distributed Set addAll()" )
3881 onosSet.update( addAllValue.split() )
3882 addResponses = []
3883 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003884 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003885 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003886 name="setTestAddAll-" + str( i ),
3887 args=[ onosSetName, addAllValue ] )
3888 threads.append( t )
3889 t.start()
3890 for t in threads:
3891 t.join()
3892 addResponses.append( t.result )
3893
3894 # main.TRUE = successfully changed the set
3895 # main.FALSE = action resulted in no change in set
3896 # main.ERROR - Some error in executing the function
3897 addAllResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003898 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003899 if addResponses[ i ] == main.TRUE:
3900 # All is well
3901 pass
3902 elif addResponses[ i ] == main.FALSE:
3903 # Already in set, probably fine
3904 pass
3905 elif addResponses[ i ] == main.ERROR:
3906 # Error in execution
3907 addAllResults = main.FALSE
3908 else:
3909 # unexpected result
3910 addAllResults = main.FALSE
3911 if addAllResults != main.TRUE:
3912 main.log.error( "Error executing set addAll" )
3913
3914 # Check if set is still correct
3915 size = len( onosSet )
3916 getResponses = []
3917 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003918 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003919 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003920 name="setTestGet-" + str( i ),
3921 args=[ onosSetName ] )
3922 threads.append( t )
3923 t.start()
3924 for t in threads:
3925 t.join()
3926 getResponses.append( t.result )
3927 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003928 for i in range( len( main.activeNodes ) ):
3929 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003930 if isinstance( getResponses[ i ], list):
3931 current = set( getResponses[ i ] )
3932 if len( current ) == len( getResponses[ i ] ):
3933 # no repeats
3934 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003935 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003936 " has incorrect view" +
3937 " of set " + onosSetName + ":\n" +
3938 str( getResponses[ i ] ) )
3939 main.log.debug( "Expected: " + str( onosSet ) )
3940 main.log.debug( "Actual: " + str( current ) )
3941 getResults = main.FALSE
3942 else:
3943 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003944 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003945 " has repeat elements in" +
3946 " set " + onosSetName + ":\n" +
3947 str( getResponses[ i ] ) )
3948 getResults = main.FALSE
3949 elif getResponses[ i ] == main.ERROR:
3950 getResults = main.FALSE
3951 sizeResponses = []
3952 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003953 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003954 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003955 name="setTestSize-" + str( i ),
3956 args=[ onosSetName ] )
3957 threads.append( t )
3958 t.start()
3959 for t in threads:
3960 t.join()
3961 sizeResponses.append( t.result )
3962 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003963 for i in range( len( main.activeNodes ) ):
3964 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003965 if size != sizeResponses[ i ]:
3966 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003967 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003968 " expected a size of " + str( size ) +
3969 " for set " + onosSetName +
3970 " but got " + str( sizeResponses[ i ] ) )
3971 addAllResults = addAllResults and getResults and sizeResults
3972 utilities.assert_equals( expect=main.TRUE,
3973 actual=addAllResults,
3974 onpass="Set addAll correct",
3975 onfail="Set addAll was incorrect" )
3976
3977 main.step( "Distributed Set clear()" )
3978 onosSet.clear()
3979 clearResponses = []
3980 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003981 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003982 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003983 name="setTestClear-" + str( i ),
3984 args=[ onosSetName, " "], # Values doesn't matter
3985 kwargs={ "clear": True } )
3986 threads.append( t )
3987 t.start()
3988 for t in threads:
3989 t.join()
3990 clearResponses.append( t.result )
3991
3992 # main.TRUE = successfully changed the set
3993 # main.FALSE = action resulted in no change in set
3994 # main.ERROR - Some error in executing the function
3995 clearResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003996 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003997 if clearResponses[ i ] == main.TRUE:
3998 # All is well
3999 pass
4000 elif clearResponses[ i ] == main.FALSE:
4001 # Nothing set, probably fine
4002 pass
4003 elif clearResponses[ i ] == main.ERROR:
4004 # Error in execution
4005 clearResults = main.FALSE
4006 else:
4007 # unexpected result
4008 clearResults = main.FALSE
4009 if clearResults != main.TRUE:
4010 main.log.error( "Error executing set clear" )
4011
4012 # Check if set is still correct
4013 size = len( onosSet )
4014 getResponses = []
4015 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004016 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004017 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004018 name="setTestGet-" + str( i ),
4019 args=[ onosSetName ] )
4020 threads.append( t )
4021 t.start()
4022 for t in threads:
4023 t.join()
4024 getResponses.append( t.result )
4025 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004026 for i in range( len( main.activeNodes ) ):
4027 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004028 if isinstance( getResponses[ i ], list):
4029 current = set( getResponses[ i ] )
4030 if len( current ) == len( getResponses[ i ] ):
4031 # no repeats
4032 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004033 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004034 " has incorrect view" +
4035 " of set " + onosSetName + ":\n" +
4036 str( getResponses[ i ] ) )
4037 main.log.debug( "Expected: " + str( onosSet ) )
4038 main.log.debug( "Actual: " + str( current ) )
4039 getResults = main.FALSE
4040 else:
4041 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004042 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004043 " has repeat elements in" +
4044 " set " + onosSetName + ":\n" +
4045 str( getResponses[ i ] ) )
4046 getResults = main.FALSE
4047 elif getResponses[ i ] == main.ERROR:
4048 getResults = main.FALSE
4049 sizeResponses = []
4050 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004051 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004052 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004053 name="setTestSize-" + str( i ),
4054 args=[ onosSetName ] )
4055 threads.append( t )
4056 t.start()
4057 for t in threads:
4058 t.join()
4059 sizeResponses.append( t.result )
4060 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004061 for i in range( len( main.activeNodes ) ):
4062 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004063 if size != sizeResponses[ i ]:
4064 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004065 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004066 " expected a size of " + str( size ) +
4067 " for set " + onosSetName +
4068 " but got " + str( sizeResponses[ i ] ) )
4069 clearResults = clearResults and getResults and sizeResults
4070 utilities.assert_equals( expect=main.TRUE,
4071 actual=clearResults,
4072 onpass="Set clear correct",
4073 onfail="Set clear was incorrect" )
4074
4075 main.step( "Distributed Set addAll()" )
4076 onosSet.update( addAllValue.split() )
4077 addResponses = []
4078 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004079 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004080 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004081 name="setTestAddAll-" + str( i ),
4082 args=[ onosSetName, addAllValue ] )
4083 threads.append( t )
4084 t.start()
4085 for t in threads:
4086 t.join()
4087 addResponses.append( t.result )
4088
4089 # main.TRUE = successfully changed the set
4090 # main.FALSE = action resulted in no change in set
4091 # main.ERROR - Some error in executing the function
4092 addAllResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004093 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004094 if addResponses[ i ] == main.TRUE:
4095 # All is well
4096 pass
4097 elif addResponses[ i ] == main.FALSE:
4098 # Already in set, probably fine
4099 pass
4100 elif addResponses[ i ] == main.ERROR:
4101 # Error in execution
4102 addAllResults = main.FALSE
4103 else:
4104 # unexpected result
4105 addAllResults = main.FALSE
4106 if addAllResults != main.TRUE:
4107 main.log.error( "Error executing set addAll" )
4108
4109 # Check if set is still correct
4110 size = len( onosSet )
4111 getResponses = []
4112 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004113 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004114 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004115 name="setTestGet-" + str( i ),
4116 args=[ onosSetName ] )
4117 threads.append( t )
4118 t.start()
4119 for t in threads:
4120 t.join()
4121 getResponses.append( t.result )
4122 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004123 for i in range( len( main.activeNodes ) ):
4124 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004125 if isinstance( getResponses[ i ], list):
4126 current = set( getResponses[ i ] )
4127 if len( current ) == len( getResponses[ i ] ):
4128 # no repeats
4129 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004130 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004131 " has incorrect view" +
4132 " of set " + onosSetName + ":\n" +
4133 str( getResponses[ i ] ) )
4134 main.log.debug( "Expected: " + str( onosSet ) )
4135 main.log.debug( "Actual: " + str( current ) )
4136 getResults = main.FALSE
4137 else:
4138 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004139 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004140 " has repeat elements in" +
4141 " set " + onosSetName + ":\n" +
4142 str( getResponses[ i ] ) )
4143 getResults = main.FALSE
4144 elif getResponses[ i ] == main.ERROR:
4145 getResults = main.FALSE
4146 sizeResponses = []
4147 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004148 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004149 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004150 name="setTestSize-" + str( i ),
4151 args=[ onosSetName ] )
4152 threads.append( t )
4153 t.start()
4154 for t in threads:
4155 t.join()
4156 sizeResponses.append( t.result )
4157 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004158 for i in range( len( main.activeNodes ) ):
4159 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004160 if size != sizeResponses[ i ]:
4161 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004162 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004163 " expected a size of " + str( size ) +
4164 " for set " + onosSetName +
4165 " but got " + str( sizeResponses[ i ] ) )
4166 addAllResults = addAllResults and getResults and sizeResults
4167 utilities.assert_equals( expect=main.TRUE,
4168 actual=addAllResults,
4169 onpass="Set addAll correct",
4170 onfail="Set addAll was incorrect" )
4171
4172 main.step( "Distributed Set retain()" )
4173 onosSet.intersection_update( retainValue.split() )
4174 retainResponses = []
4175 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004176 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004177 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004178 name="setTestRetain-" + str( i ),
4179 args=[ onosSetName, retainValue ],
4180 kwargs={ "retain": True } )
4181 threads.append( t )
4182 t.start()
4183 for t in threads:
4184 t.join()
4185 retainResponses.append( t.result )
4186
4187 # main.TRUE = successfully changed the set
4188 # main.FALSE = action resulted in no change in set
4189 # main.ERROR - Some error in executing the function
4190 retainResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004191 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004192 if retainResponses[ i ] == main.TRUE:
4193 # All is well
4194 pass
4195 elif retainResponses[ i ] == main.FALSE:
4196 # Already in set, probably fine
4197 pass
4198 elif retainResponses[ i ] == main.ERROR:
4199 # Error in execution
4200 retainResults = main.FALSE
4201 else:
4202 # unexpected result
4203 retainResults = main.FALSE
4204 if retainResults != main.TRUE:
4205 main.log.error( "Error executing set retain" )
4206
4207 # Check if set is still correct
4208 size = len( onosSet )
4209 getResponses = []
4210 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004211 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004212 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004213 name="setTestGet-" + str( i ),
4214 args=[ onosSetName ] )
4215 threads.append( t )
4216 t.start()
4217 for t in threads:
4218 t.join()
4219 getResponses.append( t.result )
4220 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004221 for i in range( len( main.activeNodes ) ):
4222 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004223 if isinstance( getResponses[ i ], list):
4224 current = set( getResponses[ i ] )
4225 if len( current ) == len( getResponses[ i ] ):
4226 # no repeats
4227 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004228 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004229 " has incorrect view" +
4230 " of set " + onosSetName + ":\n" +
4231 str( getResponses[ i ] ) )
4232 main.log.debug( "Expected: " + str( onosSet ) )
4233 main.log.debug( "Actual: " + str( current ) )
4234 getResults = main.FALSE
4235 else:
4236 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004237 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004238 " has repeat elements in" +
4239 " set " + onosSetName + ":\n" +
4240 str( getResponses[ i ] ) )
4241 getResults = main.FALSE
4242 elif getResponses[ i ] == main.ERROR:
4243 getResults = main.FALSE
4244 sizeResponses = []
4245 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004246 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004247 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004248 name="setTestSize-" + str( i ),
4249 args=[ onosSetName ] )
4250 threads.append( t )
4251 t.start()
4252 for t in threads:
4253 t.join()
4254 sizeResponses.append( t.result )
4255 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004256 for i in range( len( main.activeNodes ) ):
4257 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004258 if size != sizeResponses[ i ]:
4259 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004260 main.log.error( "ONOS" + node + " expected a size of " +
Jon Hall5cf14d52015-07-16 12:15:19 -07004261 str( size ) + " for set " + onosSetName +
4262 " but got " + str( sizeResponses[ i ] ) )
4263 retainResults = retainResults and getResults and sizeResults
4264 utilities.assert_equals( expect=main.TRUE,
4265 actual=retainResults,
4266 onpass="Set retain correct",
4267 onfail="Set retain was incorrect" )
4268
Jon Hall2a5002c2015-08-21 16:49:11 -07004269 # Transactional maps
4270 main.step( "Partitioned Transactional maps put" )
4271 tMapValue = "Testing"
4272 numKeys = 100
4273 putResult = True
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004274 node = main.activeNodes[0]
4275 putResponses = main.CLIs[node].transactionalMapPut( numKeys, tMapValue )
Jon Hall6e709752016-02-01 13:38:46 -08004276 if putResponses and len( putResponses ) == 100:
Jon Hall2a5002c2015-08-21 16:49:11 -07004277 for i in putResponses:
4278 if putResponses[ i ][ 'value' ] != tMapValue:
4279 putResult = False
4280 else:
4281 putResult = False
4282 if not putResult:
4283 main.log.debug( "Put response values: " + str( putResponses ) )
4284 utilities.assert_equals( expect=True,
4285 actual=putResult,
4286 onpass="Partitioned Transactional Map put successful",
4287 onfail="Partitioned Transactional Map put values are incorrect" )
4288
4289 main.step( "Partitioned Transactional maps get" )
4290 getCheck = True
4291 for n in range( 1, numKeys + 1 ):
4292 getResponses = []
4293 threads = []
4294 valueCheck = True
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004295 for i in main.activeNodes:
Jon Hall2a5002c2015-08-21 16:49:11 -07004296 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4297 name="TMap-get-" + str( i ),
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004298 args=[ "Key" + str( n ) ] )
Jon Hall2a5002c2015-08-21 16:49:11 -07004299 threads.append( t )
4300 t.start()
4301 for t in threads:
4302 t.join()
4303 getResponses.append( t.result )
4304 for node in getResponses:
4305 if node != tMapValue:
4306 valueCheck = False
4307 if not valueCheck:
4308 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4309 main.log.warn( getResponses )
4310 getCheck = getCheck and valueCheck
4311 utilities.assert_equals( expect=True,
4312 actual=getCheck,
4313 onpass="Partitioned Transactional Map get values were correct",
4314 onfail="Partitioned Transactional Map values incorrect" )