blob: 62062fceb1886b6c8eb9ea5bc19ec0f239f13ec9 [file] [log] [blame]
Jon Hall5cf14d52015-07-16 12:15:19 -07001"""
2Description: This test is to determine if ONOS can handle
3 a minority of it's nodes restarting
4
5List of test cases:
6CASE1: Compile ONOS and push it to the test machines
7CASE2: Assign devices to controllers
8CASE21: Assign mastership to controllers
9CASE3: Assign intents
10CASE4: Ping across added host intents
11CASE5: Reading state of ONOS
Jon Hallb3ed8ed2015-10-28 16:43:55 -070012CASE61: The Failure inducing case.
13CASE62: The Failure recovery case.
Jon Hall5cf14d52015-07-16 12:15:19 -070014CASE7: Check state after control plane failure
15CASE8: Compare topo
16CASE9: Link s3-s28 down
17CASE10: Link s3-s28 up
18CASE11: Switch down
19CASE12: Switch up
20CASE13: Clean up
21CASE14: start election app on all onos nodes
22CASE15: Check that Leadership Election is still functional
23CASE16: Install Distributed Primitives app
24CASE17: Check for basic functionality with distributed primitives
25"""
26
27
Jon Hallb3ed8ed2015-10-28 16:43:55 -070028class HAkillNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -070029
30 def __init__( self ):
31 self.default = ''
32
33 def CASE1( self, main ):
34 """
35 CASE1 is to compile ONOS and push it to the test machines
36
37 Startup sequence:
38 cell <name>
39 onos-verify-cell
40 NOTE: temporary - onos-remove-raft-logs
41 onos-uninstall
42 start mininet
43 git pull
44 mvn clean install
45 onos-package
46 onos-install -f
47 onos-wait-for-start
48 start cli sessions
49 start tcpdump
50 """
Jon Halle1a3b752015-07-22 13:02:46 -070051 import imp
Jon Hall3b489db2015-10-05 14:38:37 -070052 import pexpect
Jon Hall6e709752016-02-01 13:38:46 -080053 import time
Jon Halla440e872016-03-31 15:15:50 -070054 import json
Jon Hall6e709752016-02-01 13:38:46 -080055 main.log.info( "ONOS HA test: Restart a minority of ONOS nodes - " +
Jon Hall5cf14d52015-07-16 12:15:19 -070056 "initialization" )
57 main.case( "Setting up test environment" )
Jon Hall783bbf92015-07-23 14:33:19 -070058 main.caseExplanation = "Setup the test environment including " +\
Jon Hall5cf14d52015-07-16 12:15:19 -070059 "installing ONOS, starting Mininet and ONOS" +\
60 "cli sessions."
Jon Hall5cf14d52015-07-16 12:15:19 -070061
62 # load some variables from the params file
63 PULLCODE = False
64 if main.params[ 'Git' ] == 'True':
65 PULLCODE = True
66 gitBranch = main.params[ 'branch' ]
67 cellName = main.params[ 'ENV' ][ 'cellName' ]
68
Jon Halle1a3b752015-07-22 13:02:46 -070069 main.numCtrls = int( main.params[ 'num_controllers' ] )
Jon Hall5cf14d52015-07-16 12:15:19 -070070 if main.ONOSbench.maxNodes:
Jon Halle1a3b752015-07-22 13:02:46 -070071 if main.ONOSbench.maxNodes < main.numCtrls:
72 main.numCtrls = int( main.ONOSbench.maxNodes )
73 # set global variables
Jon Hall5cf14d52015-07-16 12:15:19 -070074 global ONOS1Port
75 global ONOS2Port
76 global ONOS3Port
77 global ONOS4Port
78 global ONOS5Port
79 global ONOS6Port
80 global ONOS7Port
Jon Halla440e872016-03-31 15:15:50 -070081 # These are for csv plotting in jenkins
82 global labels
83 global data
84 labels = []
85 data = []
Jon Hall5cf14d52015-07-16 12:15:19 -070086
87 # FIXME: just get controller port from params?
88 # TODO: do we really need all these?
89 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
90 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
91 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
92 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
93 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
94 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
95 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
96
Jon Halle1a3b752015-07-22 13:02:46 -070097 try:
Jon Hall53c5e662016-04-13 16:06:56 -070098 from tests.HA.dependencies.HA import HA
Jon Hall41d39f12016-04-11 22:54:35 -070099 main.HA = HA()
Jon Halle1a3b752015-07-22 13:02:46 -0700100 except Exception as e:
101 main.log.exception( e )
102 main.cleanup()
103 main.exit()
104
105 main.CLIs = []
106 main.nodes = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700107 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700108 for i in range( 1, main.numCtrls + 1 ):
109 try:
110 main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
111 main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
112 ipList.append( main.nodes[ -1 ].ip_address )
113 except AttributeError:
114 break
Jon Hall5cf14d52015-07-16 12:15:19 -0700115
116 main.step( "Create cell file" )
117 cellAppString = main.params[ 'ENV' ][ 'appString' ]
118 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
119 main.Mininet1.ip_address,
120 cellAppString, ipList )
121 main.step( "Applying cell variable to environment" )
122 cellResult = main.ONOSbench.setCell( cellName )
123 verifyResult = main.ONOSbench.verifyCell()
124
125 # FIXME:this is short term fix
126 main.log.info( "Removing raft logs" )
127 main.ONOSbench.onosRemoveRaftLogs()
128
129 main.log.info( "Uninstalling ONOS" )
Jon Halle1a3b752015-07-22 13:02:46 -0700130 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700131 main.ONOSbench.onosUninstall( node.ip_address )
132
133 # Make sure ONOS is DEAD
134 main.log.info( "Killing any ONOS processes" )
135 killResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700136 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700137 killed = main.ONOSbench.onosKill( node.ip_address )
138 killResults = killResults and killed
139
140 cleanInstallResult = main.TRUE
141 gitPullResult = main.TRUE
142
143 main.step( "Starting Mininet" )
144 # scp topo file to mininet
145 # TODO: move to params?
146 topoName = "obelisk.py"
147 filePath = main.ONOSbench.home + "/tools/test/topos/"
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700148 main.ONOSbench.scp( main.Mininet1,
149 filePath + topoName,
150 main.Mininet1.home,
151 direction="to" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700152 mnResult = main.Mininet1.startNet( )
153 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
154 onpass="Mininet Started",
155 onfail="Error starting Mininet" )
156
157 main.step( "Git checkout and pull " + gitBranch )
158 if PULLCODE:
159 main.ONOSbench.gitCheckout( gitBranch )
160 gitPullResult = main.ONOSbench.gitPull()
161 # values of 1 or 3 are good
162 utilities.assert_lesser( expect=0, actual=gitPullResult,
163 onpass="Git pull successful",
164 onfail="Git pull failed" )
165 main.ONOSbench.getVersion( report=True )
166
167 main.step( "Using mvn clean install" )
168 cleanInstallResult = main.TRUE
169 if PULLCODE and gitPullResult == main.TRUE:
170 cleanInstallResult = main.ONOSbench.cleanInstall()
171 else:
172 main.log.warn( "Did not pull new code so skipping mvn " +
173 "clean install" )
174 utilities.assert_equals( expect=main.TRUE,
175 actual=cleanInstallResult,
176 onpass="MCI successful",
177 onfail="MCI failed" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700178
179 main.step( "Make sure ONOS service doesn't automatically respawn" )
180 handle = main.ONOSbench.handle
181 handle.sendline( "sed -i -e 's/^respawn$/#respawn/g' tools/package/init/onos.conf" )
182 handle.expect( "\$" ) # $ from the command
183 handle.expect( "\$" ) # $ from the prompt
184
Jon Hall5cf14d52015-07-16 12:15:19 -0700185 # GRAPHS
186 # NOTE: important params here:
187 # job = name of Jenkins job
188 # Plot Name = Plot-HA, only can be used if multiple plots
189 # index = The number of the graph under plot name
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700190 job = "HAkillNodes"
Jon Hall5cf14d52015-07-16 12:15:19 -0700191 plotName = "Plot-HA"
Jon Hall843f8bc2016-03-18 14:28:13 -0700192 index = "2"
Jon Hall5cf14d52015-07-16 12:15:19 -0700193 graphs = '<ac:structured-macro ac:name="html">\n'
194 graphs += '<ac:plain-text-body><![CDATA[\n'
195 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
Jon Halla9845df2016-01-15 14:55:58 -0800196 '/plot/' + plotName + '/getPlot?index=' + index +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700197 '&width=500&height=300"' +\
198 'noborder="0" width="500" height="300" scrolling="yes" ' +\
199 'seamless="seamless"></iframe>\n'
200 graphs += ']]></ac:plain-text-body>\n'
201 graphs += '</ac:structured-macro>\n'
202 main.log.wiki(graphs)
203
204 main.step( "Creating ONOS package" )
Jon Hall3b489db2015-10-05 14:38:37 -0700205 # copy gen-partions file to ONOS
206 # NOTE: this assumes TestON and ONOS are on the same machine
Jon Hall53c5e662016-04-13 16:06:56 -0700207 srcFile = main.testDir + "/HA/dependencies/onos-gen-partitions"
Jon Hall3b489db2015-10-05 14:38:37 -0700208 dstDir = main.ONOSbench.home + "/tools/test/bin/onos-gen-partitions"
209 cpResult = main.ONOSbench.secureCopy( main.ONOSbench.user_name,
210 main.ONOSbench.ip_address,
211 srcFile,
212 dstDir,
213 pwd=main.ONOSbench.pwd,
214 direction="from" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700215 packageResult = main.ONOSbench.onosPackage()
216 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
217 onpass="ONOS package successful",
218 onfail="ONOS package failed" )
219
220 main.step( "Installing ONOS package" )
221 onosInstallResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700222 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700223 tmpResult = main.ONOSbench.onosInstall( options="-f",
224 node=node.ip_address )
225 onosInstallResult = onosInstallResult and tmpResult
226 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
227 onpass="ONOS install successful",
228 onfail="ONOS install failed" )
Jon Hall3b489db2015-10-05 14:38:37 -0700229 # clean up gen-partitions file
230 try:
231 main.ONOSbench.handle.sendline( "cd " + main.ONOSbench.home )
232 main.ONOSbench.handle.expect( main.ONOSbench.home + "\$" )
233 main.ONOSbench.handle.sendline( "git checkout -- tools/test/bin/onos-gen-partitions" )
234 main.ONOSbench.handle.expect( main.ONOSbench.home + "\$" )
235 main.log.info( " Cleaning custom gen partitions file, response was: \n" +
236 str( main.ONOSbench.handle.before ) )
237 except ( pexpect.TIMEOUT, pexpect.EOF ):
238 main.log.exception( "ONOSbench: pexpect exception found:" +
239 main.ONOSbench.handle.before )
240 main.cleanup()
241 main.exit()
Jon Hall5cf14d52015-07-16 12:15:19 -0700242
243 main.step( "Checking if ONOS is up yet" )
244 for i in range( 2 ):
245 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700246 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700247 started = main.ONOSbench.isup( node.ip_address )
248 if not started:
Jon Hallc6793552016-01-19 14:18:37 -0800249 main.log.error( node.name + " hasn't started" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700250 onosIsupResult = onosIsupResult and started
251 if onosIsupResult == main.TRUE:
252 break
253 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
254 onpass="ONOS startup successful",
255 onfail="ONOS startup failed" )
256
257 main.log.step( "Starting ONOS CLI sessions" )
258 cliResults = main.TRUE
259 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700260 for i in range( main.numCtrls ):
261 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -0700262 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -0700263 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -0700264 threads.append( t )
265 t.start()
266
267 for t in threads:
268 t.join()
269 cliResults = cliResults and t.result
270 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
271 onpass="ONOS cli startup successful",
272 onfail="ONOS cli startup failed" )
273
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700274 # Create a list of active nodes for use when some nodes are stopped
275 main.activeNodes = [ i for i in range( 0, len( main.CLIs ) ) ]
276
Jon Hall5cf14d52015-07-16 12:15:19 -0700277 if main.params[ 'tcpdump' ].lower() == "true":
278 main.step( "Start Packet Capture MN" )
279 main.Mininet2.startTcpdump(
280 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
281 + "-MN.pcap",
282 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
283 port=main.params[ 'MNtcpdump' ][ 'port' ] )
284
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700285 main.step( "Clean up ONOS service changes" )
286 handle.sendline( "git checkout -- tools/package/init/onos.conf" )
287 handle.expect( "\$" )
288
Jon Halla440e872016-03-31 15:15:50 -0700289 main.step( "Checking ONOS nodes" )
Jon Hall41d39f12016-04-11 22:54:35 -0700290 nodeResults = utilities.retry( main.HA.nodesCheck,
291 False,
292 args=[main.activeNodes],
293 attempts=5 )
Jon Halla440e872016-03-31 15:15:50 -0700294
Jon Hall41d39f12016-04-11 22:54:35 -0700295 utilities.assert_equals( expect=True, actual=nodeResults,
Jon Halla440e872016-03-31 15:15:50 -0700296 onpass="Nodes check successful",
297 onfail="Nodes check NOT successful" )
298
299 if not nodeResults:
Jon Hall7ac7bc32016-05-05 10:57:02 -0700300 for i in main.activeNodes:
301 cli = main.CLIs[i]
Jon Halla440e872016-03-31 15:15:50 -0700302 main.log.debug( "{} components not ACTIVE: \n{}".format(
303 cli.name,
304 cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
305
Jon Hall5cf14d52015-07-16 12:15:19 -0700306 if cliResults == main.FALSE:
307 main.log.error( "Failed to start ONOS, stopping test" )
308 main.cleanup()
309 main.exit()
310
Jon Hall172b7ba2016-04-07 18:12:20 -0700311 main.step( "Activate apps defined in the params file" )
312 # get data from the params
313 apps = main.params.get( 'apps' )
314 if apps:
315 apps = apps.split(',')
316 main.log.warn( apps )
317 activateResult = True
318 for app in apps:
319 main.CLIs[ 0 ].app( app, "Activate" )
320 # TODO: check this worked
321 time.sleep( 10 ) # wait for apps to activate
322 for app in apps:
323 state = main.CLIs[ 0 ].appStatus( app )
324 if state == "ACTIVE":
325 activateResult = activeResult and True
326 else:
327 main.log.error( "{} is in {} state".format( app, state ) )
328 activeResult = False
329 utilities.assert_equals( expect=True,
330 actual=activateResult,
331 onpass="Successfully activated apps",
332 onfail="Failed to activate apps" )
333 else:
334 main.log.warn( "No apps were specified to be loaded after startup" )
335
336 main.step( "Set ONOS configurations" )
337 config = main.params.get( 'ONOS_Configuration' )
338 if config:
339 main.log.debug( config )
340 checkResult = main.TRUE
341 for component in config:
342 for setting in config[component]:
343 value = config[component][setting]
344 check = main.CLIs[ 0 ].setCfg( component, setting, value )
345 main.log.info( "Value was changed? {}".format( main.TRUE == check ) )
346 checkResult = check and checkResult
347 utilities.assert_equals( expect=main.TRUE,
348 actual=checkResult,
349 onpass="Successfully set config",
350 onfail="Failed to set config" )
351 else:
352 main.log.warn( "No configurations were specified to be changed after startup" )
353
Jon Hall9d2dcad2016-04-08 10:15:20 -0700354 main.step( "App Ids check" )
355 appCheck = main.TRUE
356 threads = []
357 for i in main.activeNodes:
358 t = main.Thread( target=main.CLIs[i].appToIDCheck,
359 name="appToIDCheck-" + str( i ),
360 args=[] )
361 threads.append( t )
362 t.start()
363
364 for t in threads:
365 t.join()
366 appCheck = appCheck and t.result
367 if appCheck != main.TRUE:
368 node = main.activeNodes[0]
369 main.log.warn( main.CLIs[node].apps() )
370 main.log.warn( main.CLIs[node].appIDs() )
371 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
372 onpass="App Ids seem to be correct",
373 onfail="Something is wrong with app Ids" )
374
Jon Hall5cf14d52015-07-16 12:15:19 -0700375 def CASE2( self, main ):
376 """
377 Assign devices to controllers
378 """
379 import re
Jon Halle1a3b752015-07-22 13:02:46 -0700380 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700381 assert main, "main not defined"
382 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700383 assert main.CLIs, "main.CLIs not defined"
384 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700385 assert ONOS1Port, "ONOS1Port not defined"
386 assert ONOS2Port, "ONOS2Port not defined"
387 assert ONOS3Port, "ONOS3Port not defined"
388 assert ONOS4Port, "ONOS4Port not defined"
389 assert ONOS5Port, "ONOS5Port not defined"
390 assert ONOS6Port, "ONOS6Port not defined"
391 assert ONOS7Port, "ONOS7Port not defined"
392
393 main.case( "Assigning devices to controllers" )
Jon Hall783bbf92015-07-23 14:33:19 -0700394 main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700395 "and check that an ONOS node becomes the " +\
396 "master of the device."
397 main.step( "Assign switches to controllers" )
398
399 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700400 for i in range( main.numCtrls ):
401 ipList.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -0700402 swList = []
403 for i in range( 1, 29 ):
404 swList.append( "s" + str( i ) )
405 main.Mininet1.assignSwController( sw=swList, ip=ipList )
406
407 mastershipCheck = main.TRUE
408 for i in range( 1, 29 ):
409 response = main.Mininet1.getSwController( "s" + str( i ) )
410 try:
411 main.log.info( str( response ) )
412 except Exception:
413 main.log.info( repr( response ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700414 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700415 if re.search( "tcp:" + node.ip_address, response ):
416 mastershipCheck = mastershipCheck and main.TRUE
417 else:
418 main.log.error( "Error, node " + node.ip_address + " is " +
419 "not in the list of controllers s" +
420 str( i ) + " is connecting to." )
421 mastershipCheck = main.FALSE
422 utilities.assert_equals(
423 expect=main.TRUE,
424 actual=mastershipCheck,
425 onpass="Switch mastership assigned correctly",
426 onfail="Switches not assigned correctly to controllers" )
427
428 def CASE21( self, main ):
429 """
430 Assign mastership to controllers
431 """
Jon Hall5cf14d52015-07-16 12:15:19 -0700432 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700433 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700434 assert main, "main not defined"
435 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700436 assert main.CLIs, "main.CLIs not defined"
437 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700438 assert ONOS1Port, "ONOS1Port not defined"
439 assert ONOS2Port, "ONOS2Port not defined"
440 assert ONOS3Port, "ONOS3Port not defined"
441 assert ONOS4Port, "ONOS4Port not defined"
442 assert ONOS5Port, "ONOS5Port not defined"
443 assert ONOS6Port, "ONOS6Port not defined"
444 assert ONOS7Port, "ONOS7Port not defined"
445
446 main.case( "Assigning Controller roles for switches" )
Jon Hall783bbf92015-07-23 14:33:19 -0700447 main.caseExplanation = "Check that ONOS is connected to each " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700448 "device. Then manually assign" +\
449 " mastership to specific ONOS nodes using" +\
450 " 'device-role'"
451 main.step( "Assign mastership of switches to specific controllers" )
452 # Manually assign mastership to the controller we want
453 roleCall = main.TRUE
454
455 ipList = [ ]
456 deviceList = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700457 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -0700458 try:
459 # Assign mastership to specific controllers. This assignment was
460 # determined for a 7 node cluser, but will work with any sized
461 # cluster
462 for i in range( 1, 29 ): # switches 1 through 28
463 # set up correct variables:
464 if i == 1:
465 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700466 ip = main.nodes[ c ].ip_address # ONOS1
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700467 deviceId = onosCli.getDevice( "1000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700468 elif i == 2:
Jon Halle1a3b752015-07-22 13:02:46 -0700469 c = 1 % main.numCtrls
470 ip = main.nodes[ c ].ip_address # ONOS2
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700471 deviceId = onosCli.getDevice( "2000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700472 elif i == 3:
Jon Halle1a3b752015-07-22 13:02:46 -0700473 c = 1 % main.numCtrls
474 ip = main.nodes[ c ].ip_address # ONOS2
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700475 deviceId = onosCli.getDevice( "3000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700476 elif i == 4:
Jon Halle1a3b752015-07-22 13:02:46 -0700477 c = 3 % main.numCtrls
478 ip = main.nodes[ c ].ip_address # ONOS4
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700479 deviceId = onosCli.getDevice( "3004" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700480 elif i == 5:
Jon Halle1a3b752015-07-22 13:02:46 -0700481 c = 2 % main.numCtrls
482 ip = main.nodes[ c ].ip_address # ONOS3
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700483 deviceId = onosCli.getDevice( "5000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700484 elif i == 6:
Jon Halle1a3b752015-07-22 13:02:46 -0700485 c = 2 % main.numCtrls
486 ip = main.nodes[ c ].ip_address # ONOS3
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700487 deviceId = onosCli.getDevice( "6000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700488 elif i == 7:
Jon Halle1a3b752015-07-22 13:02:46 -0700489 c = 5 % main.numCtrls
490 ip = main.nodes[ c ].ip_address # ONOS6
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700491 deviceId = onosCli.getDevice( "6007" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700492 elif i >= 8 and i <= 17:
Jon Halle1a3b752015-07-22 13:02:46 -0700493 c = 4 % main.numCtrls
494 ip = main.nodes[ c ].ip_address # ONOS5
Jon Hall5cf14d52015-07-16 12:15:19 -0700495 dpid = '3' + str( i ).zfill( 3 )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700496 deviceId = onosCli.getDevice( dpid ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700497 elif i >= 18 and i <= 27:
Jon Halle1a3b752015-07-22 13:02:46 -0700498 c = 6 % main.numCtrls
499 ip = main.nodes[ c ].ip_address # ONOS7
Jon Hall5cf14d52015-07-16 12:15:19 -0700500 dpid = '6' + str( i ).zfill( 3 )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700501 deviceId = onosCli.getDevice( dpid ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700502 elif i == 28:
503 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700504 ip = main.nodes[ c ].ip_address # ONOS1
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700505 deviceId = onosCli.getDevice( "2800" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700506 else:
507 main.log.error( "You didn't write an else statement for " +
508 "switch s" + str( i ) )
509 roleCall = main.FALSE
510 # Assign switch
511 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
512 # TODO: make this controller dynamic
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700513 roleCall = roleCall and onosCli.deviceRole( deviceId, ip )
Jon Hall5cf14d52015-07-16 12:15:19 -0700514 ipList.append( ip )
515 deviceList.append( deviceId )
516 except ( AttributeError, AssertionError ):
517 main.log.exception( "Something is wrong with ONOS device view" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700518 main.log.info( onosCli.devices() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700519 utilities.assert_equals(
520 expect=main.TRUE,
521 actual=roleCall,
522 onpass="Re-assigned switch mastership to designated controller",
523 onfail="Something wrong with deviceRole calls" )
524
525 main.step( "Check mastership was correctly assigned" )
526 roleCheck = main.TRUE
527 # NOTE: This is due to the fact that device mastership change is not
528 # atomic and is actually a multi step process
529 time.sleep( 5 )
530 for i in range( len( ipList ) ):
531 ip = ipList[i]
532 deviceId = deviceList[i]
533 # Check assignment
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700534 master = onosCli.getRole( deviceId ).get( 'master' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700535 if ip in master:
536 roleCheck = roleCheck and main.TRUE
537 else:
538 roleCheck = roleCheck and main.FALSE
539 main.log.error( "Error, controller " + ip + " is not" +
540 " master " + "of device " +
541 str( deviceId ) + ". Master is " +
542 repr( master ) + "." )
543 utilities.assert_equals(
544 expect=main.TRUE,
545 actual=roleCheck,
546 onpass="Switches were successfully reassigned to designated " +
547 "controller",
548 onfail="Switches were not successfully reassigned" )
549
550 def CASE3( self, main ):
551 """
552 Assign intents
553 """
554 import time
555 import json
Jon Halle1a3b752015-07-22 13:02:46 -0700556 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700557 assert main, "main not defined"
558 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700559 assert main.CLIs, "main.CLIs not defined"
560 assert main.nodes, "main.nodes not defined"
Jon Halla440e872016-03-31 15:15:50 -0700561 try:
562 labels
563 except NameError:
564 main.log.error( "labels not defined, setting to []" )
565 labels = []
566 try:
567 data
568 except NameError:
569 main.log.error( "data not defined, setting to []" )
570 data = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700571 main.case( "Adding host Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700572 main.caseExplanation = "Discover hosts by using pingall then " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700573 "assign predetermined host-to-host intents." +\
574 " After installation, check that the intent" +\
575 " is distributed to all nodes and the state" +\
576 " is INSTALLED"
577
578 # install onos-app-fwd
579 main.step( "Install reactive forwarding app" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700580 onosCli = main.CLIs[ main.activeNodes[0] ]
581 installResults = onosCli.activateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700582 utilities.assert_equals( expect=main.TRUE, actual=installResults,
583 onpass="Install fwd successful",
584 onfail="Install fwd failed" )
585
586 main.step( "Check app ids" )
587 appCheck = main.TRUE
588 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700589 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -0700590 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700591 name="appToIDCheck-" + str( i ),
592 args=[] )
593 threads.append( t )
594 t.start()
595
596 for t in threads:
597 t.join()
598 appCheck = appCheck and t.result
599 if appCheck != main.TRUE:
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700600 main.log.warn( onosCli.apps() )
601 main.log.warn( onosCli.appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700602 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
603 onpass="App Ids seem to be correct",
604 onfail="Something is wrong with app Ids" )
605
606 main.step( "Discovering Hosts( Via pingall for now )" )
607 # FIXME: Once we have a host discovery mechanism, use that instead
608 # REACTIVE FWD test
609 pingResult = main.FALSE
Jon Hall96091e62015-09-21 17:34:17 -0700610 passMsg = "Reactive Pingall test passed"
611 time1 = time.time()
612 pingResult = main.Mininet1.pingall()
613 time2 = time.time()
614 if not pingResult:
615 main.log.warn("First pingall failed. Trying again...")
Jon Hall5cf14d52015-07-16 12:15:19 -0700616 pingResult = main.Mininet1.pingall()
Jon Hall96091e62015-09-21 17:34:17 -0700617 passMsg += " on the second try"
618 utilities.assert_equals(
619 expect=main.TRUE,
620 actual=pingResult,
621 onpass= passMsg,
622 onfail="Reactive Pingall failed, " +
623 "one or more ping pairs failed" )
624 main.log.info( "Time for pingall: %2f seconds" %
625 ( time2 - time1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -0700626 # timeout for fwd flows
627 time.sleep( 11 )
628 # uninstall onos-app-fwd
629 main.step( "Uninstall reactive forwarding app" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700630 node = main.activeNodes[0]
631 uninstallResult = main.CLIs[node].deactivateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700632 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
633 onpass="Uninstall fwd successful",
634 onfail="Uninstall fwd failed" )
635
636 main.step( "Check app ids" )
637 threads = []
638 appCheck2 = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700639 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -0700640 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700641 name="appToIDCheck-" + str( i ),
642 args=[] )
643 threads.append( t )
644 t.start()
645
646 for t in threads:
647 t.join()
648 appCheck2 = appCheck2 and t.result
649 if appCheck2 != main.TRUE:
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700650 node = main.activeNodes[0]
651 main.log.warn( main.CLIs[node].apps() )
652 main.log.warn( main.CLIs[node].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700653 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
654 onpass="App Ids seem to be correct",
655 onfail="Something is wrong with app Ids" )
656
657 main.step( "Add host intents via cli" )
658 intentIds = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700659 # TODO: move the host numbers to params
660 # Maybe look at all the paths we ping?
Jon Hall5cf14d52015-07-16 12:15:19 -0700661 intentAddResult = True
662 hostResult = main.TRUE
663 for i in range( 8, 18 ):
664 main.log.info( "Adding host intent between h" + str( i ) +
665 " and h" + str( i + 10 ) )
666 host1 = "00:00:00:00:00:" + \
667 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
668 host2 = "00:00:00:00:00:" + \
669 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
670 # NOTE: getHost can return None
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700671 host1Dict = onosCli.getHost( host1 )
672 host2Dict = onosCli.getHost( host2 )
Jon Hall5cf14d52015-07-16 12:15:19 -0700673 host1Id = None
674 host2Id = None
675 if host1Dict and host2Dict:
676 host1Id = host1Dict.get( 'id', None )
677 host2Id = host2Dict.get( 'id', None )
678 if host1Id and host2Id:
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700679 nodeNum = ( i % len( main.activeNodes ) )
680 node = main.activeNodes[nodeNum]
681 tmpId = main.CLIs[node].addHostIntent( host1Id, host2Id )
Jon Hall5cf14d52015-07-16 12:15:19 -0700682 if tmpId:
683 main.log.info( "Added intent with id: " + tmpId )
684 intentIds.append( tmpId )
685 else:
686 main.log.error( "addHostIntent returned: " +
687 repr( tmpId ) )
688 else:
689 main.log.error( "Error, getHost() failed for h" + str( i ) +
690 " and/or h" + str( i + 10 ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700691 node = main.activeNodes[0]
692 hosts = main.CLIs[node].hosts()
Jon Hall5cf14d52015-07-16 12:15:19 -0700693 main.log.warn( "Hosts output: " )
694 try:
695 main.log.warn( json.dumps( json.loads( hosts ),
696 sort_keys=True,
697 indent=4,
698 separators=( ',', ': ' ) ) )
699 except ( ValueError, TypeError ):
700 main.log.warn( repr( hosts ) )
701 hostResult = main.FALSE
702 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
703 onpass="Found a host id for each host",
704 onfail="Error looking up host ids" )
705
706 intentStart = time.time()
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700707 onosIds = onosCli.getAllIntentsId()
Jon Hall5cf14d52015-07-16 12:15:19 -0700708 main.log.info( "Submitted intents: " + str( intentIds ) )
709 main.log.info( "Intents in ONOS: " + str( onosIds ) )
710 for intent in intentIds:
711 if intent in onosIds:
712 pass # intent submitted is in onos
713 else:
714 intentAddResult = False
715 if intentAddResult:
716 intentStop = time.time()
717 else:
718 intentStop = None
719 # Print the intent states
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700720 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700721 intentStates = []
722 installedCheck = True
723 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
724 count = 0
725 try:
726 for intent in json.loads( intents ):
727 state = intent.get( 'state', None )
728 if "INSTALLED" not in state:
729 installedCheck = False
730 intentId = intent.get( 'id', None )
731 intentStates.append( ( intentId, state ) )
732 except ( ValueError, TypeError ):
733 main.log.exception( "Error parsing intents" )
734 # add submitted intents not in the store
735 tmplist = [ i for i, s in intentStates ]
736 missingIntents = False
737 for i in intentIds:
738 if i not in tmplist:
739 intentStates.append( ( i, " - " ) )
740 missingIntents = True
741 intentStates.sort()
742 for i, s in intentStates:
743 count += 1
744 main.log.info( "%-6s%-15s%-15s" %
745 ( str( count ), str( i ), str( s ) ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700746 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -0700747 try:
748 missing = False
749 if leaders:
750 parsedLeaders = json.loads( leaders )
751 main.log.warn( json.dumps( parsedLeaders,
752 sort_keys=True,
753 indent=4,
754 separators=( ',', ': ' ) ) )
755 # check for all intent partitions
756 topics = []
757 for i in range( 14 ):
758 topics.append( "intent-partition-" + str( i ) )
759 main.log.debug( topics )
760 ONOStopics = [ j['topic'] for j in parsedLeaders ]
761 for topic in topics:
762 if topic not in ONOStopics:
763 main.log.error( "Error: " + topic +
764 " not in leaders" )
765 missing = True
766 else:
767 main.log.error( "leaders() returned None" )
768 except ( ValueError, TypeError ):
769 main.log.exception( "Error parsing leaders" )
770 main.log.error( repr( leaders ) )
771 # Check all nodes
772 if missing:
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700773 for i in main.activeNodes:
774 response = main.CLIs[i].leaders( jsonFormat=False)
775 main.log.warn( str( main.CLIs[i].name ) + " leaders output: \n" +
Jon Hall5cf14d52015-07-16 12:15:19 -0700776 str( response ) )
777
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700778 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -0700779 try:
780 if partitions :
781 parsedPartitions = json.loads( partitions )
782 main.log.warn( json.dumps( parsedPartitions,
783 sort_keys=True,
784 indent=4,
785 separators=( ',', ': ' ) ) )
786 # TODO check for a leader in all paritions
787 # TODO check for consistency among nodes
788 else:
789 main.log.error( "partitions() returned None" )
790 except ( ValueError, TypeError ):
791 main.log.exception( "Error parsing partitions" )
792 main.log.error( repr( partitions ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700793 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -0700794 try:
795 if pendingMap :
796 parsedPending = json.loads( pendingMap )
797 main.log.warn( json.dumps( parsedPending,
798 sort_keys=True,
799 indent=4,
800 separators=( ',', ': ' ) ) )
801 # TODO check something here?
802 else:
803 main.log.error( "pendingMap() returned None" )
804 except ( ValueError, TypeError ):
805 main.log.exception( "Error parsing pending map" )
806 main.log.error( repr( pendingMap ) )
807
808 intentAddResult = bool( intentAddResult and not missingIntents and
809 installedCheck )
810 if not intentAddResult:
811 main.log.error( "Error in pushing host intents to ONOS" )
812
813 main.step( "Intent Anti-Entropy dispersion" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700814 for j in range(100):
Jon Hall5cf14d52015-07-16 12:15:19 -0700815 correct = True
816 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700817 for i in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700818 onosIds = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700819 ids = main.CLIs[i].getAllIntentsId()
Jon Hall5cf14d52015-07-16 12:15:19 -0700820 onosIds.append( ids )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700821 main.log.debug( "Intents in " + main.CLIs[i].name + ": " +
Jon Hall5cf14d52015-07-16 12:15:19 -0700822 str( sorted( onosIds ) ) )
823 if sorted( ids ) != sorted( intentIds ):
824 main.log.warn( "Set of intent IDs doesn't match" )
825 correct = False
826 break
827 else:
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700828 intents = json.loads( main.CLIs[i].intents() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700829 for intent in intents:
830 if intent[ 'state' ] != "INSTALLED":
831 main.log.warn( "Intent " + intent[ 'id' ] +
832 " is " + intent[ 'state' ] )
833 correct = False
834 break
835 if correct:
836 break
837 else:
838 time.sleep(1)
839 if not intentStop:
840 intentStop = time.time()
841 global gossipTime
842 gossipTime = intentStop - intentStart
843 main.log.info( "It took about " + str( gossipTime ) +
844 " seconds for all intents to appear in each node" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700845 gossipPeriod = int( main.params['timers']['gossip'] )
846 maxGossipTime = gossipPeriod * len( main.activeNodes )
Jon Hall5cf14d52015-07-16 12:15:19 -0700847 utilities.assert_greater_equals(
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700848 expect=maxGossipTime, actual=gossipTime,
Jon Hall5cf14d52015-07-16 12:15:19 -0700849 onpass="ECM anti-entropy for intents worked within " +
850 "expected time",
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700851 onfail="Intent ECM anti-entropy took too long. " +
852 "Expected time:{}, Actual time:{}".format( maxGossipTime,
853 gossipTime ) )
854 if gossipTime <= maxGossipTime:
Jon Hall5cf14d52015-07-16 12:15:19 -0700855 intentAddResult = True
856
857 if not intentAddResult or "key" in pendingMap:
858 import time
859 installedCheck = True
860 main.log.info( "Sleeping 60 seconds to see if intents are found" )
861 time.sleep( 60 )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700862 onosIds = onosCli.getAllIntentsId()
Jon Hall5cf14d52015-07-16 12:15:19 -0700863 main.log.info( "Submitted intents: " + str( intentIds ) )
864 main.log.info( "Intents in ONOS: " + str( onosIds ) )
865 # Print the intent states
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700866 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700867 intentStates = []
868 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
869 count = 0
870 try:
871 for intent in json.loads( intents ):
872 # Iter through intents of a node
873 state = intent.get( 'state', None )
874 if "INSTALLED" not in state:
875 installedCheck = False
876 intentId = intent.get( 'id', None )
877 intentStates.append( ( intentId, state ) )
878 except ( ValueError, TypeError ):
879 main.log.exception( "Error parsing intents" )
880 # add submitted intents not in the store
881 tmplist = [ i for i, s in intentStates ]
882 for i in intentIds:
883 if i not in tmplist:
884 intentStates.append( ( i, " - " ) )
885 intentStates.sort()
886 for i, s in intentStates:
887 count += 1
888 main.log.info( "%-6s%-15s%-15s" %
889 ( str( count ), str( i ), str( s ) ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700890 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -0700891 try:
892 missing = False
893 if leaders:
894 parsedLeaders = json.loads( leaders )
895 main.log.warn( json.dumps( parsedLeaders,
896 sort_keys=True,
897 indent=4,
898 separators=( ',', ': ' ) ) )
899 # check for all intent partitions
900 # check for election
901 topics = []
902 for i in range( 14 ):
903 topics.append( "intent-partition-" + str( i ) )
904 # FIXME: this should only be after we start the app
905 topics.append( "org.onosproject.election" )
906 main.log.debug( topics )
907 ONOStopics = [ j['topic'] for j in parsedLeaders ]
908 for topic in topics:
909 if topic not in ONOStopics:
910 main.log.error( "Error: " + topic +
911 " not in leaders" )
912 missing = True
913 else:
914 main.log.error( "leaders() returned None" )
915 except ( ValueError, TypeError ):
916 main.log.exception( "Error parsing leaders" )
917 main.log.error( repr( leaders ) )
918 # Check all nodes
919 if missing:
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700920 for i in main.activeNodes:
921 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -0700922 response = node.leaders( jsonFormat=False)
923 main.log.warn( str( node.name ) + " leaders output: \n" +
924 str( response ) )
925
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700926 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -0700927 try:
928 if partitions :
929 parsedPartitions = json.loads( partitions )
930 main.log.warn( json.dumps( parsedPartitions,
931 sort_keys=True,
932 indent=4,
933 separators=( ',', ': ' ) ) )
934 # TODO check for a leader in all paritions
935 # TODO check for consistency among nodes
936 else:
937 main.log.error( "partitions() returned None" )
938 except ( ValueError, TypeError ):
939 main.log.exception( "Error parsing partitions" )
940 main.log.error( repr( partitions ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700941 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -0700942 try:
943 if pendingMap :
944 parsedPending = json.loads( pendingMap )
945 main.log.warn( json.dumps( parsedPending,
946 sort_keys=True,
947 indent=4,
948 separators=( ',', ': ' ) ) )
949 # TODO check something here?
950 else:
951 main.log.error( "pendingMap() returned None" )
952 except ( ValueError, TypeError ):
953 main.log.exception( "Error parsing pending map" )
954 main.log.error( repr( pendingMap ) )
955
956 def CASE4( self, main ):
957 """
958 Ping across added host intents
959 """
960 import json
961 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700962 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700963 assert main, "main not defined"
964 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700965 assert main.CLIs, "main.CLIs not defined"
966 assert main.nodes, "main.nodes not defined"
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700967 main.case( "Verify connectivity by sending traffic across Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700968 main.caseExplanation = "Ping across added host intents to check " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700969 "functionality and check the state of " +\
970 "the intent"
Jon Hall5cf14d52015-07-16 12:15:19 -0700971
Jon Hall41d39f12016-04-11 22:54:35 -0700972 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -0700973 main.step( "Check Intent state" )
974 installedCheck = False
975 loopCount = 0
976 while not installedCheck and loopCount < 40:
977 installedCheck = True
978 # Print the intent states
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700979 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700980 intentStates = []
981 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
982 count = 0
983 # Iter through intents of a node
984 try:
985 for intent in json.loads( intents ):
986 state = intent.get( 'state', None )
987 if "INSTALLED" not in state:
988 installedCheck = False
989 intentId = intent.get( 'id', None )
990 intentStates.append( ( intentId, state ) )
991 except ( ValueError, TypeError ):
992 main.log.exception( "Error parsing intents." )
993 # Print states
994 intentStates.sort()
995 for i, s in intentStates:
996 count += 1
997 main.log.info( "%-6s%-15s%-15s" %
998 ( str( count ), str( i ), str( s ) ) )
999 if not installedCheck:
1000 time.sleep( 1 )
1001 loopCount += 1
1002 utilities.assert_equals( expect=True, actual=installedCheck,
1003 onpass="Intents are all INSTALLED",
1004 onfail="Intents are not all in " +
1005 "INSTALLED state" )
1006
Jon Hall9d2dcad2016-04-08 10:15:20 -07001007 main.step( "Ping across added host intents" )
Jon Hall9d2dcad2016-04-08 10:15:20 -07001008 PingResult = main.TRUE
1009 for i in range( 8, 18 ):
1010 ping = main.Mininet1.pingHost( src="h" + str( i ),
1011 target="h" + str( i + 10 ) )
1012 PingResult = PingResult and ping
1013 if ping == main.FALSE:
1014 main.log.warn( "Ping failed between h" + str( i ) +
1015 " and h" + str( i + 10 ) )
1016 elif ping == main.TRUE:
1017 main.log.info( "Ping test passed!" )
1018 # Don't set PingResult or you'd override failures
1019 if PingResult == main.FALSE:
1020 main.log.error(
1021 "Intents have not been installed correctly, pings failed." )
1022 # TODO: pretty print
1023 main.log.warn( "ONOS1 intents: " )
1024 try:
1025 tmpIntents = onosCli.intents()
1026 main.log.warn( json.dumps( json.loads( tmpIntents ),
1027 sort_keys=True,
1028 indent=4,
1029 separators=( ',', ': ' ) ) )
1030 except ( ValueError, TypeError ):
1031 main.log.warn( repr( tmpIntents ) )
1032 utilities.assert_equals(
1033 expect=main.TRUE,
1034 actual=PingResult,
1035 onpass="Intents have been installed correctly and pings work",
1036 onfail="Intents have not been installed correctly, pings failed." )
1037
Jon Hall5cf14d52015-07-16 12:15:19 -07001038 main.step( "Check leadership of topics" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001039 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -07001040 topicCheck = main.TRUE
1041 try:
1042 if leaders:
1043 parsedLeaders = json.loads( leaders )
1044 main.log.warn( json.dumps( parsedLeaders,
1045 sort_keys=True,
1046 indent=4,
1047 separators=( ',', ': ' ) ) )
1048 # check for all intent partitions
1049 # check for election
1050 # TODO: Look at Devices as topics now that it uses this system
1051 topics = []
1052 for i in range( 14 ):
1053 topics.append( "intent-partition-" + str( i ) )
1054 # FIXME: this should only be after we start the app
1055 # FIXME: topics.append( "org.onosproject.election" )
1056 # Print leaders output
1057 main.log.debug( topics )
1058 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1059 for topic in topics:
1060 if topic not in ONOStopics:
1061 main.log.error( "Error: " + topic +
1062 " not in leaders" )
1063 topicCheck = main.FALSE
1064 else:
1065 main.log.error( "leaders() returned None" )
1066 topicCheck = main.FALSE
1067 except ( ValueError, TypeError ):
1068 topicCheck = main.FALSE
1069 main.log.exception( "Error parsing leaders" )
1070 main.log.error( repr( leaders ) )
1071 # TODO: Check for a leader of these topics
1072 # Check all nodes
1073 if topicCheck:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001074 for i in main.activeNodes:
1075 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07001076 response = node.leaders( jsonFormat=False)
1077 main.log.warn( str( node.name ) + " leaders output: \n" +
1078 str( response ) )
1079
1080 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
1081 onpass="intent Partitions is in leaders",
1082 onfail="Some topics were lost " )
1083 # Print partitions
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001084 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -07001085 try:
1086 if partitions :
1087 parsedPartitions = json.loads( partitions )
1088 main.log.warn( json.dumps( parsedPartitions,
1089 sort_keys=True,
1090 indent=4,
1091 separators=( ',', ': ' ) ) )
1092 # TODO check for a leader in all paritions
1093 # TODO check for consistency among nodes
1094 else:
1095 main.log.error( "partitions() returned None" )
1096 except ( ValueError, TypeError ):
1097 main.log.exception( "Error parsing partitions" )
1098 main.log.error( repr( partitions ) )
1099 # Print Pending Map
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001100 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -07001101 try:
1102 if pendingMap :
1103 parsedPending = json.loads( pendingMap )
1104 main.log.warn( json.dumps( parsedPending,
1105 sort_keys=True,
1106 indent=4,
1107 separators=( ',', ': ' ) ) )
1108 # TODO check something here?
1109 else:
1110 main.log.error( "pendingMap() returned None" )
1111 except ( ValueError, TypeError ):
1112 main.log.exception( "Error parsing pending map" )
1113 main.log.error( repr( pendingMap ) )
1114
1115 if not installedCheck:
1116 main.log.info( "Waiting 60 seconds to see if the state of " +
1117 "intents change" )
1118 time.sleep( 60 )
1119 # Print the intent states
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001120 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -07001121 intentStates = []
1122 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
1123 count = 0
1124 # Iter through intents of a node
1125 try:
1126 for intent in json.loads( intents ):
1127 state = intent.get( 'state', None )
1128 if "INSTALLED" not in state:
1129 installedCheck = False
1130 intentId = intent.get( 'id', None )
1131 intentStates.append( ( intentId, state ) )
1132 except ( ValueError, TypeError ):
1133 main.log.exception( "Error parsing intents." )
1134 intentStates.sort()
1135 for i, s in intentStates:
1136 count += 1
1137 main.log.info( "%-6s%-15s%-15s" %
1138 ( str( count ), str( i ), str( s ) ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001139 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -07001140 try:
1141 missing = False
1142 if leaders:
1143 parsedLeaders = json.loads( leaders )
1144 main.log.warn( json.dumps( parsedLeaders,
1145 sort_keys=True,
1146 indent=4,
1147 separators=( ',', ': ' ) ) )
1148 # check for all intent partitions
1149 # check for election
1150 topics = []
1151 for i in range( 14 ):
1152 topics.append( "intent-partition-" + str( i ) )
1153 # FIXME: this should only be after we start the app
1154 topics.append( "org.onosproject.election" )
1155 main.log.debug( topics )
1156 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1157 for topic in topics:
1158 if topic not in ONOStopics:
1159 main.log.error( "Error: " + topic +
1160 " not in leaders" )
1161 missing = True
1162 else:
1163 main.log.error( "leaders() returned None" )
1164 except ( ValueError, TypeError ):
1165 main.log.exception( "Error parsing leaders" )
1166 main.log.error( repr( leaders ) )
1167 if missing:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001168 for i in main.activeNodes:
1169 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07001170 response = node.leaders( jsonFormat=False)
1171 main.log.warn( str( node.name ) + " leaders output: \n" +
1172 str( response ) )
1173
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001174 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -07001175 try:
1176 if partitions :
1177 parsedPartitions = json.loads( partitions )
1178 main.log.warn( json.dumps( parsedPartitions,
1179 sort_keys=True,
1180 indent=4,
1181 separators=( ',', ': ' ) ) )
1182 # TODO check for a leader in all paritions
1183 # TODO check for consistency among nodes
1184 else:
1185 main.log.error( "partitions() returned None" )
1186 except ( ValueError, TypeError ):
1187 main.log.exception( "Error parsing partitions" )
1188 main.log.error( repr( partitions ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001189 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -07001190 try:
1191 if pendingMap :
1192 parsedPending = json.loads( pendingMap )
1193 main.log.warn( json.dumps( parsedPending,
1194 sort_keys=True,
1195 indent=4,
1196 separators=( ',', ': ' ) ) )
1197 # TODO check something here?
1198 else:
1199 main.log.error( "pendingMap() returned None" )
1200 except ( ValueError, TypeError ):
1201 main.log.exception( "Error parsing pending map" )
1202 main.log.error( repr( pendingMap ) )
1203 # Print flowrules
Jon Hall41d39f12016-04-11 22:54:35 -07001204 main.log.debug( onosCli.flows( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001205 main.step( "Wait a minute then ping again" )
1206 # the wait is above
1207 PingResult = main.TRUE
1208 for i in range( 8, 18 ):
1209 ping = main.Mininet1.pingHost( src="h" + str( i ),
1210 target="h" + str( i + 10 ) )
1211 PingResult = PingResult and ping
1212 if ping == main.FALSE:
1213 main.log.warn( "Ping failed between h" + str( i ) +
1214 " and h" + str( i + 10 ) )
1215 elif ping == main.TRUE:
1216 main.log.info( "Ping test passed!" )
1217 # Don't set PingResult or you'd override failures
1218 if PingResult == main.FALSE:
1219 main.log.error(
1220 "Intents have not been installed correctly, pings failed." )
1221 # TODO: pretty print
1222 main.log.warn( "ONOS1 intents: " )
1223 try:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001224 tmpIntents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -07001225 main.log.warn( json.dumps( json.loads( tmpIntents ),
1226 sort_keys=True,
1227 indent=4,
1228 separators=( ',', ': ' ) ) )
1229 except ( ValueError, TypeError ):
1230 main.log.warn( repr( tmpIntents ) )
1231 utilities.assert_equals(
1232 expect=main.TRUE,
1233 actual=PingResult,
1234 onpass="Intents have been installed correctly and pings work",
1235 onfail="Intents have not been installed correctly, pings failed." )
1236
1237 def CASE5( self, main ):
1238 """
1239 Reading state of ONOS
1240 """
1241 import json
1242 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001243 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001244 assert main, "main not defined"
1245 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001246 assert main.CLIs, "main.CLIs not defined"
1247 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001248
1249 main.case( "Setting up and gathering data for current state" )
1250 # The general idea for this test case is to pull the state of
1251 # ( intents,flows, topology,... ) from each ONOS node
1252 # We can then compare them with each other and also with past states
1253
1254 main.step( "Check that each switch has a master" )
1255 global mastershipState
1256 mastershipState = '[]'
1257
1258 # Assert that each device has a master
1259 rolesNotNull = main.TRUE
1260 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001261 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001262 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001263 name="rolesNotNull-" + str( i ),
1264 args=[] )
1265 threads.append( t )
1266 t.start()
1267
1268 for t in threads:
1269 t.join()
1270 rolesNotNull = rolesNotNull and t.result
1271 utilities.assert_equals(
1272 expect=main.TRUE,
1273 actual=rolesNotNull,
1274 onpass="Each device has a master",
1275 onfail="Some devices don't have a master assigned" )
1276
1277 main.step( "Get the Mastership of each switch from each controller" )
1278 ONOSMastership = []
1279 mastershipCheck = main.FALSE
1280 consistentMastership = True
1281 rolesResults = True
1282 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001283 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001284 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001285 name="roles-" + str( i ),
1286 args=[] )
1287 threads.append( t )
1288 t.start()
1289
1290 for t in threads:
1291 t.join()
1292 ONOSMastership.append( t.result )
1293
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001294 for i in range( len( ONOSMastership ) ):
1295 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001296 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001297 main.log.error( "Error in getting ONOS" + node + " roles" )
1298 main.log.warn( "ONOS" + node + " mastership response: " +
1299 repr( ONOSMastership[i] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001300 rolesResults = False
1301 utilities.assert_equals(
1302 expect=True,
1303 actual=rolesResults,
1304 onpass="No error in reading roles output",
1305 onfail="Error in reading roles from ONOS" )
1306
1307 main.step( "Check for consistency in roles from each controller" )
1308 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1309 main.log.info(
1310 "Switch roles are consistent across all ONOS nodes" )
1311 else:
1312 consistentMastership = False
1313 utilities.assert_equals(
1314 expect=True,
1315 actual=consistentMastership,
1316 onpass="Switch roles are consistent across all ONOS nodes",
1317 onfail="ONOS nodes have different views of switch roles" )
1318
1319 if rolesResults and not consistentMastership:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001320 for i in range( len( main.activeNodes ) ):
1321 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001322 try:
1323 main.log.warn(
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001324 "ONOS" + node + " roles: ",
Jon Hall5cf14d52015-07-16 12:15:19 -07001325 json.dumps(
1326 json.loads( ONOSMastership[ i ] ),
1327 sort_keys=True,
1328 indent=4,
1329 separators=( ',', ': ' ) ) )
1330 except ( ValueError, TypeError ):
1331 main.log.warn( repr( ONOSMastership[ i ] ) )
1332 elif rolesResults and consistentMastership:
1333 mastershipCheck = main.TRUE
1334 mastershipState = ONOSMastership[ 0 ]
1335
1336 main.step( "Get the intents from each controller" )
1337 global intentState
1338 intentState = []
1339 ONOSIntents = []
1340 intentCheck = main.FALSE
1341 consistentIntents = True
1342 intentsResults = True
1343 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001344 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001345 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001346 name="intents-" + str( i ),
1347 args=[],
1348 kwargs={ 'jsonFormat': True } )
1349 threads.append( t )
1350 t.start()
1351
1352 for t in threads:
1353 t.join()
1354 ONOSIntents.append( t.result )
1355
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001356 for i in range( len( ONOSIntents ) ):
1357 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001358 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001359 main.log.error( "Error in getting ONOS" + node + " intents" )
1360 main.log.warn( "ONOS" + node + " intents response: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07001361 repr( ONOSIntents[ i ] ) )
1362 intentsResults = False
1363 utilities.assert_equals(
1364 expect=True,
1365 actual=intentsResults,
1366 onpass="No error in reading intents output",
1367 onfail="Error in reading intents from ONOS" )
1368
1369 main.step( "Check for consistency in Intents from each controller" )
1370 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1371 main.log.info( "Intents are consistent across all ONOS " +
1372 "nodes" )
1373 else:
1374 consistentIntents = False
1375 main.log.error( "Intents not consistent" )
1376 utilities.assert_equals(
1377 expect=True,
1378 actual=consistentIntents,
1379 onpass="Intents are consistent across all ONOS nodes",
1380 onfail="ONOS nodes have different views of intents" )
1381
1382 if intentsResults:
1383 # Try to make it easy to figure out what is happening
1384 #
1385 # Intent ONOS1 ONOS2 ...
1386 # 0x01 INSTALLED INSTALLING
1387 # ... ... ...
1388 # ... ... ...
1389 title = " Id"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001390 for n in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001391 title += " " * 10 + "ONOS" + str( n + 1 )
1392 main.log.warn( title )
1393 # get all intent keys in the cluster
1394 keys = []
Jon Halla440e872016-03-31 15:15:50 -07001395 try:
1396 # Get the set of all intent keys
Jon Hall5cf14d52015-07-16 12:15:19 -07001397 for nodeStr in ONOSIntents:
1398 node = json.loads( nodeStr )
1399 for intent in node:
Jon Halla440e872016-03-31 15:15:50 -07001400 keys.append( intent.get( 'id' ) )
1401 keys = set( keys )
1402 # For each intent key, print the state on each node
1403 for key in keys:
1404 row = "%-13s" % key
1405 for nodeStr in ONOSIntents:
1406 node = json.loads( nodeStr )
1407 for intent in node:
1408 if intent.get( 'id', "Error" ) == key:
1409 row += "%-15s" % intent.get( 'state' )
1410 main.log.warn( row )
1411 # End of intent state table
1412 except ValueError as e:
1413 main.log.exception( e )
1414 main.log.debug( "nodeStr was: " + repr( nodeStr ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001415
1416 if intentsResults and not consistentIntents:
1417 # print the json objects
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001418 n = str( main.activeNodes[-1] + 1 )
1419 main.log.debug( "ONOS" + n + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07001420 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1421 sort_keys=True,
1422 indent=4,
1423 separators=( ',', ': ' ) ) )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001424 for i in range( len( ONOSIntents ) ):
1425 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001426 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001427 main.log.debug( "ONOS" + node + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07001428 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1429 sort_keys=True,
1430 indent=4,
1431 separators=( ',', ': ' ) ) )
1432 else:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001433 main.log.debug( "ONOS" + node + " intents match ONOS" +
1434 n + " intents" )
Jon Hall5cf14d52015-07-16 12:15:19 -07001435 elif intentsResults and consistentIntents:
1436 intentCheck = main.TRUE
1437 intentState = ONOSIntents[ 0 ]
1438
1439 main.step( "Get the flows from each controller" )
1440 global flowState
1441 flowState = []
1442 ONOSFlows = []
1443 ONOSFlowsJson = []
1444 flowCheck = main.FALSE
1445 consistentFlows = True
1446 flowsResults = True
1447 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001448 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001449 t = main.Thread( target=main.CLIs[i].flows,
Jon Hall5cf14d52015-07-16 12:15:19 -07001450 name="flows-" + str( i ),
1451 args=[],
1452 kwargs={ 'jsonFormat': True } )
1453 threads.append( t )
1454 t.start()
1455
1456 # NOTE: Flows command can take some time to run
1457 time.sleep(30)
1458 for t in threads:
1459 t.join()
1460 result = t.result
1461 ONOSFlows.append( result )
1462
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001463 for i in range( len( ONOSFlows ) ):
1464 num = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001465 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1466 main.log.error( "Error in getting ONOS" + num + " flows" )
1467 main.log.warn( "ONOS" + num + " flows response: " +
1468 repr( ONOSFlows[ i ] ) )
1469 flowsResults = False
1470 ONOSFlowsJson.append( None )
1471 else:
1472 try:
1473 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1474 except ( ValueError, TypeError ):
1475 # FIXME: change this to log.error?
1476 main.log.exception( "Error in parsing ONOS" + num +
1477 " response as json." )
1478 main.log.error( repr( ONOSFlows[ i ] ) )
1479 ONOSFlowsJson.append( None )
1480 flowsResults = False
1481 utilities.assert_equals(
1482 expect=True,
1483 actual=flowsResults,
1484 onpass="No error in reading flows output",
1485 onfail="Error in reading flows from ONOS" )
1486
1487 main.step( "Check for consistency in Flows from each controller" )
1488 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1489 if all( tmp ):
1490 main.log.info( "Flow count is consistent across all ONOS nodes" )
1491 else:
1492 consistentFlows = False
1493 utilities.assert_equals(
1494 expect=True,
1495 actual=consistentFlows,
1496 onpass="The flow count is consistent across all ONOS nodes",
1497 onfail="ONOS nodes have different flow counts" )
1498
1499 if flowsResults and not consistentFlows:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001500 for i in range( len( ONOSFlows ) ):
1501 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001502 try:
1503 main.log.warn(
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001504 "ONOS" + node + " flows: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07001505 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1506 indent=4, separators=( ',', ': ' ) ) )
1507 except ( ValueError, TypeError ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001508 main.log.warn( "ONOS" + node + " flows: " +
1509 repr( ONOSFlows[ i ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001510 elif flowsResults and consistentFlows:
1511 flowCheck = main.TRUE
1512 flowState = ONOSFlows[ 0 ]
1513
1514 main.step( "Get the OF Table entries" )
1515 global flows
1516 flows = []
1517 for i in range( 1, 29 ):
GlennRC68467eb2015-11-16 18:01:01 -08001518 flows.append( main.Mininet1.getFlowTable( "s" + str( i ), version="1.3", debug=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001519 if flowCheck == main.FALSE:
1520 for table in flows:
1521 main.log.warn( table )
1522 # TODO: Compare switch flow tables with ONOS flow tables
1523
1524 main.step( "Start continuous pings" )
1525 main.Mininet2.pingLong(
1526 src=main.params[ 'PING' ][ 'source1' ],
1527 target=main.params[ 'PING' ][ 'target1' ],
1528 pingTime=500 )
1529 main.Mininet2.pingLong(
1530 src=main.params[ 'PING' ][ 'source2' ],
1531 target=main.params[ 'PING' ][ 'target2' ],
1532 pingTime=500 )
1533 main.Mininet2.pingLong(
1534 src=main.params[ 'PING' ][ 'source3' ],
1535 target=main.params[ 'PING' ][ 'target3' ],
1536 pingTime=500 )
1537 main.Mininet2.pingLong(
1538 src=main.params[ 'PING' ][ 'source4' ],
1539 target=main.params[ 'PING' ][ 'target4' ],
1540 pingTime=500 )
1541 main.Mininet2.pingLong(
1542 src=main.params[ 'PING' ][ 'source5' ],
1543 target=main.params[ 'PING' ][ 'target5' ],
1544 pingTime=500 )
1545 main.Mininet2.pingLong(
1546 src=main.params[ 'PING' ][ 'source6' ],
1547 target=main.params[ 'PING' ][ 'target6' ],
1548 pingTime=500 )
1549 main.Mininet2.pingLong(
1550 src=main.params[ 'PING' ][ 'source7' ],
1551 target=main.params[ 'PING' ][ 'target7' ],
1552 pingTime=500 )
1553 main.Mininet2.pingLong(
1554 src=main.params[ 'PING' ][ 'source8' ],
1555 target=main.params[ 'PING' ][ 'target8' ],
1556 pingTime=500 )
1557 main.Mininet2.pingLong(
1558 src=main.params[ 'PING' ][ 'source9' ],
1559 target=main.params[ 'PING' ][ 'target9' ],
1560 pingTime=500 )
1561 main.Mininet2.pingLong(
1562 src=main.params[ 'PING' ][ 'source10' ],
1563 target=main.params[ 'PING' ][ 'target10' ],
1564 pingTime=500 )
1565
1566 main.step( "Collecting topology information from ONOS" )
1567 devices = []
1568 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001569 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001570 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07001571 name="devices-" + str( i ),
1572 args=[ ] )
1573 threads.append( t )
1574 t.start()
1575
1576 for t in threads:
1577 t.join()
1578 devices.append( t.result )
1579 hosts = []
1580 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001581 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001582 t = main.Thread( target=main.CLIs[i].hosts,
Jon Hall5cf14d52015-07-16 12:15:19 -07001583 name="hosts-" + str( i ),
1584 args=[ ] )
1585 threads.append( t )
1586 t.start()
1587
1588 for t in threads:
1589 t.join()
1590 try:
1591 hosts.append( json.loads( t.result ) )
1592 except ( ValueError, TypeError ):
1593 # FIXME: better handling of this, print which node
1594 # Maybe use thread name?
1595 main.log.exception( "Error parsing json output of hosts" )
Jon Hallf3d16e72015-12-16 17:45:08 -08001596 main.log.warn( repr( t.result ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001597 hosts.append( None )
1598
1599 ports = []
1600 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001601 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001602 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07001603 name="ports-" + str( i ),
1604 args=[ ] )
1605 threads.append( t )
1606 t.start()
1607
1608 for t in threads:
1609 t.join()
1610 ports.append( t.result )
1611 links = []
1612 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001613 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001614 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07001615 name="links-" + str( i ),
1616 args=[ ] )
1617 threads.append( t )
1618 t.start()
1619
1620 for t in threads:
1621 t.join()
1622 links.append( t.result )
1623 clusters = []
1624 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001625 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001626 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07001627 name="clusters-" + str( i ),
1628 args=[ ] )
1629 threads.append( t )
1630 t.start()
1631
1632 for t in threads:
1633 t.join()
1634 clusters.append( t.result )
1635 # Compare json objects for hosts and dataplane clusters
1636
1637 # hosts
1638 main.step( "Host view is consistent across ONOS nodes" )
1639 consistentHostsResult = main.TRUE
1640 for controller in range( len( hosts ) ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001641 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hallf3d16e72015-12-16 17:45:08 -08001642 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001643 if hosts[ controller ] == hosts[ 0 ]:
1644 continue
1645 else: # hosts not consistent
1646 main.log.error( "hosts from ONOS" +
1647 controllerStr +
1648 " is inconsistent with ONOS1" )
1649 main.log.warn( repr( hosts[ controller ] ) )
1650 consistentHostsResult = main.FALSE
1651
1652 else:
1653 main.log.error( "Error in getting ONOS hosts from ONOS" +
1654 controllerStr )
1655 consistentHostsResult = main.FALSE
1656 main.log.warn( "ONOS" + controllerStr +
1657 " hosts response: " +
1658 repr( hosts[ controller ] ) )
1659 utilities.assert_equals(
1660 expect=main.TRUE,
1661 actual=consistentHostsResult,
1662 onpass="Hosts view is consistent across all ONOS nodes",
1663 onfail="ONOS nodes have different views of hosts" )
1664
1665 main.step( "Each host has an IP address" )
1666 ipResult = main.TRUE
1667 for controller in range( 0, len( hosts ) ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001668 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hallf3d16e72015-12-16 17:45:08 -08001669 if hosts[ controller ]:
1670 for host in hosts[ controller ]:
1671 if not host.get( 'ipAddresses', [ ] ):
1672 main.log.error( "Error with host ips on controller" +
1673 controllerStr + ": " + str( host ) )
1674 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07001675 utilities.assert_equals(
1676 expect=main.TRUE,
1677 actual=ipResult,
1678 onpass="The ips of the hosts aren't empty",
1679 onfail="The ip of at least one host is missing" )
1680
1681 # Strongly connected clusters of devices
1682 main.step( "Cluster view is consistent across ONOS nodes" )
1683 consistentClustersResult = main.TRUE
1684 for controller in range( len( clusters ) ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001685 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001686 if "Error" not in clusters[ controller ]:
1687 if clusters[ controller ] == clusters[ 0 ]:
1688 continue
1689 else: # clusters not consistent
1690 main.log.error( "clusters from ONOS" + controllerStr +
1691 " is inconsistent with ONOS1" )
1692 consistentClustersResult = main.FALSE
1693
1694 else:
1695 main.log.error( "Error in getting dataplane clusters " +
1696 "from ONOS" + controllerStr )
1697 consistentClustersResult = main.FALSE
1698 main.log.warn( "ONOS" + controllerStr +
1699 " clusters response: " +
1700 repr( clusters[ controller ] ) )
1701 utilities.assert_equals(
1702 expect=main.TRUE,
1703 actual=consistentClustersResult,
1704 onpass="Clusters view is consistent across all ONOS nodes",
1705 onfail="ONOS nodes have different views of clusters" )
Jon Hall172b7ba2016-04-07 18:12:20 -07001706 if consistentClustersResult != main.TRUE:
1707 main.log.debug( clusters )
Jon Hall5cf14d52015-07-16 12:15:19 -07001708 # there should always only be one cluster
1709 main.step( "Cluster view correct across ONOS nodes" )
1710 try:
1711 numClusters = len( json.loads( clusters[ 0 ] ) )
1712 except ( ValueError, TypeError ):
1713 main.log.exception( "Error parsing clusters[0]: " +
1714 repr( clusters[ 0 ] ) )
Jon Hall6e709752016-02-01 13:38:46 -08001715 numClusters = "ERROR"
Jon Hall5cf14d52015-07-16 12:15:19 -07001716 clusterResults = main.FALSE
1717 if numClusters == 1:
1718 clusterResults = main.TRUE
1719 utilities.assert_equals(
1720 expect=1,
1721 actual=numClusters,
1722 onpass="ONOS shows 1 SCC",
1723 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1724
1725 main.step( "Comparing ONOS topology to MN" )
1726 devicesResults = main.TRUE
1727 linksResults = main.TRUE
1728 hostsResults = main.TRUE
1729 mnSwitches = main.Mininet1.getSwitches()
1730 mnLinks = main.Mininet1.getLinks()
1731 mnHosts = main.Mininet1.getHosts()
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001732 for controller in main.activeNodes:
1733 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001734 if devices[ controller ] and ports[ controller ] and\
1735 "Error" not in devices[ controller ] and\
1736 "Error" not in ports[ controller ]:
Jon Hall6e709752016-02-01 13:38:46 -08001737 currentDevicesResult = main.Mininet1.compareSwitches(
1738 mnSwitches,
1739 json.loads( devices[ controller ] ),
1740 json.loads( ports[ controller ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001741 else:
1742 currentDevicesResult = main.FALSE
1743 utilities.assert_equals( expect=main.TRUE,
1744 actual=currentDevicesResult,
1745 onpass="ONOS" + controllerStr +
1746 " Switches view is correct",
1747 onfail="ONOS" + controllerStr +
1748 " Switches view is incorrect" )
1749 if links[ controller ] and "Error" not in links[ controller ]:
1750 currentLinksResult = main.Mininet1.compareLinks(
1751 mnSwitches, mnLinks,
1752 json.loads( links[ controller ] ) )
1753 else:
1754 currentLinksResult = main.FALSE
1755 utilities.assert_equals( expect=main.TRUE,
1756 actual=currentLinksResult,
1757 onpass="ONOS" + controllerStr +
1758 " links view is correct",
1759 onfail="ONOS" + controllerStr +
1760 " links view is incorrect" )
1761
Jon Hall657cdf62015-12-17 14:40:51 -08001762 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001763 currentHostsResult = main.Mininet1.compareHosts(
1764 mnHosts,
1765 hosts[ controller ] )
1766 else:
1767 currentHostsResult = main.FALSE
1768 utilities.assert_equals( expect=main.TRUE,
1769 actual=currentHostsResult,
1770 onpass="ONOS" + controllerStr +
1771 " hosts exist in Mininet",
1772 onfail="ONOS" + controllerStr +
1773 " hosts don't match Mininet" )
1774
1775 devicesResults = devicesResults and currentDevicesResult
1776 linksResults = linksResults and currentLinksResult
1777 hostsResults = hostsResults and currentHostsResult
1778
1779 main.step( "Device information is correct" )
1780 utilities.assert_equals(
1781 expect=main.TRUE,
1782 actual=devicesResults,
1783 onpass="Device information is correct",
1784 onfail="Device information is incorrect" )
1785
1786 main.step( "Links are correct" )
1787 utilities.assert_equals(
1788 expect=main.TRUE,
1789 actual=linksResults,
1790 onpass="Link are correct",
1791 onfail="Links are incorrect" )
1792
1793 main.step( "Hosts are correct" )
1794 utilities.assert_equals(
1795 expect=main.TRUE,
1796 actual=hostsResults,
1797 onpass="Hosts are correct",
1798 onfail="Hosts are incorrect" )
1799
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001800 def CASE61( self, main ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001801 """
1802 The Failure case.
1803 """
Jon Halle1a3b752015-07-22 13:02:46 -07001804 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001805 assert main, "main not defined"
1806 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001807 assert main.CLIs, "main.CLIs not defined"
1808 assert main.nodes, "main.nodes not defined"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001809 main.case( "Kill minority of ONOS nodes" )
Jon Hall96091e62015-09-21 17:34:17 -07001810
1811 main.step( "Checking ONOS Logs for errors" )
1812 for node in main.nodes:
1813 main.log.debug( "Checking logs for errors on " + node.name + ":" )
1814 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
1815
Jon Hall3b489db2015-10-05 14:38:37 -07001816 n = len( main.nodes ) # Number of nodes
1817 p = ( ( n + 1 ) / 2 ) + 1 # Number of partitions
1818 main.kill = [ 0 ] # ONOS node to kill, listed by index in main.nodes
1819 if n > 3:
1820 main.kill.append( p - 1 )
1821 # NOTE: This only works for cluster sizes of 3,5, or 7.
1822
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001823 main.step( "Kill " + str( len( main.kill ) ) + " ONOS nodes" )
Jon Hall3b489db2015-10-05 14:38:37 -07001824 killResults = main.TRUE
1825 for i in main.kill:
1826 killResults = killResults and\
1827 main.ONOSbench.onosKill( main.nodes[i].ip_address )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001828 main.activeNodes.remove( i )
Jon Hall5cf14d52015-07-16 12:15:19 -07001829 utilities.assert_equals( expect=main.TRUE, actual=killResults,
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001830 onpass="ONOS nodes killed successfully",
1831 onfail="ONOS nodes NOT successfully killed" )
1832
1833 def CASE62( self, main ):
1834 """
1835 The bring up stopped nodes
1836 """
1837 import time
1838 assert main.numCtrls, "main.numCtrls not defined"
1839 assert main, "main not defined"
1840 assert utilities.assert_equals, "utilities.assert_equals not defined"
1841 assert main.CLIs, "main.CLIs not defined"
1842 assert main.nodes, "main.nodes not defined"
1843 assert main.kill, "main.kill not defined"
1844 main.case( "Restart minority of ONOS nodes" )
1845
1846 main.step( "Restarting " + str( len( main.kill ) ) + " ONOS nodes" )
1847 startResults = main.TRUE
1848 restartTime = time.time()
1849 for i in main.kill:
1850 startResults = startResults and\
1851 main.ONOSbench.onosStart( main.nodes[i].ip_address )
1852 utilities.assert_equals( expect=main.TRUE, actual=startResults,
1853 onpass="ONOS nodes started successfully",
1854 onfail="ONOS nodes NOT successfully started" )
Jon Hall5cf14d52015-07-16 12:15:19 -07001855
1856 main.step( "Checking if ONOS is up yet" )
1857 count = 0
1858 onosIsupResult = main.FALSE
1859 while onosIsupResult == main.FALSE and count < 10:
Jon Hall3b489db2015-10-05 14:38:37 -07001860 onosIsupResult = main.TRUE
1861 for i in main.kill:
1862 onosIsupResult = onosIsupResult and\
1863 main.ONOSbench.isup( main.nodes[i].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -07001864 count = count + 1
Jon Hall5cf14d52015-07-16 12:15:19 -07001865 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1866 onpass="ONOS restarted successfully",
1867 onfail="ONOS restart NOT successful" )
1868
Jon Halle1a3b752015-07-22 13:02:46 -07001869 main.step( "Restarting ONOS main.CLIs" )
Jon Hall3b489db2015-10-05 14:38:37 -07001870 cliResults = main.TRUE
1871 for i in main.kill:
1872 cliResults = cliResults and\
1873 main.CLIs[i].startOnosCli( main.nodes[i].ip_address )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001874 main.activeNodes.append( i )
Jon Hall5cf14d52015-07-16 12:15:19 -07001875 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1876 onpass="ONOS cli restarted",
1877 onfail="ONOS cli did not restart" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001878 main.activeNodes.sort()
1879 try:
1880 assert list( set( main.activeNodes ) ) == main.activeNodes,\
1881 "List of active nodes has duplicates, this likely indicates something was run out of order"
1882 except AssertionError:
1883 main.log.exception( "" )
1884 main.cleanup()
1885 main.exit()
Jon Hall5cf14d52015-07-16 12:15:19 -07001886
1887 # Grab the time of restart so we chan check how long the gossip
1888 # protocol has had time to work
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001889 main.restartTime = time.time() - restartTime
Jon Hall5cf14d52015-07-16 12:15:19 -07001890 main.log.debug( "Restart time: " + str( main.restartTime ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001891 # TODO: MAke this configurable. Also, we are breaking the above timer
1892 time.sleep( 60 )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001893 node = main.activeNodes[0]
1894 main.log.debug( main.CLIs[node].nodes( jsonFormat=False ) )
1895 main.log.debug( main.CLIs[node].leaders( jsonFormat=False ) )
1896 main.log.debug( main.CLIs[node].partitions( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001897
Jon Halla440e872016-03-31 15:15:50 -07001898 main.step( "Rerun for election on the node(s) that were killed" )
1899 runResults = main.TRUE
1900 for i in main.kill:
1901 runResults = runResults and\
1902 main.CLIs[i].electionTestRun()
1903 utilities.assert_equals( expect=main.TRUE, actual=runResults,
1904 onpass="ONOS nodes reran for election topic",
1905 onfail="Errror rerunning for election" )
1906
Jon Hall5cf14d52015-07-16 12:15:19 -07001907 def CASE7( self, main ):
1908 """
1909 Check state after ONOS failure
1910 """
1911 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001912 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001913 assert main, "main not defined"
1914 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001915 assert main.CLIs, "main.CLIs not defined"
1916 assert main.nodes, "main.nodes not defined"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001917 try:
1918 main.kill
1919 except AttributeError:
1920 main.kill = []
1921
Jon Hall5cf14d52015-07-16 12:15:19 -07001922 main.case( "Running ONOS Constant State Tests" )
1923
1924 main.step( "Check that each switch has a master" )
1925 # Assert that each device has a master
1926 rolesNotNull = main.TRUE
1927 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001928 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001929 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001930 name="rolesNotNull-" + str( i ),
1931 args=[ ] )
1932 threads.append( t )
1933 t.start()
1934
1935 for t in threads:
1936 t.join()
1937 rolesNotNull = rolesNotNull and t.result
1938 utilities.assert_equals(
1939 expect=main.TRUE,
1940 actual=rolesNotNull,
1941 onpass="Each device has a master",
1942 onfail="Some devices don't have a master assigned" )
1943
1944 main.step( "Read device roles from ONOS" )
1945 ONOSMastership = []
Jon Halla440e872016-03-31 15:15:50 -07001946 mastershipCheck = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07001947 consistentMastership = True
1948 rolesResults = True
1949 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001950 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001951 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001952 name="roles-" + str( i ),
1953 args=[] )
1954 threads.append( t )
1955 t.start()
1956
1957 for t in threads:
1958 t.join()
1959 ONOSMastership.append( t.result )
1960
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001961 for i in range( len( ONOSMastership ) ):
1962 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001963 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001964 main.log.error( "Error in getting ONOS" + node + " roles" )
1965 main.log.warn( "ONOS" + node + " mastership response: " +
1966 repr( ONOSMastership[i] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001967 rolesResults = False
1968 utilities.assert_equals(
1969 expect=True,
1970 actual=rolesResults,
1971 onpass="No error in reading roles output",
1972 onfail="Error in reading roles from ONOS" )
1973
1974 main.step( "Check for consistency in roles from each controller" )
1975 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1976 main.log.info(
1977 "Switch roles are consistent across all ONOS nodes" )
1978 else:
1979 consistentMastership = False
1980 utilities.assert_equals(
1981 expect=True,
1982 actual=consistentMastership,
1983 onpass="Switch roles are consistent across all ONOS nodes",
1984 onfail="ONOS nodes have different views of switch roles" )
1985
1986 if rolesResults and not consistentMastership:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07001987 for i in range( len( ONOSMastership ) ):
1988 node = str( main.activeNodes[i] + 1 )
1989 main.log.warn( "ONOS" + node + " roles: ",
1990 json.dumps( json.loads( ONOSMastership[ i ] ),
1991 sort_keys=True,
1992 indent=4,
1993 separators=( ',', ': ' ) ) )
Jon Halla440e872016-03-31 15:15:50 -07001994 elif rolesResults and consistentMastership:
1995 mastershipCheck = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07001996
1997 # NOTE: we expect mastership to change on controller failure
Jon Hall5cf14d52015-07-16 12:15:19 -07001998
1999 main.step( "Get the intents and compare across all nodes" )
2000 ONOSIntents = []
2001 intentCheck = main.FALSE
2002 consistentIntents = True
2003 intentsResults = True
2004 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002005 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002006 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07002007 name="intents-" + str( i ),
2008 args=[],
2009 kwargs={ 'jsonFormat': True } )
2010 threads.append( t )
2011 t.start()
2012
2013 for t in threads:
2014 t.join()
2015 ONOSIntents.append( t.result )
2016
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002017 for i in range( len( ONOSIntents) ):
2018 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002019 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002020 main.log.error( "Error in getting ONOS" + node + " intents" )
2021 main.log.warn( "ONOS" + node + " intents response: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07002022 repr( ONOSIntents[ i ] ) )
2023 intentsResults = False
2024 utilities.assert_equals(
2025 expect=True,
2026 actual=intentsResults,
2027 onpass="No error in reading intents output",
2028 onfail="Error in reading intents from ONOS" )
2029
2030 main.step( "Check for consistency in Intents from each controller" )
2031 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
2032 main.log.info( "Intents are consistent across all ONOS " +
2033 "nodes" )
2034 else:
2035 consistentIntents = False
2036
2037 # Try to make it easy to figure out what is happening
2038 #
2039 # Intent ONOS1 ONOS2 ...
2040 # 0x01 INSTALLED INSTALLING
2041 # ... ... ...
2042 # ... ... ...
2043 title = " ID"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002044 for n in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07002045 title += " " * 10 + "ONOS" + str( n + 1 )
2046 main.log.warn( title )
2047 # get all intent keys in the cluster
2048 keys = []
2049 for nodeStr in ONOSIntents:
2050 node = json.loads( nodeStr )
2051 for intent in node:
2052 keys.append( intent.get( 'id' ) )
2053 keys = set( keys )
2054 for key in keys:
2055 row = "%-13s" % key
2056 for nodeStr in ONOSIntents:
2057 node = json.loads( nodeStr )
2058 for intent in node:
2059 if intent.get( 'id' ) == key:
2060 row += "%-15s" % intent.get( 'state' )
2061 main.log.warn( row )
2062 # End table view
2063
2064 utilities.assert_equals(
2065 expect=True,
2066 actual=consistentIntents,
2067 onpass="Intents are consistent across all ONOS nodes",
2068 onfail="ONOS nodes have different views of intents" )
2069 intentStates = []
2070 for node in ONOSIntents: # Iter through ONOS nodes
2071 nodeStates = []
2072 # Iter through intents of a node
2073 try:
2074 for intent in json.loads( node ):
2075 nodeStates.append( intent[ 'state' ] )
2076 except ( ValueError, TypeError ):
2077 main.log.exception( "Error in parsing intents" )
2078 main.log.error( repr( node ) )
2079 intentStates.append( nodeStates )
2080 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
2081 main.log.info( dict( out ) )
2082
2083 if intentsResults and not consistentIntents:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002084 for i in range( len( main.activeNodes ) ):
2085 node = str( main.activeNodes[i] + 1 )
2086 main.log.warn( "ONOS" + node + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07002087 main.log.warn( json.dumps(
2088 json.loads( ONOSIntents[ i ] ),
2089 sort_keys=True,
2090 indent=4,
2091 separators=( ',', ': ' ) ) )
2092 elif intentsResults and consistentIntents:
2093 intentCheck = main.TRUE
2094
2095 # NOTE: Store has no durability, so intents are lost across system
2096 # restarts
2097 main.step( "Compare current intents with intents before the failure" )
2098 # NOTE: this requires case 5 to pass for intentState to be set.
2099 # maybe we should stop the test if that fails?
2100 sameIntents = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002101 try:
2102 intentState
2103 except NameError:
2104 main.log.warn( "No previous intent state was saved" )
2105 else:
2106 if intentState and intentState == ONOSIntents[ 0 ]:
2107 sameIntents = main.TRUE
2108 main.log.info( "Intents are consistent with before failure" )
2109 # TODO: possibly the states have changed? we may need to figure out
2110 # what the acceptable states are
2111 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
2112 sameIntents = main.TRUE
2113 try:
2114 before = json.loads( intentState )
2115 after = json.loads( ONOSIntents[ 0 ] )
2116 for intent in before:
2117 if intent not in after:
2118 sameIntents = main.FALSE
2119 main.log.debug( "Intent is not currently in ONOS " +
2120 "(at least in the same form):" )
2121 main.log.debug( json.dumps( intent ) )
2122 except ( ValueError, TypeError ):
2123 main.log.exception( "Exception printing intents" )
2124 main.log.debug( repr( ONOSIntents[0] ) )
2125 main.log.debug( repr( intentState ) )
2126 if sameIntents == main.FALSE:
2127 try:
2128 main.log.debug( "ONOS intents before: " )
2129 main.log.debug( json.dumps( json.loads( intentState ),
2130 sort_keys=True, indent=4,
2131 separators=( ',', ': ' ) ) )
2132 main.log.debug( "Current ONOS intents: " )
2133 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
2134 sort_keys=True, indent=4,
2135 separators=( ',', ': ' ) ) )
2136 except ( ValueError, TypeError ):
2137 main.log.exception( "Exception printing intents" )
2138 main.log.debug( repr( ONOSIntents[0] ) )
2139 main.log.debug( repr( intentState ) )
2140 utilities.assert_equals(
2141 expect=main.TRUE,
2142 actual=sameIntents,
2143 onpass="Intents are consistent with before failure",
2144 onfail="The Intents changed during failure" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002145 intentCheck = intentCheck and sameIntents
2146
2147 main.step( "Get the OF Table entries and compare to before " +
2148 "component failure" )
2149 FlowTables = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002150 for i in range( 28 ):
2151 main.log.info( "Checking flow table on s" + str( i + 1 ) )
GlennRC68467eb2015-11-16 18:01:01 -08002152 tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
Jon Hall41d39f12016-04-11 22:54:35 -07002153 curSwitch = main.Mininet1.flowTableComp( flows[i], tmpFlows )
2154 FlowTables = FlowTables and curSwitch
2155 if curSwitch == main.FALSE:
GlennRC68467eb2015-11-16 18:01:01 -08002156 main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002157 utilities.assert_equals(
2158 expect=main.TRUE,
2159 actual=FlowTables,
2160 onpass="No changes were found in the flow tables",
2161 onfail="Changes were found in the flow tables" )
2162
2163 main.Mininet2.pingLongKill()
2164 '''
2165 main.step( "Check the continuous pings to ensure that no packets " +
2166 "were dropped during component failure" )
2167 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
2168 main.params[ 'TESTONIP' ] )
2169 LossInPings = main.FALSE
2170 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
2171 for i in range( 8, 18 ):
2172 main.log.info(
2173 "Checking for a loss in pings along flow from s" +
2174 str( i ) )
2175 LossInPings = main.Mininet2.checkForLoss(
2176 "/tmp/ping.h" +
2177 str( i ) ) or LossInPings
2178 if LossInPings == main.TRUE:
2179 main.log.info( "Loss in ping detected" )
2180 elif LossInPings == main.ERROR:
2181 main.log.info( "There are multiple mininet process running" )
2182 elif LossInPings == main.FALSE:
2183 main.log.info( "No Loss in the pings" )
2184 main.log.info( "No loss of dataplane connectivity" )
2185 utilities.assert_equals(
2186 expect=main.FALSE,
2187 actual=LossInPings,
2188 onpass="No Loss of connectivity",
2189 onfail="Loss of dataplane connectivity detected" )
2190 '''
2191
2192 main.step( "Leadership Election is still functional" )
2193 # Test of LeadershipElection
2194 leaderList = []
Jon Hall5cf14d52015-07-16 12:15:19 -07002195
Jon Hall3b489db2015-10-05 14:38:37 -07002196 restarted = []
2197 for i in main.kill:
2198 restarted.append( main.nodes[i].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -07002199 leaderResult = main.TRUE
Jon Hall3b489db2015-10-05 14:38:37 -07002200
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002201 for i in main.activeNodes:
2202 cli = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07002203 leaderN = cli.electionTestLeader()
2204 leaderList.append( leaderN )
2205 if leaderN == main.FALSE:
2206 # error in response
2207 main.log.error( "Something is wrong with " +
2208 "electionTestLeader function, check the" +
2209 " error logs" )
2210 leaderResult = main.FALSE
2211 elif leaderN is None:
2212 main.log.error( cli.name +
2213 " shows no leader for the election-app was" +
2214 " elected after the old one died" )
2215 leaderResult = main.FALSE
2216 elif leaderN in restarted:
2217 main.log.error( cli.name + " shows " + str( leaderN ) +
2218 " as leader for the election-app, but it " +
2219 "was restarted" )
2220 leaderResult = main.FALSE
2221 if len( set( leaderList ) ) != 1:
2222 leaderResult = main.FALSE
2223 main.log.error(
2224 "Inconsistent view of leader for the election test app" )
2225 # TODO: print the list
2226 utilities.assert_equals(
2227 expect=main.TRUE,
2228 actual=leaderResult,
2229 onpass="Leadership election passed",
2230 onfail="Something went wrong with Leadership election" )
2231
2232 def CASE8( self, main ):
2233 """
2234 Compare topo
2235 """
2236 import json
2237 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002238 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002239 assert main, "main not defined"
2240 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002241 assert main.CLIs, "main.CLIs not defined"
2242 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002243
2244 main.case( "Compare ONOS Topology view to Mininet topology" )
Jon Hall783bbf92015-07-23 14:33:19 -07002245 main.caseExplanation = "Compare topology objects between Mininet" +\
Jon Hall5cf14d52015-07-16 12:15:19 -07002246 " and ONOS"
Jon Hall5cf14d52015-07-16 12:15:19 -07002247 topoResult = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08002248 topoFailMsg = "ONOS topology don't match Mininet"
Jon Hall5cf14d52015-07-16 12:15:19 -07002249 elapsed = 0
2250 count = 0
Jon Halle9b1fa32015-12-08 15:32:21 -08002251 main.step( "Comparing ONOS topology to MN topology" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002252 startTime = time.time()
2253 # Give time for Gossip to work
Jon Halle9b1fa32015-12-08 15:32:21 -08002254 while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
Jon Hall96091e62015-09-21 17:34:17 -07002255 devicesResults = main.TRUE
2256 linksResults = main.TRUE
2257 hostsResults = main.TRUE
2258 hostAttachmentResults = True
Jon Hall5cf14d52015-07-16 12:15:19 -07002259 count += 1
2260 cliStart = time.time()
2261 devices = []
2262 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002263 for i in main.activeNodes:
Jon Hall6e709752016-02-01 13:38:46 -08002264 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002265 name="devices-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08002266 args=[ main.CLIs[i].devices, [ None ] ],
2267 kwargs= { 'sleep': 5, 'attempts': 5,
2268 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002269 threads.append( t )
2270 t.start()
2271
2272 for t in threads:
2273 t.join()
2274 devices.append( t.result )
2275 hosts = []
2276 ipResult = main.TRUE
2277 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002278 for i in main.activeNodes:
Jon Halld8f6de82015-12-17 17:04:34 -08002279 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002280 name="hosts-" + str( i ),
Jon Halld8f6de82015-12-17 17:04:34 -08002281 args=[ main.CLIs[i].hosts, [ None ] ],
2282 kwargs= { 'sleep': 5, 'attempts': 5,
2283 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002284 threads.append( t )
2285 t.start()
2286
2287 for t in threads:
2288 t.join()
2289 try:
2290 hosts.append( json.loads( t.result ) )
2291 except ( ValueError, TypeError ):
2292 main.log.exception( "Error parsing hosts results" )
2293 main.log.error( repr( t.result ) )
Jon Hallf3d16e72015-12-16 17:45:08 -08002294 hosts.append( None )
Jon Hall5cf14d52015-07-16 12:15:19 -07002295 for controller in range( 0, len( hosts ) ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002296 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hallacd1b182015-12-17 11:43:20 -08002297 if hosts[ controller ]:
2298 for host in hosts[ controller ]:
2299 if host is None or host.get( 'ipAddresses', [] ) == []:
2300 main.log.error(
2301 "Error with host ipAddresses on controller" +
2302 controllerStr + ": " + str( host ) )
2303 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002304 ports = []
2305 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002306 for i in main.activeNodes:
Jon Hall6e709752016-02-01 13:38:46 -08002307 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002308 name="ports-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08002309 args=[ main.CLIs[i].ports, [ None ] ],
2310 kwargs= { 'sleep': 5, 'attempts': 5,
2311 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002312 threads.append( t )
2313 t.start()
2314
2315 for t in threads:
2316 t.join()
2317 ports.append( t.result )
2318 links = []
2319 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002320 for i in main.activeNodes:
Jon Hall6e709752016-02-01 13:38:46 -08002321 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002322 name="links-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08002323 args=[ main.CLIs[i].links, [ None ] ],
2324 kwargs= { 'sleep': 5, 'attempts': 5,
2325 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002326 threads.append( t )
2327 t.start()
2328
2329 for t in threads:
2330 t.join()
2331 links.append( t.result )
2332 clusters = []
2333 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002334 for i in main.activeNodes:
Jon Hall6e709752016-02-01 13:38:46 -08002335 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002336 name="clusters-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08002337 args=[ main.CLIs[i].clusters, [ None ] ],
2338 kwargs= { 'sleep': 5, 'attempts': 5,
2339 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002340 threads.append( t )
2341 t.start()
2342
2343 for t in threads:
2344 t.join()
2345 clusters.append( t.result )
2346
2347 elapsed = time.time() - startTime
2348 cliTime = time.time() - cliStart
2349 print "Elapsed time: " + str( elapsed )
2350 print "CLI time: " + str( cliTime )
2351
Jon Hall6e709752016-02-01 13:38:46 -08002352 if all( e is None for e in devices ) and\
2353 all( e is None for e in hosts ) and\
2354 all( e is None for e in ports ) and\
2355 all( e is None for e in links ) and\
2356 all( e is None for e in clusters ):
2357 topoFailMsg = "Could not get topology from ONOS"
2358 main.log.error( topoFailMsg )
2359 continue # Try again, No use trying to compare
2360
Jon Hall5cf14d52015-07-16 12:15:19 -07002361 mnSwitches = main.Mininet1.getSwitches()
2362 mnLinks = main.Mininet1.getLinks()
2363 mnHosts = main.Mininet1.getHosts()
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002364 for controller in range( len( main.activeNodes ) ):
2365 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002366 if devices[ controller ] and ports[ controller ] and\
2367 "Error" not in devices[ controller ] and\
2368 "Error" not in ports[ controller ]:
2369
Jon Hallc6793552016-01-19 14:18:37 -08002370 try:
2371 currentDevicesResult = main.Mininet1.compareSwitches(
2372 mnSwitches,
2373 json.loads( devices[ controller ] ),
2374 json.loads( ports[ controller ] ) )
2375 except ( TypeError, ValueError ) as e:
2376 main.log.exception( "Object not as expected; devices={!r}\nports={!r}".format(
2377 devices[ controller ], ports[ controller ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002378 else:
2379 currentDevicesResult = main.FALSE
2380 utilities.assert_equals( expect=main.TRUE,
2381 actual=currentDevicesResult,
2382 onpass="ONOS" + controllerStr +
2383 " Switches view is correct",
2384 onfail="ONOS" + controllerStr +
2385 " Switches view is incorrect" )
2386
2387 if links[ controller ] and "Error" not in links[ controller ]:
2388 currentLinksResult = main.Mininet1.compareLinks(
2389 mnSwitches, mnLinks,
2390 json.loads( links[ controller ] ) )
2391 else:
2392 currentLinksResult = main.FALSE
2393 utilities.assert_equals( expect=main.TRUE,
2394 actual=currentLinksResult,
2395 onpass="ONOS" + controllerStr +
2396 " links view is correct",
2397 onfail="ONOS" + controllerStr +
2398 " links view is incorrect" )
Jon Hall657cdf62015-12-17 14:40:51 -08002399 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002400 currentHostsResult = main.Mininet1.compareHosts(
2401 mnHosts,
2402 hosts[ controller ] )
Jon Hall13b446e2016-01-05 12:17:01 -08002403 elif hosts[ controller ] == []:
2404 currentHostsResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002405 else:
2406 currentHostsResult = main.FALSE
2407 utilities.assert_equals( expect=main.TRUE,
2408 actual=currentHostsResult,
2409 onpass="ONOS" + controllerStr +
2410 " hosts exist in Mininet",
2411 onfail="ONOS" + controllerStr +
2412 " hosts don't match Mininet" )
2413 # CHECKING HOST ATTACHMENT POINTS
2414 hostAttachment = True
2415 zeroHosts = False
2416 # FIXME: topo-HA/obelisk specific mappings:
2417 # key is mac and value is dpid
2418 mappings = {}
2419 for i in range( 1, 29 ): # hosts 1 through 28
2420 # set up correct variables:
2421 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2422 if i == 1:
2423 deviceId = "1000".zfill(16)
2424 elif i == 2:
2425 deviceId = "2000".zfill(16)
2426 elif i == 3:
2427 deviceId = "3000".zfill(16)
2428 elif i == 4:
2429 deviceId = "3004".zfill(16)
2430 elif i == 5:
2431 deviceId = "5000".zfill(16)
2432 elif i == 6:
2433 deviceId = "6000".zfill(16)
2434 elif i == 7:
2435 deviceId = "6007".zfill(16)
2436 elif i >= 8 and i <= 17:
2437 dpid = '3' + str( i ).zfill( 3 )
2438 deviceId = dpid.zfill(16)
2439 elif i >= 18 and i <= 27:
2440 dpid = '6' + str( i ).zfill( 3 )
2441 deviceId = dpid.zfill(16)
2442 elif i == 28:
2443 deviceId = "2800".zfill(16)
2444 mappings[ macId ] = deviceId
Jon Halld8f6de82015-12-17 17:04:34 -08002445 if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002446 if hosts[ controller ] == []:
2447 main.log.warn( "There are no hosts discovered" )
2448 zeroHosts = True
2449 else:
2450 for host in hosts[ controller ]:
2451 mac = None
2452 location = None
2453 device = None
2454 port = None
2455 try:
2456 mac = host.get( 'mac' )
2457 assert mac, "mac field could not be found for this host object"
2458
2459 location = host.get( 'location' )
2460 assert location, "location field could not be found for this host object"
2461
2462 # Trim the protocol identifier off deviceId
2463 device = str( location.get( 'elementId' ) ).split(':')[1]
2464 assert device, "elementId field could not be found for this host location object"
2465
2466 port = location.get( 'port' )
2467 assert port, "port field could not be found for this host location object"
2468
2469 # Now check if this matches where they should be
2470 if mac and device and port:
2471 if str( port ) != "1":
2472 main.log.error( "The attachment port is incorrect for " +
2473 "host " + str( mac ) +
2474 ". Expected: 1 Actual: " + str( port) )
2475 hostAttachment = False
2476 if device != mappings[ str( mac ) ]:
2477 main.log.error( "The attachment device is incorrect for " +
2478 "host " + str( mac ) +
2479 ". Expected: " + mappings[ str( mac ) ] +
2480 " Actual: " + device )
2481 hostAttachment = False
2482 else:
2483 hostAttachment = False
2484 except AssertionError:
2485 main.log.exception( "Json object not as expected" )
2486 main.log.error( repr( host ) )
2487 hostAttachment = False
2488 else:
2489 main.log.error( "No hosts json output or \"Error\"" +
2490 " in output. hosts = " +
2491 repr( hosts[ controller ] ) )
2492 if zeroHosts is False:
2493 hostAttachment = True
2494
2495 # END CHECKING HOST ATTACHMENT POINTS
2496 devicesResults = devicesResults and currentDevicesResult
2497 linksResults = linksResults and currentLinksResult
2498 hostsResults = hostsResults and currentHostsResult
2499 hostAttachmentResults = hostAttachmentResults and\
2500 hostAttachment
Jon Halla440e872016-03-31 15:15:50 -07002501 topoResult = ( devicesResults and linksResults
2502 and hostsResults and ipResult and
2503 hostAttachmentResults )
Jon Halle9b1fa32015-12-08 15:32:21 -08002504 utilities.assert_equals( expect=True,
2505 actual=topoResult,
2506 onpass="ONOS topology matches Mininet",
Jon Hall6e709752016-02-01 13:38:46 -08002507 onfail=topoFailMsg )
Jon Halle9b1fa32015-12-08 15:32:21 -08002508 # End of While loop to pull ONOS state
Jon Hall5cf14d52015-07-16 12:15:19 -07002509
2510 # Compare json objects for hosts and dataplane clusters
2511
2512 # hosts
2513 main.step( "Hosts view is consistent across all ONOS nodes" )
2514 consistentHostsResult = main.TRUE
2515 for controller in range( len( hosts ) ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002516 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall13b446e2016-01-05 12:17:01 -08002517 if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002518 if hosts[ controller ] == hosts[ 0 ]:
2519 continue
2520 else: # hosts not consistent
2521 main.log.error( "hosts from ONOS" + controllerStr +
2522 " is inconsistent with ONOS1" )
2523 main.log.warn( repr( hosts[ controller ] ) )
2524 consistentHostsResult = main.FALSE
2525
2526 else:
2527 main.log.error( "Error in getting ONOS hosts from ONOS" +
2528 controllerStr )
2529 consistentHostsResult = main.FALSE
2530 main.log.warn( "ONOS" + controllerStr +
2531 " hosts response: " +
2532 repr( hosts[ controller ] ) )
2533 utilities.assert_equals(
2534 expect=main.TRUE,
2535 actual=consistentHostsResult,
2536 onpass="Hosts view is consistent across all ONOS nodes",
2537 onfail="ONOS nodes have different views of hosts" )
2538
2539 main.step( "Hosts information is correct" )
2540 hostsResults = hostsResults and ipResult
2541 utilities.assert_equals(
2542 expect=main.TRUE,
2543 actual=hostsResults,
2544 onpass="Host information is correct",
2545 onfail="Host information is incorrect" )
2546
2547 main.step( "Host attachment points to the network" )
2548 utilities.assert_equals(
2549 expect=True,
2550 actual=hostAttachmentResults,
2551 onpass="Hosts are correctly attached to the network",
2552 onfail="ONOS did not correctly attach hosts to the network" )
2553
2554 # Strongly connected clusters of devices
2555 main.step( "Clusters view is consistent across all ONOS nodes" )
2556 consistentClustersResult = main.TRUE
2557 for controller in range( len( clusters ) ):
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002558 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002559 if "Error" not in clusters[ controller ]:
2560 if clusters[ controller ] == clusters[ 0 ]:
2561 continue
2562 else: # clusters not consistent
2563 main.log.error( "clusters from ONOS" +
2564 controllerStr +
2565 " is inconsistent with ONOS1" )
2566 consistentClustersResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002567 else:
2568 main.log.error( "Error in getting dataplane clusters " +
2569 "from ONOS" + controllerStr )
2570 consistentClustersResult = main.FALSE
2571 main.log.warn( "ONOS" + controllerStr +
2572 " clusters response: " +
2573 repr( clusters[ controller ] ) )
2574 utilities.assert_equals(
2575 expect=main.TRUE,
2576 actual=consistentClustersResult,
2577 onpass="Clusters view is consistent across all ONOS nodes",
2578 onfail="ONOS nodes have different views of clusters" )
2579
2580 main.step( "There is only one SCC" )
2581 # there should always only be one cluster
2582 try:
2583 numClusters = len( json.loads( clusters[ 0 ] ) )
2584 except ( ValueError, TypeError ):
2585 main.log.exception( "Error parsing clusters[0]: " +
2586 repr( clusters[0] ) )
Jon Halla440e872016-03-31 15:15:50 -07002587 numClusters = "ERROR"
Jon Hall5cf14d52015-07-16 12:15:19 -07002588 clusterResults = main.FALSE
2589 if numClusters == 1:
2590 clusterResults = main.TRUE
2591 utilities.assert_equals(
2592 expect=1,
2593 actual=numClusters,
2594 onpass="ONOS shows 1 SCC",
2595 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2596
2597 topoResult = ( devicesResults and linksResults
2598 and hostsResults and consistentHostsResult
2599 and consistentClustersResult and clusterResults
2600 and ipResult and hostAttachmentResults )
2601
2602 topoResult = topoResult and int( count <= 2 )
2603 note = "note it takes about " + str( int( cliTime ) ) + \
2604 " seconds for the test to make all the cli calls to fetch " +\
2605 "the topology from each ONOS instance"
2606 main.log.info(
2607 "Very crass estimate for topology discovery/convergence( " +
2608 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2609 str( count ) + " tries" )
2610
2611 main.step( "Device information is correct" )
2612 utilities.assert_equals(
2613 expect=main.TRUE,
2614 actual=devicesResults,
2615 onpass="Device information is correct",
2616 onfail="Device information is incorrect" )
2617
2618 main.step( "Links are correct" )
2619 utilities.assert_equals(
2620 expect=main.TRUE,
2621 actual=linksResults,
2622 onpass="Link are correct",
2623 onfail="Links are incorrect" )
2624
Jon Halla440e872016-03-31 15:15:50 -07002625 main.step( "Hosts are correct" )
2626 utilities.assert_equals(
2627 expect=main.TRUE,
2628 actual=hostsResults,
2629 onpass="Hosts are correct",
2630 onfail="Hosts are incorrect" )
2631
Jon Hall5cf14d52015-07-16 12:15:19 -07002632 # FIXME: move this to an ONOS state case
2633 main.step( "Checking ONOS nodes" )
Jon Hall41d39f12016-04-11 22:54:35 -07002634 nodeResults = utilities.retry( main.HA.nodesCheck,
2635 False,
2636 args=[main.activeNodes],
2637 attempts=5 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002638
Jon Hall41d39f12016-04-11 22:54:35 -07002639 utilities.assert_equals( expect=True, actual=nodeResults,
Jon Hall5cf14d52015-07-16 12:15:19 -07002640 onpass="Nodes check successful",
2641 onfail="Nodes check NOT successful" )
Jon Halla440e872016-03-31 15:15:50 -07002642 if not nodeResults:
Jon Hall41d39f12016-04-11 22:54:35 -07002643 for i in main.activeNodes:
Jon Halla440e872016-03-31 15:15:50 -07002644 main.log.debug( "{} components not ACTIVE: \n{}".format(
Jon Hall41d39f12016-04-11 22:54:35 -07002645 main.CLIs[i].name,
2646 main.CLIs[i].sendline( "scr:list | grep -v ACTIVE" ) ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002647
2648 def CASE9( self, main ):
2649 """
2650 Link s3-s28 down
2651 """
2652 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002653 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002654 assert main, "main not defined"
2655 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002656 assert main.CLIs, "main.CLIs not defined"
2657 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002658 # NOTE: You should probably run a topology check after this
2659
2660 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2661
2662 description = "Turn off a link to ensure that Link Discovery " +\
2663 "is working properly"
2664 main.case( description )
2665
2666 main.step( "Kill Link between s3 and s28" )
2667 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
2668 main.log.info( "Waiting " + str( linkSleep ) +
2669 " seconds for link down to be discovered" )
2670 time.sleep( linkSleep )
2671 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
2672 onpass="Link down successful",
2673 onfail="Failed to bring link down" )
2674 # TODO do some sort of check here
2675
2676 def CASE10( self, main ):
2677 """
2678 Link s3-s28 up
2679 """
2680 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002681 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002682 assert main, "main not defined"
2683 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002684 assert main.CLIs, "main.CLIs not defined"
2685 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002686 # NOTE: You should probably run a topology check after this
2687
2688 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2689
2690 description = "Restore a link to ensure that Link Discovery is " + \
2691 "working properly"
2692 main.case( description )
2693
2694 main.step( "Bring link between s3 and s28 back up" )
2695 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
2696 main.log.info( "Waiting " + str( linkSleep ) +
2697 " seconds for link up to be discovered" )
2698 time.sleep( linkSleep )
2699 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
2700 onpass="Link up successful",
2701 onfail="Failed to bring link up" )
2702 # TODO do some sort of check here
2703
2704 def CASE11( self, main ):
2705 """
2706 Switch Down
2707 """
2708 # NOTE: You should probably run a topology check after this
2709 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002710 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002711 assert main, "main not defined"
2712 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002713 assert main.CLIs, "main.CLIs not defined"
2714 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002715
2716 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2717
2718 description = "Killing a switch to ensure it is discovered correctly"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002719 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002720 main.case( description )
2721 switch = main.params[ 'kill' ][ 'switch' ]
2722 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2723
2724 # TODO: Make this switch parameterizable
2725 main.step( "Kill " + switch )
2726 main.log.info( "Deleting " + switch )
2727 main.Mininet1.delSwitch( switch )
2728 main.log.info( "Waiting " + str( switchSleep ) +
2729 " seconds for switch down to be discovered" )
2730 time.sleep( switchSleep )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002731 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall5cf14d52015-07-16 12:15:19 -07002732 # Peek at the deleted switch
2733 main.log.warn( str( device ) )
2734 result = main.FALSE
2735 if device and device[ 'available' ] is False:
2736 result = main.TRUE
2737 utilities.assert_equals( expect=main.TRUE, actual=result,
2738 onpass="Kill switch successful",
2739 onfail="Failed to kill switch?" )
2740
2741 def CASE12( self, main ):
2742 """
2743 Switch Up
2744 """
2745 # NOTE: You should probably run a topology check after this
2746 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002747 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002748 assert main, "main not defined"
2749 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002750 assert main.CLIs, "main.CLIs not defined"
2751 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002752 assert ONOS1Port, "ONOS1Port not defined"
2753 assert ONOS2Port, "ONOS2Port not defined"
2754 assert ONOS3Port, "ONOS3Port not defined"
2755 assert ONOS4Port, "ONOS4Port not defined"
2756 assert ONOS5Port, "ONOS5Port not defined"
2757 assert ONOS6Port, "ONOS6Port not defined"
2758 assert ONOS7Port, "ONOS7Port not defined"
2759
2760 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2761 switch = main.params[ 'kill' ][ 'switch' ]
2762 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2763 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002764 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002765 description = "Adding a switch to ensure it is discovered correctly"
2766 main.case( description )
2767
2768 main.step( "Add back " + switch )
2769 main.Mininet1.addSwitch( switch, dpid=switchDPID )
2770 for peer in links:
2771 main.Mininet1.addLink( switch, peer )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002772 ipList = [ node.ip_address for node in main.nodes ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002773 main.Mininet1.assignSwController( sw=switch, ip=ipList )
2774 main.log.info( "Waiting " + str( switchSleep ) +
2775 " seconds for switch up to be discovered" )
2776 time.sleep( switchSleep )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002777 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall5cf14d52015-07-16 12:15:19 -07002778 # Peek at the deleted switch
2779 main.log.warn( str( device ) )
2780 result = main.FALSE
2781 if device and device[ 'available' ]:
2782 result = main.TRUE
2783 utilities.assert_equals( expect=main.TRUE, actual=result,
2784 onpass="add switch successful",
2785 onfail="Failed to add switch?" )
2786
2787 def CASE13( self, main ):
2788 """
2789 Clean up
2790 """
2791 import os
2792 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002793 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002794 assert main, "main not defined"
2795 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002796 assert main.CLIs, "main.CLIs not defined"
2797 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002798
2799 # printing colors to terminal
2800 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2801 'blue': '\033[94m', 'green': '\033[92m',
2802 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
2803 main.case( "Test Cleanup" )
2804 main.step( "Killing tcpdumps" )
2805 main.Mininet2.stopTcpdump()
2806
2807 testname = main.TEST
Jon Hall96091e62015-09-21 17:34:17 -07002808 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall5cf14d52015-07-16 12:15:19 -07002809 main.step( "Copying MN pcap and ONOS log files to test station" )
2810 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
2811 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
Jon Hall96091e62015-09-21 17:34:17 -07002812 # NOTE: MN Pcap file is being saved to logdir.
2813 # We scp this file as MN and TestON aren't necessarily the same vm
2814
2815 # FIXME: To be replaced with a Jenkin's post script
Jon Hall5cf14d52015-07-16 12:15:19 -07002816 # TODO: Load these from params
2817 # NOTE: must end in /
2818 logFolder = "/opt/onos/log/"
2819 logFiles = [ "karaf.log", "karaf.log.1" ]
2820 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002821 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002822 for node in main.nodes:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002823 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002824 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2825 logFolder + f, dstName )
Jon Hall5cf14d52015-07-16 12:15:19 -07002826 # std*.log's
2827 # NOTE: must end in /
2828 logFolder = "/opt/onos/var/"
2829 logFiles = [ "stderr.log", "stdout.log" ]
2830 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002831 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002832 for node in main.nodes:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002833 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002834 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2835 logFolder + f, dstName )
2836 else:
2837 main.log.debug( "skipping saving log files" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002838
2839 main.step( "Stopping Mininet" )
2840 mnResult = main.Mininet1.stopNet()
2841 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2842 onpass="Mininet stopped",
2843 onfail="MN cleanup NOT successful" )
2844
2845 main.step( "Checking ONOS Logs for errors" )
Jon Halle1a3b752015-07-22 13:02:46 -07002846 for node in main.nodes:
Jon Hall96091e62015-09-21 17:34:17 -07002847 main.log.debug( "Checking logs for errors on " + node.name + ":" )
2848 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002849
2850 try:
2851 timerLog = open( main.logdir + "/Timers.csv", 'w')
2852 # Overwrite with empty line and close
2853 labels = "Gossip Intents, Restart"
2854 data = str( gossipTime ) + ", " + str( main.restartTime )
2855 timerLog.write( labels + "\n" + data )
2856 timerLog.close()
2857 except NameError, e:
2858 main.log.exception(e)
2859
2860 def CASE14( self, main ):
2861 """
2862 start election app on all onos nodes
2863 """
Jon Halle1a3b752015-07-22 13:02:46 -07002864 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002865 assert main, "main not defined"
2866 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002867 assert main.CLIs, "main.CLIs not defined"
2868 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002869
2870 main.case("Start Leadership Election app")
2871 main.step( "Install leadership election app" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002872 onosCli = main.CLIs[ main.activeNodes[0] ]
2873 appResult = onosCli.activateApp( "org.onosproject.election" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002874 utilities.assert_equals(
2875 expect=main.TRUE,
2876 actual=appResult,
2877 onpass="Election app installed",
2878 onfail="Something went wrong with installing Leadership election" )
2879
2880 main.step( "Run for election on each node" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002881 for i in main.activeNodes:
2882 main.CLIs[i].electionTestRun()
Jon Hall25463a82016-04-13 14:03:52 -07002883 time.sleep(5)
2884 activeCLIs = [ main.CLIs[i] for i in main.activeNodes ]
2885 sameResult, leaders = main.HA.consistentLeaderboards( activeCLIs )
Jon Hall5cf14d52015-07-16 12:15:19 -07002886 utilities.assert_equals(
Jon Hall25463a82016-04-13 14:03:52 -07002887 expect=True,
2888 actual=sameResult,
2889 onpass="All nodes see the same leaderboards",
2890 onfail="Inconsistent leaderboards" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002891
Jon Hall25463a82016-04-13 14:03:52 -07002892 if sameResult:
2893 leader = leaders[ 0 ][ 0 ]
2894 if main.nodes[main.activeNodes[0]].ip_address in leader:
2895 correctLeader = True
2896 else:
2897 correctLeader = False
2898 main.step( "First node was elected leader" )
2899 utilities.assert_equals(
2900 expect=True,
2901 actual=correctLeader,
2902 onpass="Correct leader was elected",
2903 onfail="Incorrect leader" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002904
2905 def CASE15( self, main ):
2906 """
2907 Check that Leadership Election is still functional
acsmars71adceb2015-08-31 15:09:26 -07002908 15.1 Run election on each node
2909 15.2 Check that each node has the same leaders and candidates
2910 15.3 Find current leader and withdraw
2911 15.4 Check that a new node was elected leader
2912 15.5 Check that that new leader was the candidate of old leader
2913 15.6 Run for election on old leader
2914 15.7 Check that oldLeader is a candidate, and leader if only 1 node
2915 15.8 Make sure that the old leader was added to the candidate list
2916
2917 old and new variable prefixes refer to data from before vs after
2918 withdrawl and later before withdrawl vs after re-election
Jon Hall5cf14d52015-07-16 12:15:19 -07002919 """
2920 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002921 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002922 assert main, "main not defined"
2923 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002924 assert main.CLIs, "main.CLIs not defined"
2925 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002926
Jon Hall5cf14d52015-07-16 12:15:19 -07002927 description = "Check that Leadership Election is still functional"
2928 main.case( description )
Jon Halla440e872016-03-31 15:15:50 -07002929 # NOTE: Need to re-run after restarts since being a canidate is not persistant
Jon Hall5cf14d52015-07-16 12:15:19 -07002930
Jon Halla440e872016-03-31 15:15:50 -07002931 oldLeaders = [] # list of lists of each nodes' candidates before
2932 newLeaders = [] # list of lists of each nodes' candidates after
acsmars71adceb2015-08-31 15:09:26 -07002933 oldLeader = '' # the old leader from oldLeaders, None if not same
2934 newLeader = '' # the new leaders fron newLoeaders, None if not same
2935 oldLeaderCLI = None # the CLI of the old leader used for re-electing
2936 expectNoLeader = False # True when there is only one leader
2937 if main.numCtrls == 1:
2938 expectNoLeader = True
2939
2940 main.step( "Run for election on each node" )
2941 electionResult = main.TRUE
2942
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002943 for i in main.activeNodes: # run test election on each node
2944 if main.CLIs[i].electionTestRun() == main.FALSE:
acsmars71adceb2015-08-31 15:09:26 -07002945 electionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002946 utilities.assert_equals(
2947 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002948 actual=electionResult,
2949 onpass="All nodes successfully ran for leadership",
2950 onfail="At least one node failed to run for leadership" )
2951
acsmars3a72bde2015-09-02 14:16:22 -07002952 if electionResult == main.FALSE:
2953 main.log.error(
2954 "Skipping Test Case because Election Test App isn't loaded" )
2955 main.skipCase()
2956
acsmars71adceb2015-08-31 15:09:26 -07002957 main.step( "Check that each node shows the same leader and candidates" )
Jon Halla440e872016-03-31 15:15:50 -07002958 failMessage = "Nodes have different leaderboards"
Jon Halla440e872016-03-31 15:15:50 -07002959 activeCLIs = [ main.CLIs[i] for i in main.activeNodes ]
Jon Hall41d39f12016-04-11 22:54:35 -07002960 sameResult, oldLeaders = main.HA.consistentLeaderboards( activeCLIs )
Jon Halla440e872016-03-31 15:15:50 -07002961 if sameResult:
2962 oldLeader = oldLeaders[ 0 ][ 0 ]
2963 main.log.warn( oldLeader )
acsmars71adceb2015-08-31 15:09:26 -07002964 else:
Jon Halla440e872016-03-31 15:15:50 -07002965 oldLeader = None
acsmars71adceb2015-08-31 15:09:26 -07002966 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07002967 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07002968 actual=sameResult,
Jon Halla440e872016-03-31 15:15:50 -07002969 onpass="Leaderboards are consistent for the election topic",
acsmars71adceb2015-08-31 15:09:26 -07002970 onfail=failMessage )
Jon Hall5cf14d52015-07-16 12:15:19 -07002971
2972 main.step( "Find current leader and withdraw" )
acsmars71adceb2015-08-31 15:09:26 -07002973 withdrawResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002974 # do some sanity checking on leader before using it
acsmars71adceb2015-08-31 15:09:26 -07002975 if oldLeader is None:
2976 main.log.error( "Leadership isn't consistent." )
2977 withdrawResult = main.FALSE
2978 # Get the CLI of the oldLeader
Jon Hallb3ed8ed2015-10-28 16:43:55 -07002979 for i in main.activeNodes:
acsmars71adceb2015-08-31 15:09:26 -07002980 if oldLeader == main.nodes[ i ].ip_address:
2981 oldLeaderCLI = main.CLIs[ i ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002982 break
2983 else: # FOR/ELSE statement
2984 main.log.error( "Leader election, could not find current leader" )
2985 if oldLeader:
acsmars71adceb2015-08-31 15:09:26 -07002986 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall5cf14d52015-07-16 12:15:19 -07002987 utilities.assert_equals(
2988 expect=main.TRUE,
2989 actual=withdrawResult,
2990 onpass="Node was withdrawn from election",
2991 onfail="Node was not withdrawn from election" )
2992
acsmars71adceb2015-08-31 15:09:26 -07002993 main.step( "Check that a new node was elected leader" )
acsmars71adceb2015-08-31 15:09:26 -07002994 failMessage = "Nodes have different leaders"
acsmars71adceb2015-08-31 15:09:26 -07002995 # Get new leaders and candidates
Jon Hall41d39f12016-04-11 22:54:35 -07002996 newLeaderResult, newLeaders = main.HA.consistentLeaderboards( activeCLIs )
Jon Hall3a7843a2016-04-12 03:01:09 -07002997 newLeader = None
Jon Halla440e872016-03-31 15:15:50 -07002998 if newLeaderResult:
Jon Hall3a7843a2016-04-12 03:01:09 -07002999 if newLeaders[ 0 ][ 0 ] == 'none':
3000 main.log.error( "No leader was elected on at least 1 node" )
3001 if not expectNoLeader:
3002 newLeaderResult = False
Jon Hall25463a82016-04-13 14:03:52 -07003003 newLeader = newLeaders[ 0 ][ 0 ]
acsmars71adceb2015-08-31 15:09:26 -07003004
3005 # Check that the new leader is not the older leader, which was withdrawn
3006 if newLeader == oldLeader:
Jon Halla440e872016-03-31 15:15:50 -07003007 newLeaderResult = False
Jon Hall6e709752016-02-01 13:38:46 -08003008 main.log.error( "All nodes still see old leader: " + str( oldLeader ) +
acsmars71adceb2015-08-31 15:09:26 -07003009 " as the current leader" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003010 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07003011 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07003012 actual=newLeaderResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07003013 onpass="Leadership election passed",
3014 onfail="Something went wrong with Leadership election" )
3015
Jon Halla440e872016-03-31 15:15:50 -07003016 main.step( "Check that that new leader was the candidate of old leader" )
Jon Hall6e709752016-02-01 13:38:46 -08003017 # candidates[ 2 ] should become the top candidate after withdrawl
acsmars71adceb2015-08-31 15:09:26 -07003018 correctCandidateResult = main.TRUE
3019 if expectNoLeader:
3020 if newLeader == 'none':
3021 main.log.info( "No leader expected. None found. Pass" )
3022 correctCandidateResult = main.TRUE
3023 else:
3024 main.log.info( "Expected no leader, got: " + str( newLeader ) )
3025 correctCandidateResult = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003026 elif len( oldLeaders[0] ) >= 3:
3027 if newLeader == oldLeaders[ 0 ][ 2 ]:
3028 # correct leader was elected
3029 correctCandidateResult = main.TRUE
3030 else:
3031 correctCandidateResult = main.FALSE
3032 main.log.error( "Candidate {} was elected. {} should have had priority.".format(
3033 newLeader, oldLeaders[ 0 ][ 2 ] ) )
Jon Hall6e709752016-02-01 13:38:46 -08003034 else:
3035 main.log.warn( "Could not determine who should be the correct leader" )
Jon Halla440e872016-03-31 15:15:50 -07003036 main.log.debug( oldLeaders[ 0 ] )
Jon Hall6e709752016-02-01 13:38:46 -08003037 correctCandidateResult = main.FALSE
acsmars71adceb2015-08-31 15:09:26 -07003038 utilities.assert_equals(
3039 expect=main.TRUE,
3040 actual=correctCandidateResult,
3041 onpass="Correct Candidate Elected",
3042 onfail="Incorrect Candidate Elected" )
3043
Jon Hall5cf14d52015-07-16 12:15:19 -07003044 main.step( "Run for election on old leader( just so everyone " +
3045 "is in the hat )" )
acsmars71adceb2015-08-31 15:09:26 -07003046 if oldLeaderCLI is not None:
3047 runResult = oldLeaderCLI.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07003048 else:
acsmars71adceb2015-08-31 15:09:26 -07003049 main.log.error( "No old leader to re-elect" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003050 runResult = main.FALSE
3051 utilities.assert_equals(
3052 expect=main.TRUE,
3053 actual=runResult,
3054 onpass="App re-ran for election",
3055 onfail="App failed to run for election" )
Jon Halla440e872016-03-31 15:15:50 -07003056
acsmars71adceb2015-08-31 15:09:26 -07003057 main.step(
3058 "Check that oldLeader is a candidate, and leader if only 1 node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003059 # verify leader didn't just change
Jon Halla440e872016-03-31 15:15:50 -07003060 # Get new leaders and candidates
3061 reRunLeaders = []
3062 time.sleep( 5 ) # Paremterize
Jon Hall41d39f12016-04-11 22:54:35 -07003063 positionResult, reRunLeaders = main.HA.consistentLeaderboards( activeCLIs )
acsmars71adceb2015-08-31 15:09:26 -07003064
3065 # Check that the re-elected node is last on the candidate List
Jon Hall3a7843a2016-04-12 03:01:09 -07003066 if not reRunLeaders[0]:
3067 positionResult = main.FALSE
3068 elif oldLeader != reRunLeaders[ 0 ][ -1 ]:
Jon Halla440e872016-03-31 15:15:50 -07003069 main.log.error( "Old Leader ({}) not in the proper position: {} ".format( str( oldLeader),
3070 str( reRunLeaders[ 0 ] ) ) )
acsmars71adceb2015-08-31 15:09:26 -07003071 positionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07003072 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07003073 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07003074 actual=positionResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07003075 onpass="Old leader successfully re-ran for election",
3076 onfail="Something went wrong with Leadership election after " +
3077 "the old leader re-ran for election" )
3078
3079 def CASE16( self, main ):
3080 """
3081 Install Distributed Primitives app
3082 """
3083 import time
Jon Halle1a3b752015-07-22 13:02:46 -07003084 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003085 assert main, "main not defined"
3086 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003087 assert main.CLIs, "main.CLIs not defined"
3088 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003089
3090 # Variables for the distributed primitives tests
3091 global pCounterName
Jon Hall5cf14d52015-07-16 12:15:19 -07003092 global pCounterValue
Jon Hall5cf14d52015-07-16 12:15:19 -07003093 global onosSet
3094 global onosSetName
3095 pCounterName = "TestON-Partitions"
Jon Hall5cf14d52015-07-16 12:15:19 -07003096 pCounterValue = 0
Jon Hall5cf14d52015-07-16 12:15:19 -07003097 onosSet = set([])
3098 onosSetName = "TestON-set"
3099
3100 description = "Install Primitives app"
3101 main.case( description )
3102 main.step( "Install Primitives app" )
3103 appName = "org.onosproject.distributedprimitives"
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003104 node = main.activeNodes[0]
3105 appResults = main.CLIs[node].activateApp( appName )
Jon Hall5cf14d52015-07-16 12:15:19 -07003106 utilities.assert_equals( expect=main.TRUE,
3107 actual=appResults,
3108 onpass="Primitives app activated",
3109 onfail="Primitives app not activated" )
3110 time.sleep( 5 ) # To allow all nodes to activate
3111
3112 def CASE17( self, main ):
3113 """
3114 Check for basic functionality with distributed primitives
3115 """
Jon Hall5cf14d52015-07-16 12:15:19 -07003116 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07003117 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003118 assert main, "main not defined"
3119 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003120 assert main.CLIs, "main.CLIs not defined"
3121 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003122 assert pCounterName, "pCounterName not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003123 assert onosSetName, "onosSetName not defined"
3124 # NOTE: assert fails if value is 0/None/Empty/False
3125 try:
3126 pCounterValue
3127 except NameError:
3128 main.log.error( "pCounterValue not defined, setting to 0" )
3129 pCounterValue = 0
3130 try:
Jon Hall5cf14d52015-07-16 12:15:19 -07003131 onosSet
3132 except NameError:
3133 main.log.error( "onosSet not defined, setting to empty Set" )
3134 onosSet = set([])
3135 # Variables for the distributed primitives tests. These are local only
3136 addValue = "a"
3137 addAllValue = "a b c d e f"
3138 retainValue = "c d e f"
3139
3140 description = "Check for basic functionality with distributed " +\
3141 "primitives"
3142 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07003143 main.caseExplanation = "Test the methods of the distributed " +\
3144 "primitives (counters and sets) throught the cli"
Jon Hall5cf14d52015-07-16 12:15:19 -07003145 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07003146 # Partitioned counters
3147 main.step( "Increment then get a default counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003148 pCounters = []
3149 threads = []
3150 addedPValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003151 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003152 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3153 name="counterAddAndGet-" + str( i ),
Jon Hall5cf14d52015-07-16 12:15:19 -07003154 args=[ pCounterName ] )
3155 pCounterValue += 1
3156 addedPValues.append( pCounterValue )
3157 threads.append( t )
3158 t.start()
3159
3160 for t in threads:
3161 t.join()
3162 pCounters.append( t.result )
3163 # Check that counter incremented numController times
3164 pCounterResults = True
3165 for i in addedPValues:
3166 tmpResult = i in pCounters
3167 pCounterResults = pCounterResults and tmpResult
3168 if not tmpResult:
3169 main.log.error( str( i ) + " is not in partitioned "
3170 "counter incremented results" )
3171 utilities.assert_equals( expect=True,
3172 actual=pCounterResults,
3173 onpass="Default counter incremented",
3174 onfail="Error incrementing default" +
3175 " counter" )
3176
Jon Halle1a3b752015-07-22 13:02:46 -07003177 main.step( "Get then Increment a default counter on each node" )
3178 pCounters = []
3179 threads = []
3180 addedPValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003181 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003182 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3183 name="counterGetAndAdd-" + str( i ),
3184 args=[ pCounterName ] )
3185 addedPValues.append( pCounterValue )
3186 pCounterValue += 1
3187 threads.append( t )
3188 t.start()
3189
3190 for t in threads:
3191 t.join()
3192 pCounters.append( t.result )
3193 # Check that counter incremented numController times
3194 pCounterResults = True
3195 for i in addedPValues:
3196 tmpResult = i in pCounters
3197 pCounterResults = pCounterResults and tmpResult
3198 if not tmpResult:
3199 main.log.error( str( i ) + " is not in partitioned "
3200 "counter incremented results" )
3201 utilities.assert_equals( expect=True,
3202 actual=pCounterResults,
3203 onpass="Default counter incremented",
3204 onfail="Error incrementing default" +
3205 " counter" )
3206
3207 main.step( "Counters we added have the correct values" )
Jon Hall41d39f12016-04-11 22:54:35 -07003208 incrementCheck = main.HA.counterCheck( pCounterName, pCounterValue )
Jon Halle1a3b752015-07-22 13:02:46 -07003209 utilities.assert_equals( expect=main.TRUE,
3210 actual=incrementCheck,
3211 onpass="Added counters are correct",
3212 onfail="Added counters are incorrect" )
3213
3214 main.step( "Add -8 to then get a default counter on each node" )
3215 pCounters = []
3216 threads = []
3217 addedPValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003218 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003219 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3220 name="counterIncrement-" + str( i ),
3221 args=[ pCounterName ],
3222 kwargs={ "delta": -8 } )
3223 pCounterValue += -8
3224 addedPValues.append( pCounterValue )
3225 threads.append( t )
3226 t.start()
3227
3228 for t in threads:
3229 t.join()
3230 pCounters.append( t.result )
3231 # Check that counter incremented numController times
3232 pCounterResults = True
3233 for i in addedPValues:
3234 tmpResult = i in pCounters
3235 pCounterResults = pCounterResults and tmpResult
3236 if not tmpResult:
3237 main.log.error( str( i ) + " is not in partitioned "
3238 "counter incremented results" )
3239 utilities.assert_equals( expect=True,
3240 actual=pCounterResults,
3241 onpass="Default counter incremented",
3242 onfail="Error incrementing default" +
3243 " counter" )
3244
3245 main.step( "Add 5 to then get a default counter on each node" )
3246 pCounters = []
3247 threads = []
3248 addedPValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003249 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003250 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3251 name="counterIncrement-" + str( i ),
3252 args=[ pCounterName ],
3253 kwargs={ "delta": 5 } )
3254 pCounterValue += 5
3255 addedPValues.append( pCounterValue )
3256 threads.append( t )
3257 t.start()
3258
3259 for t in threads:
3260 t.join()
3261 pCounters.append( t.result )
3262 # Check that counter incremented numController times
3263 pCounterResults = True
3264 for i in addedPValues:
3265 tmpResult = i in pCounters
3266 pCounterResults = pCounterResults and tmpResult
3267 if not tmpResult:
3268 main.log.error( str( i ) + " is not in partitioned "
3269 "counter incremented results" )
3270 utilities.assert_equals( expect=True,
3271 actual=pCounterResults,
3272 onpass="Default counter incremented",
3273 onfail="Error incrementing default" +
3274 " counter" )
3275
3276 main.step( "Get then add 5 to a default counter on each node" )
3277 pCounters = []
3278 threads = []
3279 addedPValues = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003280 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003281 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3282 name="counterIncrement-" + str( i ),
3283 args=[ pCounterName ],
3284 kwargs={ "delta": 5 } )
3285 addedPValues.append( pCounterValue )
3286 pCounterValue += 5
3287 threads.append( t )
3288 t.start()
3289
3290 for t in threads:
3291 t.join()
3292 pCounters.append( t.result )
3293 # Check that counter incremented numController times
3294 pCounterResults = True
3295 for i in addedPValues:
3296 tmpResult = i in pCounters
3297 pCounterResults = pCounterResults and tmpResult
3298 if not tmpResult:
3299 main.log.error( str( i ) + " is not in partitioned "
3300 "counter incremented results" )
3301 utilities.assert_equals( expect=True,
3302 actual=pCounterResults,
3303 onpass="Default counter incremented",
3304 onfail="Error incrementing default" +
3305 " counter" )
3306
3307 main.step( "Counters we added have the correct values" )
Jon Hall41d39f12016-04-11 22:54:35 -07003308 incrementCheck = main.HA.counterCheck( pCounterName, pCounterValue )
Jon Halle1a3b752015-07-22 13:02:46 -07003309 utilities.assert_equals( expect=main.TRUE,
3310 actual=incrementCheck,
3311 onpass="Added counters are correct",
3312 onfail="Added counters are incorrect" )
3313
Jon Hall5cf14d52015-07-16 12:15:19 -07003314 # DISTRIBUTED SETS
3315 main.step( "Distributed Set get" )
3316 size = len( onosSet )
3317 getResponses = []
3318 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003319 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003320 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003321 name="setTestGet-" + str( i ),
3322 args=[ onosSetName ] )
3323 threads.append( t )
3324 t.start()
3325 for t in threads:
3326 t.join()
3327 getResponses.append( t.result )
3328
3329 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003330 for i in range( len( main.activeNodes ) ):
3331 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003332 if isinstance( getResponses[ i ], list):
3333 current = set( getResponses[ i ] )
3334 if len( current ) == len( getResponses[ i ] ):
3335 # no repeats
3336 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003337 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003338 " has incorrect view" +
3339 " of set " + onosSetName + ":\n" +
3340 str( getResponses[ i ] ) )
3341 main.log.debug( "Expected: " + str( onosSet ) )
3342 main.log.debug( "Actual: " + str( current ) )
3343 getResults = main.FALSE
3344 else:
3345 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003346 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003347 " has repeat elements in" +
3348 " set " + onosSetName + ":\n" +
3349 str( getResponses[ i ] ) )
3350 getResults = main.FALSE
3351 elif getResponses[ i ] == main.ERROR:
3352 getResults = main.FALSE
3353 utilities.assert_equals( expect=main.TRUE,
3354 actual=getResults,
3355 onpass="Set elements are correct",
3356 onfail="Set elements are incorrect" )
3357
3358 main.step( "Distributed Set size" )
3359 sizeResponses = []
3360 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003361 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003362 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003363 name="setTestSize-" + str( i ),
3364 args=[ onosSetName ] )
3365 threads.append( t )
3366 t.start()
3367 for t in threads:
3368 t.join()
3369 sizeResponses.append( t.result )
3370
3371 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003372 for i in range( len( main.activeNodes ) ):
3373 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003374 if size != sizeResponses[ i ]:
3375 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003376 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003377 " expected a size of " + str( size ) +
3378 " for set " + onosSetName +
3379 " but got " + str( sizeResponses[ i ] ) )
3380 utilities.assert_equals( expect=main.TRUE,
3381 actual=sizeResults,
3382 onpass="Set sizes are correct",
3383 onfail="Set sizes are incorrect" )
3384
3385 main.step( "Distributed Set add()" )
3386 onosSet.add( addValue )
3387 addResponses = []
3388 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003389 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003390 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003391 name="setTestAdd-" + str( i ),
3392 args=[ onosSetName, addValue ] )
3393 threads.append( t )
3394 t.start()
3395 for t in threads:
3396 t.join()
3397 addResponses.append( t.result )
3398
3399 # main.TRUE = successfully changed the set
3400 # main.FALSE = action resulted in no change in set
3401 # main.ERROR - Some error in executing the function
3402 addResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003403 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003404 if addResponses[ i ] == main.TRUE:
3405 # All is well
3406 pass
3407 elif addResponses[ i ] == main.FALSE:
3408 # Already in set, probably fine
3409 pass
3410 elif addResponses[ i ] == main.ERROR:
3411 # Error in execution
3412 addResults = main.FALSE
3413 else:
3414 # unexpected result
3415 addResults = main.FALSE
3416 if addResults != main.TRUE:
3417 main.log.error( "Error executing set add" )
3418
3419 # Check if set is still correct
3420 size = len( onosSet )
3421 getResponses = []
3422 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003423 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003424 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003425 name="setTestGet-" + str( i ),
3426 args=[ onosSetName ] )
3427 threads.append( t )
3428 t.start()
3429 for t in threads:
3430 t.join()
3431 getResponses.append( t.result )
3432 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003433 for i in range( len( main.activeNodes ) ):
3434 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003435 if isinstance( getResponses[ i ], list):
3436 current = set( getResponses[ i ] )
3437 if len( current ) == len( getResponses[ i ] ):
3438 # no repeats
3439 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003440 main.log.error( "ONOS" + node + " has incorrect view" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003441 " of set " + onosSetName + ":\n" +
3442 str( getResponses[ i ] ) )
3443 main.log.debug( "Expected: " + str( onosSet ) )
3444 main.log.debug( "Actual: " + str( current ) )
3445 getResults = main.FALSE
3446 else:
3447 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003448 main.log.error( "ONOS" + node + " has repeat elements in" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003449 " set " + onosSetName + ":\n" +
3450 str( getResponses[ i ] ) )
3451 getResults = main.FALSE
3452 elif getResponses[ i ] == main.ERROR:
3453 getResults = main.FALSE
3454 sizeResponses = []
3455 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003456 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003457 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003458 name="setTestSize-" + str( i ),
3459 args=[ onosSetName ] )
3460 threads.append( t )
3461 t.start()
3462 for t in threads:
3463 t.join()
3464 sizeResponses.append( t.result )
3465 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003466 for i in range( len( main.activeNodes ) ):
3467 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003468 if size != sizeResponses[ i ]:
3469 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003470 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003471 " expected a size of " + str( size ) +
3472 " for set " + onosSetName +
3473 " but got " + str( sizeResponses[ i ] ) )
3474 addResults = addResults and getResults and sizeResults
3475 utilities.assert_equals( expect=main.TRUE,
3476 actual=addResults,
3477 onpass="Set add correct",
3478 onfail="Set add was incorrect" )
3479
3480 main.step( "Distributed Set addAll()" )
3481 onosSet.update( addAllValue.split() )
3482 addResponses = []
3483 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003484 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003485 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003486 name="setTestAddAll-" + str( i ),
3487 args=[ onosSetName, addAllValue ] )
3488 threads.append( t )
3489 t.start()
3490 for t in threads:
3491 t.join()
3492 addResponses.append( t.result )
3493
3494 # main.TRUE = successfully changed the set
3495 # main.FALSE = action resulted in no change in set
3496 # main.ERROR - Some error in executing the function
3497 addAllResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003498 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003499 if addResponses[ i ] == main.TRUE:
3500 # All is well
3501 pass
3502 elif addResponses[ i ] == main.FALSE:
3503 # Already in set, probably fine
3504 pass
3505 elif addResponses[ i ] == main.ERROR:
3506 # Error in execution
3507 addAllResults = main.FALSE
3508 else:
3509 # unexpected result
3510 addAllResults = main.FALSE
3511 if addAllResults != main.TRUE:
3512 main.log.error( "Error executing set addAll" )
3513
3514 # Check if set is still correct
3515 size = len( onosSet )
3516 getResponses = []
3517 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003518 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003519 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003520 name="setTestGet-" + str( i ),
3521 args=[ onosSetName ] )
3522 threads.append( t )
3523 t.start()
3524 for t in threads:
3525 t.join()
3526 getResponses.append( t.result )
3527 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003528 for i in range( len( main.activeNodes ) ):
3529 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003530 if isinstance( getResponses[ i ], list):
3531 current = set( getResponses[ i ] )
3532 if len( current ) == len( getResponses[ i ] ):
3533 # no repeats
3534 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003535 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003536 " has incorrect view" +
3537 " of set " + onosSetName + ":\n" +
3538 str( getResponses[ i ] ) )
3539 main.log.debug( "Expected: " + str( onosSet ) )
3540 main.log.debug( "Actual: " + str( current ) )
3541 getResults = main.FALSE
3542 else:
3543 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003544 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003545 " has repeat elements in" +
3546 " set " + onosSetName + ":\n" +
3547 str( getResponses[ i ] ) )
3548 getResults = main.FALSE
3549 elif getResponses[ i ] == main.ERROR:
3550 getResults = main.FALSE
3551 sizeResponses = []
3552 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003553 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003554 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003555 name="setTestSize-" + str( i ),
3556 args=[ onosSetName ] )
3557 threads.append( t )
3558 t.start()
3559 for t in threads:
3560 t.join()
3561 sizeResponses.append( t.result )
3562 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003563 for i in range( len( main.activeNodes ) ):
3564 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003565 if size != sizeResponses[ i ]:
3566 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003567 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003568 " expected a size of " + str( size ) +
3569 " for set " + onosSetName +
3570 " but got " + str( sizeResponses[ i ] ) )
3571 addAllResults = addAllResults and getResults and sizeResults
3572 utilities.assert_equals( expect=main.TRUE,
3573 actual=addAllResults,
3574 onpass="Set addAll correct",
3575 onfail="Set addAll was incorrect" )
3576
3577 main.step( "Distributed Set contains()" )
3578 containsResponses = []
3579 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003580 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003581 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003582 name="setContains-" + str( i ),
3583 args=[ onosSetName ],
3584 kwargs={ "values": addValue } )
3585 threads.append( t )
3586 t.start()
3587 for t in threads:
3588 t.join()
3589 # NOTE: This is the tuple
3590 containsResponses.append( t.result )
3591
3592 containsResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003593 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003594 if containsResponses[ i ] == main.ERROR:
3595 containsResults = main.FALSE
3596 else:
3597 containsResults = containsResults and\
3598 containsResponses[ i ][ 1 ]
3599 utilities.assert_equals( expect=main.TRUE,
3600 actual=containsResults,
3601 onpass="Set contains is functional",
3602 onfail="Set contains failed" )
3603
3604 main.step( "Distributed Set containsAll()" )
3605 containsAllResponses = []
3606 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003607 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003608 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003609 name="setContainsAll-" + str( i ),
3610 args=[ onosSetName ],
3611 kwargs={ "values": addAllValue } )
3612 threads.append( t )
3613 t.start()
3614 for t in threads:
3615 t.join()
3616 # NOTE: This is the tuple
3617 containsAllResponses.append( t.result )
3618
3619 containsAllResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003620 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003621 if containsResponses[ i ] == main.ERROR:
3622 containsResults = main.FALSE
3623 else:
3624 containsResults = containsResults and\
3625 containsResponses[ i ][ 1 ]
3626 utilities.assert_equals( expect=main.TRUE,
3627 actual=containsAllResults,
3628 onpass="Set containsAll is functional",
3629 onfail="Set containsAll failed" )
3630
3631 main.step( "Distributed Set remove()" )
3632 onosSet.remove( addValue )
3633 removeResponses = []
3634 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003635 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003636 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003637 name="setTestRemove-" + str( i ),
3638 args=[ onosSetName, addValue ] )
3639 threads.append( t )
3640 t.start()
3641 for t in threads:
3642 t.join()
3643 removeResponses.append( t.result )
3644
3645 # main.TRUE = successfully changed the set
3646 # main.FALSE = action resulted in no change in set
3647 # main.ERROR - Some error in executing the function
3648 removeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003649 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003650 if removeResponses[ i ] == main.TRUE:
3651 # All is well
3652 pass
3653 elif removeResponses[ i ] == main.FALSE:
3654 # not in set, probably fine
3655 pass
3656 elif removeResponses[ i ] == main.ERROR:
3657 # Error in execution
3658 removeResults = main.FALSE
3659 else:
3660 # unexpected result
3661 removeResults = main.FALSE
3662 if removeResults != main.TRUE:
3663 main.log.error( "Error executing set remove" )
3664
3665 # Check if set is still correct
3666 size = len( onosSet )
3667 getResponses = []
3668 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003669 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003670 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003671 name="setTestGet-" + str( i ),
3672 args=[ onosSetName ] )
3673 threads.append( t )
3674 t.start()
3675 for t in threads:
3676 t.join()
3677 getResponses.append( t.result )
3678 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003679 for i in range( len( main.activeNodes ) ):
3680 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003681 if isinstance( getResponses[ i ], list):
3682 current = set( getResponses[ i ] )
3683 if len( current ) == len( getResponses[ i ] ):
3684 # no repeats
3685 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003686 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003687 " has incorrect view" +
3688 " of set " + onosSetName + ":\n" +
3689 str( getResponses[ i ] ) )
3690 main.log.debug( "Expected: " + str( onosSet ) )
3691 main.log.debug( "Actual: " + str( current ) )
3692 getResults = main.FALSE
3693 else:
3694 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003695 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003696 " has repeat elements in" +
3697 " set " + onosSetName + ":\n" +
3698 str( getResponses[ i ] ) )
3699 getResults = main.FALSE
3700 elif getResponses[ i ] == main.ERROR:
3701 getResults = main.FALSE
3702 sizeResponses = []
3703 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003704 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003705 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003706 name="setTestSize-" + str( i ),
3707 args=[ onosSetName ] )
3708 threads.append( t )
3709 t.start()
3710 for t in threads:
3711 t.join()
3712 sizeResponses.append( t.result )
3713 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003714 for i in range( len( main.activeNodes ) ):
3715 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003716 if size != sizeResponses[ i ]:
3717 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003718 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003719 " expected a size of " + str( size ) +
3720 " for set " + onosSetName +
3721 " but got " + str( sizeResponses[ i ] ) )
3722 removeResults = removeResults and getResults and sizeResults
3723 utilities.assert_equals( expect=main.TRUE,
3724 actual=removeResults,
3725 onpass="Set remove correct",
3726 onfail="Set remove was incorrect" )
3727
3728 main.step( "Distributed Set removeAll()" )
3729 onosSet.difference_update( addAllValue.split() )
3730 removeAllResponses = []
3731 threads = []
3732 try:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003733 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003734 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003735 name="setTestRemoveAll-" + str( i ),
3736 args=[ onosSetName, addAllValue ] )
3737 threads.append( t )
3738 t.start()
3739 for t in threads:
3740 t.join()
3741 removeAllResponses.append( t.result )
3742 except Exception, e:
3743 main.log.exception(e)
3744
3745 # main.TRUE = successfully changed the set
3746 # main.FALSE = action resulted in no change in set
3747 # main.ERROR - Some error in executing the function
3748 removeAllResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003749 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003750 if removeAllResponses[ i ] == main.TRUE:
3751 # All is well
3752 pass
3753 elif removeAllResponses[ i ] == main.FALSE:
3754 # not in set, probably fine
3755 pass
3756 elif removeAllResponses[ i ] == main.ERROR:
3757 # Error in execution
3758 removeAllResults = main.FALSE
3759 else:
3760 # unexpected result
3761 removeAllResults = main.FALSE
3762 if removeAllResults != main.TRUE:
3763 main.log.error( "Error executing set removeAll" )
3764
3765 # Check if set is still correct
3766 size = len( onosSet )
3767 getResponses = []
3768 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003769 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003770 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003771 name="setTestGet-" + str( i ),
3772 args=[ onosSetName ] )
3773 threads.append( t )
3774 t.start()
3775 for t in threads:
3776 t.join()
3777 getResponses.append( t.result )
3778 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003779 for i in range( len( main.activeNodes ) ):
3780 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003781 if isinstance( getResponses[ i ], list):
3782 current = set( getResponses[ i ] )
3783 if len( current ) == len( getResponses[ i ] ):
3784 # no repeats
3785 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003786 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003787 " has incorrect view" +
3788 " of set " + onosSetName + ":\n" +
3789 str( getResponses[ i ] ) )
3790 main.log.debug( "Expected: " + str( onosSet ) )
3791 main.log.debug( "Actual: " + str( current ) )
3792 getResults = main.FALSE
3793 else:
3794 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003795 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003796 " has repeat elements in" +
3797 " set " + onosSetName + ":\n" +
3798 str( getResponses[ i ] ) )
3799 getResults = main.FALSE
3800 elif getResponses[ i ] == main.ERROR:
3801 getResults = main.FALSE
3802 sizeResponses = []
3803 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003804 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003805 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003806 name="setTestSize-" + str( i ),
3807 args=[ onosSetName ] )
3808 threads.append( t )
3809 t.start()
3810 for t in threads:
3811 t.join()
3812 sizeResponses.append( t.result )
3813 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003814 for i in range( len( main.activeNodes ) ):
3815 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003816 if size != sizeResponses[ i ]:
3817 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003818 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003819 " expected a size of " + str( size ) +
3820 " for set " + onosSetName +
3821 " but got " + str( sizeResponses[ i ] ) )
3822 removeAllResults = removeAllResults and getResults and sizeResults
3823 utilities.assert_equals( expect=main.TRUE,
3824 actual=removeAllResults,
3825 onpass="Set removeAll correct",
3826 onfail="Set removeAll was incorrect" )
3827
3828 main.step( "Distributed Set addAll()" )
3829 onosSet.update( addAllValue.split() )
3830 addResponses = []
3831 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003832 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003833 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003834 name="setTestAddAll-" + str( i ),
3835 args=[ onosSetName, addAllValue ] )
3836 threads.append( t )
3837 t.start()
3838 for t in threads:
3839 t.join()
3840 addResponses.append( t.result )
3841
3842 # main.TRUE = successfully changed the set
3843 # main.FALSE = action resulted in no change in set
3844 # main.ERROR - Some error in executing the function
3845 addAllResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003846 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003847 if addResponses[ i ] == main.TRUE:
3848 # All is well
3849 pass
3850 elif addResponses[ i ] == main.FALSE:
3851 # Already in set, probably fine
3852 pass
3853 elif addResponses[ i ] == main.ERROR:
3854 # Error in execution
3855 addAllResults = main.FALSE
3856 else:
3857 # unexpected result
3858 addAllResults = main.FALSE
3859 if addAllResults != main.TRUE:
3860 main.log.error( "Error executing set addAll" )
3861
3862 # Check if set is still correct
3863 size = len( onosSet )
3864 getResponses = []
3865 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003866 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003867 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003868 name="setTestGet-" + str( i ),
3869 args=[ onosSetName ] )
3870 threads.append( t )
3871 t.start()
3872 for t in threads:
3873 t.join()
3874 getResponses.append( t.result )
3875 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003876 for i in range( len( main.activeNodes ) ):
3877 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003878 if isinstance( getResponses[ i ], list):
3879 current = set( getResponses[ i ] )
3880 if len( current ) == len( getResponses[ i ] ):
3881 # no repeats
3882 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003883 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003884 " has incorrect view" +
3885 " of set " + onosSetName + ":\n" +
3886 str( getResponses[ i ] ) )
3887 main.log.debug( "Expected: " + str( onosSet ) )
3888 main.log.debug( "Actual: " + str( current ) )
3889 getResults = main.FALSE
3890 else:
3891 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003892 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003893 " has repeat elements in" +
3894 " set " + onosSetName + ":\n" +
3895 str( getResponses[ i ] ) )
3896 getResults = main.FALSE
3897 elif getResponses[ i ] == main.ERROR:
3898 getResults = main.FALSE
3899 sizeResponses = []
3900 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003901 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003902 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003903 name="setTestSize-" + str( i ),
3904 args=[ onosSetName ] )
3905 threads.append( t )
3906 t.start()
3907 for t in threads:
3908 t.join()
3909 sizeResponses.append( t.result )
3910 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003911 for i in range( len( main.activeNodes ) ):
3912 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003913 if size != sizeResponses[ i ]:
3914 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003915 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003916 " expected a size of " + str( size ) +
3917 " for set " + onosSetName +
3918 " but got " + str( sizeResponses[ i ] ) )
3919 addAllResults = addAllResults and getResults and sizeResults
3920 utilities.assert_equals( expect=main.TRUE,
3921 actual=addAllResults,
3922 onpass="Set addAll correct",
3923 onfail="Set addAll was incorrect" )
3924
3925 main.step( "Distributed Set clear()" )
3926 onosSet.clear()
3927 clearResponses = []
3928 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003929 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003930 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003931 name="setTestClear-" + str( i ),
3932 args=[ onosSetName, " "], # Values doesn't matter
3933 kwargs={ "clear": True } )
3934 threads.append( t )
3935 t.start()
3936 for t in threads:
3937 t.join()
3938 clearResponses.append( t.result )
3939
3940 # main.TRUE = successfully changed the set
3941 # main.FALSE = action resulted in no change in set
3942 # main.ERROR - Some error in executing the function
3943 clearResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003944 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003945 if clearResponses[ i ] == main.TRUE:
3946 # All is well
3947 pass
3948 elif clearResponses[ i ] == main.FALSE:
3949 # Nothing set, probably fine
3950 pass
3951 elif clearResponses[ i ] == main.ERROR:
3952 # Error in execution
3953 clearResults = main.FALSE
3954 else:
3955 # unexpected result
3956 clearResults = main.FALSE
3957 if clearResults != main.TRUE:
3958 main.log.error( "Error executing set clear" )
3959
3960 # Check if set is still correct
3961 size = len( onosSet )
3962 getResponses = []
3963 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003964 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003965 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003966 name="setTestGet-" + str( i ),
3967 args=[ onosSetName ] )
3968 threads.append( t )
3969 t.start()
3970 for t in threads:
3971 t.join()
3972 getResponses.append( t.result )
3973 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003974 for i in range( len( main.activeNodes ) ):
3975 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003976 if isinstance( getResponses[ i ], list):
3977 current = set( getResponses[ i ] )
3978 if len( current ) == len( getResponses[ i ] ):
3979 # no repeats
3980 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003981 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003982 " has incorrect view" +
3983 " of set " + onosSetName + ":\n" +
3984 str( getResponses[ i ] ) )
3985 main.log.debug( "Expected: " + str( onosSet ) )
3986 main.log.debug( "Actual: " + str( current ) )
3987 getResults = main.FALSE
3988 else:
3989 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003990 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003991 " has repeat elements in" +
3992 " set " + onosSetName + ":\n" +
3993 str( getResponses[ i ] ) )
3994 getResults = main.FALSE
3995 elif getResponses[ i ] == main.ERROR:
3996 getResults = main.FALSE
3997 sizeResponses = []
3998 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07003999 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004000 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004001 name="setTestSize-" + str( i ),
4002 args=[ onosSetName ] )
4003 threads.append( t )
4004 t.start()
4005 for t in threads:
4006 t.join()
4007 sizeResponses.append( t.result )
4008 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004009 for i in range( len( main.activeNodes ) ):
4010 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004011 if size != sizeResponses[ i ]:
4012 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004013 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004014 " expected a size of " + str( size ) +
4015 " for set " + onosSetName +
4016 " but got " + str( sizeResponses[ i ] ) )
4017 clearResults = clearResults and getResults and sizeResults
4018 utilities.assert_equals( expect=main.TRUE,
4019 actual=clearResults,
4020 onpass="Set clear correct",
4021 onfail="Set clear was incorrect" )
4022
4023 main.step( "Distributed Set addAll()" )
4024 onosSet.update( addAllValue.split() )
4025 addResponses = []
4026 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004027 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004028 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004029 name="setTestAddAll-" + str( i ),
4030 args=[ onosSetName, addAllValue ] )
4031 threads.append( t )
4032 t.start()
4033 for t in threads:
4034 t.join()
4035 addResponses.append( t.result )
4036
4037 # main.TRUE = successfully changed the set
4038 # main.FALSE = action resulted in no change in set
4039 # main.ERROR - Some error in executing the function
4040 addAllResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004041 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004042 if addResponses[ i ] == main.TRUE:
4043 # All is well
4044 pass
4045 elif addResponses[ i ] == main.FALSE:
4046 # Already in set, probably fine
4047 pass
4048 elif addResponses[ i ] == main.ERROR:
4049 # Error in execution
4050 addAllResults = main.FALSE
4051 else:
4052 # unexpected result
4053 addAllResults = main.FALSE
4054 if addAllResults != main.TRUE:
4055 main.log.error( "Error executing set addAll" )
4056
4057 # Check if set is still correct
4058 size = len( onosSet )
4059 getResponses = []
4060 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004061 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004062 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004063 name="setTestGet-" + str( i ),
4064 args=[ onosSetName ] )
4065 threads.append( t )
4066 t.start()
4067 for t in threads:
4068 t.join()
4069 getResponses.append( t.result )
4070 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004071 for i in range( len( main.activeNodes ) ):
4072 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004073 if isinstance( getResponses[ i ], list):
4074 current = set( getResponses[ i ] )
4075 if len( current ) == len( getResponses[ i ] ):
4076 # no repeats
4077 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004078 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004079 " has incorrect view" +
4080 " of set " + onosSetName + ":\n" +
4081 str( getResponses[ i ] ) )
4082 main.log.debug( "Expected: " + str( onosSet ) )
4083 main.log.debug( "Actual: " + str( current ) )
4084 getResults = main.FALSE
4085 else:
4086 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004087 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004088 " has repeat elements in" +
4089 " set " + onosSetName + ":\n" +
4090 str( getResponses[ i ] ) )
4091 getResults = main.FALSE
4092 elif getResponses[ i ] == main.ERROR:
4093 getResults = main.FALSE
4094 sizeResponses = []
4095 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004096 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004097 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004098 name="setTestSize-" + str( i ),
4099 args=[ onosSetName ] )
4100 threads.append( t )
4101 t.start()
4102 for t in threads:
4103 t.join()
4104 sizeResponses.append( t.result )
4105 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004106 for i in range( len( main.activeNodes ) ):
4107 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004108 if size != sizeResponses[ i ]:
4109 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004110 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004111 " expected a size of " + str( size ) +
4112 " for set " + onosSetName +
4113 " but got " + str( sizeResponses[ i ] ) )
4114 addAllResults = addAllResults and getResults and sizeResults
4115 utilities.assert_equals( expect=main.TRUE,
4116 actual=addAllResults,
4117 onpass="Set addAll correct",
4118 onfail="Set addAll was incorrect" )
4119
4120 main.step( "Distributed Set retain()" )
4121 onosSet.intersection_update( retainValue.split() )
4122 retainResponses = []
4123 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004124 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004125 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004126 name="setTestRetain-" + str( i ),
4127 args=[ onosSetName, retainValue ],
4128 kwargs={ "retain": True } )
4129 threads.append( t )
4130 t.start()
4131 for t in threads:
4132 t.join()
4133 retainResponses.append( t.result )
4134
4135 # main.TRUE = successfully changed the set
4136 # main.FALSE = action resulted in no change in set
4137 # main.ERROR - Some error in executing the function
4138 retainResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004139 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004140 if retainResponses[ i ] == main.TRUE:
4141 # All is well
4142 pass
4143 elif retainResponses[ i ] == main.FALSE:
4144 # Already in set, probably fine
4145 pass
4146 elif retainResponses[ i ] == main.ERROR:
4147 # Error in execution
4148 retainResults = main.FALSE
4149 else:
4150 # unexpected result
4151 retainResults = main.FALSE
4152 if retainResults != main.TRUE:
4153 main.log.error( "Error executing set retain" )
4154
4155 # Check if set is still correct
4156 size = len( onosSet )
4157 getResponses = []
4158 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004159 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004160 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004161 name="setTestGet-" + str( i ),
4162 args=[ onosSetName ] )
4163 threads.append( t )
4164 t.start()
4165 for t in threads:
4166 t.join()
4167 getResponses.append( t.result )
4168 getResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004169 for i in range( len( main.activeNodes ) ):
4170 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004171 if isinstance( getResponses[ i ], list):
4172 current = set( getResponses[ i ] )
4173 if len( current ) == len( getResponses[ i ] ):
4174 # no repeats
4175 if onosSet != current:
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004176 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004177 " has incorrect view" +
4178 " of set " + onosSetName + ":\n" +
4179 str( getResponses[ i ] ) )
4180 main.log.debug( "Expected: " + str( onosSet ) )
4181 main.log.debug( "Actual: " + str( current ) )
4182 getResults = main.FALSE
4183 else:
4184 # error, set is not a set
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004185 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004186 " has repeat elements in" +
4187 " set " + onosSetName + ":\n" +
4188 str( getResponses[ i ] ) )
4189 getResults = main.FALSE
4190 elif getResponses[ i ] == main.ERROR:
4191 getResults = main.FALSE
4192 sizeResponses = []
4193 threads = []
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004194 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004195 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004196 name="setTestSize-" + str( i ),
4197 args=[ onosSetName ] )
4198 threads.append( t )
4199 t.start()
4200 for t in threads:
4201 t.join()
4202 sizeResponses.append( t.result )
4203 sizeResults = main.TRUE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004204 for i in range( len( main.activeNodes ) ):
4205 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004206 if size != sizeResponses[ i ]:
4207 sizeResults = main.FALSE
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004208 main.log.error( "ONOS" + node + " expected a size of " +
Jon Hall5cf14d52015-07-16 12:15:19 -07004209 str( size ) + " for set " + onosSetName +
4210 " but got " + str( sizeResponses[ i ] ) )
4211 retainResults = retainResults and getResults and sizeResults
4212 utilities.assert_equals( expect=main.TRUE,
4213 actual=retainResults,
4214 onpass="Set retain correct",
4215 onfail="Set retain was incorrect" )
4216
Jon Hall2a5002c2015-08-21 16:49:11 -07004217 # Transactional maps
4218 main.step( "Partitioned Transactional maps put" )
4219 tMapValue = "Testing"
4220 numKeys = 100
4221 putResult = True
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004222 node = main.activeNodes[0]
4223 putResponses = main.CLIs[node].transactionalMapPut( numKeys, tMapValue )
Jon Hall6e709752016-02-01 13:38:46 -08004224 if putResponses and len( putResponses ) == 100:
Jon Hall2a5002c2015-08-21 16:49:11 -07004225 for i in putResponses:
4226 if putResponses[ i ][ 'value' ] != tMapValue:
4227 putResult = False
4228 else:
4229 putResult = False
4230 if not putResult:
4231 main.log.debug( "Put response values: " + str( putResponses ) )
4232 utilities.assert_equals( expect=True,
4233 actual=putResult,
4234 onpass="Partitioned Transactional Map put successful",
4235 onfail="Partitioned Transactional Map put values are incorrect" )
4236
4237 main.step( "Partitioned Transactional maps get" )
4238 getCheck = True
4239 for n in range( 1, numKeys + 1 ):
4240 getResponses = []
4241 threads = []
4242 valueCheck = True
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004243 for i in main.activeNodes:
Jon Hall2a5002c2015-08-21 16:49:11 -07004244 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4245 name="TMap-get-" + str( i ),
Jon Hallb3ed8ed2015-10-28 16:43:55 -07004246 args=[ "Key" + str( n ) ] )
Jon Hall2a5002c2015-08-21 16:49:11 -07004247 threads.append( t )
4248 t.start()
4249 for t in threads:
4250 t.join()
4251 getResponses.append( t.result )
4252 for node in getResponses:
4253 if node != tMapValue:
4254 valueCheck = False
4255 if not valueCheck:
4256 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4257 main.log.warn( getResponses )
4258 getCheck = getCheck and valueCheck
4259 utilities.assert_equals( expect=True,
4260 actual=getCheck,
4261 onpass="Partitioned Transactional Map get values were correct",
4262 onfail="Partitioned Transactional Map values incorrect" )