blob: 03c14f1f46baedec395bf137db602236675a5443 [file] [log] [blame]
Jon Hall5cf14d52015-07-16 12:15:19 -07001"""
2Description: This test is to determine if ONOS can handle
3 all 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
12CASE6: The Failure case.
13CASE7: Check state after control plane failure
14CASE8: Compare topo
15CASE9: Link s3-s28 down
16CASE10: Link s3-s28 up
17CASE11: Switch down
18CASE12: Switch up
19CASE13: Clean up
20CASE14: start election app on all onos nodes
21CASE15: Check that Leadership Election is still functional
22CASE16: Install Distributed Primitives app
23CASE17: Check for basic functionality with distributed primitives
24"""
25
26
27class HAclusterRestart:
28
29 def __init__( self ):
30 self.default = ''
31
32 def CASE1( self, main ):
33 """
34 CASE1 is to compile ONOS and push it to the test machines
35
36 Startup sequence:
37 cell <name>
38 onos-verify-cell
39 NOTE: temporary - onos-remove-raft-logs
40 onos-uninstall
41 start mininet
42 git pull
43 mvn clean install
44 onos-package
45 onos-install -f
46 onos-wait-for-start
47 start cli sessions
48 start tcpdump
49 """
Jon Halle1a3b752015-07-22 13:02:46 -070050 import imp
Jon Hallf3d16e72015-12-16 17:45:08 -080051 import time
Jon Halla440e872016-03-31 15:15:50 -070052 import json
Jon Hall5cf14d52015-07-16 12:15:19 -070053 main.log.info( "ONOS HA test: Restart all ONOS nodes - " +
54 "initialization" )
55 main.case( "Setting up test environment" )
Jon Hall783bbf92015-07-23 14:33:19 -070056 main.caseExplanation = "Setup the test environment including " +\
Jon Hall5cf14d52015-07-16 12:15:19 -070057 "installing ONOS, starting Mininet and ONOS" +\
58 "cli sessions."
Jon Hall5cf14d52015-07-16 12:15:19 -070059
60 # load some variables from the params file
61 PULLCODE = False
62 if main.params[ 'Git' ] == 'True':
63 PULLCODE = True
64 gitBranch = main.params[ 'branch' ]
65 cellName = main.params[ 'ENV' ][ 'cellName' ]
66
Jon Halle1a3b752015-07-22 13:02:46 -070067 main.numCtrls = int( main.params[ 'num_controllers' ] )
Jon Hall5cf14d52015-07-16 12:15:19 -070068 if main.ONOSbench.maxNodes:
Jon Halle1a3b752015-07-22 13:02:46 -070069 if main.ONOSbench.maxNodes < main.numCtrls:
70 main.numCtrls = int( main.ONOSbench.maxNodes )
71 # set global variables
Jon Hall5cf14d52015-07-16 12:15:19 -070072 global ONOS1Port
73 global ONOS2Port
74 global ONOS3Port
75 global ONOS4Port
76 global ONOS5Port
77 global ONOS6Port
78 global ONOS7Port
79 # These are for csv plotting in jenkins
80 global labels
81 global data
82 labels = []
83 data = []
84
85 # FIXME: just get controller port from params?
86 # TODO: do we really need all these?
87 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
88 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
89 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
90 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
91 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
92 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
93 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
94
Jon Halle1a3b752015-07-22 13:02:46 -070095 try:
Jon Halla440e872016-03-31 15:15:50 -070096 from tests.HAsanity.dependencies.Counters import Counters
97 main.Counters = Counters()
Jon Halle1a3b752015-07-22 13:02:46 -070098 except Exception as e:
99 main.log.exception( e )
100 main.cleanup()
101 main.exit()
102
103 main.CLIs = []
104 main.nodes = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700105 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700106 for i in range( 1, main.numCtrls + 1 ):
107 try:
108 main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
109 main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
110 ipList.append( main.nodes[ -1 ].ip_address )
111 except AttributeError:
112 break
Jon Hall5cf14d52015-07-16 12:15:19 -0700113
114 main.step( "Create cell file" )
115 cellAppString = main.params[ 'ENV' ][ 'appString' ]
116 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
117 main.Mininet1.ip_address,
118 cellAppString, ipList )
119 main.step( "Applying cell variable to environment" )
120 cellResult = main.ONOSbench.setCell( cellName )
121 verifyResult = main.ONOSbench.verifyCell()
122
123 # FIXME:this is short term fix
124 main.log.info( "Removing raft logs" )
125 main.ONOSbench.onosRemoveRaftLogs()
126
127 main.log.info( "Uninstalling ONOS" )
Jon Halle1a3b752015-07-22 13:02:46 -0700128 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700129 main.ONOSbench.onosUninstall( node.ip_address )
130
131 # Make sure ONOS is DEAD
132 main.log.info( "Killing any ONOS processes" )
133 killResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700134 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700135 killed = main.ONOSbench.onosKill( node.ip_address )
136 killResults = killResults and killed
137
138 cleanInstallResult = main.TRUE
139 gitPullResult = main.TRUE
140
141 main.step( "Starting Mininet" )
142 # scp topo file to mininet
143 # TODO: move to params?
144 topoName = "obelisk.py"
145 filePath = main.ONOSbench.home + "/tools/test/topos/"
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700146 main.ONOSbench.scp( main.Mininet1,
147 filePath + topoName,
148 main.Mininet1.home,
149 direction="to" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700150 mnResult = main.Mininet1.startNet( )
151 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
152 onpass="Mininet Started",
153 onfail="Error starting Mininet" )
154
155 main.step( "Git checkout and pull " + gitBranch )
156 if PULLCODE:
157 main.ONOSbench.gitCheckout( gitBranch )
158 gitPullResult = main.ONOSbench.gitPull()
159 # values of 1 or 3 are good
160 utilities.assert_lesser( expect=0, actual=gitPullResult,
161 onpass="Git pull successful",
162 onfail="Git pull failed" )
163 main.ONOSbench.getVersion( report=True )
164
165 main.step( "Using mvn clean install" )
166 cleanInstallResult = main.TRUE
167 if PULLCODE and gitPullResult == main.TRUE:
168 cleanInstallResult = main.ONOSbench.cleanInstall()
169 else:
170 main.log.warn( "Did not pull new code so skipping mvn " +
171 "clean install" )
172 utilities.assert_equals( expect=main.TRUE,
173 actual=cleanInstallResult,
174 onpass="MCI successful",
175 onfail="MCI failed" )
176 # GRAPHS
177 # NOTE: important params here:
178 # job = name of Jenkins job
179 # Plot Name = Plot-HA, only can be used if multiple plots
180 # index = The number of the graph under plot name
181 job = "HAclusterRestart"
182 plotName = "Plot-HA"
Jon Hall843f8bc2016-03-18 14:28:13 -0700183 index = "2"
Jon Hall5cf14d52015-07-16 12:15:19 -0700184 graphs = '<ac:structured-macro ac:name="html">\n'
185 graphs += '<ac:plain-text-body><![CDATA[\n'
186 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
Jon Halla9845df2016-01-15 14:55:58 -0800187 '/plot/' + plotName + '/getPlot?index=' + index +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700188 '&width=500&height=300"' +\
189 'noborder="0" width="500" height="300" scrolling="yes" ' +\
190 'seamless="seamless"></iframe>\n'
191 graphs += ']]></ac:plain-text-body>\n'
192 graphs += '</ac:structured-macro>\n'
193 main.log.wiki(graphs)
194
195 main.step( "Creating ONOS package" )
196 packageResult = main.ONOSbench.onosPackage()
197 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
198 onpass="ONOS package successful",
199 onfail="ONOS package failed" )
200
201 main.step( "Installing ONOS package" )
202 onosInstallResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700203 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700204 tmpResult = main.ONOSbench.onosInstall( options="-f",
205 node=node.ip_address )
206 onosInstallResult = onosInstallResult and tmpResult
207 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
208 onpass="ONOS install successful",
209 onfail="ONOS install failed" )
210
211 main.step( "Checking if ONOS is up yet" )
212 for i in range( 2 ):
213 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700214 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700215 started = main.ONOSbench.isup( node.ip_address )
216 if not started:
Jon Hallc6793552016-01-19 14:18:37 -0800217 main.log.error( node.name + " hasn't started" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700218 onosIsupResult = onosIsupResult and started
219 if onosIsupResult == main.TRUE:
220 break
221 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
222 onpass="ONOS startup successful",
223 onfail="ONOS startup failed" )
224
225 main.log.step( "Starting ONOS CLI sessions" )
226 cliResults = main.TRUE
227 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700228 for i in range( main.numCtrls ):
229 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -0700230 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -0700231 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -0700232 threads.append( t )
233 t.start()
234
235 for t in threads:
236 t.join()
237 cliResults = cliResults and t.result
238 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
239 onpass="ONOS cli startup successful",
240 onfail="ONOS cli startup failed" )
241
Jon Halla440e872016-03-31 15:15:50 -0700242 # Create a list of active nodes for use when some nodes are stopped
243 main.activeNodes = [ i for i in range( 0, len( main.CLIs ) ) ]
244
Jon Hall5cf14d52015-07-16 12:15:19 -0700245 if main.params[ 'tcpdump' ].lower() == "true":
246 main.step( "Start Packet Capture MN" )
247 main.Mininet2.startTcpdump(
248 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
249 + "-MN.pcap",
250 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
251 port=main.params[ 'MNtcpdump' ][ 'port' ] )
252
253 main.step( "App Ids check" )
254 appCheck = main.TRUE
255 threads = []
Jon Halla440e872016-03-31 15:15:50 -0700256 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -0700257 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700258 name="appToIDCheck-" + str( i ),
259 args=[] )
260 threads.append( t )
261 t.start()
262
263 for t in threads:
264 t.join()
265 appCheck = appCheck and t.result
266 if appCheck != main.TRUE:
Jon Halla440e872016-03-31 15:15:50 -0700267 node = main.activeNodes[0]
268 main.log.warn( main.CLIs[node].apps() )
269 main.log.warn( main.CLIs[node].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700270 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
271 onpass="App Ids seem to be correct",
272 onfail="Something is wrong with app Ids" )
273
Jon Halla440e872016-03-31 15:15:50 -0700274 main.step( "Checking ONOS nodes" )
275 nodesOutput = []
276 nodeResults = main.TRUE
277 threads = []
278 for i in main.activeNodes:
279 t = main.Thread( target=main.CLIs[i].nodes,
280 name="nodes-" + str( i ),
281 args=[ ] )
282 threads.append( t )
283 t.start()
284
285 for t in threads:
286 t.join()
287 nodesOutput.append( t.result )
288 ips = [ main.nodes[node].ip_address for node in main.activeNodes ]
289 ips.sort()
290 for i in nodesOutput:
291 try:
292 current = json.loads( i )
293 activeIps = []
294 currentResult = main.FALSE
295 for node in current:
296 if node['state'] == 'READY':
297 activeIps.append( node['ip'] )
298 activeIps.sort()
299 if ips == activeIps:
300 currentResult = main.TRUE
301 except ( ValueError, TypeError ):
302 main.log.error( "Error parsing nodes output" )
303 main.log.warn( repr( i ) )
304 currentResult = main.FALSE
305 nodeResults = nodeResults and currentResult
306 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
307 onpass="Nodes check successful",
308 onfail="Nodes check NOT successful" )
309
310 if not nodeResults:
311 for cli in main.CLIs:
312 main.log.debug( "{} components not ACTIVE: \n{}".format(
313 cli.name,
314 cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
315
Jon Hall5cf14d52015-07-16 12:15:19 -0700316 if cliResults == main.FALSE:
317 main.log.error( "Failed to start ONOS, stopping test" )
318 main.cleanup()
319 main.exit()
320
Jon Hall172b7ba2016-04-07 18:12:20 -0700321 main.step( "Activate apps defined in the params file" )
322 # get data from the params
323 apps = main.params.get( 'apps' )
324 if apps:
325 apps = apps.split(',')
326 main.log.warn( apps )
327 activateResult = True
328 for app in apps:
329 main.CLIs[ 0 ].app( app, "Activate" )
330 # TODO: check this worked
331 time.sleep( 10 ) # wait for apps to activate
332 for app in apps:
333 state = main.CLIs[ 0 ].appStatus( app )
334 if state == "ACTIVE":
335 activateResult = activeResult and True
336 else:
337 main.log.error( "{} is in {} state".format( app, state ) )
338 activeResult = False
339 utilities.assert_equals( expect=True,
340 actual=activateResult,
341 onpass="Successfully activated apps",
342 onfail="Failed to activate apps" )
343 else:
344 main.log.warn( "No apps were specified to be loaded after startup" )
345
346 main.step( "Set ONOS configurations" )
347 config = main.params.get( 'ONOS_Configuration' )
348 if config:
349 main.log.debug( config )
350 checkResult = main.TRUE
351 for component in config:
352 for setting in config[component]:
353 value = config[component][setting]
354 check = main.CLIs[ 0 ].setCfg( component, setting, value )
355 main.log.info( "Value was changed? {}".format( main.TRUE == check ) )
356 checkResult = check and checkResult
357 utilities.assert_equals( expect=main.TRUE,
358 actual=checkResult,
359 onpass="Successfully set config",
360 onfail="Failed to set config" )
361 else:
362 main.log.warn( "No configurations were specified to be changed after startup" )
363
Jon Hall5cf14d52015-07-16 12:15:19 -0700364 def CASE2( self, main ):
365 """
366 Assign devices to controllers
367 """
368 import re
Jon Halle1a3b752015-07-22 13:02:46 -0700369 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700370 assert main, "main not defined"
371 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700372 assert main.CLIs, "main.CLIs not defined"
373 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700374 assert ONOS1Port, "ONOS1Port not defined"
375 assert ONOS2Port, "ONOS2Port not defined"
376 assert ONOS3Port, "ONOS3Port not defined"
377 assert ONOS4Port, "ONOS4Port not defined"
378 assert ONOS5Port, "ONOS5Port not defined"
379 assert ONOS6Port, "ONOS6Port not defined"
380 assert ONOS7Port, "ONOS7Port not defined"
381
382 main.case( "Assigning devices to controllers" )
Jon Hall783bbf92015-07-23 14:33:19 -0700383 main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700384 "and check that an ONOS node becomes the " +\
385 "master of the device."
386 main.step( "Assign switches to controllers" )
387
388 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700389 for i in range( main.numCtrls ):
390 ipList.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -0700391 swList = []
392 for i in range( 1, 29 ):
393 swList.append( "s" + str( i ) )
394 main.Mininet1.assignSwController( sw=swList, ip=ipList )
395
396 mastershipCheck = main.TRUE
397 for i in range( 1, 29 ):
398 response = main.Mininet1.getSwController( "s" + str( i ) )
399 try:
400 main.log.info( str( response ) )
401 except Exception:
402 main.log.info( repr( response ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700403 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700404 if re.search( "tcp:" + node.ip_address, response ):
405 mastershipCheck = mastershipCheck and main.TRUE
406 else:
407 main.log.error( "Error, node " + node.ip_address + " is " +
408 "not in the list of controllers s" +
409 str( i ) + " is connecting to." )
410 mastershipCheck = main.FALSE
411 utilities.assert_equals(
412 expect=main.TRUE,
413 actual=mastershipCheck,
414 onpass="Switch mastership assigned correctly",
415 onfail="Switches not assigned correctly to controllers" )
416
417 def CASE21( self, main ):
418 """
419 Assign mastership to controllers
420 """
Jon Hall5cf14d52015-07-16 12:15:19 -0700421 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700422 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700423 assert main, "main not defined"
424 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700425 assert main.CLIs, "main.CLIs not defined"
426 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700427 assert ONOS1Port, "ONOS1Port not defined"
428 assert ONOS2Port, "ONOS2Port not defined"
429 assert ONOS3Port, "ONOS3Port not defined"
430 assert ONOS4Port, "ONOS4Port not defined"
431 assert ONOS5Port, "ONOS5Port not defined"
432 assert ONOS6Port, "ONOS6Port not defined"
433 assert ONOS7Port, "ONOS7Port not defined"
434
435 main.case( "Assigning Controller roles for switches" )
Jon Hall783bbf92015-07-23 14:33:19 -0700436 main.caseExplanation = "Check that ONOS is connected to each " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700437 "device. Then manually assign" +\
438 " mastership to specific ONOS nodes using" +\
439 " 'device-role'"
440 main.step( "Assign mastership of switches to specific controllers" )
441 # Manually assign mastership to the controller we want
442 roleCall = main.TRUE
443
444 ipList = [ ]
445 deviceList = []
Jon Halla440e872016-03-31 15:15:50 -0700446 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -0700447 try:
448 # Assign mastership to specific controllers. This assignment was
449 # determined for a 7 node cluser, but will work with any sized
450 # cluster
451 for i in range( 1, 29 ): # switches 1 through 28
452 # set up correct variables:
453 if i == 1:
454 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700455 ip = main.nodes[ c ].ip_address # ONOS1
Jon Halla440e872016-03-31 15:15:50 -0700456 deviceId = onosCli.getDevice( "1000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700457 elif i == 2:
Jon Halle1a3b752015-07-22 13:02:46 -0700458 c = 1 % main.numCtrls
459 ip = main.nodes[ c ].ip_address # ONOS2
Jon Halla440e872016-03-31 15:15:50 -0700460 deviceId = onosCli.getDevice( "2000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700461 elif i == 3:
Jon Halle1a3b752015-07-22 13:02:46 -0700462 c = 1 % main.numCtrls
463 ip = main.nodes[ c ].ip_address # ONOS2
Jon Halla440e872016-03-31 15:15:50 -0700464 deviceId = onosCli.getDevice( "3000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700465 elif i == 4:
Jon Halle1a3b752015-07-22 13:02:46 -0700466 c = 3 % main.numCtrls
467 ip = main.nodes[ c ].ip_address # ONOS4
Jon Halla440e872016-03-31 15:15:50 -0700468 deviceId = onosCli.getDevice( "3004" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700469 elif i == 5:
Jon Halle1a3b752015-07-22 13:02:46 -0700470 c = 2 % main.numCtrls
471 ip = main.nodes[ c ].ip_address # ONOS3
Jon Halla440e872016-03-31 15:15:50 -0700472 deviceId = onosCli.getDevice( "5000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700473 elif i == 6:
Jon Halle1a3b752015-07-22 13:02:46 -0700474 c = 2 % main.numCtrls
475 ip = main.nodes[ c ].ip_address # ONOS3
Jon Halla440e872016-03-31 15:15:50 -0700476 deviceId = onosCli.getDevice( "6000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700477 elif i == 7:
Jon Halle1a3b752015-07-22 13:02:46 -0700478 c = 5 % main.numCtrls
479 ip = main.nodes[ c ].ip_address # ONOS6
Jon Halla440e872016-03-31 15:15:50 -0700480 deviceId = onosCli.getDevice( "6007" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700481 elif i >= 8 and i <= 17:
Jon Halle1a3b752015-07-22 13:02:46 -0700482 c = 4 % main.numCtrls
483 ip = main.nodes[ c ].ip_address # ONOS5
Jon Hall5cf14d52015-07-16 12:15:19 -0700484 dpid = '3' + str( i ).zfill( 3 )
Jon Halla440e872016-03-31 15:15:50 -0700485 deviceId = onosCli.getDevice( dpid ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700486 elif i >= 18 and i <= 27:
Jon Halle1a3b752015-07-22 13:02:46 -0700487 c = 6 % main.numCtrls
488 ip = main.nodes[ c ].ip_address # ONOS7
Jon Hall5cf14d52015-07-16 12:15:19 -0700489 dpid = '6' + str( i ).zfill( 3 )
Jon Halla440e872016-03-31 15:15:50 -0700490 deviceId = onosCli.getDevice( dpid ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700491 elif i == 28:
492 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700493 ip = main.nodes[ c ].ip_address # ONOS1
Jon Halla440e872016-03-31 15:15:50 -0700494 deviceId = onosCli.getDevice( "2800" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700495 else:
496 main.log.error( "You didn't write an else statement for " +
497 "switch s" + str( i ) )
498 roleCall = main.FALSE
499 # Assign switch
500 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
501 # TODO: make this controller dynamic
Jon Halla440e872016-03-31 15:15:50 -0700502 roleCall = roleCall and onosCli.deviceRole( deviceId, ip )
Jon Hall5cf14d52015-07-16 12:15:19 -0700503 ipList.append( ip )
504 deviceList.append( deviceId )
505 except ( AttributeError, AssertionError ):
506 main.log.exception( "Something is wrong with ONOS device view" )
Jon Halla440e872016-03-31 15:15:50 -0700507 main.log.info( onosCli.devices() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700508 utilities.assert_equals(
509 expect=main.TRUE,
510 actual=roleCall,
511 onpass="Re-assigned switch mastership to designated controller",
512 onfail="Something wrong with deviceRole calls" )
513
514 main.step( "Check mastership was correctly assigned" )
515 roleCheck = main.TRUE
516 # NOTE: This is due to the fact that device mastership change is not
517 # atomic and is actually a multi step process
518 time.sleep( 5 )
519 for i in range( len( ipList ) ):
520 ip = ipList[i]
521 deviceId = deviceList[i]
522 # Check assignment
Jon Halla440e872016-03-31 15:15:50 -0700523 master = onosCli.getRole( deviceId ).get( 'master' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700524 if ip in master:
525 roleCheck = roleCheck and main.TRUE
526 else:
527 roleCheck = roleCheck and main.FALSE
528 main.log.error( "Error, controller " + ip + " is not" +
529 " master " + "of device " +
530 str( deviceId ) + ". Master is " +
531 repr( master ) + "." )
532 utilities.assert_equals(
533 expect=main.TRUE,
534 actual=roleCheck,
535 onpass="Switches were successfully reassigned to designated " +
536 "controller",
537 onfail="Switches were not successfully reassigned" )
538
539 def CASE3( self, main ):
540 """
541 Assign intents
542 """
543 import time
544 import json
Jon Halle1a3b752015-07-22 13:02:46 -0700545 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700546 assert main, "main not defined"
547 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700548 assert main.CLIs, "main.CLIs not defined"
549 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700550 try:
551 labels
552 except NameError:
553 main.log.error( "labels not defined, setting to []" )
554 labels = []
555 try:
556 data
557 except NameError:
558 main.log.error( "data not defined, setting to []" )
559 data = []
560 # NOTE: we must reinstall intents until we have a persistant intent
561 # datastore!
562 main.case( "Adding host Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700563 main.caseExplanation = "Discover hosts by using pingall then " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700564 "assign predetermined host-to-host intents." +\
565 " After installation, check that the intent" +\
566 " is distributed to all nodes and the state" +\
567 " is INSTALLED"
568
569 # install onos-app-fwd
570 main.step( "Install reactive forwarding app" )
Jon Halla440e872016-03-31 15:15:50 -0700571 onosCli = main.CLIs[ main.activeNodes[0] ]
572 installResults = onosCli.activateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700573 utilities.assert_equals( expect=main.TRUE, actual=installResults,
574 onpass="Install fwd successful",
575 onfail="Install fwd failed" )
576
577 main.step( "Check app ids" )
578 appCheck = main.TRUE
579 threads = []
Jon Halla440e872016-03-31 15:15:50 -0700580 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -0700581 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700582 name="appToIDCheck-" + str( i ),
583 args=[] )
584 threads.append( t )
585 t.start()
586
587 for t in threads:
588 t.join()
589 appCheck = appCheck and t.result
590 if appCheck != main.TRUE:
Jon Halla440e872016-03-31 15:15:50 -0700591 main.log.warn( onosCli.apps() )
592 main.log.warn( onosCli.appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700593 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
594 onpass="App Ids seem to be correct",
595 onfail="Something is wrong with app Ids" )
596
597 main.step( "Discovering Hosts( Via pingall for now )" )
598 # FIXME: Once we have a host discovery mechanism, use that instead
599 # REACTIVE FWD test
600 pingResult = main.FALSE
Jon Hall96091e62015-09-21 17:34:17 -0700601 passMsg = "Reactive Pingall test passed"
602 time1 = time.time()
603 pingResult = main.Mininet1.pingall()
604 time2 = time.time()
605 if not pingResult:
606 main.log.warn("First pingall failed. Trying again...")
Jon Hall5cf14d52015-07-16 12:15:19 -0700607 pingResult = main.Mininet1.pingall()
Jon Hall96091e62015-09-21 17:34:17 -0700608 passMsg += " on the second try"
609 utilities.assert_equals(
610 expect=main.TRUE,
611 actual=pingResult,
612 onpass= passMsg,
613 onfail="Reactive Pingall failed, " +
614 "one or more ping pairs failed" )
615 main.log.info( "Time for pingall: %2f seconds" %
616 ( time2 - time1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -0700617 # timeout for fwd flows
618 time.sleep( 11 )
619 # uninstall onos-app-fwd
620 main.step( "Uninstall reactive forwarding app" )
Jon Halla440e872016-03-31 15:15:50 -0700621 node = main.activeNodes[0]
622 uninstallResult = main.CLIs[node].deactivateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700623 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
624 onpass="Uninstall fwd successful",
625 onfail="Uninstall fwd failed" )
626
627 main.step( "Check app ids" )
628 threads = []
629 appCheck2 = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -0700630 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -0700631 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700632 name="appToIDCheck-" + str( i ),
633 args=[] )
634 threads.append( t )
635 t.start()
636
637 for t in threads:
638 t.join()
639 appCheck2 = appCheck2 and t.result
640 if appCheck2 != main.TRUE:
Jon Halla440e872016-03-31 15:15:50 -0700641 node = main.activeNodes[0]
642 main.log.warn( main.CLIs[node].apps() )
643 main.log.warn( main.CLIs[node].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700644 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
645 onpass="App Ids seem to be correct",
646 onfail="Something is wrong with app Ids" )
647
648 main.step( "Add host intents via cli" )
649 intentIds = []
Jon Hall6e709752016-02-01 13:38:46 -0800650 # TODO: move the host numbers to params
651 # Maybe look at all the paths we ping?
Jon Hall5cf14d52015-07-16 12:15:19 -0700652 intentAddResult = True
653 hostResult = main.TRUE
654 for i in range( 8, 18 ):
655 main.log.info( "Adding host intent between h" + str( i ) +
656 " and h" + str( i + 10 ) )
657 host1 = "00:00:00:00:00:" + \
658 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
659 host2 = "00:00:00:00:00:" + \
660 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
661 # NOTE: getHost can return None
Jon Halla440e872016-03-31 15:15:50 -0700662 host1Dict = onosCli.getHost( host1 )
663 host2Dict = onosCli.getHost( host2 )
Jon Hall5cf14d52015-07-16 12:15:19 -0700664 host1Id = None
665 host2Id = None
666 if host1Dict and host2Dict:
667 host1Id = host1Dict.get( 'id', None )
668 host2Id = host2Dict.get( 'id', None )
669 if host1Id and host2Id:
Jon Halla440e872016-03-31 15:15:50 -0700670 nodeNum = ( i % len( main.activeNodes ) )
671 node = main.activeNodes[nodeNum]
672 tmpId = main.CLIs[node].addHostIntent( host1Id, host2Id )
Jon Hall5cf14d52015-07-16 12:15:19 -0700673 if tmpId:
674 main.log.info( "Added intent with id: " + tmpId )
675 intentIds.append( tmpId )
676 else:
677 main.log.error( "addHostIntent returned: " +
678 repr( tmpId ) )
679 else:
680 main.log.error( "Error, getHost() failed for h" + str( i ) +
681 " and/or h" + str( i + 10 ) )
Jon Halla440e872016-03-31 15:15:50 -0700682 node = main.activeNodes[0]
683 hosts = main.CLIs[node].hosts()
Jon Hall5cf14d52015-07-16 12:15:19 -0700684 main.log.warn( "Hosts output: " )
685 try:
686 main.log.warn( json.dumps( json.loads( hosts ),
687 sort_keys=True,
688 indent=4,
689 separators=( ',', ': ' ) ) )
690 except ( ValueError, TypeError ):
691 main.log.warn( repr( hosts ) )
692 hostResult = main.FALSE
693 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
694 onpass="Found a host id for each host",
695 onfail="Error looking up host ids" )
696
697 intentStart = time.time()
Jon Halla440e872016-03-31 15:15:50 -0700698 onosIds = onosCli.getAllIntentsId()
Jon Hall5cf14d52015-07-16 12:15:19 -0700699 main.log.info( "Submitted intents: " + str( intentIds ) )
700 main.log.info( "Intents in ONOS: " + str( onosIds ) )
701 for intent in intentIds:
702 if intent in onosIds:
703 pass # intent submitted is in onos
704 else:
705 intentAddResult = False
706 if intentAddResult:
707 intentStop = time.time()
708 else:
709 intentStop = None
710 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -0700711 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700712 intentStates = []
713 installedCheck = True
714 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
715 count = 0
716 try:
717 for intent in json.loads( intents ):
718 state = intent.get( 'state', None )
719 if "INSTALLED" not in state:
720 installedCheck = False
721 intentId = intent.get( 'id', None )
722 intentStates.append( ( intentId, state ) )
723 except ( ValueError, TypeError ):
724 main.log.exception( "Error parsing intents" )
725 # add submitted intents not in the store
726 tmplist = [ i for i, s in intentStates ]
727 missingIntents = False
728 for i in intentIds:
729 if i not in tmplist:
730 intentStates.append( ( i, " - " ) )
731 missingIntents = True
732 intentStates.sort()
733 for i, s in intentStates:
734 count += 1
735 main.log.info( "%-6s%-15s%-15s" %
736 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -0700737 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -0700738 try:
739 missing = False
740 if leaders:
741 parsedLeaders = json.loads( leaders )
742 main.log.warn( json.dumps( parsedLeaders,
743 sort_keys=True,
744 indent=4,
745 separators=( ',', ': ' ) ) )
746 # check for all intent partitions
747 topics = []
748 for i in range( 14 ):
749 topics.append( "intent-partition-" + str( i ) )
750 main.log.debug( topics )
751 ONOStopics = [ j['topic'] for j in parsedLeaders ]
752 for topic in topics:
753 if topic not in ONOStopics:
754 main.log.error( "Error: " + topic +
755 " not in leaders" )
756 missing = True
757 else:
758 main.log.error( "leaders() returned None" )
759 except ( ValueError, TypeError ):
760 main.log.exception( "Error parsing leaders" )
761 main.log.error( repr( leaders ) )
762 # Check all nodes
763 if missing:
Jon Halla440e872016-03-31 15:15:50 -0700764 for i in main.activeNodes:
765 response = main.CLIs[i].leaders( jsonFormat=False)
766 main.log.warn( str( main.CLIs[i].name ) + " leaders output: \n" +
Jon Hall5cf14d52015-07-16 12:15:19 -0700767 str( response ) )
768
Jon Halla440e872016-03-31 15:15:50 -0700769 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -0700770 try:
771 if partitions :
772 parsedPartitions = json.loads( partitions )
773 main.log.warn( json.dumps( parsedPartitions,
774 sort_keys=True,
775 indent=4,
776 separators=( ',', ': ' ) ) )
777 # TODO check for a leader in all paritions
778 # TODO check for consistency among nodes
779 else:
780 main.log.error( "partitions() returned None" )
781 except ( ValueError, TypeError ):
782 main.log.exception( "Error parsing partitions" )
783 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -0700784 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -0700785 try:
786 if pendingMap :
787 parsedPending = json.loads( pendingMap )
788 main.log.warn( json.dumps( parsedPending,
789 sort_keys=True,
790 indent=4,
791 separators=( ',', ': ' ) ) )
792 # TODO check something here?
793 else:
794 main.log.error( "pendingMap() returned None" )
795 except ( ValueError, TypeError ):
796 main.log.exception( "Error parsing pending map" )
797 main.log.error( repr( pendingMap ) )
798
799 intentAddResult = bool( intentAddResult and not missingIntents and
800 installedCheck )
801 if not intentAddResult:
802 main.log.error( "Error in pushing host intents to ONOS" )
803
804 main.step( "Intent Anti-Entropy dispersion" )
Jon Halla440e872016-03-31 15:15:50 -0700805 for j in range(100):
Jon Hall5cf14d52015-07-16 12:15:19 -0700806 correct = True
807 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Halla440e872016-03-31 15:15:50 -0700808 for i in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700809 onosIds = []
Jon Halla440e872016-03-31 15:15:50 -0700810 ids = main.CLIs[i].getAllIntentsId()
Jon Hall5cf14d52015-07-16 12:15:19 -0700811 onosIds.append( ids )
Jon Halla440e872016-03-31 15:15:50 -0700812 main.log.debug( "Intents in " + main.CLIs[i].name + ": " +
Jon Hall5cf14d52015-07-16 12:15:19 -0700813 str( sorted( onosIds ) ) )
814 if sorted( ids ) != sorted( intentIds ):
815 main.log.warn( "Set of intent IDs doesn't match" )
816 correct = False
817 break
818 else:
Jon Halla440e872016-03-31 15:15:50 -0700819 intents = json.loads( main.CLIs[i].intents() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700820 for intent in intents:
821 if intent[ 'state' ] != "INSTALLED":
822 main.log.warn( "Intent " + intent[ 'id' ] +
823 " is " + intent[ 'state' ] )
824 correct = False
825 break
826 if correct:
827 break
828 else:
829 time.sleep(1)
830 if not intentStop:
831 intentStop = time.time()
832 global gossipTime
833 gossipTime = intentStop - intentStart
834 main.log.info( "It took about " + str( gossipTime ) +
835 " seconds for all intents to appear in each node" )
836 append = False
837 title = "Gossip Intents"
838 count = 1
839 while append is False:
840 curTitle = title + str( count )
841 if curTitle not in labels:
842 labels.append( curTitle )
843 data.append( str( gossipTime ) )
844 append = True
845 else:
846 count += 1
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700847 gossipPeriod = int( main.params['timers']['gossip'] )
Jon Halla440e872016-03-31 15:15:50 -0700848 maxGossipTime = gossipPeriod * len( main.activeNodes )
Jon Hall5cf14d52015-07-16 12:15:19 -0700849 utilities.assert_greater_equals(
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700850 expect=maxGossipTime, actual=gossipTime,
Jon Hall5cf14d52015-07-16 12:15:19 -0700851 onpass="ECM anti-entropy for intents worked within " +
852 "expected time",
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700853 onfail="Intent ECM anti-entropy took too long. " +
854 "Expected time:{}, Actual time:{}".format( maxGossipTime,
855 gossipTime ) )
856 if gossipTime <= maxGossipTime:
Jon Hall5cf14d52015-07-16 12:15:19 -0700857 intentAddResult = True
858
859 if not intentAddResult or "key" in pendingMap:
860 import time
861 installedCheck = True
862 main.log.info( "Sleeping 60 seconds to see if intents are found" )
863 time.sleep( 60 )
Jon Halla440e872016-03-31 15:15:50 -0700864 onosIds = onosCli.getAllIntentsId()
Jon Hall5cf14d52015-07-16 12:15:19 -0700865 main.log.info( "Submitted intents: " + str( intentIds ) )
866 main.log.info( "Intents in ONOS: " + str( onosIds ) )
867 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -0700868 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700869 intentStates = []
870 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
871 count = 0
872 try:
873 for intent in json.loads( intents ):
874 # Iter through intents of a node
875 state = intent.get( 'state', None )
876 if "INSTALLED" not in state:
877 installedCheck = False
878 intentId = intent.get( 'id', None )
879 intentStates.append( ( intentId, state ) )
880 except ( ValueError, TypeError ):
881 main.log.exception( "Error parsing intents" )
882 # add submitted intents not in the store
883 tmplist = [ i for i, s in intentStates ]
884 for i in intentIds:
885 if i not in tmplist:
886 intentStates.append( ( i, " - " ) )
887 intentStates.sort()
888 for i, s in intentStates:
889 count += 1
890 main.log.info( "%-6s%-15s%-15s" %
891 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -0700892 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -0700893 try:
894 missing = False
895 if leaders:
896 parsedLeaders = json.loads( leaders )
897 main.log.warn( json.dumps( parsedLeaders,
898 sort_keys=True,
899 indent=4,
900 separators=( ',', ': ' ) ) )
901 # check for all intent partitions
902 # check for election
903 topics = []
904 for i in range( 14 ):
905 topics.append( "intent-partition-" + str( i ) )
906 # FIXME: this should only be after we start the app
907 topics.append( "org.onosproject.election" )
908 main.log.debug( topics )
909 ONOStopics = [ j['topic'] for j in parsedLeaders ]
910 for topic in topics:
911 if topic not in ONOStopics:
912 main.log.error( "Error: " + topic +
913 " not in leaders" )
914 missing = True
915 else:
916 main.log.error( "leaders() returned None" )
917 except ( ValueError, TypeError ):
918 main.log.exception( "Error parsing leaders" )
919 main.log.error( repr( leaders ) )
920 # Check all nodes
921 if missing:
Jon Halla440e872016-03-31 15:15:50 -0700922 for i in main.activeNodes:
923 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -0700924 response = node.leaders( jsonFormat=False)
925 main.log.warn( str( node.name ) + " leaders output: \n" +
926 str( response ) )
927
Jon Halla440e872016-03-31 15:15:50 -0700928 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -0700929 try:
930 if partitions :
931 parsedPartitions = json.loads( partitions )
932 main.log.warn( json.dumps( parsedPartitions,
933 sort_keys=True,
934 indent=4,
935 separators=( ',', ': ' ) ) )
936 # TODO check for a leader in all paritions
937 # TODO check for consistency among nodes
938 else:
939 main.log.error( "partitions() returned None" )
940 except ( ValueError, TypeError ):
941 main.log.exception( "Error parsing partitions" )
942 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -0700943 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -0700944 try:
945 if pendingMap :
946 parsedPending = json.loads( pendingMap )
947 main.log.warn( json.dumps( parsedPending,
948 sort_keys=True,
949 indent=4,
950 separators=( ',', ': ' ) ) )
951 # TODO check something here?
952 else:
953 main.log.error( "pendingMap() returned None" )
954 except ( ValueError, TypeError ):
955 main.log.exception( "Error parsing pending map" )
956 main.log.error( repr( pendingMap ) )
957
958 def CASE4( self, main ):
959 """
960 Ping across added host intents
961 """
962 import json
963 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700964 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700965 assert main, "main not defined"
966 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700967 assert main.CLIs, "main.CLIs not defined"
968 assert main.nodes, "main.nodes not defined"
Jon Hall6e709752016-02-01 13:38:46 -0800969 main.case( "Verify connectivity by sending traffic across Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700970 main.caseExplanation = "Ping across added host intents to check " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700971 "functionality and check the state of " +\
972 "the intent"
973 main.step( "Ping across added host intents" )
Jon Halla440e872016-03-31 15:15:50 -0700974 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -0700975 PingResult = main.TRUE
976 for i in range( 8, 18 ):
977 ping = main.Mininet1.pingHost( src="h" + str( i ),
978 target="h" + str( i + 10 ) )
979 PingResult = PingResult and ping
980 if ping == main.FALSE:
981 main.log.warn( "Ping failed between h" + str( i ) +
982 " and h" + str( i + 10 ) )
983 elif ping == main.TRUE:
984 main.log.info( "Ping test passed!" )
985 # Don't set PingResult or you'd override failures
986 if PingResult == main.FALSE:
987 main.log.error(
988 "Intents have not been installed correctly, pings failed." )
989 # TODO: pretty print
990 main.log.warn( "ONOS1 intents: " )
991 try:
Jon Halla440e872016-03-31 15:15:50 -0700992 tmpIntents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700993 main.log.warn( json.dumps( json.loads( tmpIntents ),
994 sort_keys=True,
995 indent=4,
996 separators=( ',', ': ' ) ) )
997 except ( ValueError, TypeError ):
998 main.log.warn( repr( tmpIntents ) )
999 utilities.assert_equals(
1000 expect=main.TRUE,
1001 actual=PingResult,
1002 onpass="Intents have been installed correctly and pings work",
1003 onfail="Intents have not been installed correctly, pings failed." )
1004
1005 main.step( "Check Intent state" )
1006 installedCheck = False
1007 loopCount = 0
1008 while not installedCheck and loopCount < 40:
1009 installedCheck = True
1010 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -07001011 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -07001012 intentStates = []
1013 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
Jon Halle1a3b752015-07-22 13:02:46 -07001014 count = 0
Jon Hall5cf14d52015-07-16 12:15:19 -07001015 # Iter through intents of a node
1016 try:
1017 for intent in json.loads( intents ):
1018 state = intent.get( 'state', None )
1019 if "INSTALLED" not in state:
1020 installedCheck = False
1021 intentId = intent.get( 'id', None )
1022 intentStates.append( ( intentId, state ) )
1023 except ( ValueError, TypeError ):
1024 main.log.exception( "Error parsing intents." )
1025 # Print states
1026 intentStates.sort()
1027 for i, s in intentStates:
1028 count += 1
1029 main.log.info( "%-6s%-15s%-15s" %
1030 ( str( count ), str( i ), str( s ) ) )
1031 if not installedCheck:
1032 time.sleep( 1 )
1033 loopCount += 1
1034 utilities.assert_equals( expect=True, actual=installedCheck,
1035 onpass="Intents are all INSTALLED",
1036 onfail="Intents are not all in " +
1037 "INSTALLED state" )
1038
1039 main.step( "Check leadership of topics" )
Jon Halla440e872016-03-31 15:15:50 -07001040 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -07001041 topicCheck = main.TRUE
1042 try:
1043 if leaders:
1044 parsedLeaders = json.loads( leaders )
1045 main.log.warn( json.dumps( parsedLeaders,
1046 sort_keys=True,
1047 indent=4,
1048 separators=( ',', ': ' ) ) )
1049 # check for all intent partitions
1050 # check for election
1051 # TODO: Look at Devices as topics now that it uses this system
1052 topics = []
1053 for i in range( 14 ):
1054 topics.append( "intent-partition-" + str( i ) )
1055 # FIXME: this should only be after we start the app
1056 # FIXME: topics.append( "org.onosproject.election" )
1057 # Print leaders output
1058 main.log.debug( topics )
1059 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1060 for topic in topics:
1061 if topic not in ONOStopics:
1062 main.log.error( "Error: " + topic +
1063 " not in leaders" )
1064 topicCheck = main.FALSE
1065 else:
1066 main.log.error( "leaders() returned None" )
1067 topicCheck = main.FALSE
1068 except ( ValueError, TypeError ):
1069 topicCheck = main.FALSE
1070 main.log.exception( "Error parsing leaders" )
1071 main.log.error( repr( leaders ) )
1072 # TODO: Check for a leader of these topics
1073 # Check all nodes
1074 if topicCheck:
Jon Halla440e872016-03-31 15:15:50 -07001075 for i in main.activeNodes:
1076 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07001077 response = node.leaders( jsonFormat=False)
1078 main.log.warn( str( node.name ) + " leaders output: \n" +
1079 str( response ) )
1080
1081 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
1082 onpass="intent Partitions is in leaders",
1083 onfail="Some topics were lost " )
1084 # Print partitions
Jon Halla440e872016-03-31 15:15:50 -07001085 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -07001086 try:
1087 if partitions :
1088 parsedPartitions = json.loads( partitions )
1089 main.log.warn( json.dumps( parsedPartitions,
1090 sort_keys=True,
1091 indent=4,
1092 separators=( ',', ': ' ) ) )
1093 # TODO check for a leader in all paritions
1094 # TODO check for consistency among nodes
1095 else:
1096 main.log.error( "partitions() returned None" )
1097 except ( ValueError, TypeError ):
1098 main.log.exception( "Error parsing partitions" )
1099 main.log.error( repr( partitions ) )
1100 # Print Pending Map
Jon Halla440e872016-03-31 15:15:50 -07001101 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -07001102 try:
1103 if pendingMap :
1104 parsedPending = json.loads( pendingMap )
1105 main.log.warn( json.dumps( parsedPending,
1106 sort_keys=True,
1107 indent=4,
1108 separators=( ',', ': ' ) ) )
1109 # TODO check something here?
1110 else:
1111 main.log.error( "pendingMap() returned None" )
1112 except ( ValueError, TypeError ):
1113 main.log.exception( "Error parsing pending map" )
1114 main.log.error( repr( pendingMap ) )
1115
1116 if not installedCheck:
1117 main.log.info( "Waiting 60 seconds to see if the state of " +
1118 "intents change" )
1119 time.sleep( 60 )
1120 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -07001121 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -07001122 intentStates = []
1123 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
1124 count = 0
1125 # Iter through intents of a node
1126 try:
1127 for intent in json.loads( intents ):
1128 state = intent.get( 'state', None )
1129 if "INSTALLED" not in state:
1130 installedCheck = False
1131 intentId = intent.get( 'id', None )
1132 intentStates.append( ( intentId, state ) )
1133 except ( ValueError, TypeError ):
1134 main.log.exception( "Error parsing intents." )
1135 intentStates.sort()
1136 for i, s in intentStates:
1137 count += 1
1138 main.log.info( "%-6s%-15s%-15s" %
1139 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -07001140 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -07001141 try:
1142 missing = False
1143 if leaders:
1144 parsedLeaders = json.loads( leaders )
1145 main.log.warn( json.dumps( parsedLeaders,
1146 sort_keys=True,
1147 indent=4,
1148 separators=( ',', ': ' ) ) )
1149 # check for all intent partitions
1150 # check for election
1151 topics = []
1152 for i in range( 14 ):
1153 topics.append( "intent-partition-" + str( i ) )
1154 # FIXME: this should only be after we start the app
1155 topics.append( "org.onosproject.election" )
1156 main.log.debug( topics )
1157 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1158 for topic in topics:
1159 if topic not in ONOStopics:
1160 main.log.error( "Error: " + topic +
1161 " not in leaders" )
1162 missing = True
1163 else:
1164 main.log.error( "leaders() returned None" )
1165 except ( ValueError, TypeError ):
1166 main.log.exception( "Error parsing leaders" )
1167 main.log.error( repr( leaders ) )
1168 if missing:
Jon Halla440e872016-03-31 15:15:50 -07001169 for i in main.activeNodes:
1170 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07001171 response = node.leaders( jsonFormat=False)
1172 main.log.warn( str( node.name ) + " leaders output: \n" +
1173 str( response ) )
1174
Jon Halla440e872016-03-31 15:15:50 -07001175 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -07001176 try:
1177 if partitions :
1178 parsedPartitions = json.loads( partitions )
1179 main.log.warn( json.dumps( parsedPartitions,
1180 sort_keys=True,
1181 indent=4,
1182 separators=( ',', ': ' ) ) )
1183 # TODO check for a leader in all paritions
1184 # TODO check for consistency among nodes
1185 else:
1186 main.log.error( "partitions() returned None" )
1187 except ( ValueError, TypeError ):
1188 main.log.exception( "Error parsing partitions" )
1189 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -07001190 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -07001191 try:
1192 if pendingMap :
1193 parsedPending = json.loads( pendingMap )
1194 main.log.warn( json.dumps( parsedPending,
1195 sort_keys=True,
1196 indent=4,
1197 separators=( ',', ': ' ) ) )
1198 # TODO check something here?
1199 else:
1200 main.log.error( "pendingMap() returned None" )
1201 except ( ValueError, TypeError ):
1202 main.log.exception( "Error parsing pending map" )
1203 main.log.error( repr( pendingMap ) )
1204 # Print flowrules
Jon Halla440e872016-03-31 15:15:50 -07001205 node = main.activeNodes[0]
1206 main.log.debug( main.CLIs[node].flows( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001207 main.step( "Wait a minute then ping again" )
1208 # the wait is above
1209 PingResult = main.TRUE
1210 for i in range( 8, 18 ):
1211 ping = main.Mininet1.pingHost( src="h" + str( i ),
1212 target="h" + str( i + 10 ) )
1213 PingResult = PingResult and ping
1214 if ping == main.FALSE:
1215 main.log.warn( "Ping failed between h" + str( i ) +
1216 " and h" + str( i + 10 ) )
1217 elif ping == main.TRUE:
1218 main.log.info( "Ping test passed!" )
1219 # Don't set PingResult or you'd override failures
1220 if PingResult == main.FALSE:
1221 main.log.error(
1222 "Intents have not been installed correctly, pings failed." )
1223 # TODO: pretty print
1224 main.log.warn( "ONOS1 intents: " )
1225 try:
Jon Halla440e872016-03-31 15:15:50 -07001226 tmpIntents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -07001227 main.log.warn( json.dumps( json.loads( tmpIntents ),
1228 sort_keys=True,
1229 indent=4,
1230 separators=( ',', ': ' ) ) )
1231 except ( ValueError, TypeError ):
1232 main.log.warn( repr( tmpIntents ) )
1233 utilities.assert_equals(
1234 expect=main.TRUE,
1235 actual=PingResult,
1236 onpass="Intents have been installed correctly and pings work",
1237 onfail="Intents have not been installed correctly, pings failed." )
1238
1239 def CASE5( self, main ):
1240 """
1241 Reading state of ONOS
1242 """
1243 import json
1244 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001245 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001246 assert main, "main not defined"
1247 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001248 assert main.CLIs, "main.CLIs not defined"
1249 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001250
1251 main.case( "Setting up and gathering data for current state" )
1252 # The general idea for this test case is to pull the state of
1253 # ( intents,flows, topology,... ) from each ONOS node
1254 # We can then compare them with each other and also with past states
1255
1256 main.step( "Check that each switch has a master" )
1257 global mastershipState
1258 mastershipState = '[]'
1259
1260 # Assert that each device has a master
1261 rolesNotNull = main.TRUE
1262 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001263 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001264 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001265 name="rolesNotNull-" + str( i ),
1266 args=[] )
1267 threads.append( t )
1268 t.start()
1269
1270 for t in threads:
1271 t.join()
1272 rolesNotNull = rolesNotNull and t.result
1273 utilities.assert_equals(
1274 expect=main.TRUE,
1275 actual=rolesNotNull,
1276 onpass="Each device has a master",
1277 onfail="Some devices don't have a master assigned" )
1278
1279 main.step( "Get the Mastership of each switch from each controller" )
1280 ONOSMastership = []
1281 mastershipCheck = main.FALSE
1282 consistentMastership = True
1283 rolesResults = True
1284 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001285 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001286 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001287 name="roles-" + str( i ),
1288 args=[] )
1289 threads.append( t )
1290 t.start()
1291
1292 for t in threads:
1293 t.join()
1294 ONOSMastership.append( t.result )
1295
Jon Halla440e872016-03-31 15:15:50 -07001296 for i in range( len( ONOSMastership ) ):
1297 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001298 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Halla440e872016-03-31 15:15:50 -07001299 main.log.error( "Error in getting ONOS" + node + " roles" )
1300 main.log.warn( "ONOS" + node + " mastership response: " +
1301 repr( ONOSMastership[i] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001302 rolesResults = False
1303 utilities.assert_equals(
1304 expect=True,
1305 actual=rolesResults,
1306 onpass="No error in reading roles output",
1307 onfail="Error in reading roles from ONOS" )
1308
1309 main.step( "Check for consistency in roles from each controller" )
1310 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1311 main.log.info(
1312 "Switch roles are consistent across all ONOS nodes" )
1313 else:
1314 consistentMastership = False
1315 utilities.assert_equals(
1316 expect=True,
1317 actual=consistentMastership,
1318 onpass="Switch roles are consistent across all ONOS nodes",
1319 onfail="ONOS nodes have different views of switch roles" )
1320
1321 if rolesResults and not consistentMastership:
Jon Halla440e872016-03-31 15:15:50 -07001322 for i in range( len( main.activeNodes ) ):
1323 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001324 try:
1325 main.log.warn(
Jon Halla440e872016-03-31 15:15:50 -07001326 "ONOS" + node + " roles: ",
Jon Hall5cf14d52015-07-16 12:15:19 -07001327 json.dumps(
1328 json.loads( ONOSMastership[ i ] ),
1329 sort_keys=True,
1330 indent=4,
1331 separators=( ',', ': ' ) ) )
1332 except ( ValueError, TypeError ):
1333 main.log.warn( repr( ONOSMastership[ i ] ) )
1334 elif rolesResults and consistentMastership:
1335 mastershipCheck = main.TRUE
1336 mastershipState = ONOSMastership[ 0 ]
1337
1338 main.step( "Get the intents from each controller" )
1339 global intentState
1340 intentState = []
1341 ONOSIntents = []
1342 intentCheck = main.FALSE
1343 consistentIntents = True
1344 intentsResults = True
1345 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001346 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001347 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001348 name="intents-" + str( i ),
1349 args=[],
1350 kwargs={ 'jsonFormat': True } )
1351 threads.append( t )
1352 t.start()
1353
1354 for t in threads:
1355 t.join()
1356 ONOSIntents.append( t.result )
1357
Jon Halla440e872016-03-31 15:15:50 -07001358 for i in range( len( ONOSIntents ) ):
1359 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001360 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall6e709752016-02-01 13:38:46 -08001361 main.log.error( "Error in getting ONOS" + node + " intents" )
1362 main.log.warn( "ONOS" + node + " intents response: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07001363 repr( ONOSIntents[ i ] ) )
1364 intentsResults = False
1365 utilities.assert_equals(
1366 expect=True,
1367 actual=intentsResults,
1368 onpass="No error in reading intents output",
1369 onfail="Error in reading intents from ONOS" )
1370
1371 main.step( "Check for consistency in Intents from each controller" )
1372 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1373 main.log.info( "Intents are consistent across all ONOS " +
1374 "nodes" )
1375 else:
1376 consistentIntents = False
1377 main.log.error( "Intents not consistent" )
1378 utilities.assert_equals(
1379 expect=True,
1380 actual=consistentIntents,
1381 onpass="Intents are consistent across all ONOS nodes",
1382 onfail="ONOS nodes have different views of intents" )
1383
1384 if intentsResults:
1385 # Try to make it easy to figure out what is happening
1386 #
1387 # Intent ONOS1 ONOS2 ...
1388 # 0x01 INSTALLED INSTALLING
1389 # ... ... ...
1390 # ... ... ...
1391 title = " Id"
Jon Halla440e872016-03-31 15:15:50 -07001392 for n in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001393 title += " " * 10 + "ONOS" + str( n + 1 )
1394 main.log.warn( title )
1395 # get all intent keys in the cluster
1396 keys = []
Jon Halla440e872016-03-31 15:15:50 -07001397 try:
1398 # Get the set of all intent keys
Jon Hall5cf14d52015-07-16 12:15:19 -07001399 for nodeStr in ONOSIntents:
1400 node = json.loads( nodeStr )
1401 for intent in node:
Jon Halla440e872016-03-31 15:15:50 -07001402 keys.append( intent.get( 'id' ) )
1403 keys = set( keys )
1404 # For each intent key, print the state on each node
1405 for key in keys:
1406 row = "%-13s" % key
1407 for nodeStr in ONOSIntents:
1408 node = json.loads( nodeStr )
1409 for intent in node:
1410 if intent.get( 'id', "Error" ) == key:
1411 row += "%-15s" % intent.get( 'state' )
1412 main.log.warn( row )
1413 # End of intent state table
1414 except ValueError as e:
1415 main.log.exception( e )
1416 main.log.debug( "nodeStr was: " + repr( nodeStr ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001417
1418 if intentsResults and not consistentIntents:
1419 # print the json objects
Jon Halla440e872016-03-31 15:15:50 -07001420 n = str( main.activeNodes[-1] + 1 )
1421 main.log.debug( "ONOS" + n + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07001422 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1423 sort_keys=True,
1424 indent=4,
1425 separators=( ',', ': ' ) ) )
Jon Halla440e872016-03-31 15:15:50 -07001426 for i in range( len( ONOSIntents ) ):
1427 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001428 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
Jon Halla440e872016-03-31 15:15:50 -07001429 main.log.debug( "ONOS" + node + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07001430 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1431 sort_keys=True,
1432 indent=4,
1433 separators=( ',', ': ' ) ) )
1434 else:
Jon Halla440e872016-03-31 15:15:50 -07001435 main.log.debug( "ONOS" + node + " intents match ONOS" +
1436 n + " intents" )
Jon Hall5cf14d52015-07-16 12:15:19 -07001437 elif intentsResults and consistentIntents:
1438 intentCheck = main.TRUE
1439 intentState = ONOSIntents[ 0 ]
1440
1441 main.step( "Get the flows from each controller" )
1442 global flowState
1443 flowState = []
1444 ONOSFlows = []
1445 ONOSFlowsJson = []
1446 flowCheck = main.FALSE
1447 consistentFlows = True
1448 flowsResults = True
1449 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001450 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001451 t = main.Thread( target=main.CLIs[i].flows,
Jon Hall5cf14d52015-07-16 12:15:19 -07001452 name="flows-" + str( i ),
1453 args=[],
1454 kwargs={ 'jsonFormat': True } )
1455 threads.append( t )
1456 t.start()
1457
1458 # NOTE: Flows command can take some time to run
1459 time.sleep(30)
1460 for t in threads:
1461 t.join()
1462 result = t.result
1463 ONOSFlows.append( result )
1464
Jon Halla440e872016-03-31 15:15:50 -07001465 for i in range( len( ONOSFlows ) ):
1466 num = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001467 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1468 main.log.error( "Error in getting ONOS" + num + " flows" )
1469 main.log.warn( "ONOS" + num + " flows response: " +
1470 repr( ONOSFlows[ i ] ) )
1471 flowsResults = False
1472 ONOSFlowsJson.append( None )
1473 else:
1474 try:
1475 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1476 except ( ValueError, TypeError ):
1477 # FIXME: change this to log.error?
1478 main.log.exception( "Error in parsing ONOS" + num +
1479 " response as json." )
1480 main.log.error( repr( ONOSFlows[ i ] ) )
1481 ONOSFlowsJson.append( None )
1482 flowsResults = False
1483 utilities.assert_equals(
1484 expect=True,
1485 actual=flowsResults,
1486 onpass="No error in reading flows output",
1487 onfail="Error in reading flows from ONOS" )
1488
1489 main.step( "Check for consistency in Flows from each controller" )
1490 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1491 if all( tmp ):
1492 main.log.info( "Flow count is consistent across all ONOS nodes" )
1493 else:
1494 consistentFlows = False
1495 utilities.assert_equals(
1496 expect=True,
1497 actual=consistentFlows,
1498 onpass="The flow count is consistent across all ONOS nodes",
1499 onfail="ONOS nodes have different flow counts" )
1500
1501 if flowsResults and not consistentFlows:
Jon Halla440e872016-03-31 15:15:50 -07001502 for i in range( len( ONOSFlows ) ):
1503 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001504 try:
1505 main.log.warn(
Jon Halla440e872016-03-31 15:15:50 -07001506 "ONOS" + node + " flows: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07001507 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1508 indent=4, separators=( ',', ': ' ) ) )
1509 except ( ValueError, TypeError ):
Jon Halla440e872016-03-31 15:15:50 -07001510 main.log.warn( "ONOS" + node + " flows: " +
1511 repr( ONOSFlows[ i ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001512 elif flowsResults and consistentFlows:
1513 flowCheck = main.TRUE
1514 flowState = ONOSFlows[ 0 ]
1515
1516 main.step( "Get the OF Table entries" )
1517 global flows
1518 flows = []
1519 for i in range( 1, 29 ):
Jon Halla440e872016-03-31 15:15:50 -07001520 flows.append( main.Mininet1.getFlowTable( "s" + str( i ), version="1.3", debug=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001521 if flowCheck == main.FALSE:
1522 for table in flows:
1523 main.log.warn( table )
1524 # TODO: Compare switch flow tables with ONOS flow tables
1525
1526 main.step( "Start continuous pings" )
1527 main.Mininet2.pingLong(
1528 src=main.params[ 'PING' ][ 'source1' ],
1529 target=main.params[ 'PING' ][ 'target1' ],
1530 pingTime=500 )
1531 main.Mininet2.pingLong(
1532 src=main.params[ 'PING' ][ 'source2' ],
1533 target=main.params[ 'PING' ][ 'target2' ],
1534 pingTime=500 )
1535 main.Mininet2.pingLong(
1536 src=main.params[ 'PING' ][ 'source3' ],
1537 target=main.params[ 'PING' ][ 'target3' ],
1538 pingTime=500 )
1539 main.Mininet2.pingLong(
1540 src=main.params[ 'PING' ][ 'source4' ],
1541 target=main.params[ 'PING' ][ 'target4' ],
1542 pingTime=500 )
1543 main.Mininet2.pingLong(
1544 src=main.params[ 'PING' ][ 'source5' ],
1545 target=main.params[ 'PING' ][ 'target5' ],
1546 pingTime=500 )
1547 main.Mininet2.pingLong(
1548 src=main.params[ 'PING' ][ 'source6' ],
1549 target=main.params[ 'PING' ][ 'target6' ],
1550 pingTime=500 )
1551 main.Mininet2.pingLong(
1552 src=main.params[ 'PING' ][ 'source7' ],
1553 target=main.params[ 'PING' ][ 'target7' ],
1554 pingTime=500 )
1555 main.Mininet2.pingLong(
1556 src=main.params[ 'PING' ][ 'source8' ],
1557 target=main.params[ 'PING' ][ 'target8' ],
1558 pingTime=500 )
1559 main.Mininet2.pingLong(
1560 src=main.params[ 'PING' ][ 'source9' ],
1561 target=main.params[ 'PING' ][ 'target9' ],
1562 pingTime=500 )
1563 main.Mininet2.pingLong(
1564 src=main.params[ 'PING' ][ 'source10' ],
1565 target=main.params[ 'PING' ][ 'target10' ],
1566 pingTime=500 )
1567
1568 main.step( "Collecting topology information from ONOS" )
1569 devices = []
1570 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001571 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001572 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07001573 name="devices-" + str( i ),
1574 args=[ ] )
1575 threads.append( t )
1576 t.start()
1577
1578 for t in threads:
1579 t.join()
1580 devices.append( t.result )
1581 hosts = []
1582 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001583 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001584 t = main.Thread( target=main.CLIs[i].hosts,
Jon Hall5cf14d52015-07-16 12:15:19 -07001585 name="hosts-" + str( i ),
1586 args=[ ] )
1587 threads.append( t )
1588 t.start()
1589
1590 for t in threads:
1591 t.join()
1592 try:
1593 hosts.append( json.loads( t.result ) )
1594 except ( ValueError, TypeError ):
1595 # FIXME: better handling of this, print which node
1596 # Maybe use thread name?
1597 main.log.exception( "Error parsing json output of hosts" )
Jon Hall3afe4c92015-12-14 19:30:38 -08001598 main.log.warn( repr( t.result ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001599 hosts.append( None )
1600
1601 ports = []
1602 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001603 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001604 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07001605 name="ports-" + str( i ),
1606 args=[ ] )
1607 threads.append( t )
1608 t.start()
1609
1610 for t in threads:
1611 t.join()
1612 ports.append( t.result )
1613 links = []
1614 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001615 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001616 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07001617 name="links-" + str( i ),
1618 args=[ ] )
1619 threads.append( t )
1620 t.start()
1621
1622 for t in threads:
1623 t.join()
1624 links.append( t.result )
1625 clusters = []
1626 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001627 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001628 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07001629 name="clusters-" + str( i ),
1630 args=[ ] )
1631 threads.append( t )
1632 t.start()
1633
1634 for t in threads:
1635 t.join()
1636 clusters.append( t.result )
1637 # Compare json objects for hosts and dataplane clusters
1638
1639 # hosts
1640 main.step( "Host view is consistent across ONOS nodes" )
1641 consistentHostsResult = main.TRUE
1642 for controller in range( len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07001643 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall3afe4c92015-12-14 19:30:38 -08001644 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001645 if hosts[ controller ] == hosts[ 0 ]:
1646 continue
1647 else: # hosts not consistent
1648 main.log.error( "hosts from ONOS" +
1649 controllerStr +
1650 " is inconsistent with ONOS1" )
1651 main.log.warn( repr( hosts[ controller ] ) )
1652 consistentHostsResult = main.FALSE
1653
1654 else:
1655 main.log.error( "Error in getting ONOS hosts from ONOS" +
1656 controllerStr )
1657 consistentHostsResult = main.FALSE
1658 main.log.warn( "ONOS" + controllerStr +
1659 " hosts response: " +
1660 repr( hosts[ controller ] ) )
1661 utilities.assert_equals(
1662 expect=main.TRUE,
1663 actual=consistentHostsResult,
1664 onpass="Hosts view is consistent across all ONOS nodes",
1665 onfail="ONOS nodes have different views of hosts" )
1666
1667 main.step( "Each host has an IP address" )
1668 ipResult = main.TRUE
1669 for controller in range( 0, len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07001670 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall3afe4c92015-12-14 19:30:38 -08001671 if hosts[ controller ]:
1672 for host in hosts[ controller ]:
1673 if not host.get( 'ipAddresses', [ ] ):
Jon Hallf3d16e72015-12-16 17:45:08 -08001674 main.log.error( "Error with host ips on controller" +
Jon Hall3afe4c92015-12-14 19:30:38 -08001675 controllerStr + ": " + str( host ) )
1676 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07001677 utilities.assert_equals(
1678 expect=main.TRUE,
1679 actual=ipResult,
1680 onpass="The ips of the hosts aren't empty",
1681 onfail="The ip of at least one host is missing" )
1682
1683 # Strongly connected clusters of devices
1684 main.step( "Cluster view is consistent across ONOS nodes" )
1685 consistentClustersResult = main.TRUE
1686 for controller in range( len( clusters ) ):
Jon Halla440e872016-03-31 15:15:50 -07001687 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001688 if "Error" not in clusters[ controller ]:
1689 if clusters[ controller ] == clusters[ 0 ]:
1690 continue
1691 else: # clusters not consistent
1692 main.log.error( "clusters from ONOS" + controllerStr +
1693 " is inconsistent with ONOS1" )
1694 consistentClustersResult = main.FALSE
1695
1696 else:
1697 main.log.error( "Error in getting dataplane clusters " +
1698 "from ONOS" + controllerStr )
1699 consistentClustersResult = main.FALSE
1700 main.log.warn( "ONOS" + controllerStr +
1701 " clusters response: " +
1702 repr( clusters[ controller ] ) )
1703 utilities.assert_equals(
1704 expect=main.TRUE,
1705 actual=consistentClustersResult,
1706 onpass="Clusters view is consistent across all ONOS nodes",
1707 onfail="ONOS nodes have different views of clusters" )
Jon Hall172b7ba2016-04-07 18:12:20 -07001708 if consistentClustersResult != main.TRUE:
1709 main.log.debug( clusters )
Jon Hall5cf14d52015-07-16 12:15:19 -07001710 # there should always only be one cluster
1711 main.step( "Cluster view correct across ONOS nodes" )
1712 try:
1713 numClusters = len( json.loads( clusters[ 0 ] ) )
1714 except ( ValueError, TypeError ):
1715 main.log.exception( "Error parsing clusters[0]: " +
1716 repr( clusters[ 0 ] ) )
Jon Hall6e709752016-02-01 13:38:46 -08001717 numClusters = "ERROR"
Jon Hall5cf14d52015-07-16 12:15:19 -07001718 clusterResults = main.FALSE
1719 if numClusters == 1:
1720 clusterResults = main.TRUE
1721 utilities.assert_equals(
1722 expect=1,
1723 actual=numClusters,
1724 onpass="ONOS shows 1 SCC",
1725 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1726
1727 main.step( "Comparing ONOS topology to MN" )
1728 devicesResults = main.TRUE
1729 linksResults = main.TRUE
1730 hostsResults = main.TRUE
1731 mnSwitches = main.Mininet1.getSwitches()
1732 mnLinks = main.Mininet1.getLinks()
1733 mnHosts = main.Mininet1.getHosts()
Jon Halla440e872016-03-31 15:15:50 -07001734 for controller in main.activeNodes:
1735 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001736 if devices[ controller ] and ports[ controller ] and\
1737 "Error" not in devices[ controller ] and\
1738 "Error" not in ports[ controller ]:
Jon Halle1a3b752015-07-22 13:02:46 -07001739 currentDevicesResult = main.Mininet1.compareSwitches(
1740 mnSwitches,
1741 json.loads( devices[ controller ] ),
1742 json.loads( ports[ controller ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001743 else:
1744 currentDevicesResult = main.FALSE
1745 utilities.assert_equals( expect=main.TRUE,
1746 actual=currentDevicesResult,
1747 onpass="ONOS" + controllerStr +
1748 " Switches view is correct",
1749 onfail="ONOS" + controllerStr +
1750 " Switches view is incorrect" )
1751 if links[ controller ] and "Error" not in links[ controller ]:
1752 currentLinksResult = main.Mininet1.compareLinks(
1753 mnSwitches, mnLinks,
1754 json.loads( links[ controller ] ) )
1755 else:
1756 currentLinksResult = main.FALSE
1757 utilities.assert_equals( expect=main.TRUE,
1758 actual=currentLinksResult,
1759 onpass="ONOS" + controllerStr +
1760 " links view is correct",
1761 onfail="ONOS" + controllerStr +
1762 " links view is incorrect" )
1763
Jon Hall657cdf62015-12-17 14:40:51 -08001764 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001765 currentHostsResult = main.Mininet1.compareHosts(
1766 mnHosts,
1767 hosts[ controller ] )
1768 else:
1769 currentHostsResult = main.FALSE
1770 utilities.assert_equals( expect=main.TRUE,
1771 actual=currentHostsResult,
1772 onpass="ONOS" + controllerStr +
1773 " hosts exist in Mininet",
1774 onfail="ONOS" + controllerStr +
1775 " hosts don't match Mininet" )
1776
1777 devicesResults = devicesResults and currentDevicesResult
1778 linksResults = linksResults and currentLinksResult
1779 hostsResults = hostsResults and currentHostsResult
1780
1781 main.step( "Device information is correct" )
1782 utilities.assert_equals(
1783 expect=main.TRUE,
1784 actual=devicesResults,
1785 onpass="Device information is correct",
1786 onfail="Device information is incorrect" )
1787
1788 main.step( "Links are correct" )
1789 utilities.assert_equals(
1790 expect=main.TRUE,
1791 actual=linksResults,
1792 onpass="Link are correct",
1793 onfail="Links are incorrect" )
1794
1795 main.step( "Hosts are correct" )
1796 utilities.assert_equals(
1797 expect=main.TRUE,
1798 actual=hostsResults,
1799 onpass="Hosts are correct",
1800 onfail="Hosts are incorrect" )
1801
1802 def CASE6( self, main ):
1803 """
1804 The Failure case.
1805 """
1806 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001807 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001808 assert main, "main not defined"
1809 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001810 assert main.CLIs, "main.CLIs not defined"
1811 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001812 try:
1813 labels
1814 except NameError:
1815 main.log.error( "labels not defined, setting to []" )
1816 global labels
1817 labels = []
1818 try:
1819 data
1820 except NameError:
1821 main.log.error( "data not defined, setting to []" )
1822 global data
1823 data = []
1824 # Reset non-persistent variables
1825 try:
1826 iCounterValue = 0
1827 except NameError:
1828 main.log.error( "iCounterValue not defined, setting to 0" )
1829 iCounterValue = 0
1830
1831 main.case( "Restart entire ONOS cluster" )
1832
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001833 main.step( "Checking ONOS Logs for errors" )
1834 for node in main.nodes:
1835 main.log.debug( "Checking logs for errors on " + node.name + ":" )
1836 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
1837
Jon Hall5cf14d52015-07-16 12:15:19 -07001838 main.step( "Killing ONOS nodes" )
1839 killResults = main.TRUE
1840 killTime = time.time()
Jon Halle1a3b752015-07-22 13:02:46 -07001841 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001842 killed = main.ONOSbench.onosKill( node.ip_address )
1843 killResults = killResults and killed
1844 utilities.assert_equals( expect=main.TRUE, actual=killResults,
1845 onpass="ONOS nodes killed",
1846 onfail="ONOS kill unsuccessful" )
1847
1848 main.step( "Checking if ONOS is up yet" )
1849 for i in range( 2 ):
1850 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001851 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001852 started = main.ONOSbench.isup( node.ip_address )
1853 if not started:
1854 main.log.error( node.name + " didn't start!" )
1855 onosIsupResult = onosIsupResult and started
1856 if onosIsupResult == main.TRUE:
1857 break
1858 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1859 onpass="ONOS restarted",
1860 onfail="ONOS restart NOT successful" )
1861
1862 main.log.step( "Starting ONOS CLI sessions" )
1863 cliResults = main.TRUE
1864 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001865 for i in range( main.numCtrls ):
1866 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -07001867 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -07001868 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -07001869 threads.append( t )
1870 t.start()
1871
1872 for t in threads:
1873 t.join()
1874 cliResults = cliResults and t.result
1875 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1876 onpass="ONOS cli started",
1877 onfail="ONOS clis did not restart" )
1878
Jon Hall6e709752016-02-01 13:38:46 -08001879 for i in range( 10 ):
1880 ready = True
1881 for cli in main.CLIs:
1882 output = cli.summary()
1883 if not output:
1884 ready = False
1885 time.sleep( 30 )
1886 utilities.assert_equals( expect=True, actual=ready,
1887 onpass="ONOS summary command succeded",
1888 onfail="ONOS summary command failed" )
1889 if not ready:
1890 main.cleanup()
1891 main.exit()
1892
Jon Hall5cf14d52015-07-16 12:15:19 -07001893 # Grab the time of restart so we chan check how long the gossip
1894 # protocol has had time to work
1895 main.restartTime = time.time() - killTime
1896 main.log.debug( "Restart time: " + str( main.restartTime ) )
1897 labels.append( "Restart" )
1898 data.append( str( main.restartTime ) )
1899
Jon Hall5cf14d52015-07-16 12:15:19 -07001900 # Rerun for election on restarted nodes
1901 runResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001902 for cli in main.CLIs:
Jon Halla440e872016-03-31 15:15:50 -07001903 run = cli.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07001904 if run != main.TRUE:
1905 main.log.error( "Error running for election on " + cli.name )
1906 runResults = runResults and run
1907 utilities.assert_equals( expect=main.TRUE, actual=runResults,
1908 onpass="Reran for election",
1909 onfail="Failed to rerun for election" )
1910
1911 # TODO: Make this configurable
1912 time.sleep( 60 )
Jon Halla440e872016-03-31 15:15:50 -07001913 node = main.activeNodes[0]
1914 main.log.debug( main.CLIs[node].nodes( jsonFormat=False ) )
1915 main.log.debug( main.CLIs[node].leaders( jsonFormat=False ) )
1916 main.log.debug( main.CLIs[node].partitions( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001917
1918 def CASE7( self, main ):
1919 """
1920 Check state after ONOS failure
1921 """
1922 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001923 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001924 assert main, "main not defined"
1925 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001926 assert main.CLIs, "main.CLIs not defined"
1927 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001928 main.case( "Running ONOS Constant State Tests" )
1929
1930 main.step( "Check that each switch has a master" )
1931 # Assert that each device has a master
1932 rolesNotNull = main.TRUE
1933 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001934 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001935 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001936 name="rolesNotNull-" + str( i ),
1937 args=[ ] )
1938 threads.append( t )
1939 t.start()
1940
1941 for t in threads:
1942 t.join()
1943 rolesNotNull = rolesNotNull and t.result
1944 utilities.assert_equals(
1945 expect=main.TRUE,
1946 actual=rolesNotNull,
1947 onpass="Each device has a master",
1948 onfail="Some devices don't have a master assigned" )
1949
1950 main.step( "Read device roles from ONOS" )
1951 ONOSMastership = []
1952 mastershipCheck = main.FALSE
1953 consistentMastership = True
1954 rolesResults = True
1955 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001956 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001957 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001958 name="roles-" + str( i ),
1959 args=[] )
1960 threads.append( t )
1961 t.start()
1962
1963 for t in threads:
1964 t.join()
1965 ONOSMastership.append( t.result )
1966
Jon Halla440e872016-03-31 15:15:50 -07001967 for i in range( len( ONOSMastership ) ):
1968 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001969 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Halla440e872016-03-31 15:15:50 -07001970 main.log.error( "Error in getting ONOS" + node + " roles" )
1971 main.log.warn( "ONOS" + node + " mastership response: " +
1972 repr( ONOSMastership[i] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001973 rolesResults = False
1974 utilities.assert_equals(
1975 expect=True,
1976 actual=rolesResults,
1977 onpass="No error in reading roles output",
1978 onfail="Error in reading roles from ONOS" )
1979
1980 main.step( "Check for consistency in roles from each controller" )
1981 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1982 main.log.info(
1983 "Switch roles are consistent across all ONOS nodes" )
1984 else:
1985 consistentMastership = False
1986 utilities.assert_equals(
1987 expect=True,
1988 actual=consistentMastership,
1989 onpass="Switch roles are consistent across all ONOS nodes",
1990 onfail="ONOS nodes have different views of switch roles" )
1991
1992 if rolesResults and not consistentMastership:
Jon Halla440e872016-03-31 15:15:50 -07001993 for i in range( len( ONOSMastership ) ):
1994 node = str( main.activeNodes[i] + 1 )
1995 main.log.warn( "ONOS" + node + " roles: ",
Jon Hall6e709752016-02-01 13:38:46 -08001996 json.dumps( json.loads( ONOSMastership[ i ] ),
1997 sort_keys=True,
1998 indent=4,
1999 separators=( ',', ': ' ) ) )
2000 elif rolesResults and consistentMastership:
Jon Hall5cf14d52015-07-16 12:15:19 -07002001 mastershipCheck = main.TRUE
2002
Jon Hall5cf14d52015-07-16 12:15:19 -07002003 # NOTE: we expect mastership to change on controller failure
2004
2005 main.step( "Get the intents and compare across all nodes" )
2006 ONOSIntents = []
2007 intentCheck = main.FALSE
2008 consistentIntents = True
2009 intentsResults = True
2010 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002011 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002012 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07002013 name="intents-" + str( i ),
2014 args=[],
2015 kwargs={ 'jsonFormat': True } )
2016 threads.append( t )
2017 t.start()
2018
2019 for t in threads:
2020 t.join()
2021 ONOSIntents.append( t.result )
2022
Jon Halla440e872016-03-31 15:15:50 -07002023 for i in range( len( ONOSIntents) ):
2024 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002025 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Halla440e872016-03-31 15:15:50 -07002026 main.log.error( "Error in getting ONOS" + node + " intents" )
2027 main.log.warn( "ONOS" + node + " intents response: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07002028 repr( ONOSIntents[ i ] ) )
2029 intentsResults = False
2030 utilities.assert_equals(
2031 expect=True,
2032 actual=intentsResults,
2033 onpass="No error in reading intents output",
2034 onfail="Error in reading intents from ONOS" )
2035
2036 main.step( "Check for consistency in Intents from each controller" )
2037 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
2038 main.log.info( "Intents are consistent across all ONOS " +
2039 "nodes" )
2040 else:
2041 consistentIntents = False
2042
2043 # Try to make it easy to figure out what is happening
2044 #
2045 # Intent ONOS1 ONOS2 ...
2046 # 0x01 INSTALLED INSTALLING
2047 # ... ... ...
2048 # ... ... ...
2049 title = " ID"
Jon Halla440e872016-03-31 15:15:50 -07002050 for n in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07002051 title += " " * 10 + "ONOS" + str( n + 1 )
2052 main.log.warn( title )
2053 # get all intent keys in the cluster
2054 keys = []
2055 for nodeStr in ONOSIntents:
2056 node = json.loads( nodeStr )
2057 for intent in node:
2058 keys.append( intent.get( 'id' ) )
2059 keys = set( keys )
2060 for key in keys:
2061 row = "%-13s" % key
2062 for nodeStr in ONOSIntents:
2063 node = json.loads( nodeStr )
2064 for intent in node:
2065 if intent.get( 'id' ) == key:
2066 row += "%-15s" % intent.get( 'state' )
2067 main.log.warn( row )
2068 # End table view
2069
2070 utilities.assert_equals(
2071 expect=True,
2072 actual=consistentIntents,
2073 onpass="Intents are consistent across all ONOS nodes",
2074 onfail="ONOS nodes have different views of intents" )
2075 intentStates = []
2076 for node in ONOSIntents: # Iter through ONOS nodes
2077 nodeStates = []
2078 # Iter through intents of a node
2079 try:
2080 for intent in json.loads( node ):
2081 nodeStates.append( intent[ 'state' ] )
2082 except ( ValueError, TypeError ):
2083 main.log.exception( "Error in parsing intents" )
2084 main.log.error( repr( node ) )
2085 intentStates.append( nodeStates )
2086 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
2087 main.log.info( dict( out ) )
2088
2089 if intentsResults and not consistentIntents:
Jon Halla440e872016-03-31 15:15:50 -07002090 for i in range( len( main.activeNodes ) ):
2091 node = str( main.activeNodes[i] + 1 )
2092 main.log.warn( "ONOS" + node + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07002093 main.log.warn( json.dumps(
2094 json.loads( ONOSIntents[ i ] ),
2095 sort_keys=True,
2096 indent=4,
2097 separators=( ',', ': ' ) ) )
2098 elif intentsResults and consistentIntents:
2099 intentCheck = main.TRUE
2100
2101 # NOTE: Store has no durability, so intents are lost across system
2102 # restarts
2103 """
2104 main.step( "Compare current intents with intents before the failure" )
2105 # NOTE: this requires case 5 to pass for intentState to be set.
2106 # maybe we should stop the test if that fails?
2107 sameIntents = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002108 try:
2109 intentState
2110 except NameError:
2111 main.log.warn( "No previous intent state was saved" )
2112 else:
2113 if intentState and intentState == ONOSIntents[ 0 ]:
2114 sameIntents = main.TRUE
2115 main.log.info( "Intents are consistent with before failure" )
2116 # TODO: possibly the states have changed? we may need to figure out
2117 # what the acceptable states are
2118 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
2119 sameIntents = main.TRUE
2120 try:
2121 before = json.loads( intentState )
2122 after = json.loads( ONOSIntents[ 0 ] )
2123 for intent in before:
2124 if intent not in after:
2125 sameIntents = main.FALSE
2126 main.log.debug( "Intent is not currently in ONOS " +
2127 "(at least in the same form):" )
2128 main.log.debug( json.dumps( intent ) )
2129 except ( ValueError, TypeError ):
2130 main.log.exception( "Exception printing intents" )
2131 main.log.debug( repr( ONOSIntents[0] ) )
2132 main.log.debug( repr( intentState ) )
2133 if sameIntents == main.FALSE:
2134 try:
2135 main.log.debug( "ONOS intents before: " )
2136 main.log.debug( json.dumps( json.loads( intentState ),
2137 sort_keys=True, indent=4,
2138 separators=( ',', ': ' ) ) )
2139 main.log.debug( "Current ONOS intents: " )
2140 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
2141 sort_keys=True, indent=4,
2142 separators=( ',', ': ' ) ) )
2143 except ( ValueError, TypeError ):
2144 main.log.exception( "Exception printing intents" )
2145 main.log.debug( repr( ONOSIntents[0] ) )
2146 main.log.debug( repr( intentState ) )
2147 utilities.assert_equals(
2148 expect=main.TRUE,
2149 actual=sameIntents,
2150 onpass="Intents are consistent with before failure",
2151 onfail="The Intents changed during failure" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002152 intentCheck = intentCheck and sameIntents
2153 """
2154 main.step( "Get the OF Table entries and compare to before " +
2155 "component failure" )
2156 FlowTables = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002157 for i in range( 28 ):
2158 main.log.info( "Checking flow table on s" + str( i + 1 ) )
GlennRC68467eb2015-11-16 18:01:01 -08002159 tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
2160 FlowTables = FlowTables and main.Mininet1.flowTableComp( flows[i], tmpFlows )
Jon Hall5cf14d52015-07-16 12:15:19 -07002161 if FlowTables == main.FALSE:
GlennRC68467eb2015-11-16 18:01:01 -08002162 main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002163 utilities.assert_equals(
2164 expect=main.TRUE,
2165 actual=FlowTables,
2166 onpass="No changes were found in the flow tables",
2167 onfail="Changes were found in the flow tables" )
2168
2169 main.Mininet2.pingLongKill()
2170 '''
2171 # main.step( "Check the continuous pings to ensure that no packets " +
2172 # "were dropped during component failure" )
2173 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
2174 main.params[ 'TESTONIP' ] )
2175 LossInPings = main.FALSE
2176 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
2177 for i in range( 8, 18 ):
2178 main.log.info(
2179 "Checking for a loss in pings along flow from s" +
2180 str( i ) )
2181 LossInPings = main.Mininet2.checkForLoss(
2182 "/tmp/ping.h" +
2183 str( i ) ) or LossInPings
2184 if LossInPings == main.TRUE:
2185 main.log.info( "Loss in ping detected" )
2186 elif LossInPings == main.ERROR:
2187 main.log.info( "There are multiple mininet process running" )
2188 elif LossInPings == main.FALSE:
2189 main.log.info( "No Loss in the pings" )
2190 main.log.info( "No loss of dataplane connectivity" )
2191 # utilities.assert_equals(
2192 # expect=main.FALSE,
2193 # actual=LossInPings,
2194 # onpass="No Loss of connectivity",
2195 # onfail="Loss of dataplane connectivity detected" )
2196
2197 # NOTE: Since intents are not persisted with IntnentStore,
2198 # we expect loss in dataplane connectivity
2199 LossInPings = main.FALSE
2200 '''
2201
2202 main.step( "Leadership Election is still functional" )
2203 # Test of LeadershipElection
2204 leaderList = []
2205 leaderResult = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002206
2207 for i in main.activeNodes:
2208 cli = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07002209 leaderN = cli.electionTestLeader()
2210 leaderList.append( leaderN )
2211 if leaderN == main.FALSE:
2212 # error in response
2213 main.log.error( "Something is wrong with " +
2214 "electionTestLeader function, check the" +
2215 " error logs" )
2216 leaderResult = main.FALSE
2217 elif leaderN is None:
2218 main.log.error( cli.name +
2219 " shows no leader for the election-app." )
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 Hallba609822015-09-18 12:00:21 -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 Halla440e872016-03-31 15:15:50 -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 Halla440e872016-03-31 15:15:50 -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 Hall3afe4c92015-12-14 19:30:38 -08002294 hosts.append( None )
Jon Hall5cf14d52015-07-16 12:15:19 -07002295 for controller in range( 0, len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -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 Halla440e872016-03-31 15:15:50 -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 Halla440e872016-03-31 15:15:50 -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 Halla440e872016-03-31 15:15:50 -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 Halla440e872016-03-31 15:15:50 -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
Jon Halla440e872016-03-31 15:15:50 -07002415 zeroHosts = False
Jon Hall5cf14d52015-07-16 12:15:19 -07002416 # 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" )
Jon Halla440e872016-03-31 15:15:50 -07002448 zeroHosts = True
Jon Hall5cf14d52015-07-16 12:15:19 -07002449 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 ] ) )
Jon Halla440e872016-03-31 15:15:50 -07002492 if zeroHosts is False:
Jon Hall5cf14d52015-07-16 12:15:19 -07002493 # TODO: Find a way to know if there should be hosts in a
2494 # given point of the test
2495 hostAttachment = True
2496
2497 # END CHECKING HOST ATTACHMENT POINTS
2498 devicesResults = devicesResults and currentDevicesResult
2499 linksResults = linksResults and currentLinksResult
2500 hostsResults = hostsResults and currentHostsResult
2501 hostAttachmentResults = hostAttachmentResults and\
2502 hostAttachment
2503 topoResult = ( devicesResults and linksResults
2504 and hostsResults and ipResult and
2505 hostAttachmentResults )
Jon Halle9b1fa32015-12-08 15:32:21 -08002506 utilities.assert_equals( expect=True,
2507 actual=topoResult,
2508 onpass="ONOS topology matches Mininet",
Jon Hall6e709752016-02-01 13:38:46 -08002509 onfail=topoFailMsg )
Jon Halle9b1fa32015-12-08 15:32:21 -08002510 # End of While loop to pull ONOS state
Jon Hall5cf14d52015-07-16 12:15:19 -07002511
2512 # Compare json objects for hosts and dataplane clusters
2513
2514 # hosts
2515 main.step( "Hosts view is consistent across all ONOS nodes" )
2516 consistentHostsResult = main.TRUE
2517 for controller in range( len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07002518 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall13b446e2016-01-05 12:17:01 -08002519 if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002520 if hosts[ controller ] == hosts[ 0 ]:
2521 continue
2522 else: # hosts not consistent
2523 main.log.error( "hosts from ONOS" + controllerStr +
2524 " is inconsistent with ONOS1" )
2525 main.log.warn( repr( hosts[ controller ] ) )
2526 consistentHostsResult = main.FALSE
2527
2528 else:
2529 main.log.error( "Error in getting ONOS hosts from ONOS" +
2530 controllerStr )
2531 consistentHostsResult = main.FALSE
2532 main.log.warn( "ONOS" + controllerStr +
2533 " hosts response: " +
2534 repr( hosts[ controller ] ) )
2535 utilities.assert_equals(
2536 expect=main.TRUE,
2537 actual=consistentHostsResult,
2538 onpass="Hosts view is consistent across all ONOS nodes",
2539 onfail="ONOS nodes have different views of hosts" )
2540
2541 main.step( "Hosts information is correct" )
2542 hostsResults = hostsResults and ipResult
2543 utilities.assert_equals(
2544 expect=main.TRUE,
2545 actual=hostsResults,
2546 onpass="Host information is correct",
2547 onfail="Host information is incorrect" )
2548
2549 main.step( "Host attachment points to the network" )
2550 utilities.assert_equals(
2551 expect=True,
2552 actual=hostAttachmentResults,
2553 onpass="Hosts are correctly attached to the network",
2554 onfail="ONOS did not correctly attach hosts to the network" )
2555
2556 # Strongly connected clusters of devices
2557 main.step( "Clusters view is consistent across all ONOS nodes" )
2558 consistentClustersResult = main.TRUE
2559 for controller in range( len( clusters ) ):
Jon Halla440e872016-03-31 15:15:50 -07002560 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002561 if "Error" not in clusters[ controller ]:
2562 if clusters[ controller ] == clusters[ 0 ]:
2563 continue
2564 else: # clusters not consistent
2565 main.log.error( "clusters from ONOS" +
2566 controllerStr +
2567 " is inconsistent with ONOS1" )
2568 consistentClustersResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002569 else:
2570 main.log.error( "Error in getting dataplane clusters " +
2571 "from ONOS" + controllerStr )
2572 consistentClustersResult = main.FALSE
2573 main.log.warn( "ONOS" + controllerStr +
2574 " clusters response: " +
2575 repr( clusters[ controller ] ) )
2576 utilities.assert_equals(
2577 expect=main.TRUE,
2578 actual=consistentClustersResult,
2579 onpass="Clusters view is consistent across all ONOS nodes",
2580 onfail="ONOS nodes have different views of clusters" )
2581
2582 main.step( "There is only one SCC" )
2583 # there should always only be one cluster
2584 try:
2585 numClusters = len( json.loads( clusters[ 0 ] ) )
2586 except ( ValueError, TypeError ):
2587 main.log.exception( "Error parsing clusters[0]: " +
2588 repr( clusters[0] ) )
Jon Halla440e872016-03-31 15:15:50 -07002589 numClusters = "ERROR"
Jon Hall5cf14d52015-07-16 12:15:19 -07002590 clusterResults = main.FALSE
2591 if numClusters == 1:
2592 clusterResults = main.TRUE
2593 utilities.assert_equals(
2594 expect=1,
2595 actual=numClusters,
2596 onpass="ONOS shows 1 SCC",
2597 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2598
2599 topoResult = ( devicesResults and linksResults
2600 and hostsResults and consistentHostsResult
2601 and consistentClustersResult and clusterResults
2602 and ipResult and hostAttachmentResults )
2603
2604 topoResult = topoResult and int( count <= 2 )
2605 note = "note it takes about " + str( int( cliTime ) ) + \
2606 " seconds for the test to make all the cli calls to fetch " +\
2607 "the topology from each ONOS instance"
2608 main.log.info(
2609 "Very crass estimate for topology discovery/convergence( " +
2610 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2611 str( count ) + " tries" )
2612
2613 main.step( "Device information is correct" )
2614 utilities.assert_equals(
2615 expect=main.TRUE,
2616 actual=devicesResults,
2617 onpass="Device information is correct",
2618 onfail="Device information is incorrect" )
2619
2620 main.step( "Links are correct" )
2621 utilities.assert_equals(
2622 expect=main.TRUE,
2623 actual=linksResults,
2624 onpass="Link are correct",
2625 onfail="Links are incorrect" )
2626
Jon Halla440e872016-03-31 15:15:50 -07002627 main.step( "Hosts are correct" )
2628 utilities.assert_equals(
2629 expect=main.TRUE,
2630 actual=hostsResults,
2631 onpass="Hosts are correct",
2632 onfail="Hosts are incorrect" )
2633
Jon Hall5cf14d52015-07-16 12:15:19 -07002634 # FIXME: move this to an ONOS state case
2635 main.step( "Checking ONOS nodes" )
2636 nodesOutput = []
2637 nodeResults = main.TRUE
2638 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002639 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002640 t = main.Thread( target=main.CLIs[i].nodes,
Jon Hall5cf14d52015-07-16 12:15:19 -07002641 name="nodes-" + str( i ),
2642 args=[ ] )
2643 threads.append( t )
2644 t.start()
2645
2646 for t in threads:
2647 t.join()
2648 nodesOutput.append( t.result )
Jon Halla440e872016-03-31 15:15:50 -07002649 ips = [ main.nodes[node].ip_address for node in main.activeNodes ]
Jon Halle9b1fa32015-12-08 15:32:21 -08002650 ips.sort()
Jon Hall5cf14d52015-07-16 12:15:19 -07002651 for i in nodesOutput:
2652 try:
2653 current = json.loads( i )
Jon Halle9b1fa32015-12-08 15:32:21 -08002654 activeIps = []
2655 currentResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002656 for node in current:
Jon Hallbd182782016-03-28 16:42:22 -07002657 if node['state'] == 'READY':
Jon Halle9b1fa32015-12-08 15:32:21 -08002658 activeIps.append( node['ip'] )
2659 activeIps.sort()
2660 if ips == activeIps:
2661 currentResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002662 except ( ValueError, TypeError ):
2663 main.log.error( "Error parsing nodes output" )
2664 main.log.warn( repr( i ) )
Jon Halle9b1fa32015-12-08 15:32:21 -08002665 currentResult = main.FALSE
2666 nodeResults = nodeResults and currentResult
Jon Hall5cf14d52015-07-16 12:15:19 -07002667 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2668 onpass="Nodes check successful",
2669 onfail="Nodes check NOT successful" )
Jon Halla440e872016-03-31 15:15:50 -07002670 if not nodeResults:
2671 for cli in main.CLIs:
2672 main.log.debug( "{} components not ACTIVE: \n{}".format(
2673 cli.name,
2674 cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002675
2676 def CASE9( self, main ):
2677 """
2678 Link s3-s28 down
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 = "Turn off a link to ensure that Link Discovery " +\
2691 "is working properly"
2692 main.case( description )
2693
2694 main.step( "Kill Link between s3 and s28" )
2695 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
2696 main.log.info( "Waiting " + str( linkSleep ) +
2697 " seconds for link down to be discovered" )
2698 time.sleep( linkSleep )
2699 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
2700 onpass="Link down successful",
2701 onfail="Failed to bring link down" )
2702 # TODO do some sort of check here
2703
2704 def CASE10( self, main ):
2705 """
2706 Link s3-s28 up
2707 """
2708 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002709 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002710 assert main, "main not defined"
2711 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002712 assert main.CLIs, "main.CLIs not defined"
2713 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002714 # NOTE: You should probably run a topology check after this
2715
2716 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2717
2718 description = "Restore a link to ensure that Link Discovery is " + \
2719 "working properly"
2720 main.case( description )
2721
2722 main.step( "Bring link between s3 and s28 back up" )
2723 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
2724 main.log.info( "Waiting " + str( linkSleep ) +
2725 " seconds for link up to be discovered" )
2726 time.sleep( linkSleep )
2727 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
2728 onpass="Link up successful",
2729 onfail="Failed to bring link up" )
2730 # TODO do some sort of check here
2731
2732 def CASE11( self, main ):
2733 """
2734 Switch Down
2735 """
2736 # NOTE: You should probably run a topology check after this
2737 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002738 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002739 assert main, "main not defined"
2740 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002741 assert main.CLIs, "main.CLIs not defined"
2742 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002743
2744 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2745
2746 description = "Killing a switch to ensure it is discovered correctly"
Jon Halla440e872016-03-31 15:15:50 -07002747 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002748 main.case( description )
2749 switch = main.params[ 'kill' ][ 'switch' ]
2750 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2751
2752 # TODO: Make this switch parameterizable
2753 main.step( "Kill " + switch )
2754 main.log.info( "Deleting " + switch )
2755 main.Mininet1.delSwitch( switch )
2756 main.log.info( "Waiting " + str( switchSleep ) +
2757 " seconds for switch down to be discovered" )
2758 time.sleep( switchSleep )
Jon Halla440e872016-03-31 15:15:50 -07002759 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall5cf14d52015-07-16 12:15:19 -07002760 # Peek at the deleted switch
2761 main.log.warn( str( device ) )
2762 result = main.FALSE
2763 if device and device[ 'available' ] is False:
2764 result = main.TRUE
2765 utilities.assert_equals( expect=main.TRUE, actual=result,
2766 onpass="Kill switch successful",
2767 onfail="Failed to kill switch?" )
2768
2769 def CASE12( self, main ):
2770 """
2771 Switch Up
2772 """
2773 # NOTE: You should probably run a topology check after this
2774 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002775 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002776 assert main, "main not defined"
2777 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002778 assert main.CLIs, "main.CLIs not defined"
2779 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002780 assert ONOS1Port, "ONOS1Port not defined"
2781 assert ONOS2Port, "ONOS2Port not defined"
2782 assert ONOS3Port, "ONOS3Port not defined"
2783 assert ONOS4Port, "ONOS4Port not defined"
2784 assert ONOS5Port, "ONOS5Port not defined"
2785 assert ONOS6Port, "ONOS6Port not defined"
2786 assert ONOS7Port, "ONOS7Port not defined"
2787
2788 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2789 switch = main.params[ 'kill' ][ 'switch' ]
2790 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2791 links = main.params[ 'kill' ][ 'links' ].split()
Jon Halla440e872016-03-31 15:15:50 -07002792 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002793 description = "Adding a switch to ensure it is discovered correctly"
2794 main.case( description )
2795
2796 main.step( "Add back " + switch )
2797 main.Mininet1.addSwitch( switch, dpid=switchDPID )
2798 for peer in links:
2799 main.Mininet1.addLink( switch, peer )
Jon Halla440e872016-03-31 15:15:50 -07002800 ipList = [ node.ip_address for node in main.nodes ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002801 main.Mininet1.assignSwController( sw=switch, ip=ipList )
2802 main.log.info( "Waiting " + str( switchSleep ) +
2803 " seconds for switch up to be discovered" )
2804 time.sleep( switchSleep )
Jon Halla440e872016-03-31 15:15:50 -07002805 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall5cf14d52015-07-16 12:15:19 -07002806 # Peek at the deleted switch
2807 main.log.warn( str( device ) )
2808 result = main.FALSE
2809 if device and device[ 'available' ]:
2810 result = main.TRUE
2811 utilities.assert_equals( expect=main.TRUE, actual=result,
2812 onpass="add switch successful",
2813 onfail="Failed to add switch?" )
2814
2815 def CASE13( self, main ):
2816 """
2817 Clean up
2818 """
2819 import os
2820 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002821 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002822 assert main, "main not defined"
2823 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002824 assert main.CLIs, "main.CLIs not defined"
2825 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002826
2827 # printing colors to terminal
2828 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2829 'blue': '\033[94m', 'green': '\033[92m',
2830 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
2831 main.case( "Test Cleanup" )
2832 main.step( "Killing tcpdumps" )
2833 main.Mininet2.stopTcpdump()
2834
2835 testname = main.TEST
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002836 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall5cf14d52015-07-16 12:15:19 -07002837 main.step( "Copying MN pcap and ONOS log files to test station" )
2838 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
2839 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
Jon Hall96091e62015-09-21 17:34:17 -07002840 # NOTE: MN Pcap file is being saved to logdir.
2841 # We scp this file as MN and TestON aren't necessarily the same vm
2842
2843 # FIXME: To be replaced with a Jenkin's post script
Jon Hall5cf14d52015-07-16 12:15:19 -07002844 # TODO: Load these from params
2845 # NOTE: must end in /
2846 logFolder = "/opt/onos/log/"
2847 logFiles = [ "karaf.log", "karaf.log.1" ]
2848 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002849 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002850 for node in main.nodes:
Jon Hall6e709752016-02-01 13:38:46 -08002851 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002852 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2853 logFolder + f, dstName )
Jon Hall5cf14d52015-07-16 12:15:19 -07002854 # std*.log's
2855 # NOTE: must end in /
2856 logFolder = "/opt/onos/var/"
2857 logFiles = [ "stderr.log", "stdout.log" ]
2858 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002859 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002860 for node in main.nodes:
Jon Hall6e709752016-02-01 13:38:46 -08002861 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002862 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2863 logFolder + f, dstName )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002864 else:
2865 main.log.debug( "skipping saving log files" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002866
2867 main.step( "Stopping Mininet" )
2868 mnResult = main.Mininet1.stopNet()
2869 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2870 onpass="Mininet stopped",
2871 onfail="MN cleanup NOT successful" )
2872
2873 main.step( "Checking ONOS Logs for errors" )
Jon Halle1a3b752015-07-22 13:02:46 -07002874 for node in main.nodes:
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002875 main.log.debug( "Checking logs for errors on " + node.name + ":" )
2876 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002877
2878 try:
2879 timerLog = open( main.logdir + "/Timers.csv", 'w')
2880 main.log.error( ", ".join( labels ) + "\n" + ", ".join( data ) )
2881 timerLog.write( ", ".join( labels ) + "\n" + ", ".join( data ) )
2882 timerLog.close()
2883 except NameError, e:
2884 main.log.exception(e)
2885
2886 def CASE14( self, main ):
2887 """
2888 start election app on all onos nodes
2889 """
Jon Halle1a3b752015-07-22 13:02:46 -07002890 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002891 assert main, "main not defined"
2892 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002893 assert main.CLIs, "main.CLIs not defined"
2894 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002895
2896 main.case("Start Leadership Election app")
2897 main.step( "Install leadership election app" )
Jon Halla440e872016-03-31 15:15:50 -07002898 onosCli = main.CLIs[ main.activeNodes[0] ]
2899 appResult = onosCli.activateApp( "org.onosproject.election" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002900 utilities.assert_equals(
2901 expect=main.TRUE,
2902 actual=appResult,
2903 onpass="Election app installed",
2904 onfail="Something went wrong with installing Leadership election" )
2905
2906 main.step( "Run for election on each node" )
2907 leaderResult = main.TRUE
2908 leaders = []
Jon Halla440e872016-03-31 15:15:50 -07002909 for i in main.activeNodes:
2910 main.CLIs[i].electionTestRun()
2911 for i in main.activeNodes:
2912 cli = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07002913 leader = cli.electionTestLeader()
2914 if leader is None or leader == main.FALSE:
2915 main.log.error( cli.name + ": Leader for the election app " +
2916 "should be an ONOS node, instead got '" +
2917 str( leader ) + "'" )
2918 leaderResult = main.FALSE
2919 leaders.append( leader )
2920 utilities.assert_equals(
2921 expect=main.TRUE,
2922 actual=leaderResult,
2923 onpass="Successfully ran for leadership",
2924 onfail="Failed to run for leadership" )
2925
2926 main.step( "Check that each node shows the same leader" )
2927 sameLeader = main.TRUE
2928 if len( set( leaders ) ) != 1:
2929 sameLeader = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08002930 main.log.error( "Results of electionTestLeader is order of main.CLIs:" +
Jon Hall5cf14d52015-07-16 12:15:19 -07002931 str( leaders ) )
2932 utilities.assert_equals(
2933 expect=main.TRUE,
2934 actual=sameLeader,
2935 onpass="Leadership is consistent for the election topic",
2936 onfail="Nodes have different leaders" )
2937
2938 def CASE15( self, main ):
2939 """
2940 Check that Leadership Election is still functional
acsmars9475b1c2015-08-28 18:02:08 -07002941 15.1 Run election on each node
2942 15.2 Check that each node has the same leaders and candidates
2943 15.3 Find current leader and withdraw
2944 15.4 Check that a new node was elected leader
2945 15.5 Check that that new leader was the candidate of old leader
2946 15.6 Run for election on old leader
2947 15.7 Check that oldLeader is a candidate, and leader if only 1 node
2948 15.8 Make sure that the old leader was added to the candidate list
2949
2950 old and new variable prefixes refer to data from before vs after
2951 withdrawl and later before withdrawl vs after re-election
Jon Hall5cf14d52015-07-16 12:15:19 -07002952 """
2953 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002954 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002955 assert main, "main not defined"
2956 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002957 assert main.CLIs, "main.CLIs not defined"
2958 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002959
Jon Hall5cf14d52015-07-16 12:15:19 -07002960 description = "Check that Leadership Election is still functional"
2961 main.case( description )
Jon Halla440e872016-03-31 15:15:50 -07002962 # NOTE: Need to re-run after restarts since being a canidate is not persistant
acsmars9475b1c2015-08-28 18:02:08 -07002963
Jon Halla440e872016-03-31 15:15:50 -07002964 oldLeaders = [] # list of lists of each nodes' candidates before
2965 newLeaders = [] # list of lists of each nodes' candidates after
acsmars9475b1c2015-08-28 18:02:08 -07002966 oldLeader = '' # the old leader from oldLeaders, None if not same
2967 newLeader = '' # the new leaders fron newLoeaders, None if not same
2968 oldLeaderCLI = None # the CLI of the old leader used for re-electing
acsmars71adceb2015-08-31 15:09:26 -07002969 expectNoLeader = False # True when there is only one leader
2970 if main.numCtrls == 1:
2971 expectNoLeader = True
acsmars9475b1c2015-08-28 18:02:08 -07002972
Jon Hall5cf14d52015-07-16 12:15:19 -07002973 main.step( "Run for election on each node" )
acsmars9475b1c2015-08-28 18:02:08 -07002974 electionResult = main.TRUE
2975
Jon Halla440e872016-03-31 15:15:50 -07002976 for i in main.activeNodes: # run test election on each node
2977 if main.CLIs[i].electionTestRun() == main.FALSE:
acsmars9475b1c2015-08-28 18:02:08 -07002978 electionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002979 utilities.assert_equals(
2980 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07002981 actual=electionResult,
2982 onpass="All nodes successfully ran for leadership",
2983 onfail="At least one node failed to run for leadership" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002984
acsmars3a72bde2015-09-02 14:16:22 -07002985 if electionResult == main.FALSE:
2986 main.log.error(
2987 "Skipping Test Case because Election Test App isn't loaded" )
2988 main.skipCase()
2989
acsmars9475b1c2015-08-28 18:02:08 -07002990 main.step( "Check that each node shows the same leader and candidates" )
Jon Halla440e872016-03-31 15:15:50 -07002991 failMessage = "Nodes have different leaderboards"
2992 def consistentLeaderboards( nodes ):
2993 TOPIC = 'org.onosproject.election'
2994 # FIXME: use threads
2995 #FIXME: should we retry outside the function?
2996 for n in range( 5 ): # Retry in case election is still happening
2997 leaderList = []
2998 # Get all leaderboards
2999 for cli in nodes:
3000 leaderList.append( cli.specificLeaderCandidate( TOPIC ) )
3001 # Compare leaderboards
3002 result = all( i == leaderList[0] for i in leaderList ) and\
3003 leaderList is not None
3004 main.log.debug( leaderList )
3005 main.log.warn( result )
3006 if result:
3007 return ( result, leaderList )
3008 time.sleep(5) #TODO: paramerterize
3009 main.log.error( "Inconsistent leaderboards:" + str( leaderList ) )
3010 activeCLIs = [ main.CLIs[i] for i in main.activeNodes ]
3011 sameResult, oldLeaders = consistentLeaderboards( activeCLIs )
3012 if sameResult:
3013 oldLeader = oldLeaders[ 0 ][ 0 ]
3014 main.log.warn( oldLeader )
acsmars9475b1c2015-08-28 18:02:08 -07003015 else:
Jon Halla440e872016-03-31 15:15:50 -07003016 oldLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07003017 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07003018 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07003019 actual=sameResult,
Jon Halla440e872016-03-31 15:15:50 -07003020 onpass="Leaderboards are consistent for the election topic",
acsmars9475b1c2015-08-28 18:02:08 -07003021 onfail=failMessage )
Jon Hall5cf14d52015-07-16 12:15:19 -07003022
3023 main.step( "Find current leader and withdraw" )
acsmars9475b1c2015-08-28 18:02:08 -07003024 withdrawResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07003025 # do some sanity checking on leader before using it
acsmars9475b1c2015-08-28 18:02:08 -07003026 if oldLeader is None:
3027 main.log.error( "Leadership isn't consistent." )
3028 withdrawResult = main.FALSE
3029 # Get the CLI of the oldLeader
Jon Halla440e872016-03-31 15:15:50 -07003030 for i in main.activeNodes:
acsmars9475b1c2015-08-28 18:02:08 -07003031 if oldLeader == main.nodes[ i ].ip_address:
3032 oldLeaderCLI = main.CLIs[ i ]
Jon Hall5cf14d52015-07-16 12:15:19 -07003033 break
3034 else: # FOR/ELSE statement
3035 main.log.error( "Leader election, could not find current leader" )
3036 if oldLeader:
acsmars9475b1c2015-08-28 18:02:08 -07003037 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall5cf14d52015-07-16 12:15:19 -07003038 utilities.assert_equals(
3039 expect=main.TRUE,
3040 actual=withdrawResult,
3041 onpass="Node was withdrawn from election",
3042 onfail="Node was not withdrawn from election" )
3043
acsmars9475b1c2015-08-28 18:02:08 -07003044 main.step( "Check that a new node was elected leader" )
acsmars9475b1c2015-08-28 18:02:08 -07003045 failMessage = "Nodes have different leaders"
acsmars9475b1c2015-08-28 18:02:08 -07003046 # Get new leaders and candidates
Jon Halla440e872016-03-31 15:15:50 -07003047 newLeaderResult, newLeaders = consistentLeaderboards( activeCLIs )
3048 if newLeaders[ 0 ][ 0 ] == 'none':
3049 main.log.error( "No leader was elected on at least 1 node" )
3050 if not expectNoLeader:
3051 newLeaderResult = False
3052 if newLeaderResult:
3053 newLeader = newLeaders[ 0 ][ 0 ]
Jon Hall5cf14d52015-07-16 12:15:19 -07003054 else:
Jon Halla440e872016-03-31 15:15:50 -07003055 newLeader = None
acsmars71adceb2015-08-31 15:09:26 -07003056
acsmars9475b1c2015-08-28 18:02:08 -07003057 # Check that the new leader is not the older leader, which was withdrawn
3058 if newLeader == oldLeader:
Jon Halla440e872016-03-31 15:15:50 -07003059 newLeaderResult = False
Jon Hall6e709752016-02-01 13:38:46 -08003060 main.log.error( "All nodes still see old leader: " + str( oldLeader ) +
acsmars9475b1c2015-08-28 18:02:08 -07003061 " as the current leader" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003062 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07003063 expect=True,
acsmars9475b1c2015-08-28 18:02:08 -07003064 actual=newLeaderResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07003065 onpass="Leadership election passed",
3066 onfail="Something went wrong with Leadership election" )
3067
Jon Halla440e872016-03-31 15:15:50 -07003068 main.step( "Check that that new leader was the candidate of old leader" )
Jon Hall6e709752016-02-01 13:38:46 -08003069 # candidates[ 2 ] should become the top candidate after withdrawl
acsmars9475b1c2015-08-28 18:02:08 -07003070 correctCandidateResult = main.TRUE
acsmars71adceb2015-08-31 15:09:26 -07003071 if expectNoLeader:
3072 if newLeader == 'none':
3073 main.log.info( "No leader expected. None found. Pass" )
3074 correctCandidateResult = main.TRUE
3075 else:
3076 main.log.info( "Expected no leader, got: " + str( newLeader ) )
3077 correctCandidateResult = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003078 elif len( oldLeaders[0] ) >= 3:
3079 if newLeader == oldLeaders[ 0 ][ 2 ]:
3080 # correct leader was elected
3081 correctCandidateResult = main.TRUE
3082 else:
3083 correctCandidateResult = main.FALSE
3084 main.log.error( "Candidate {} was elected. {} should have had priority.".format(
3085 newLeader, oldLeaders[ 0 ][ 2 ] ) )
Jon Hall6e709752016-02-01 13:38:46 -08003086 else:
3087 main.log.warn( "Could not determine who should be the correct leader" )
Jon Halla440e872016-03-31 15:15:50 -07003088 main.log.debug( oldLeaders[ 0 ] )
Jon Hall6e709752016-02-01 13:38:46 -08003089 correctCandidateResult = main.FALSE
acsmars9475b1c2015-08-28 18:02:08 -07003090 utilities.assert_equals(
3091 expect=main.TRUE,
3092 actual=correctCandidateResult,
3093 onpass="Correct Candidate Elected",
3094 onfail="Incorrect Candidate Elected" )
3095
Jon Hall5cf14d52015-07-16 12:15:19 -07003096 main.step( "Run for election on old leader( just so everyone " +
3097 "is in the hat )" )
acsmars9475b1c2015-08-28 18:02:08 -07003098 if oldLeaderCLI is not None:
3099 runResult = oldLeaderCLI.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07003100 else:
acsmars9475b1c2015-08-28 18:02:08 -07003101 main.log.error( "No old leader to re-elect" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003102 runResult = main.FALSE
3103 utilities.assert_equals(
3104 expect=main.TRUE,
3105 actual=runResult,
3106 onpass="App re-ran for election",
3107 onfail="App failed to run for election" )
Jon Halla440e872016-03-31 15:15:50 -07003108
acsmars9475b1c2015-08-28 18:02:08 -07003109 main.step(
3110 "Check that oldLeader is a candidate, and leader if only 1 node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003111 # verify leader didn't just change
Jon Halla440e872016-03-31 15:15:50 -07003112 # Get new leaders and candidates
3113 reRunLeaders = []
3114 time.sleep( 5 ) # Paremterize
3115 positionResult, reRunLeaders = consistentLeaderboards( activeCLIs )
acsmars71adceb2015-08-31 15:09:26 -07003116
acsmars9475b1c2015-08-28 18:02:08 -07003117 # Check that the re-elected node is last on the candidate List
Jon Halla440e872016-03-31 15:15:50 -07003118 if oldLeader != reRunLeaders[ 0 ][ -1 ]:
3119 main.log.error( "Old Leader ({}) not in the proper position: {} ".format( str( oldLeader),
3120 str( reRunLeaders[ 0 ] ) ) )
acsmars9475b1c2015-08-28 18:02:08 -07003121 positionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07003122
3123 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07003124 expect=True,
acsmars9475b1c2015-08-28 18:02:08 -07003125 actual=positionResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07003126 onpass="Old leader successfully re-ran for election",
3127 onfail="Something went wrong with Leadership election after " +
3128 "the old leader re-ran for election" )
3129
3130 def CASE16( self, main ):
3131 """
3132 Install Distributed Primitives app
3133 """
3134 import time
Jon Halle1a3b752015-07-22 13:02:46 -07003135 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003136 assert main, "main not defined"
3137 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003138 assert main.CLIs, "main.CLIs not defined"
3139 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003140
3141 # Variables for the distributed primitives tests
3142 global pCounterName
Jon Hall5cf14d52015-07-16 12:15:19 -07003143 global pCounterValue
Jon Hall5cf14d52015-07-16 12:15:19 -07003144 global onosSet
3145 global onosSetName
3146 pCounterName = "TestON-Partitions"
Jon Hall5cf14d52015-07-16 12:15:19 -07003147 pCounterValue = 0
Jon Hall5cf14d52015-07-16 12:15:19 -07003148 onosSet = set([])
3149 onosSetName = "TestON-set"
3150
3151 description = "Install Primitives app"
3152 main.case( description )
3153 main.step( "Install Primitives app" )
3154 appName = "org.onosproject.distributedprimitives"
Jon Halla440e872016-03-31 15:15:50 -07003155 node = main.activeNodes[0]
3156 appResults = main.CLIs[node].activateApp( appName )
Jon Hall5cf14d52015-07-16 12:15:19 -07003157 utilities.assert_equals( expect=main.TRUE,
3158 actual=appResults,
3159 onpass="Primitives app activated",
3160 onfail="Primitives app not activated" )
3161 time.sleep( 5 ) # To allow all nodes to activate
3162
3163 def CASE17( self, main ):
3164 """
3165 Check for basic functionality with distributed primitives
3166 """
Jon Hall5cf14d52015-07-16 12:15:19 -07003167 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07003168 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003169 assert main, "main not defined"
3170 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003171 assert main.CLIs, "main.CLIs not defined"
3172 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003173 assert pCounterName, "pCounterName not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003174 assert onosSetName, "onosSetName not defined"
3175 # NOTE: assert fails if value is 0/None/Empty/False
3176 try:
3177 pCounterValue
3178 except NameError:
3179 main.log.error( "pCounterValue not defined, setting to 0" )
3180 pCounterValue = 0
3181 try:
Jon Hall5cf14d52015-07-16 12:15:19 -07003182 onosSet
3183 except NameError:
3184 main.log.error( "onosSet not defined, setting to empty Set" )
3185 onosSet = set([])
3186 # Variables for the distributed primitives tests. These are local only
3187 addValue = "a"
3188 addAllValue = "a b c d e f"
3189 retainValue = "c d e f"
3190
3191 description = "Check for basic functionality with distributed " +\
3192 "primitives"
3193 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07003194 main.caseExplanation = "Test the methods of the distributed " +\
3195 "primitives (counters and sets) throught the cli"
Jon Hall5cf14d52015-07-16 12:15:19 -07003196 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07003197 # Partitioned counters
3198 main.step( "Increment then get a default counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003199 pCounters = []
3200 threads = []
3201 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003202 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003203 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3204 name="counterAddAndGet-" + str( i ),
Jon Hall5cf14d52015-07-16 12:15:19 -07003205 args=[ pCounterName ] )
3206 pCounterValue += 1
3207 addedPValues.append( pCounterValue )
3208 threads.append( t )
3209 t.start()
3210
3211 for t in threads:
3212 t.join()
3213 pCounters.append( t.result )
3214 # Check that counter incremented numController times
3215 pCounterResults = True
3216 for i in addedPValues:
3217 tmpResult = i in pCounters
3218 pCounterResults = pCounterResults and tmpResult
3219 if not tmpResult:
3220 main.log.error( str( i ) + " is not in partitioned "
3221 "counter incremented results" )
3222 utilities.assert_equals( expect=True,
3223 actual=pCounterResults,
3224 onpass="Default counter incremented",
3225 onfail="Error incrementing default" +
3226 " counter" )
3227
Jon Halle1a3b752015-07-22 13:02:46 -07003228 main.step( "Get then Increment a default counter on each node" )
3229 pCounters = []
3230 threads = []
3231 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003232 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003233 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3234 name="counterGetAndAdd-" + str( i ),
3235 args=[ pCounterName ] )
3236 addedPValues.append( pCounterValue )
3237 pCounterValue += 1
3238 threads.append( t )
3239 t.start()
3240
3241 for t in threads:
3242 t.join()
3243 pCounters.append( t.result )
3244 # Check that counter incremented numController times
3245 pCounterResults = True
3246 for i in addedPValues:
3247 tmpResult = i in pCounters
3248 pCounterResults = pCounterResults and tmpResult
3249 if not tmpResult:
3250 main.log.error( str( i ) + " is not in partitioned "
3251 "counter incremented results" )
3252 utilities.assert_equals( expect=True,
3253 actual=pCounterResults,
3254 onpass="Default counter incremented",
3255 onfail="Error incrementing default" +
3256 " counter" )
3257
3258 main.step( "Counters we added have the correct values" )
3259 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3260 utilities.assert_equals( expect=main.TRUE,
3261 actual=incrementCheck,
3262 onpass="Added counters are correct",
3263 onfail="Added counters are incorrect" )
3264
3265 main.step( "Add -8 to then get a default counter on each node" )
3266 pCounters = []
3267 threads = []
3268 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003269 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003270 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3271 name="counterIncrement-" + str( i ),
3272 args=[ pCounterName ],
3273 kwargs={ "delta": -8 } )
3274 pCounterValue += -8
3275 addedPValues.append( pCounterValue )
3276 threads.append( t )
3277 t.start()
3278
3279 for t in threads:
3280 t.join()
3281 pCounters.append( t.result )
3282 # Check that counter incremented numController times
3283 pCounterResults = True
3284 for i in addedPValues:
3285 tmpResult = i in pCounters
3286 pCounterResults = pCounterResults and tmpResult
3287 if not tmpResult:
3288 main.log.error( str( i ) + " is not in partitioned "
3289 "counter incremented results" )
3290 utilities.assert_equals( expect=True,
3291 actual=pCounterResults,
3292 onpass="Default counter incremented",
3293 onfail="Error incrementing default" +
3294 " counter" )
3295
3296 main.step( "Add 5 to then get a default counter on each node" )
3297 pCounters = []
3298 threads = []
3299 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003300 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003301 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3302 name="counterIncrement-" + str( i ),
3303 args=[ pCounterName ],
3304 kwargs={ "delta": 5 } )
3305 pCounterValue += 5
3306 addedPValues.append( pCounterValue )
3307 threads.append( t )
3308 t.start()
3309
3310 for t in threads:
3311 t.join()
3312 pCounters.append( t.result )
3313 # Check that counter incremented numController times
3314 pCounterResults = True
3315 for i in addedPValues:
3316 tmpResult = i in pCounters
3317 pCounterResults = pCounterResults and tmpResult
3318 if not tmpResult:
3319 main.log.error( str( i ) + " is not in partitioned "
3320 "counter incremented results" )
3321 utilities.assert_equals( expect=True,
3322 actual=pCounterResults,
3323 onpass="Default counter incremented",
3324 onfail="Error incrementing default" +
3325 " counter" )
3326
3327 main.step( "Get then add 5 to a default counter on each node" )
3328 pCounters = []
3329 threads = []
3330 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003331 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003332 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3333 name="counterIncrement-" + str( i ),
3334 args=[ pCounterName ],
3335 kwargs={ "delta": 5 } )
3336 addedPValues.append( pCounterValue )
3337 pCounterValue += 5
3338 threads.append( t )
3339 t.start()
3340
3341 for t in threads:
3342 t.join()
3343 pCounters.append( t.result )
3344 # Check that counter incremented numController times
3345 pCounterResults = True
3346 for i in addedPValues:
3347 tmpResult = i in pCounters
3348 pCounterResults = pCounterResults and tmpResult
3349 if not tmpResult:
3350 main.log.error( str( i ) + " is not in partitioned "
3351 "counter incremented results" )
3352 utilities.assert_equals( expect=True,
3353 actual=pCounterResults,
3354 onpass="Default counter incremented",
3355 onfail="Error incrementing default" +
3356 " counter" )
3357
3358 main.step( "Counters we added have the correct values" )
3359 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3360 utilities.assert_equals( expect=main.TRUE,
3361 actual=incrementCheck,
3362 onpass="Added counters are correct",
3363 onfail="Added counters are incorrect" )
3364
Jon Hall5cf14d52015-07-16 12:15:19 -07003365 # DISTRIBUTED SETS
3366 main.step( "Distributed Set get" )
3367 size = len( onosSet )
3368 getResponses = []
3369 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003370 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003371 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003372 name="setTestGet-" + str( i ),
3373 args=[ onosSetName ] )
3374 threads.append( t )
3375 t.start()
3376 for t in threads:
3377 t.join()
3378 getResponses.append( t.result )
3379
3380 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003381 for i in range( len( main.activeNodes ) ):
3382 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003383 if isinstance( getResponses[ i ], list):
3384 current = set( getResponses[ i ] )
3385 if len( current ) == len( getResponses[ i ] ):
3386 # no repeats
3387 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003388 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003389 " has incorrect view" +
3390 " of set " + onosSetName + ":\n" +
3391 str( getResponses[ i ] ) )
3392 main.log.debug( "Expected: " + str( onosSet ) )
3393 main.log.debug( "Actual: " + str( current ) )
3394 getResults = main.FALSE
3395 else:
3396 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003397 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003398 " has repeat elements in" +
3399 " set " + onosSetName + ":\n" +
3400 str( getResponses[ i ] ) )
3401 getResults = main.FALSE
3402 elif getResponses[ i ] == main.ERROR:
3403 getResults = main.FALSE
3404 utilities.assert_equals( expect=main.TRUE,
3405 actual=getResults,
3406 onpass="Set elements are correct",
3407 onfail="Set elements are incorrect" )
3408
3409 main.step( "Distributed Set size" )
3410 sizeResponses = []
3411 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003412 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003413 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003414 name="setTestSize-" + str( i ),
3415 args=[ onosSetName ] )
3416 threads.append( t )
3417 t.start()
3418 for t in threads:
3419 t.join()
3420 sizeResponses.append( t.result )
3421
3422 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003423 for i in range( len( main.activeNodes ) ):
3424 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003425 if size != sizeResponses[ i ]:
3426 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003427 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003428 " expected a size of " + str( size ) +
3429 " for set " + onosSetName +
3430 " but got " + str( sizeResponses[ i ] ) )
3431 utilities.assert_equals( expect=main.TRUE,
3432 actual=sizeResults,
3433 onpass="Set sizes are correct",
3434 onfail="Set sizes are incorrect" )
3435
3436 main.step( "Distributed Set add()" )
3437 onosSet.add( addValue )
3438 addResponses = []
3439 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003440 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003441 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003442 name="setTestAdd-" + str( i ),
3443 args=[ onosSetName, addValue ] )
3444 threads.append( t )
3445 t.start()
3446 for t in threads:
3447 t.join()
3448 addResponses.append( t.result )
3449
3450 # main.TRUE = successfully changed the set
3451 # main.FALSE = action resulted in no change in set
3452 # main.ERROR - Some error in executing the function
3453 addResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003454 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003455 if addResponses[ i ] == main.TRUE:
3456 # All is well
3457 pass
3458 elif addResponses[ i ] == main.FALSE:
3459 # Already in set, probably fine
3460 pass
3461 elif addResponses[ i ] == main.ERROR:
3462 # Error in execution
3463 addResults = main.FALSE
3464 else:
3465 # unexpected result
3466 addResults = main.FALSE
3467 if addResults != main.TRUE:
3468 main.log.error( "Error executing set add" )
3469
3470 # Check if set is still correct
3471 size = len( onosSet )
3472 getResponses = []
3473 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003474 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003475 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003476 name="setTestGet-" + str( i ),
3477 args=[ onosSetName ] )
3478 threads.append( t )
3479 t.start()
3480 for t in threads:
3481 t.join()
3482 getResponses.append( t.result )
3483 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003484 for i in range( len( main.activeNodes ) ):
3485 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003486 if isinstance( getResponses[ i ], list):
3487 current = set( getResponses[ i ] )
3488 if len( current ) == len( getResponses[ i ] ):
3489 # no repeats
3490 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003491 main.log.error( "ONOS" + node + " has incorrect view" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003492 " of set " + onosSetName + ":\n" +
3493 str( getResponses[ i ] ) )
3494 main.log.debug( "Expected: " + str( onosSet ) )
3495 main.log.debug( "Actual: " + str( current ) )
3496 getResults = main.FALSE
3497 else:
3498 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003499 main.log.error( "ONOS" + node + " has repeat elements in" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003500 " set " + onosSetName + ":\n" +
3501 str( getResponses[ i ] ) )
3502 getResults = main.FALSE
3503 elif getResponses[ i ] == main.ERROR:
3504 getResults = main.FALSE
3505 sizeResponses = []
3506 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003507 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003508 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003509 name="setTestSize-" + str( i ),
3510 args=[ onosSetName ] )
3511 threads.append( t )
3512 t.start()
3513 for t in threads:
3514 t.join()
3515 sizeResponses.append( t.result )
3516 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003517 for i in range( len( main.activeNodes ) ):
3518 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003519 if size != sizeResponses[ i ]:
3520 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003521 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003522 " expected a size of " + str( size ) +
3523 " for set " + onosSetName +
3524 " but got " + str( sizeResponses[ i ] ) )
3525 addResults = addResults and getResults and sizeResults
3526 utilities.assert_equals( expect=main.TRUE,
3527 actual=addResults,
3528 onpass="Set add correct",
3529 onfail="Set add was incorrect" )
3530
3531 main.step( "Distributed Set addAll()" )
3532 onosSet.update( addAllValue.split() )
3533 addResponses = []
3534 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003535 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003536 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003537 name="setTestAddAll-" + str( i ),
3538 args=[ onosSetName, addAllValue ] )
3539 threads.append( t )
3540 t.start()
3541 for t in threads:
3542 t.join()
3543 addResponses.append( t.result )
3544
3545 # main.TRUE = successfully changed the set
3546 # main.FALSE = action resulted in no change in set
3547 # main.ERROR - Some error in executing the function
3548 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003549 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003550 if addResponses[ i ] == main.TRUE:
3551 # All is well
3552 pass
3553 elif addResponses[ i ] == main.FALSE:
3554 # Already in set, probably fine
3555 pass
3556 elif addResponses[ i ] == main.ERROR:
3557 # Error in execution
3558 addAllResults = main.FALSE
3559 else:
3560 # unexpected result
3561 addAllResults = main.FALSE
3562 if addAllResults != main.TRUE:
3563 main.log.error( "Error executing set addAll" )
3564
3565 # Check if set is still correct
3566 size = len( onosSet )
3567 getResponses = []
3568 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003569 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003570 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003571 name="setTestGet-" + str( i ),
3572 args=[ onosSetName ] )
3573 threads.append( t )
3574 t.start()
3575 for t in threads:
3576 t.join()
3577 getResponses.append( t.result )
3578 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003579 for i in range( len( main.activeNodes ) ):
3580 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003581 if isinstance( getResponses[ i ], list):
3582 current = set( getResponses[ i ] )
3583 if len( current ) == len( getResponses[ i ] ):
3584 # no repeats
3585 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003586 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003587 " has incorrect view" +
3588 " of set " + onosSetName + ":\n" +
3589 str( getResponses[ i ] ) )
3590 main.log.debug( "Expected: " + str( onosSet ) )
3591 main.log.debug( "Actual: " + str( current ) )
3592 getResults = main.FALSE
3593 else:
3594 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003595 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003596 " has repeat elements in" +
3597 " set " + onosSetName + ":\n" +
3598 str( getResponses[ i ] ) )
3599 getResults = main.FALSE
3600 elif getResponses[ i ] == main.ERROR:
3601 getResults = main.FALSE
3602 sizeResponses = []
3603 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003604 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003605 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003606 name="setTestSize-" + str( i ),
3607 args=[ onosSetName ] )
3608 threads.append( t )
3609 t.start()
3610 for t in threads:
3611 t.join()
3612 sizeResponses.append( t.result )
3613 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003614 for i in range( len( main.activeNodes ) ):
3615 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003616 if size != sizeResponses[ i ]:
3617 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003618 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003619 " expected a size of " + str( size ) +
3620 " for set " + onosSetName +
3621 " but got " + str( sizeResponses[ i ] ) )
3622 addAllResults = addAllResults and getResults and sizeResults
3623 utilities.assert_equals( expect=main.TRUE,
3624 actual=addAllResults,
3625 onpass="Set addAll correct",
3626 onfail="Set addAll was incorrect" )
3627
3628 main.step( "Distributed Set contains()" )
3629 containsResponses = []
3630 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003631 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003632 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003633 name="setContains-" + str( i ),
3634 args=[ onosSetName ],
3635 kwargs={ "values": addValue } )
3636 threads.append( t )
3637 t.start()
3638 for t in threads:
3639 t.join()
3640 # NOTE: This is the tuple
3641 containsResponses.append( t.result )
3642
3643 containsResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003644 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003645 if containsResponses[ i ] == main.ERROR:
3646 containsResults = main.FALSE
3647 else:
3648 containsResults = containsResults and\
3649 containsResponses[ i ][ 1 ]
3650 utilities.assert_equals( expect=main.TRUE,
3651 actual=containsResults,
3652 onpass="Set contains is functional",
3653 onfail="Set contains failed" )
3654
3655 main.step( "Distributed Set containsAll()" )
3656 containsAllResponses = []
3657 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003658 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003659 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003660 name="setContainsAll-" + str( i ),
3661 args=[ onosSetName ],
3662 kwargs={ "values": addAllValue } )
3663 threads.append( t )
3664 t.start()
3665 for t in threads:
3666 t.join()
3667 # NOTE: This is the tuple
3668 containsAllResponses.append( t.result )
3669
3670 containsAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003671 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003672 if containsResponses[ i ] == main.ERROR:
3673 containsResults = main.FALSE
3674 else:
3675 containsResults = containsResults and\
3676 containsResponses[ i ][ 1 ]
3677 utilities.assert_equals( expect=main.TRUE,
3678 actual=containsAllResults,
3679 onpass="Set containsAll is functional",
3680 onfail="Set containsAll failed" )
3681
3682 main.step( "Distributed Set remove()" )
3683 onosSet.remove( addValue )
3684 removeResponses = []
3685 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003686 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003687 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003688 name="setTestRemove-" + str( i ),
3689 args=[ onosSetName, addValue ] )
3690 threads.append( t )
3691 t.start()
3692 for t in threads:
3693 t.join()
3694 removeResponses.append( t.result )
3695
3696 # main.TRUE = successfully changed the set
3697 # main.FALSE = action resulted in no change in set
3698 # main.ERROR - Some error in executing the function
3699 removeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003700 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003701 if removeResponses[ i ] == main.TRUE:
3702 # All is well
3703 pass
3704 elif removeResponses[ i ] == main.FALSE:
3705 # not in set, probably fine
3706 pass
3707 elif removeResponses[ i ] == main.ERROR:
3708 # Error in execution
3709 removeResults = main.FALSE
3710 else:
3711 # unexpected result
3712 removeResults = main.FALSE
3713 if removeResults != main.TRUE:
3714 main.log.error( "Error executing set remove" )
3715
3716 # Check if set is still correct
3717 size = len( onosSet )
3718 getResponses = []
3719 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003720 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003721 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003722 name="setTestGet-" + str( i ),
3723 args=[ onosSetName ] )
3724 threads.append( t )
3725 t.start()
3726 for t in threads:
3727 t.join()
3728 getResponses.append( t.result )
3729 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003730 for i in range( len( main.activeNodes ) ):
3731 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003732 if isinstance( getResponses[ i ], list):
3733 current = set( getResponses[ i ] )
3734 if len( current ) == len( getResponses[ i ] ):
3735 # no repeats
3736 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003737 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003738 " has incorrect view" +
3739 " of set " + onosSetName + ":\n" +
3740 str( getResponses[ i ] ) )
3741 main.log.debug( "Expected: " + str( onosSet ) )
3742 main.log.debug( "Actual: " + str( current ) )
3743 getResults = main.FALSE
3744 else:
3745 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003746 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003747 " has repeat elements in" +
3748 " set " + onosSetName + ":\n" +
3749 str( getResponses[ i ] ) )
3750 getResults = main.FALSE
3751 elif getResponses[ i ] == main.ERROR:
3752 getResults = main.FALSE
3753 sizeResponses = []
3754 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003755 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003756 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003757 name="setTestSize-" + str( i ),
3758 args=[ onosSetName ] )
3759 threads.append( t )
3760 t.start()
3761 for t in threads:
3762 t.join()
3763 sizeResponses.append( t.result )
3764 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003765 for i in range( len( main.activeNodes ) ):
3766 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003767 if size != sizeResponses[ i ]:
3768 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003769 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003770 " expected a size of " + str( size ) +
3771 " for set " + onosSetName +
3772 " but got " + str( sizeResponses[ i ] ) )
3773 removeResults = removeResults and getResults and sizeResults
3774 utilities.assert_equals( expect=main.TRUE,
3775 actual=removeResults,
3776 onpass="Set remove correct",
3777 onfail="Set remove was incorrect" )
3778
3779 main.step( "Distributed Set removeAll()" )
3780 onosSet.difference_update( addAllValue.split() )
3781 removeAllResponses = []
3782 threads = []
3783 try:
Jon Halla440e872016-03-31 15:15:50 -07003784 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003785 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003786 name="setTestRemoveAll-" + str( i ),
3787 args=[ onosSetName, addAllValue ] )
3788 threads.append( t )
3789 t.start()
3790 for t in threads:
3791 t.join()
3792 removeAllResponses.append( t.result )
3793 except Exception, e:
3794 main.log.exception(e)
3795
3796 # main.TRUE = successfully changed the set
3797 # main.FALSE = action resulted in no change in set
3798 # main.ERROR - Some error in executing the function
3799 removeAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003800 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003801 if removeAllResponses[ i ] == main.TRUE:
3802 # All is well
3803 pass
3804 elif removeAllResponses[ i ] == main.FALSE:
3805 # not in set, probably fine
3806 pass
3807 elif removeAllResponses[ i ] == main.ERROR:
3808 # Error in execution
3809 removeAllResults = main.FALSE
3810 else:
3811 # unexpected result
3812 removeAllResults = main.FALSE
3813 if removeAllResults != main.TRUE:
3814 main.log.error( "Error executing set removeAll" )
3815
3816 # Check if set is still correct
3817 size = len( onosSet )
3818 getResponses = []
3819 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003820 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003821 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003822 name="setTestGet-" + str( i ),
3823 args=[ onosSetName ] )
3824 threads.append( t )
3825 t.start()
3826 for t in threads:
3827 t.join()
3828 getResponses.append( t.result )
3829 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003830 for i in range( len( main.activeNodes ) ):
3831 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003832 if isinstance( getResponses[ i ], list):
3833 current = set( getResponses[ i ] )
3834 if len( current ) == len( getResponses[ i ] ):
3835 # no repeats
3836 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003837 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003838 " has incorrect view" +
3839 " of set " + onosSetName + ":\n" +
3840 str( getResponses[ i ] ) )
3841 main.log.debug( "Expected: " + str( onosSet ) )
3842 main.log.debug( "Actual: " + str( current ) )
3843 getResults = main.FALSE
3844 else:
3845 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003846 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003847 " has repeat elements in" +
3848 " set " + onosSetName + ":\n" +
3849 str( getResponses[ i ] ) )
3850 getResults = main.FALSE
3851 elif getResponses[ i ] == main.ERROR:
3852 getResults = main.FALSE
3853 sizeResponses = []
3854 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003855 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003856 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003857 name="setTestSize-" + str( i ),
3858 args=[ onosSetName ] )
3859 threads.append( t )
3860 t.start()
3861 for t in threads:
3862 t.join()
3863 sizeResponses.append( t.result )
3864 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003865 for i in range( len( main.activeNodes ) ):
3866 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003867 if size != sizeResponses[ i ]:
3868 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003869 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003870 " expected a size of " + str( size ) +
3871 " for set " + onosSetName +
3872 " but got " + str( sizeResponses[ i ] ) )
3873 removeAllResults = removeAllResults and getResults and sizeResults
3874 utilities.assert_equals( expect=main.TRUE,
3875 actual=removeAllResults,
3876 onpass="Set removeAll correct",
3877 onfail="Set removeAll was incorrect" )
3878
3879 main.step( "Distributed Set addAll()" )
3880 onosSet.update( addAllValue.split() )
3881 addResponses = []
3882 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003883 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003884 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003885 name="setTestAddAll-" + str( i ),
3886 args=[ onosSetName, addAllValue ] )
3887 threads.append( t )
3888 t.start()
3889 for t in threads:
3890 t.join()
3891 addResponses.append( t.result )
3892
3893 # main.TRUE = successfully changed the set
3894 # main.FALSE = action resulted in no change in set
3895 # main.ERROR - Some error in executing the function
3896 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003897 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003898 if addResponses[ i ] == main.TRUE:
3899 # All is well
3900 pass
3901 elif addResponses[ i ] == main.FALSE:
3902 # Already in set, probably fine
3903 pass
3904 elif addResponses[ i ] == main.ERROR:
3905 # Error in execution
3906 addAllResults = main.FALSE
3907 else:
3908 # unexpected result
3909 addAllResults = main.FALSE
3910 if addAllResults != main.TRUE:
3911 main.log.error( "Error executing set addAll" )
3912
3913 # Check if set is still correct
3914 size = len( onosSet )
3915 getResponses = []
3916 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003917 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003918 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003919 name="setTestGet-" + str( i ),
3920 args=[ onosSetName ] )
3921 threads.append( t )
3922 t.start()
3923 for t in threads:
3924 t.join()
3925 getResponses.append( t.result )
3926 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003927 for i in range( len( main.activeNodes ) ):
3928 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003929 if isinstance( getResponses[ i ], list):
3930 current = set( getResponses[ i ] )
3931 if len( current ) == len( getResponses[ i ] ):
3932 # no repeats
3933 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003934 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003935 " has incorrect view" +
3936 " of set " + onosSetName + ":\n" +
3937 str( getResponses[ i ] ) )
3938 main.log.debug( "Expected: " + str( onosSet ) )
3939 main.log.debug( "Actual: " + str( current ) )
3940 getResults = main.FALSE
3941 else:
3942 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003943 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003944 " has repeat elements in" +
3945 " set " + onosSetName + ":\n" +
3946 str( getResponses[ i ] ) )
3947 getResults = main.FALSE
3948 elif getResponses[ i ] == main.ERROR:
3949 getResults = main.FALSE
3950 sizeResponses = []
3951 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003952 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003953 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003954 name="setTestSize-" + str( i ),
3955 args=[ onosSetName ] )
3956 threads.append( t )
3957 t.start()
3958 for t in threads:
3959 t.join()
3960 sizeResponses.append( t.result )
3961 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003962 for i in range( len( main.activeNodes ) ):
3963 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003964 if size != sizeResponses[ i ]:
3965 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003966 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003967 " expected a size of " + str( size ) +
3968 " for set " + onosSetName +
3969 " but got " + str( sizeResponses[ i ] ) )
3970 addAllResults = addAllResults and getResults and sizeResults
3971 utilities.assert_equals( expect=main.TRUE,
3972 actual=addAllResults,
3973 onpass="Set addAll correct",
3974 onfail="Set addAll was incorrect" )
3975
3976 main.step( "Distributed Set clear()" )
3977 onosSet.clear()
3978 clearResponses = []
3979 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003980 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003981 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003982 name="setTestClear-" + str( i ),
3983 args=[ onosSetName, " "], # Values doesn't matter
3984 kwargs={ "clear": True } )
3985 threads.append( t )
3986 t.start()
3987 for t in threads:
3988 t.join()
3989 clearResponses.append( t.result )
3990
3991 # main.TRUE = successfully changed the set
3992 # main.FALSE = action resulted in no change in set
3993 # main.ERROR - Some error in executing the function
3994 clearResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003995 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003996 if clearResponses[ i ] == main.TRUE:
3997 # All is well
3998 pass
3999 elif clearResponses[ i ] == main.FALSE:
4000 # Nothing set, probably fine
4001 pass
4002 elif clearResponses[ i ] == main.ERROR:
4003 # Error in execution
4004 clearResults = main.FALSE
4005 else:
4006 # unexpected result
4007 clearResults = main.FALSE
4008 if clearResults != main.TRUE:
4009 main.log.error( "Error executing set clear" )
4010
4011 # Check if set is still correct
4012 size = len( onosSet )
4013 getResponses = []
4014 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004015 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004016 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004017 name="setTestGet-" + str( i ),
4018 args=[ onosSetName ] )
4019 threads.append( t )
4020 t.start()
4021 for t in threads:
4022 t.join()
4023 getResponses.append( t.result )
4024 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004025 for i in range( len( main.activeNodes ) ):
4026 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004027 if isinstance( getResponses[ i ], list):
4028 current = set( getResponses[ i ] )
4029 if len( current ) == len( getResponses[ i ] ):
4030 # no repeats
4031 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08004032 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004033 " has incorrect view" +
4034 " of set " + onosSetName + ":\n" +
4035 str( getResponses[ i ] ) )
4036 main.log.debug( "Expected: " + str( onosSet ) )
4037 main.log.debug( "Actual: " + str( current ) )
4038 getResults = main.FALSE
4039 else:
4040 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08004041 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004042 " has repeat elements in" +
4043 " set " + onosSetName + ":\n" +
4044 str( getResponses[ i ] ) )
4045 getResults = main.FALSE
4046 elif getResponses[ i ] == main.ERROR:
4047 getResults = main.FALSE
4048 sizeResponses = []
4049 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004050 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004051 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004052 name="setTestSize-" + str( i ),
4053 args=[ onosSetName ] )
4054 threads.append( t )
4055 t.start()
4056 for t in threads:
4057 t.join()
4058 sizeResponses.append( t.result )
4059 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004060 for i in range( len( main.activeNodes ) ):
4061 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004062 if size != sizeResponses[ i ]:
4063 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08004064 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004065 " expected a size of " + str( size ) +
4066 " for set " + onosSetName +
4067 " but got " + str( sizeResponses[ i ] ) )
4068 clearResults = clearResults and getResults and sizeResults
4069 utilities.assert_equals( expect=main.TRUE,
4070 actual=clearResults,
4071 onpass="Set clear correct",
4072 onfail="Set clear was incorrect" )
4073
4074 main.step( "Distributed Set addAll()" )
4075 onosSet.update( addAllValue.split() )
4076 addResponses = []
4077 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004078 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004079 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004080 name="setTestAddAll-" + str( i ),
4081 args=[ onosSetName, addAllValue ] )
4082 threads.append( t )
4083 t.start()
4084 for t in threads:
4085 t.join()
4086 addResponses.append( t.result )
4087
4088 # main.TRUE = successfully changed the set
4089 # main.FALSE = action resulted in no change in set
4090 # main.ERROR - Some error in executing the function
4091 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004092 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004093 if addResponses[ i ] == main.TRUE:
4094 # All is well
4095 pass
4096 elif addResponses[ i ] == main.FALSE:
4097 # Already in set, probably fine
4098 pass
4099 elif addResponses[ i ] == main.ERROR:
4100 # Error in execution
4101 addAllResults = main.FALSE
4102 else:
4103 # unexpected result
4104 addAllResults = main.FALSE
4105 if addAllResults != main.TRUE:
4106 main.log.error( "Error executing set addAll" )
4107
4108 # Check if set is still correct
4109 size = len( onosSet )
4110 getResponses = []
4111 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004112 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004113 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004114 name="setTestGet-" + str( i ),
4115 args=[ onosSetName ] )
4116 threads.append( t )
4117 t.start()
4118 for t in threads:
4119 t.join()
4120 getResponses.append( t.result )
4121 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004122 for i in range( len( main.activeNodes ) ):
4123 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004124 if isinstance( getResponses[ i ], list):
4125 current = set( getResponses[ i ] )
4126 if len( current ) == len( getResponses[ i ] ):
4127 # no repeats
4128 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08004129 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004130 " has incorrect view" +
4131 " of set " + onosSetName + ":\n" +
4132 str( getResponses[ i ] ) )
4133 main.log.debug( "Expected: " + str( onosSet ) )
4134 main.log.debug( "Actual: " + str( current ) )
4135 getResults = main.FALSE
4136 else:
4137 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08004138 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004139 " has repeat elements in" +
4140 " set " + onosSetName + ":\n" +
4141 str( getResponses[ i ] ) )
4142 getResults = main.FALSE
4143 elif getResponses[ i ] == main.ERROR:
4144 getResults = main.FALSE
4145 sizeResponses = []
4146 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004147 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004148 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004149 name="setTestSize-" + str( i ),
4150 args=[ onosSetName ] )
4151 threads.append( t )
4152 t.start()
4153 for t in threads:
4154 t.join()
4155 sizeResponses.append( t.result )
4156 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004157 for i in range( len( main.activeNodes ) ):
4158 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004159 if size != sizeResponses[ i ]:
4160 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08004161 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004162 " expected a size of " + str( size ) +
4163 " for set " + onosSetName +
4164 " but got " + str( sizeResponses[ i ] ) )
4165 addAllResults = addAllResults and getResults and sizeResults
4166 utilities.assert_equals( expect=main.TRUE,
4167 actual=addAllResults,
4168 onpass="Set addAll correct",
4169 onfail="Set addAll was incorrect" )
4170
4171 main.step( "Distributed Set retain()" )
4172 onosSet.intersection_update( retainValue.split() )
4173 retainResponses = []
4174 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004175 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004176 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004177 name="setTestRetain-" + str( i ),
4178 args=[ onosSetName, retainValue ],
4179 kwargs={ "retain": True } )
4180 threads.append( t )
4181 t.start()
4182 for t in threads:
4183 t.join()
4184 retainResponses.append( t.result )
4185
4186 # main.TRUE = successfully changed the set
4187 # main.FALSE = action resulted in no change in set
4188 # main.ERROR - Some error in executing the function
4189 retainResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004190 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004191 if retainResponses[ i ] == main.TRUE:
4192 # All is well
4193 pass
4194 elif retainResponses[ i ] == main.FALSE:
4195 # Already in set, probably fine
4196 pass
4197 elif retainResponses[ i ] == main.ERROR:
4198 # Error in execution
4199 retainResults = main.FALSE
4200 else:
4201 # unexpected result
4202 retainResults = main.FALSE
4203 if retainResults != main.TRUE:
4204 main.log.error( "Error executing set retain" )
4205
4206 # Check if set is still correct
4207 size = len( onosSet )
4208 getResponses = []
4209 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004210 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004211 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004212 name="setTestGet-" + str( i ),
4213 args=[ onosSetName ] )
4214 threads.append( t )
4215 t.start()
4216 for t in threads:
4217 t.join()
4218 getResponses.append( t.result )
4219 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004220 for i in range( len( main.activeNodes ) ):
4221 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004222 if isinstance( getResponses[ i ], list):
4223 current = set( getResponses[ i ] )
4224 if len( current ) == len( getResponses[ i ] ):
4225 # no repeats
4226 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08004227 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004228 " has incorrect view" +
4229 " of set " + onosSetName + ":\n" +
4230 str( getResponses[ i ] ) )
4231 main.log.debug( "Expected: " + str( onosSet ) )
4232 main.log.debug( "Actual: " + str( current ) )
4233 getResults = main.FALSE
4234 else:
4235 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08004236 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004237 " has repeat elements in" +
4238 " set " + onosSetName + ":\n" +
4239 str( getResponses[ i ] ) )
4240 getResults = main.FALSE
4241 elif getResponses[ i ] == main.ERROR:
4242 getResults = main.FALSE
4243 sizeResponses = []
4244 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004245 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004246 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004247 name="setTestSize-" + str( i ),
4248 args=[ onosSetName ] )
4249 threads.append( t )
4250 t.start()
4251 for t in threads:
4252 t.join()
4253 sizeResponses.append( t.result )
4254 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004255 for i in range( len( main.activeNodes ) ):
4256 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004257 if size != sizeResponses[ i ]:
4258 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08004259 main.log.error( "ONOS" + node + " expected a size of " +
Jon Hall5cf14d52015-07-16 12:15:19 -07004260 str( size ) + " for set " + onosSetName +
4261 " but got " + str( sizeResponses[ i ] ) )
4262 retainResults = retainResults and getResults and sizeResults
4263 utilities.assert_equals( expect=main.TRUE,
4264 actual=retainResults,
4265 onpass="Set retain correct",
4266 onfail="Set retain was incorrect" )
4267
Jon Hall2a5002c2015-08-21 16:49:11 -07004268 # Transactional maps
4269 main.step( "Partitioned Transactional maps put" )
4270 tMapValue = "Testing"
4271 numKeys = 100
4272 putResult = True
Jon Halla440e872016-03-31 15:15:50 -07004273 node = main.activeNodes[0]
4274 putResponses = main.CLIs[node].transactionalMapPut( numKeys, tMapValue )
Jon Hall6e709752016-02-01 13:38:46 -08004275 if putResponses and len( putResponses ) == 100:
Jon Hall2a5002c2015-08-21 16:49:11 -07004276 for i in putResponses:
4277 if putResponses[ i ][ 'value' ] != tMapValue:
4278 putResult = False
4279 else:
4280 putResult = False
4281 if not putResult:
4282 main.log.debug( "Put response values: " + str( putResponses ) )
4283 utilities.assert_equals( expect=True,
4284 actual=putResult,
4285 onpass="Partitioned Transactional Map put successful",
4286 onfail="Partitioned Transactional Map put values are incorrect" )
4287
4288 main.step( "Partitioned Transactional maps get" )
4289 getCheck = True
4290 for n in range( 1, numKeys + 1 ):
4291 getResponses = []
4292 threads = []
4293 valueCheck = True
Jon Halla440e872016-03-31 15:15:50 -07004294 for i in main.activeNodes:
Jon Hall2a5002c2015-08-21 16:49:11 -07004295 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4296 name="TMap-get-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08004297 args=[ "Key" + str( n ) ] )
Jon Hall2a5002c2015-08-21 16:49:11 -07004298 threads.append( t )
4299 t.start()
4300 for t in threads:
4301 t.join()
4302 getResponses.append( t.result )
4303 for node in getResponses:
4304 if node != tMapValue:
4305 valueCheck = False
4306 if not valueCheck:
4307 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4308 main.log.warn( getResponses )
4309 getCheck = getCheck and valueCheck
4310 utilities.assert_equals( expect=True,
4311 actual=getCheck,
4312 onpass="Partitioned Transactional Map get values were correct",
4313 onfail="Partitioned Transactional Map values incorrect" )