blob: cb40b4f0f9db6e466d65e70c02f1b99f3e02d694 [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
Jon Halla440e872016-03-31 15:15:50 -0700253 main.step( "Checking ONOS nodes" )
254 nodesOutput = []
255 nodeResults = main.TRUE
256 threads = []
257 for i in main.activeNodes:
258 t = main.Thread( target=main.CLIs[i].nodes,
259 name="nodes-" + str( i ),
260 args=[ ] )
261 threads.append( t )
262 t.start()
263
264 for t in threads:
265 t.join()
266 nodesOutput.append( t.result )
267 ips = [ main.nodes[node].ip_address for node in main.activeNodes ]
268 ips.sort()
269 for i in nodesOutput:
270 try:
271 current = json.loads( i )
272 activeIps = []
273 currentResult = main.FALSE
274 for node in current:
275 if node['state'] == 'READY':
276 activeIps.append( node['ip'] )
277 activeIps.sort()
278 if ips == activeIps:
279 currentResult = main.TRUE
280 except ( ValueError, TypeError ):
281 main.log.error( "Error parsing nodes output" )
282 main.log.warn( repr( i ) )
283 currentResult = main.FALSE
284 nodeResults = nodeResults and currentResult
285 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
286 onpass="Nodes check successful",
287 onfail="Nodes check NOT successful" )
288
289 if not nodeResults:
290 for cli in main.CLIs:
291 main.log.debug( "{} components not ACTIVE: \n{}".format(
292 cli.name,
293 cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
294
Jon Hall5cf14d52015-07-16 12:15:19 -0700295 if cliResults == main.FALSE:
296 main.log.error( "Failed to start ONOS, stopping test" )
297 main.cleanup()
298 main.exit()
299
Jon Hall172b7ba2016-04-07 18:12:20 -0700300 main.step( "Activate apps defined in the params file" )
301 # get data from the params
302 apps = main.params.get( 'apps' )
303 if apps:
304 apps = apps.split(',')
305 main.log.warn( apps )
306 activateResult = True
307 for app in apps:
308 main.CLIs[ 0 ].app( app, "Activate" )
309 # TODO: check this worked
310 time.sleep( 10 ) # wait for apps to activate
311 for app in apps:
312 state = main.CLIs[ 0 ].appStatus( app )
313 if state == "ACTIVE":
314 activateResult = activeResult and True
315 else:
316 main.log.error( "{} is in {} state".format( app, state ) )
317 activeResult = False
318 utilities.assert_equals( expect=True,
319 actual=activateResult,
320 onpass="Successfully activated apps",
321 onfail="Failed to activate apps" )
322 else:
323 main.log.warn( "No apps were specified to be loaded after startup" )
324
325 main.step( "Set ONOS configurations" )
326 config = main.params.get( 'ONOS_Configuration' )
327 if config:
328 main.log.debug( config )
329 checkResult = main.TRUE
330 for component in config:
331 for setting in config[component]:
332 value = config[component][setting]
333 check = main.CLIs[ 0 ].setCfg( component, setting, value )
334 main.log.info( "Value was changed? {}".format( main.TRUE == check ) )
335 checkResult = check and checkResult
336 utilities.assert_equals( expect=main.TRUE,
337 actual=checkResult,
338 onpass="Successfully set config",
339 onfail="Failed to set config" )
340 else:
341 main.log.warn( "No configurations were specified to be changed after startup" )
342
Jon Hall9d2dcad2016-04-08 10:15:20 -0700343 main.step( "App Ids check" )
344 appCheck = main.TRUE
345 threads = []
346 for i in main.activeNodes:
347 t = main.Thread( target=main.CLIs[i].appToIDCheck,
348 name="appToIDCheck-" + str( i ),
349 args=[] )
350 threads.append( t )
351 t.start()
352
353 for t in threads:
354 t.join()
355 appCheck = appCheck and t.result
356 if appCheck != main.TRUE:
357 node = main.activeNodes[0]
358 main.log.warn( main.CLIs[node].apps() )
359 main.log.warn( main.CLIs[node].appIDs() )
360 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
361 onpass="App Ids seem to be correct",
362 onfail="Something is wrong with app Ids" )
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"
Jon Hall5cf14d52015-07-16 12:15:19 -0700973
974 main.step( "Check Intent state" )
975 installedCheck = False
976 loopCount = 0
977 while not installedCheck and loopCount < 40:
978 installedCheck = True
979 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -0700980 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700981 intentStates = []
982 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700983 count = 0
Jon Hall5cf14d52015-07-16 12:15:19 -0700984 # Iter through intents of a node
985 try:
986 for intent in json.loads( intents ):
987 state = intent.get( 'state', None )
988 if "INSTALLED" not in state:
989 installedCheck = False
990 intentId = intent.get( 'id', None )
991 intentStates.append( ( intentId, state ) )
992 except ( ValueError, TypeError ):
993 main.log.exception( "Error parsing intents." )
994 # Print states
995 intentStates.sort()
996 for i, s in intentStates:
997 count += 1
998 main.log.info( "%-6s%-15s%-15s" %
999 ( str( count ), str( i ), str( s ) ) )
1000 if not installedCheck:
1001 time.sleep( 1 )
1002 loopCount += 1
1003 utilities.assert_equals( expect=True, actual=installedCheck,
1004 onpass="Intents are all INSTALLED",
1005 onfail="Intents are not all in " +
1006 "INSTALLED state" )
1007
Jon Hall9d2dcad2016-04-08 10:15:20 -07001008 main.step( "Ping across added host intents" )
1009 onosCli = main.CLIs[ main.activeNodes[0] ]
1010 PingResult = main.TRUE
1011 for i in range( 8, 18 ):
1012 ping = main.Mininet1.pingHost( src="h" + str( i ),
1013 target="h" + str( i + 10 ) )
1014 PingResult = PingResult and ping
1015 if ping == main.FALSE:
1016 main.log.warn( "Ping failed between h" + str( i ) +
1017 " and h" + str( i + 10 ) )
1018 elif ping == main.TRUE:
1019 main.log.info( "Ping test passed!" )
1020 # Don't set PingResult or you'd override failures
1021 if PingResult == main.FALSE:
1022 main.log.error(
1023 "Intents have not been installed correctly, pings failed." )
1024 # TODO: pretty print
1025 main.log.warn( "ONOS1 intents: " )
1026 try:
1027 tmpIntents = onosCli.intents()
1028 main.log.warn( json.dumps( json.loads( tmpIntents ),
1029 sort_keys=True,
1030 indent=4,
1031 separators=( ',', ': ' ) ) )
1032 except ( ValueError, TypeError ):
1033 main.log.warn( repr( tmpIntents ) )
1034 utilities.assert_equals(
1035 expect=main.TRUE,
1036 actual=PingResult,
1037 onpass="Intents have been installed correctly and pings work",
1038 onfail="Intents have not been installed correctly, pings failed." )
1039
Jon Hall5cf14d52015-07-16 12:15:19 -07001040 main.step( "Check leadership of topics" )
Jon Halla440e872016-03-31 15:15:50 -07001041 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -07001042 topicCheck = main.TRUE
1043 try:
1044 if leaders:
1045 parsedLeaders = json.loads( leaders )
1046 main.log.warn( json.dumps( parsedLeaders,
1047 sort_keys=True,
1048 indent=4,
1049 separators=( ',', ': ' ) ) )
1050 # check for all intent partitions
1051 # check for election
1052 # TODO: Look at Devices as topics now that it uses this system
1053 topics = []
1054 for i in range( 14 ):
1055 topics.append( "intent-partition-" + str( i ) )
1056 # FIXME: this should only be after we start the app
1057 # FIXME: topics.append( "org.onosproject.election" )
1058 # Print leaders output
1059 main.log.debug( topics )
1060 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1061 for topic in topics:
1062 if topic not in ONOStopics:
1063 main.log.error( "Error: " + topic +
1064 " not in leaders" )
1065 topicCheck = main.FALSE
1066 else:
1067 main.log.error( "leaders() returned None" )
1068 topicCheck = main.FALSE
1069 except ( ValueError, TypeError ):
1070 topicCheck = main.FALSE
1071 main.log.exception( "Error parsing leaders" )
1072 main.log.error( repr( leaders ) )
1073 # TODO: Check for a leader of these topics
1074 # Check all nodes
1075 if topicCheck:
Jon Halla440e872016-03-31 15:15:50 -07001076 for i in main.activeNodes:
1077 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07001078 response = node.leaders( jsonFormat=False)
1079 main.log.warn( str( node.name ) + " leaders output: \n" +
1080 str( response ) )
1081
1082 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
1083 onpass="intent Partitions is in leaders",
1084 onfail="Some topics were lost " )
1085 # Print partitions
Jon Halla440e872016-03-31 15:15:50 -07001086 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -07001087 try:
1088 if partitions :
1089 parsedPartitions = json.loads( partitions )
1090 main.log.warn( json.dumps( parsedPartitions,
1091 sort_keys=True,
1092 indent=4,
1093 separators=( ',', ': ' ) ) )
1094 # TODO check for a leader in all paritions
1095 # TODO check for consistency among nodes
1096 else:
1097 main.log.error( "partitions() returned None" )
1098 except ( ValueError, TypeError ):
1099 main.log.exception( "Error parsing partitions" )
1100 main.log.error( repr( partitions ) )
1101 # Print Pending Map
Jon Halla440e872016-03-31 15:15:50 -07001102 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -07001103 try:
1104 if pendingMap :
1105 parsedPending = json.loads( pendingMap )
1106 main.log.warn( json.dumps( parsedPending,
1107 sort_keys=True,
1108 indent=4,
1109 separators=( ',', ': ' ) ) )
1110 # TODO check something here?
1111 else:
1112 main.log.error( "pendingMap() returned None" )
1113 except ( ValueError, TypeError ):
1114 main.log.exception( "Error parsing pending map" )
1115 main.log.error( repr( pendingMap ) )
1116
1117 if not installedCheck:
1118 main.log.info( "Waiting 60 seconds to see if the state of " +
1119 "intents change" )
1120 time.sleep( 60 )
1121 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -07001122 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -07001123 intentStates = []
1124 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
1125 count = 0
1126 # Iter through intents of a node
1127 try:
1128 for intent in json.loads( intents ):
1129 state = intent.get( 'state', None )
1130 if "INSTALLED" not in state:
1131 installedCheck = False
1132 intentId = intent.get( 'id', None )
1133 intentStates.append( ( intentId, state ) )
1134 except ( ValueError, TypeError ):
1135 main.log.exception( "Error parsing intents." )
1136 intentStates.sort()
1137 for i, s in intentStates:
1138 count += 1
1139 main.log.info( "%-6s%-15s%-15s" %
1140 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -07001141 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -07001142 try:
1143 missing = False
1144 if leaders:
1145 parsedLeaders = json.loads( leaders )
1146 main.log.warn( json.dumps( parsedLeaders,
1147 sort_keys=True,
1148 indent=4,
1149 separators=( ',', ': ' ) ) )
1150 # check for all intent partitions
1151 # check for election
1152 topics = []
1153 for i in range( 14 ):
1154 topics.append( "intent-partition-" + str( i ) )
1155 # FIXME: this should only be after we start the app
1156 topics.append( "org.onosproject.election" )
1157 main.log.debug( topics )
1158 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1159 for topic in topics:
1160 if topic not in ONOStopics:
1161 main.log.error( "Error: " + topic +
1162 " not in leaders" )
1163 missing = True
1164 else:
1165 main.log.error( "leaders() returned None" )
1166 except ( ValueError, TypeError ):
1167 main.log.exception( "Error parsing leaders" )
1168 main.log.error( repr( leaders ) )
1169 if missing:
Jon Halla440e872016-03-31 15:15:50 -07001170 for i in main.activeNodes:
1171 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07001172 response = node.leaders( jsonFormat=False)
1173 main.log.warn( str( node.name ) + " leaders output: \n" +
1174 str( response ) )
1175
Jon Halla440e872016-03-31 15:15:50 -07001176 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -07001177 try:
1178 if partitions :
1179 parsedPartitions = json.loads( partitions )
1180 main.log.warn( json.dumps( parsedPartitions,
1181 sort_keys=True,
1182 indent=4,
1183 separators=( ',', ': ' ) ) )
1184 # TODO check for a leader in all paritions
1185 # TODO check for consistency among nodes
1186 else:
1187 main.log.error( "partitions() returned None" )
1188 except ( ValueError, TypeError ):
1189 main.log.exception( "Error parsing partitions" )
1190 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -07001191 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -07001192 try:
1193 if pendingMap :
1194 parsedPending = json.loads( pendingMap )
1195 main.log.warn( json.dumps( parsedPending,
1196 sort_keys=True,
1197 indent=4,
1198 separators=( ',', ': ' ) ) )
1199 # TODO check something here?
1200 else:
1201 main.log.error( "pendingMap() returned None" )
1202 except ( ValueError, TypeError ):
1203 main.log.exception( "Error parsing pending map" )
1204 main.log.error( repr( pendingMap ) )
1205 # Print flowrules
Jon Halla440e872016-03-31 15:15:50 -07001206 node = main.activeNodes[0]
1207 main.log.debug( main.CLIs[node].flows( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001208 main.step( "Wait a minute then ping again" )
1209 # the wait is above
1210 PingResult = main.TRUE
1211 for i in range( 8, 18 ):
1212 ping = main.Mininet1.pingHost( src="h" + str( i ),
1213 target="h" + str( i + 10 ) )
1214 PingResult = PingResult and ping
1215 if ping == main.FALSE:
1216 main.log.warn( "Ping failed between h" + str( i ) +
1217 " and h" + str( i + 10 ) )
1218 elif ping == main.TRUE:
1219 main.log.info( "Ping test passed!" )
1220 # Don't set PingResult or you'd override failures
1221 if PingResult == main.FALSE:
1222 main.log.error(
1223 "Intents have not been installed correctly, pings failed." )
1224 # TODO: pretty print
1225 main.log.warn( "ONOS1 intents: " )
1226 try:
Jon Halla440e872016-03-31 15:15:50 -07001227 tmpIntents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -07001228 main.log.warn( json.dumps( json.loads( tmpIntents ),
1229 sort_keys=True,
1230 indent=4,
1231 separators=( ',', ': ' ) ) )
1232 except ( ValueError, TypeError ):
1233 main.log.warn( repr( tmpIntents ) )
1234 utilities.assert_equals(
1235 expect=main.TRUE,
1236 actual=PingResult,
1237 onpass="Intents have been installed correctly and pings work",
1238 onfail="Intents have not been installed correctly, pings failed." )
1239
1240 def CASE5( self, main ):
1241 """
1242 Reading state of ONOS
1243 """
1244 import json
1245 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001246 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001247 assert main, "main not defined"
1248 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001249 assert main.CLIs, "main.CLIs not defined"
1250 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001251
1252 main.case( "Setting up and gathering data for current state" )
1253 # The general idea for this test case is to pull the state of
1254 # ( intents,flows, topology,... ) from each ONOS node
1255 # We can then compare them with each other and also with past states
1256
1257 main.step( "Check that each switch has a master" )
1258 global mastershipState
1259 mastershipState = '[]'
1260
1261 # Assert that each device has a master
1262 rolesNotNull = main.TRUE
1263 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001264 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001265 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001266 name="rolesNotNull-" + str( i ),
1267 args=[] )
1268 threads.append( t )
1269 t.start()
1270
1271 for t in threads:
1272 t.join()
1273 rolesNotNull = rolesNotNull and t.result
1274 utilities.assert_equals(
1275 expect=main.TRUE,
1276 actual=rolesNotNull,
1277 onpass="Each device has a master",
1278 onfail="Some devices don't have a master assigned" )
1279
1280 main.step( "Get the Mastership of each switch from each controller" )
1281 ONOSMastership = []
1282 mastershipCheck = main.FALSE
1283 consistentMastership = True
1284 rolesResults = True
1285 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001286 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001287 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001288 name="roles-" + str( i ),
1289 args=[] )
1290 threads.append( t )
1291 t.start()
1292
1293 for t in threads:
1294 t.join()
1295 ONOSMastership.append( t.result )
1296
Jon Halla440e872016-03-31 15:15:50 -07001297 for i in range( len( ONOSMastership ) ):
1298 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001299 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Halla440e872016-03-31 15:15:50 -07001300 main.log.error( "Error in getting ONOS" + node + " roles" )
1301 main.log.warn( "ONOS" + node + " mastership response: " +
1302 repr( ONOSMastership[i] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001303 rolesResults = False
1304 utilities.assert_equals(
1305 expect=True,
1306 actual=rolesResults,
1307 onpass="No error in reading roles output",
1308 onfail="Error in reading roles from ONOS" )
1309
1310 main.step( "Check for consistency in roles from each controller" )
1311 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1312 main.log.info(
1313 "Switch roles are consistent across all ONOS nodes" )
1314 else:
1315 consistentMastership = False
1316 utilities.assert_equals(
1317 expect=True,
1318 actual=consistentMastership,
1319 onpass="Switch roles are consistent across all ONOS nodes",
1320 onfail="ONOS nodes have different views of switch roles" )
1321
1322 if rolesResults and not consistentMastership:
Jon Halla440e872016-03-31 15:15:50 -07001323 for i in range( len( main.activeNodes ) ):
1324 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001325 try:
1326 main.log.warn(
Jon Halla440e872016-03-31 15:15:50 -07001327 "ONOS" + node + " roles: ",
Jon Hall5cf14d52015-07-16 12:15:19 -07001328 json.dumps(
1329 json.loads( ONOSMastership[ i ] ),
1330 sort_keys=True,
1331 indent=4,
1332 separators=( ',', ': ' ) ) )
1333 except ( ValueError, TypeError ):
1334 main.log.warn( repr( ONOSMastership[ i ] ) )
1335 elif rolesResults and consistentMastership:
1336 mastershipCheck = main.TRUE
1337 mastershipState = ONOSMastership[ 0 ]
1338
1339 main.step( "Get the intents from each controller" )
1340 global intentState
1341 intentState = []
1342 ONOSIntents = []
1343 intentCheck = main.FALSE
1344 consistentIntents = True
1345 intentsResults = True
1346 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001347 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001348 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001349 name="intents-" + str( i ),
1350 args=[],
1351 kwargs={ 'jsonFormat': True } )
1352 threads.append( t )
1353 t.start()
1354
1355 for t in threads:
1356 t.join()
1357 ONOSIntents.append( t.result )
1358
Jon Halla440e872016-03-31 15:15:50 -07001359 for i in range( len( ONOSIntents ) ):
1360 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001361 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall6e709752016-02-01 13:38:46 -08001362 main.log.error( "Error in getting ONOS" + node + " intents" )
1363 main.log.warn( "ONOS" + node + " intents response: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07001364 repr( ONOSIntents[ i ] ) )
1365 intentsResults = False
1366 utilities.assert_equals(
1367 expect=True,
1368 actual=intentsResults,
1369 onpass="No error in reading intents output",
1370 onfail="Error in reading intents from ONOS" )
1371
1372 main.step( "Check for consistency in Intents from each controller" )
1373 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1374 main.log.info( "Intents are consistent across all ONOS " +
1375 "nodes" )
1376 else:
1377 consistentIntents = False
1378 main.log.error( "Intents not consistent" )
1379 utilities.assert_equals(
1380 expect=True,
1381 actual=consistentIntents,
1382 onpass="Intents are consistent across all ONOS nodes",
1383 onfail="ONOS nodes have different views of intents" )
1384
1385 if intentsResults:
1386 # Try to make it easy to figure out what is happening
1387 #
1388 # Intent ONOS1 ONOS2 ...
1389 # 0x01 INSTALLED INSTALLING
1390 # ... ... ...
1391 # ... ... ...
1392 title = " Id"
Jon Halla440e872016-03-31 15:15:50 -07001393 for n in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001394 title += " " * 10 + "ONOS" + str( n + 1 )
1395 main.log.warn( title )
1396 # get all intent keys in the cluster
1397 keys = []
Jon Halla440e872016-03-31 15:15:50 -07001398 try:
1399 # Get the set of all intent keys
Jon Hall5cf14d52015-07-16 12:15:19 -07001400 for nodeStr in ONOSIntents:
1401 node = json.loads( nodeStr )
1402 for intent in node:
Jon Halla440e872016-03-31 15:15:50 -07001403 keys.append( intent.get( 'id' ) )
1404 keys = set( keys )
1405 # For each intent key, print the state on each node
1406 for key in keys:
1407 row = "%-13s" % key
1408 for nodeStr in ONOSIntents:
1409 node = json.loads( nodeStr )
1410 for intent in node:
1411 if intent.get( 'id', "Error" ) == key:
1412 row += "%-15s" % intent.get( 'state' )
1413 main.log.warn( row )
1414 # End of intent state table
1415 except ValueError as e:
1416 main.log.exception( e )
1417 main.log.debug( "nodeStr was: " + repr( nodeStr ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001418
1419 if intentsResults and not consistentIntents:
1420 # print the json objects
Jon Halla440e872016-03-31 15:15:50 -07001421 n = str( main.activeNodes[-1] + 1 )
1422 main.log.debug( "ONOS" + n + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07001423 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1424 sort_keys=True,
1425 indent=4,
1426 separators=( ',', ': ' ) ) )
Jon Halla440e872016-03-31 15:15:50 -07001427 for i in range( len( ONOSIntents ) ):
1428 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001429 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
Jon Halla440e872016-03-31 15:15:50 -07001430 main.log.debug( "ONOS" + node + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07001431 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1432 sort_keys=True,
1433 indent=4,
1434 separators=( ',', ': ' ) ) )
1435 else:
Jon Halla440e872016-03-31 15:15:50 -07001436 main.log.debug( "ONOS" + node + " intents match ONOS" +
1437 n + " intents" )
Jon Hall5cf14d52015-07-16 12:15:19 -07001438 elif intentsResults and consistentIntents:
1439 intentCheck = main.TRUE
1440 intentState = ONOSIntents[ 0 ]
1441
1442 main.step( "Get the flows from each controller" )
1443 global flowState
1444 flowState = []
1445 ONOSFlows = []
1446 ONOSFlowsJson = []
1447 flowCheck = main.FALSE
1448 consistentFlows = True
1449 flowsResults = True
1450 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001451 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001452 t = main.Thread( target=main.CLIs[i].flows,
Jon Hall5cf14d52015-07-16 12:15:19 -07001453 name="flows-" + str( i ),
1454 args=[],
1455 kwargs={ 'jsonFormat': True } )
1456 threads.append( t )
1457 t.start()
1458
1459 # NOTE: Flows command can take some time to run
1460 time.sleep(30)
1461 for t in threads:
1462 t.join()
1463 result = t.result
1464 ONOSFlows.append( result )
1465
Jon Halla440e872016-03-31 15:15:50 -07001466 for i in range( len( ONOSFlows ) ):
1467 num = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001468 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1469 main.log.error( "Error in getting ONOS" + num + " flows" )
1470 main.log.warn( "ONOS" + num + " flows response: " +
1471 repr( ONOSFlows[ i ] ) )
1472 flowsResults = False
1473 ONOSFlowsJson.append( None )
1474 else:
1475 try:
1476 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1477 except ( ValueError, TypeError ):
1478 # FIXME: change this to log.error?
1479 main.log.exception( "Error in parsing ONOS" + num +
1480 " response as json." )
1481 main.log.error( repr( ONOSFlows[ i ] ) )
1482 ONOSFlowsJson.append( None )
1483 flowsResults = False
1484 utilities.assert_equals(
1485 expect=True,
1486 actual=flowsResults,
1487 onpass="No error in reading flows output",
1488 onfail="Error in reading flows from ONOS" )
1489
1490 main.step( "Check for consistency in Flows from each controller" )
1491 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1492 if all( tmp ):
1493 main.log.info( "Flow count is consistent across all ONOS nodes" )
1494 else:
1495 consistentFlows = False
1496 utilities.assert_equals(
1497 expect=True,
1498 actual=consistentFlows,
1499 onpass="The flow count is consistent across all ONOS nodes",
1500 onfail="ONOS nodes have different flow counts" )
1501
1502 if flowsResults and not consistentFlows:
Jon Halla440e872016-03-31 15:15:50 -07001503 for i in range( len( ONOSFlows ) ):
1504 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001505 try:
1506 main.log.warn(
Jon Halla440e872016-03-31 15:15:50 -07001507 "ONOS" + node + " flows: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07001508 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1509 indent=4, separators=( ',', ': ' ) ) )
1510 except ( ValueError, TypeError ):
Jon Halla440e872016-03-31 15:15:50 -07001511 main.log.warn( "ONOS" + node + " flows: " +
1512 repr( ONOSFlows[ i ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001513 elif flowsResults and consistentFlows:
1514 flowCheck = main.TRUE
1515 flowState = ONOSFlows[ 0 ]
1516
1517 main.step( "Get the OF Table entries" )
1518 global flows
1519 flows = []
1520 for i in range( 1, 29 ):
Jon Halla440e872016-03-31 15:15:50 -07001521 flows.append( main.Mininet1.getFlowTable( "s" + str( i ), version="1.3", debug=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001522 if flowCheck == main.FALSE:
1523 for table in flows:
1524 main.log.warn( table )
1525 # TODO: Compare switch flow tables with ONOS flow tables
1526
1527 main.step( "Start continuous pings" )
1528 main.Mininet2.pingLong(
1529 src=main.params[ 'PING' ][ 'source1' ],
1530 target=main.params[ 'PING' ][ 'target1' ],
1531 pingTime=500 )
1532 main.Mininet2.pingLong(
1533 src=main.params[ 'PING' ][ 'source2' ],
1534 target=main.params[ 'PING' ][ 'target2' ],
1535 pingTime=500 )
1536 main.Mininet2.pingLong(
1537 src=main.params[ 'PING' ][ 'source3' ],
1538 target=main.params[ 'PING' ][ 'target3' ],
1539 pingTime=500 )
1540 main.Mininet2.pingLong(
1541 src=main.params[ 'PING' ][ 'source4' ],
1542 target=main.params[ 'PING' ][ 'target4' ],
1543 pingTime=500 )
1544 main.Mininet2.pingLong(
1545 src=main.params[ 'PING' ][ 'source5' ],
1546 target=main.params[ 'PING' ][ 'target5' ],
1547 pingTime=500 )
1548 main.Mininet2.pingLong(
1549 src=main.params[ 'PING' ][ 'source6' ],
1550 target=main.params[ 'PING' ][ 'target6' ],
1551 pingTime=500 )
1552 main.Mininet2.pingLong(
1553 src=main.params[ 'PING' ][ 'source7' ],
1554 target=main.params[ 'PING' ][ 'target7' ],
1555 pingTime=500 )
1556 main.Mininet2.pingLong(
1557 src=main.params[ 'PING' ][ 'source8' ],
1558 target=main.params[ 'PING' ][ 'target8' ],
1559 pingTime=500 )
1560 main.Mininet2.pingLong(
1561 src=main.params[ 'PING' ][ 'source9' ],
1562 target=main.params[ 'PING' ][ 'target9' ],
1563 pingTime=500 )
1564 main.Mininet2.pingLong(
1565 src=main.params[ 'PING' ][ 'source10' ],
1566 target=main.params[ 'PING' ][ 'target10' ],
1567 pingTime=500 )
1568
1569 main.step( "Collecting topology information from ONOS" )
1570 devices = []
1571 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001572 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001573 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07001574 name="devices-" + str( i ),
1575 args=[ ] )
1576 threads.append( t )
1577 t.start()
1578
1579 for t in threads:
1580 t.join()
1581 devices.append( t.result )
1582 hosts = []
1583 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001584 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001585 t = main.Thread( target=main.CLIs[i].hosts,
Jon Hall5cf14d52015-07-16 12:15:19 -07001586 name="hosts-" + str( i ),
1587 args=[ ] )
1588 threads.append( t )
1589 t.start()
1590
1591 for t in threads:
1592 t.join()
1593 try:
1594 hosts.append( json.loads( t.result ) )
1595 except ( ValueError, TypeError ):
1596 # FIXME: better handling of this, print which node
1597 # Maybe use thread name?
1598 main.log.exception( "Error parsing json output of hosts" )
Jon Hall3afe4c92015-12-14 19:30:38 -08001599 main.log.warn( repr( t.result ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001600 hosts.append( None )
1601
1602 ports = []
1603 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001604 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001605 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07001606 name="ports-" + str( i ),
1607 args=[ ] )
1608 threads.append( t )
1609 t.start()
1610
1611 for t in threads:
1612 t.join()
1613 ports.append( t.result )
1614 links = []
1615 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001616 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001617 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07001618 name="links-" + str( i ),
1619 args=[ ] )
1620 threads.append( t )
1621 t.start()
1622
1623 for t in threads:
1624 t.join()
1625 links.append( t.result )
1626 clusters = []
1627 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001628 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001629 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07001630 name="clusters-" + str( i ),
1631 args=[ ] )
1632 threads.append( t )
1633 t.start()
1634
1635 for t in threads:
1636 t.join()
1637 clusters.append( t.result )
1638 # Compare json objects for hosts and dataplane clusters
1639
1640 # hosts
1641 main.step( "Host view is consistent across ONOS nodes" )
1642 consistentHostsResult = main.TRUE
1643 for controller in range( len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07001644 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall3afe4c92015-12-14 19:30:38 -08001645 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001646 if hosts[ controller ] == hosts[ 0 ]:
1647 continue
1648 else: # hosts not consistent
1649 main.log.error( "hosts from ONOS" +
1650 controllerStr +
1651 " is inconsistent with ONOS1" )
1652 main.log.warn( repr( hosts[ controller ] ) )
1653 consistentHostsResult = main.FALSE
1654
1655 else:
1656 main.log.error( "Error in getting ONOS hosts from ONOS" +
1657 controllerStr )
1658 consistentHostsResult = main.FALSE
1659 main.log.warn( "ONOS" + controllerStr +
1660 " hosts response: " +
1661 repr( hosts[ controller ] ) )
1662 utilities.assert_equals(
1663 expect=main.TRUE,
1664 actual=consistentHostsResult,
1665 onpass="Hosts view is consistent across all ONOS nodes",
1666 onfail="ONOS nodes have different views of hosts" )
1667
1668 main.step( "Each host has an IP address" )
1669 ipResult = main.TRUE
1670 for controller in range( 0, len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07001671 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall3afe4c92015-12-14 19:30:38 -08001672 if hosts[ controller ]:
1673 for host in hosts[ controller ]:
1674 if not host.get( 'ipAddresses', [ ] ):
Jon Hallf3d16e72015-12-16 17:45:08 -08001675 main.log.error( "Error with host ips on controller" +
Jon Hall3afe4c92015-12-14 19:30:38 -08001676 controllerStr + ": " + str( host ) )
1677 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07001678 utilities.assert_equals(
1679 expect=main.TRUE,
1680 actual=ipResult,
1681 onpass="The ips of the hosts aren't empty",
1682 onfail="The ip of at least one host is missing" )
1683
1684 # Strongly connected clusters of devices
1685 main.step( "Cluster view is consistent across ONOS nodes" )
1686 consistentClustersResult = main.TRUE
1687 for controller in range( len( clusters ) ):
Jon Halla440e872016-03-31 15:15:50 -07001688 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001689 if "Error" not in clusters[ controller ]:
1690 if clusters[ controller ] == clusters[ 0 ]:
1691 continue
1692 else: # clusters not consistent
1693 main.log.error( "clusters from ONOS" + controllerStr +
1694 " is inconsistent with ONOS1" )
1695 consistentClustersResult = main.FALSE
1696
1697 else:
1698 main.log.error( "Error in getting dataplane clusters " +
1699 "from ONOS" + controllerStr )
1700 consistentClustersResult = main.FALSE
1701 main.log.warn( "ONOS" + controllerStr +
1702 " clusters response: " +
1703 repr( clusters[ controller ] ) )
1704 utilities.assert_equals(
1705 expect=main.TRUE,
1706 actual=consistentClustersResult,
1707 onpass="Clusters view is consistent across all ONOS nodes",
1708 onfail="ONOS nodes have different views of clusters" )
Jon Hall172b7ba2016-04-07 18:12:20 -07001709 if consistentClustersResult != main.TRUE:
1710 main.log.debug( clusters )
Jon Hall5cf14d52015-07-16 12:15:19 -07001711 # there should always only be one cluster
1712 main.step( "Cluster view correct across ONOS nodes" )
1713 try:
1714 numClusters = len( json.loads( clusters[ 0 ] ) )
1715 except ( ValueError, TypeError ):
1716 main.log.exception( "Error parsing clusters[0]: " +
1717 repr( clusters[ 0 ] ) )
Jon Hall6e709752016-02-01 13:38:46 -08001718 numClusters = "ERROR"
Jon Hall5cf14d52015-07-16 12:15:19 -07001719 clusterResults = main.FALSE
1720 if numClusters == 1:
1721 clusterResults = main.TRUE
1722 utilities.assert_equals(
1723 expect=1,
1724 actual=numClusters,
1725 onpass="ONOS shows 1 SCC",
1726 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1727
1728 main.step( "Comparing ONOS topology to MN" )
1729 devicesResults = main.TRUE
1730 linksResults = main.TRUE
1731 hostsResults = main.TRUE
1732 mnSwitches = main.Mininet1.getSwitches()
1733 mnLinks = main.Mininet1.getLinks()
1734 mnHosts = main.Mininet1.getHosts()
Jon Halla440e872016-03-31 15:15:50 -07001735 for controller in main.activeNodes:
1736 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001737 if devices[ controller ] and ports[ controller ] and\
1738 "Error" not in devices[ controller ] and\
1739 "Error" not in ports[ controller ]:
Jon Halle1a3b752015-07-22 13:02:46 -07001740 currentDevicesResult = main.Mininet1.compareSwitches(
1741 mnSwitches,
1742 json.loads( devices[ controller ] ),
1743 json.loads( ports[ controller ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001744 else:
1745 currentDevicesResult = main.FALSE
1746 utilities.assert_equals( expect=main.TRUE,
1747 actual=currentDevicesResult,
1748 onpass="ONOS" + controllerStr +
1749 " Switches view is correct",
1750 onfail="ONOS" + controllerStr +
1751 " Switches view is incorrect" )
1752 if links[ controller ] and "Error" not in links[ controller ]:
1753 currentLinksResult = main.Mininet1.compareLinks(
1754 mnSwitches, mnLinks,
1755 json.loads( links[ controller ] ) )
1756 else:
1757 currentLinksResult = main.FALSE
1758 utilities.assert_equals( expect=main.TRUE,
1759 actual=currentLinksResult,
1760 onpass="ONOS" + controllerStr +
1761 " links view is correct",
1762 onfail="ONOS" + controllerStr +
1763 " links view is incorrect" )
1764
Jon Hall657cdf62015-12-17 14:40:51 -08001765 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001766 currentHostsResult = main.Mininet1.compareHosts(
1767 mnHosts,
1768 hosts[ controller ] )
1769 else:
1770 currentHostsResult = main.FALSE
1771 utilities.assert_equals( expect=main.TRUE,
1772 actual=currentHostsResult,
1773 onpass="ONOS" + controllerStr +
1774 " hosts exist in Mininet",
1775 onfail="ONOS" + controllerStr +
1776 " hosts don't match Mininet" )
1777
1778 devicesResults = devicesResults and currentDevicesResult
1779 linksResults = linksResults and currentLinksResult
1780 hostsResults = hostsResults and currentHostsResult
1781
1782 main.step( "Device information is correct" )
1783 utilities.assert_equals(
1784 expect=main.TRUE,
1785 actual=devicesResults,
1786 onpass="Device information is correct",
1787 onfail="Device information is incorrect" )
1788
1789 main.step( "Links are correct" )
1790 utilities.assert_equals(
1791 expect=main.TRUE,
1792 actual=linksResults,
1793 onpass="Link are correct",
1794 onfail="Links are incorrect" )
1795
1796 main.step( "Hosts are correct" )
1797 utilities.assert_equals(
1798 expect=main.TRUE,
1799 actual=hostsResults,
1800 onpass="Hosts are correct",
1801 onfail="Hosts are incorrect" )
1802
1803 def CASE6( self, main ):
1804 """
1805 The Failure case.
1806 """
1807 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001808 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001809 assert main, "main not defined"
1810 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001811 assert main.CLIs, "main.CLIs not defined"
1812 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001813 try:
1814 labels
1815 except NameError:
1816 main.log.error( "labels not defined, setting to []" )
1817 global labels
1818 labels = []
1819 try:
1820 data
1821 except NameError:
1822 main.log.error( "data not defined, setting to []" )
1823 global data
1824 data = []
1825 # Reset non-persistent variables
1826 try:
1827 iCounterValue = 0
1828 except NameError:
1829 main.log.error( "iCounterValue not defined, setting to 0" )
1830 iCounterValue = 0
1831
1832 main.case( "Restart entire ONOS cluster" )
1833
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001834 main.step( "Checking ONOS Logs for errors" )
1835 for node in main.nodes:
1836 main.log.debug( "Checking logs for errors on " + node.name + ":" )
1837 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
1838
Jon Hall5cf14d52015-07-16 12:15:19 -07001839 main.step( "Killing ONOS nodes" )
1840 killResults = main.TRUE
1841 killTime = time.time()
Jon Halle1a3b752015-07-22 13:02:46 -07001842 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001843 killed = main.ONOSbench.onosKill( node.ip_address )
1844 killResults = killResults and killed
1845 utilities.assert_equals( expect=main.TRUE, actual=killResults,
1846 onpass="ONOS nodes killed",
1847 onfail="ONOS kill unsuccessful" )
1848
1849 main.step( "Checking if ONOS is up yet" )
1850 for i in range( 2 ):
1851 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001852 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001853 started = main.ONOSbench.isup( node.ip_address )
1854 if not started:
1855 main.log.error( node.name + " didn't start!" )
1856 onosIsupResult = onosIsupResult and started
1857 if onosIsupResult == main.TRUE:
1858 break
1859 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1860 onpass="ONOS restarted",
1861 onfail="ONOS restart NOT successful" )
1862
1863 main.log.step( "Starting ONOS CLI sessions" )
1864 cliResults = main.TRUE
1865 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001866 for i in range( main.numCtrls ):
1867 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -07001868 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -07001869 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -07001870 threads.append( t )
1871 t.start()
1872
1873 for t in threads:
1874 t.join()
1875 cliResults = cliResults and t.result
1876 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1877 onpass="ONOS cli started",
1878 onfail="ONOS clis did not restart" )
1879
Jon Hall6e709752016-02-01 13:38:46 -08001880 for i in range( 10 ):
1881 ready = True
1882 for cli in main.CLIs:
1883 output = cli.summary()
1884 if not output:
1885 ready = False
1886 time.sleep( 30 )
1887 utilities.assert_equals( expect=True, actual=ready,
1888 onpass="ONOS summary command succeded",
1889 onfail="ONOS summary command failed" )
1890 if not ready:
1891 main.cleanup()
1892 main.exit()
1893
Jon Hall5cf14d52015-07-16 12:15:19 -07001894 # Grab the time of restart so we chan check how long the gossip
1895 # protocol has had time to work
1896 main.restartTime = time.time() - killTime
1897 main.log.debug( "Restart time: " + str( main.restartTime ) )
1898 labels.append( "Restart" )
1899 data.append( str( main.restartTime ) )
1900
Jon Hall5cf14d52015-07-16 12:15:19 -07001901 # Rerun for election on restarted nodes
1902 runResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001903 for cli in main.CLIs:
Jon Halla440e872016-03-31 15:15:50 -07001904 run = cli.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07001905 if run != main.TRUE:
1906 main.log.error( "Error running for election on " + cli.name )
1907 runResults = runResults and run
1908 utilities.assert_equals( expect=main.TRUE, actual=runResults,
1909 onpass="Reran for election",
1910 onfail="Failed to rerun for election" )
1911
1912 # TODO: Make this configurable
1913 time.sleep( 60 )
Jon Halla440e872016-03-31 15:15:50 -07001914 node = main.activeNodes[0]
1915 main.log.debug( main.CLIs[node].nodes( jsonFormat=False ) )
1916 main.log.debug( main.CLIs[node].leaders( jsonFormat=False ) )
1917 main.log.debug( main.CLIs[node].partitions( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001918
1919 def CASE7( self, main ):
1920 """
1921 Check state after ONOS failure
1922 """
1923 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001924 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001925 assert main, "main not defined"
1926 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001927 assert main.CLIs, "main.CLIs not defined"
1928 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001929 main.case( "Running ONOS Constant State Tests" )
1930
1931 main.step( "Check that each switch has a master" )
1932 # Assert that each device has a master
1933 rolesNotNull = main.TRUE
1934 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001935 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001936 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001937 name="rolesNotNull-" + str( i ),
1938 args=[ ] )
1939 threads.append( t )
1940 t.start()
1941
1942 for t in threads:
1943 t.join()
1944 rolesNotNull = rolesNotNull and t.result
1945 utilities.assert_equals(
1946 expect=main.TRUE,
1947 actual=rolesNotNull,
1948 onpass="Each device has a master",
1949 onfail="Some devices don't have a master assigned" )
1950
1951 main.step( "Read device roles from ONOS" )
1952 ONOSMastership = []
1953 mastershipCheck = main.FALSE
1954 consistentMastership = True
1955 rolesResults = True
1956 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001957 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001958 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001959 name="roles-" + str( i ),
1960 args=[] )
1961 threads.append( t )
1962 t.start()
1963
1964 for t in threads:
1965 t.join()
1966 ONOSMastership.append( t.result )
1967
Jon Halla440e872016-03-31 15:15:50 -07001968 for i in range( len( ONOSMastership ) ):
1969 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001970 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Halla440e872016-03-31 15:15:50 -07001971 main.log.error( "Error in getting ONOS" + node + " roles" )
1972 main.log.warn( "ONOS" + node + " mastership response: " +
1973 repr( ONOSMastership[i] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001974 rolesResults = False
1975 utilities.assert_equals(
1976 expect=True,
1977 actual=rolesResults,
1978 onpass="No error in reading roles output",
1979 onfail="Error in reading roles from ONOS" )
1980
1981 main.step( "Check for consistency in roles from each controller" )
1982 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1983 main.log.info(
1984 "Switch roles are consistent across all ONOS nodes" )
1985 else:
1986 consistentMastership = False
1987 utilities.assert_equals(
1988 expect=True,
1989 actual=consistentMastership,
1990 onpass="Switch roles are consistent across all ONOS nodes",
1991 onfail="ONOS nodes have different views of switch roles" )
1992
1993 if rolesResults and not consistentMastership:
Jon Halla440e872016-03-31 15:15:50 -07001994 for i in range( len( ONOSMastership ) ):
1995 node = str( main.activeNodes[i] + 1 )
1996 main.log.warn( "ONOS" + node + " roles: ",
Jon Hall6e709752016-02-01 13:38:46 -08001997 json.dumps( json.loads( ONOSMastership[ i ] ),
1998 sort_keys=True,
1999 indent=4,
2000 separators=( ',', ': ' ) ) )
2001 elif rolesResults and consistentMastership:
Jon Hall5cf14d52015-07-16 12:15:19 -07002002 mastershipCheck = main.TRUE
2003
Jon Hall5cf14d52015-07-16 12:15:19 -07002004 # NOTE: we expect mastership to change on controller failure
2005
2006 main.step( "Get the intents and compare across all nodes" )
2007 ONOSIntents = []
2008 intentCheck = main.FALSE
2009 consistentIntents = True
2010 intentsResults = True
2011 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002012 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002013 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07002014 name="intents-" + str( i ),
2015 args=[],
2016 kwargs={ 'jsonFormat': True } )
2017 threads.append( t )
2018 t.start()
2019
2020 for t in threads:
2021 t.join()
2022 ONOSIntents.append( t.result )
2023
Jon Halla440e872016-03-31 15:15:50 -07002024 for i in range( len( ONOSIntents) ):
2025 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002026 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Halla440e872016-03-31 15:15:50 -07002027 main.log.error( "Error in getting ONOS" + node + " intents" )
2028 main.log.warn( "ONOS" + node + " intents response: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07002029 repr( ONOSIntents[ i ] ) )
2030 intentsResults = False
2031 utilities.assert_equals(
2032 expect=True,
2033 actual=intentsResults,
2034 onpass="No error in reading intents output",
2035 onfail="Error in reading intents from ONOS" )
2036
2037 main.step( "Check for consistency in Intents from each controller" )
2038 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
2039 main.log.info( "Intents are consistent across all ONOS " +
2040 "nodes" )
2041 else:
2042 consistentIntents = False
2043
2044 # Try to make it easy to figure out what is happening
2045 #
2046 # Intent ONOS1 ONOS2 ...
2047 # 0x01 INSTALLED INSTALLING
2048 # ... ... ...
2049 # ... ... ...
2050 title = " ID"
Jon Halla440e872016-03-31 15:15:50 -07002051 for n in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07002052 title += " " * 10 + "ONOS" + str( n + 1 )
2053 main.log.warn( title )
2054 # get all intent keys in the cluster
2055 keys = []
2056 for nodeStr in ONOSIntents:
2057 node = json.loads( nodeStr )
2058 for intent in node:
2059 keys.append( intent.get( 'id' ) )
2060 keys = set( keys )
2061 for key in keys:
2062 row = "%-13s" % key
2063 for nodeStr in ONOSIntents:
2064 node = json.loads( nodeStr )
2065 for intent in node:
2066 if intent.get( 'id' ) == key:
2067 row += "%-15s" % intent.get( 'state' )
2068 main.log.warn( row )
2069 # End table view
2070
2071 utilities.assert_equals(
2072 expect=True,
2073 actual=consistentIntents,
2074 onpass="Intents are consistent across all ONOS nodes",
2075 onfail="ONOS nodes have different views of intents" )
2076 intentStates = []
2077 for node in ONOSIntents: # Iter through ONOS nodes
2078 nodeStates = []
2079 # Iter through intents of a node
2080 try:
2081 for intent in json.loads( node ):
2082 nodeStates.append( intent[ 'state' ] )
2083 except ( ValueError, TypeError ):
2084 main.log.exception( "Error in parsing intents" )
2085 main.log.error( repr( node ) )
2086 intentStates.append( nodeStates )
2087 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
2088 main.log.info( dict( out ) )
2089
2090 if intentsResults and not consistentIntents:
Jon Halla440e872016-03-31 15:15:50 -07002091 for i in range( len( main.activeNodes ) ):
2092 node = str( main.activeNodes[i] + 1 )
2093 main.log.warn( "ONOS" + node + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07002094 main.log.warn( json.dumps(
2095 json.loads( ONOSIntents[ i ] ),
2096 sort_keys=True,
2097 indent=4,
2098 separators=( ',', ': ' ) ) )
2099 elif intentsResults and consistentIntents:
2100 intentCheck = main.TRUE
2101
2102 # NOTE: Store has no durability, so intents are lost across system
2103 # restarts
2104 """
2105 main.step( "Compare current intents with intents before the failure" )
2106 # NOTE: this requires case 5 to pass for intentState to be set.
2107 # maybe we should stop the test if that fails?
2108 sameIntents = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002109 try:
2110 intentState
2111 except NameError:
2112 main.log.warn( "No previous intent state was saved" )
2113 else:
2114 if intentState and intentState == ONOSIntents[ 0 ]:
2115 sameIntents = main.TRUE
2116 main.log.info( "Intents are consistent with before failure" )
2117 # TODO: possibly the states have changed? we may need to figure out
2118 # what the acceptable states are
2119 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
2120 sameIntents = main.TRUE
2121 try:
2122 before = json.loads( intentState )
2123 after = json.loads( ONOSIntents[ 0 ] )
2124 for intent in before:
2125 if intent not in after:
2126 sameIntents = main.FALSE
2127 main.log.debug( "Intent is not currently in ONOS " +
2128 "(at least in the same form):" )
2129 main.log.debug( json.dumps( intent ) )
2130 except ( ValueError, TypeError ):
2131 main.log.exception( "Exception printing intents" )
2132 main.log.debug( repr( ONOSIntents[0] ) )
2133 main.log.debug( repr( intentState ) )
2134 if sameIntents == main.FALSE:
2135 try:
2136 main.log.debug( "ONOS intents before: " )
2137 main.log.debug( json.dumps( json.loads( intentState ),
2138 sort_keys=True, indent=4,
2139 separators=( ',', ': ' ) ) )
2140 main.log.debug( "Current ONOS intents: " )
2141 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
2142 sort_keys=True, indent=4,
2143 separators=( ',', ': ' ) ) )
2144 except ( ValueError, TypeError ):
2145 main.log.exception( "Exception printing intents" )
2146 main.log.debug( repr( ONOSIntents[0] ) )
2147 main.log.debug( repr( intentState ) )
2148 utilities.assert_equals(
2149 expect=main.TRUE,
2150 actual=sameIntents,
2151 onpass="Intents are consistent with before failure",
2152 onfail="The Intents changed during failure" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002153 intentCheck = intentCheck and sameIntents
2154 """
2155 main.step( "Get the OF Table entries and compare to before " +
2156 "component failure" )
2157 FlowTables = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002158 for i in range( 28 ):
2159 main.log.info( "Checking flow table on s" + str( i + 1 ) )
GlennRC68467eb2015-11-16 18:01:01 -08002160 tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
2161 FlowTables = FlowTables and main.Mininet1.flowTableComp( flows[i], tmpFlows )
Jon Hall5cf14d52015-07-16 12:15:19 -07002162 if FlowTables == main.FALSE:
GlennRC68467eb2015-11-16 18:01:01 -08002163 main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002164 utilities.assert_equals(
2165 expect=main.TRUE,
2166 actual=FlowTables,
2167 onpass="No changes were found in the flow tables",
2168 onfail="Changes were found in the flow tables" )
2169
2170 main.Mininet2.pingLongKill()
2171 '''
2172 # main.step( "Check the continuous pings to ensure that no packets " +
2173 # "were dropped during component failure" )
2174 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
2175 main.params[ 'TESTONIP' ] )
2176 LossInPings = main.FALSE
2177 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
2178 for i in range( 8, 18 ):
2179 main.log.info(
2180 "Checking for a loss in pings along flow from s" +
2181 str( i ) )
2182 LossInPings = main.Mininet2.checkForLoss(
2183 "/tmp/ping.h" +
2184 str( i ) ) or LossInPings
2185 if LossInPings == main.TRUE:
2186 main.log.info( "Loss in ping detected" )
2187 elif LossInPings == main.ERROR:
2188 main.log.info( "There are multiple mininet process running" )
2189 elif LossInPings == main.FALSE:
2190 main.log.info( "No Loss in the pings" )
2191 main.log.info( "No loss of dataplane connectivity" )
2192 # utilities.assert_equals(
2193 # expect=main.FALSE,
2194 # actual=LossInPings,
2195 # onpass="No Loss of connectivity",
2196 # onfail="Loss of dataplane connectivity detected" )
2197
2198 # NOTE: Since intents are not persisted with IntnentStore,
2199 # we expect loss in dataplane connectivity
2200 LossInPings = main.FALSE
2201 '''
2202
2203 main.step( "Leadership Election is still functional" )
2204 # Test of LeadershipElection
2205 leaderList = []
2206 leaderResult = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002207
2208 for i in main.activeNodes:
2209 cli = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07002210 leaderN = cli.electionTestLeader()
2211 leaderList.append( leaderN )
2212 if leaderN == main.FALSE:
2213 # error in response
2214 main.log.error( "Something is wrong with " +
2215 "electionTestLeader function, check the" +
2216 " error logs" )
2217 leaderResult = main.FALSE
2218 elif leaderN is None:
2219 main.log.error( cli.name +
2220 " shows no leader for the election-app." )
2221 leaderResult = main.FALSE
2222 if len( set( leaderList ) ) != 1:
2223 leaderResult = main.FALSE
2224 main.log.error(
2225 "Inconsistent view of leader for the election test app" )
2226 # TODO: print the list
2227 utilities.assert_equals(
2228 expect=main.TRUE,
2229 actual=leaderResult,
2230 onpass="Leadership election passed",
2231 onfail="Something went wrong with Leadership election" )
2232
2233 def CASE8( self, main ):
2234 """
2235 Compare topo
2236 """
2237 import json
2238 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002239 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002240 assert main, "main not defined"
2241 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002242 assert main.CLIs, "main.CLIs not defined"
2243 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002244
2245 main.case( "Compare ONOS Topology view to Mininet topology" )
Jon Hall783bbf92015-07-23 14:33:19 -07002246 main.caseExplanation = "Compare topology objects between Mininet" +\
Jon Hall5cf14d52015-07-16 12:15:19 -07002247 " and ONOS"
Jon Hall5cf14d52015-07-16 12:15:19 -07002248 topoResult = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08002249 topoFailMsg = "ONOS topology don't match Mininet"
Jon Hall5cf14d52015-07-16 12:15:19 -07002250 elapsed = 0
2251 count = 0
Jon Halle9b1fa32015-12-08 15:32:21 -08002252 main.step( "Comparing ONOS topology to MN topology" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002253 startTime = time.time()
2254 # Give time for Gossip to work
Jon Halle9b1fa32015-12-08 15:32:21 -08002255 while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
Jon Hallba609822015-09-18 12:00:21 -07002256 devicesResults = main.TRUE
2257 linksResults = main.TRUE
2258 hostsResults = main.TRUE
2259 hostAttachmentResults = True
Jon Hall5cf14d52015-07-16 12:15:19 -07002260 count += 1
2261 cliStart = time.time()
2262 devices = []
2263 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002264 for i in main.activeNodes:
Jon Hall6e709752016-02-01 13:38:46 -08002265 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002266 name="devices-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08002267 args=[ main.CLIs[i].devices, [ None ] ],
2268 kwargs= { 'sleep': 5, 'attempts': 5,
2269 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002270 threads.append( t )
2271 t.start()
2272
2273 for t in threads:
2274 t.join()
2275 devices.append( t.result )
2276 hosts = []
2277 ipResult = main.TRUE
2278 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002279 for i in main.activeNodes:
Jon Halld8f6de82015-12-17 17:04:34 -08002280 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002281 name="hosts-" + str( i ),
Jon Halld8f6de82015-12-17 17:04:34 -08002282 args=[ main.CLIs[i].hosts, [ None ] ],
2283 kwargs= { 'sleep': 5, 'attempts': 5,
2284 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002285 threads.append( t )
2286 t.start()
2287
2288 for t in threads:
2289 t.join()
2290 try:
2291 hosts.append( json.loads( t.result ) )
2292 except ( ValueError, TypeError ):
2293 main.log.exception( "Error parsing hosts results" )
2294 main.log.error( repr( t.result ) )
Jon Hall3afe4c92015-12-14 19:30:38 -08002295 hosts.append( None )
Jon Hall5cf14d52015-07-16 12:15:19 -07002296 for controller in range( 0, len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07002297 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hallacd1b182015-12-17 11:43:20 -08002298 if hosts[ controller ]:
2299 for host in hosts[ controller ]:
2300 if host is None or host.get( 'ipAddresses', [] ) == []:
2301 main.log.error(
2302 "Error with host ipAddresses on controller" +
2303 controllerStr + ": " + str( host ) )
2304 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002305 ports = []
2306 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002307 for i in main.activeNodes:
Jon Hall6e709752016-02-01 13:38:46 -08002308 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002309 name="ports-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08002310 args=[ main.CLIs[i].ports, [ None ] ],
2311 kwargs= { 'sleep': 5, 'attempts': 5,
2312 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002313 threads.append( t )
2314 t.start()
2315
2316 for t in threads:
2317 t.join()
2318 ports.append( t.result )
2319 links = []
2320 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002321 for i in main.activeNodes:
Jon Hall6e709752016-02-01 13:38:46 -08002322 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002323 name="links-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08002324 args=[ main.CLIs[i].links, [ None ] ],
2325 kwargs= { 'sleep': 5, 'attempts': 5,
2326 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002327 threads.append( t )
2328 t.start()
2329
2330 for t in threads:
2331 t.join()
2332 links.append( t.result )
2333 clusters = []
2334 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002335 for i in main.activeNodes:
Jon Hall6e709752016-02-01 13:38:46 -08002336 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002337 name="clusters-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08002338 args=[ main.CLIs[i].clusters, [ None ] ],
2339 kwargs= { 'sleep': 5, 'attempts': 5,
2340 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002341 threads.append( t )
2342 t.start()
2343
2344 for t in threads:
2345 t.join()
2346 clusters.append( t.result )
2347
2348 elapsed = time.time() - startTime
2349 cliTime = time.time() - cliStart
2350 print "Elapsed time: " + str( elapsed )
2351 print "CLI time: " + str( cliTime )
2352
Jon Hall6e709752016-02-01 13:38:46 -08002353 if all( e is None for e in devices ) and\
2354 all( e is None for e in hosts ) and\
2355 all( e is None for e in ports ) and\
2356 all( e is None for e in links ) and\
2357 all( e is None for e in clusters ):
2358 topoFailMsg = "Could not get topology from ONOS"
2359 main.log.error( topoFailMsg )
2360 continue # Try again, No use trying to compare
2361
Jon Hall5cf14d52015-07-16 12:15:19 -07002362 mnSwitches = main.Mininet1.getSwitches()
2363 mnLinks = main.Mininet1.getLinks()
2364 mnHosts = main.Mininet1.getHosts()
Jon Halla440e872016-03-31 15:15:50 -07002365 for controller in range( len( main.activeNodes ) ):
2366 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002367 if devices[ controller ] and ports[ controller ] and\
2368 "Error" not in devices[ controller ] and\
2369 "Error" not in ports[ controller ]:
2370
Jon Hallc6793552016-01-19 14:18:37 -08002371 try:
2372 currentDevicesResult = main.Mininet1.compareSwitches(
2373 mnSwitches,
2374 json.loads( devices[ controller ] ),
2375 json.loads( ports[ controller ] ) )
2376 except ( TypeError, ValueError ) as e:
2377 main.log.exception( "Object not as expected; devices={!r}\nports={!r}".format(
2378 devices[ controller ], ports[ controller ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002379 else:
2380 currentDevicesResult = main.FALSE
2381 utilities.assert_equals( expect=main.TRUE,
2382 actual=currentDevicesResult,
2383 onpass="ONOS" + controllerStr +
2384 " Switches view is correct",
2385 onfail="ONOS" + controllerStr +
2386 " Switches view is incorrect" )
2387
2388 if links[ controller ] and "Error" not in links[ controller ]:
2389 currentLinksResult = main.Mininet1.compareLinks(
2390 mnSwitches, mnLinks,
2391 json.loads( links[ controller ] ) )
2392 else:
2393 currentLinksResult = main.FALSE
2394 utilities.assert_equals( expect=main.TRUE,
2395 actual=currentLinksResult,
2396 onpass="ONOS" + controllerStr +
2397 " links view is correct",
2398 onfail="ONOS" + controllerStr +
2399 " links view is incorrect" )
Jon Hall657cdf62015-12-17 14:40:51 -08002400 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002401 currentHostsResult = main.Mininet1.compareHosts(
2402 mnHosts,
2403 hosts[ controller ] )
Jon Hall13b446e2016-01-05 12:17:01 -08002404 elif hosts[ controller ] == []:
2405 currentHostsResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002406 else:
2407 currentHostsResult = main.FALSE
2408 utilities.assert_equals( expect=main.TRUE,
2409 actual=currentHostsResult,
2410 onpass="ONOS" + controllerStr +
2411 " hosts exist in Mininet",
2412 onfail="ONOS" + controllerStr +
2413 " hosts don't match Mininet" )
2414 # CHECKING HOST ATTACHMENT POINTS
2415 hostAttachment = True
Jon Halla440e872016-03-31 15:15:50 -07002416 zeroHosts = False
Jon Hall5cf14d52015-07-16 12:15:19 -07002417 # FIXME: topo-HA/obelisk specific mappings:
2418 # key is mac and value is dpid
2419 mappings = {}
2420 for i in range( 1, 29 ): # hosts 1 through 28
2421 # set up correct variables:
2422 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2423 if i == 1:
2424 deviceId = "1000".zfill(16)
2425 elif i == 2:
2426 deviceId = "2000".zfill(16)
2427 elif i == 3:
2428 deviceId = "3000".zfill(16)
2429 elif i == 4:
2430 deviceId = "3004".zfill(16)
2431 elif i == 5:
2432 deviceId = "5000".zfill(16)
2433 elif i == 6:
2434 deviceId = "6000".zfill(16)
2435 elif i == 7:
2436 deviceId = "6007".zfill(16)
2437 elif i >= 8 and i <= 17:
2438 dpid = '3' + str( i ).zfill( 3 )
2439 deviceId = dpid.zfill(16)
2440 elif i >= 18 and i <= 27:
2441 dpid = '6' + str( i ).zfill( 3 )
2442 deviceId = dpid.zfill(16)
2443 elif i == 28:
2444 deviceId = "2800".zfill(16)
2445 mappings[ macId ] = deviceId
Jon Halld8f6de82015-12-17 17:04:34 -08002446 if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002447 if hosts[ controller ] == []:
2448 main.log.warn( "There are no hosts discovered" )
Jon Halla440e872016-03-31 15:15:50 -07002449 zeroHosts = True
Jon Hall5cf14d52015-07-16 12:15:19 -07002450 else:
2451 for host in hosts[ controller ]:
2452 mac = None
2453 location = None
2454 device = None
2455 port = None
2456 try:
2457 mac = host.get( 'mac' )
2458 assert mac, "mac field could not be found for this host object"
2459
2460 location = host.get( 'location' )
2461 assert location, "location field could not be found for this host object"
2462
2463 # Trim the protocol identifier off deviceId
2464 device = str( location.get( 'elementId' ) ).split(':')[1]
2465 assert device, "elementId field could not be found for this host location object"
2466
2467 port = location.get( 'port' )
2468 assert port, "port field could not be found for this host location object"
2469
2470 # Now check if this matches where they should be
2471 if mac and device and port:
2472 if str( port ) != "1":
2473 main.log.error( "The attachment port is incorrect for " +
2474 "host " + str( mac ) +
2475 ". Expected: 1 Actual: " + str( port) )
2476 hostAttachment = False
2477 if device != mappings[ str( mac ) ]:
2478 main.log.error( "The attachment device is incorrect for " +
2479 "host " + str( mac ) +
2480 ". Expected: " + mappings[ str( mac ) ] +
2481 " Actual: " + device )
2482 hostAttachment = False
2483 else:
2484 hostAttachment = False
2485 except AssertionError:
2486 main.log.exception( "Json object not as expected" )
2487 main.log.error( repr( host ) )
2488 hostAttachment = False
2489 else:
2490 main.log.error( "No hosts json output or \"Error\"" +
2491 " in output. hosts = " +
2492 repr( hosts[ controller ] ) )
Jon Halla440e872016-03-31 15:15:50 -07002493 if zeroHosts is False:
Jon Hall5cf14d52015-07-16 12:15:19 -07002494 # TODO: Find a way to know if there should be hosts in a
2495 # given point of the test
2496 hostAttachment = True
2497
2498 # END CHECKING HOST ATTACHMENT POINTS
2499 devicesResults = devicesResults and currentDevicesResult
2500 linksResults = linksResults and currentLinksResult
2501 hostsResults = hostsResults and currentHostsResult
2502 hostAttachmentResults = hostAttachmentResults and\
2503 hostAttachment
2504 topoResult = ( devicesResults and linksResults
2505 and hostsResults and ipResult and
2506 hostAttachmentResults )
Jon Halle9b1fa32015-12-08 15:32:21 -08002507 utilities.assert_equals( expect=True,
2508 actual=topoResult,
2509 onpass="ONOS topology matches Mininet",
Jon Hall6e709752016-02-01 13:38:46 -08002510 onfail=topoFailMsg )
Jon Halle9b1fa32015-12-08 15:32:21 -08002511 # End of While loop to pull ONOS state
Jon Hall5cf14d52015-07-16 12:15:19 -07002512
2513 # Compare json objects for hosts and dataplane clusters
2514
2515 # hosts
2516 main.step( "Hosts view is consistent across all ONOS nodes" )
2517 consistentHostsResult = main.TRUE
2518 for controller in range( len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07002519 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall13b446e2016-01-05 12:17:01 -08002520 if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002521 if hosts[ controller ] == hosts[ 0 ]:
2522 continue
2523 else: # hosts not consistent
2524 main.log.error( "hosts from ONOS" + controllerStr +
2525 " is inconsistent with ONOS1" )
2526 main.log.warn( repr( hosts[ controller ] ) )
2527 consistentHostsResult = main.FALSE
2528
2529 else:
2530 main.log.error( "Error in getting ONOS hosts from ONOS" +
2531 controllerStr )
2532 consistentHostsResult = main.FALSE
2533 main.log.warn( "ONOS" + controllerStr +
2534 " hosts response: " +
2535 repr( hosts[ controller ] ) )
2536 utilities.assert_equals(
2537 expect=main.TRUE,
2538 actual=consistentHostsResult,
2539 onpass="Hosts view is consistent across all ONOS nodes",
2540 onfail="ONOS nodes have different views of hosts" )
2541
2542 main.step( "Hosts information is correct" )
2543 hostsResults = hostsResults and ipResult
2544 utilities.assert_equals(
2545 expect=main.TRUE,
2546 actual=hostsResults,
2547 onpass="Host information is correct",
2548 onfail="Host information is incorrect" )
2549
2550 main.step( "Host attachment points to the network" )
2551 utilities.assert_equals(
2552 expect=True,
2553 actual=hostAttachmentResults,
2554 onpass="Hosts are correctly attached to the network",
2555 onfail="ONOS did not correctly attach hosts to the network" )
2556
2557 # Strongly connected clusters of devices
2558 main.step( "Clusters view is consistent across all ONOS nodes" )
2559 consistentClustersResult = main.TRUE
2560 for controller in range( len( clusters ) ):
Jon Halla440e872016-03-31 15:15:50 -07002561 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002562 if "Error" not in clusters[ controller ]:
2563 if clusters[ controller ] == clusters[ 0 ]:
2564 continue
2565 else: # clusters not consistent
2566 main.log.error( "clusters from ONOS" +
2567 controllerStr +
2568 " is inconsistent with ONOS1" )
2569 consistentClustersResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002570 else:
2571 main.log.error( "Error in getting dataplane clusters " +
2572 "from ONOS" + controllerStr )
2573 consistentClustersResult = main.FALSE
2574 main.log.warn( "ONOS" + controllerStr +
2575 " clusters response: " +
2576 repr( clusters[ controller ] ) )
2577 utilities.assert_equals(
2578 expect=main.TRUE,
2579 actual=consistentClustersResult,
2580 onpass="Clusters view is consistent across all ONOS nodes",
2581 onfail="ONOS nodes have different views of clusters" )
2582
2583 main.step( "There is only one SCC" )
2584 # there should always only be one cluster
2585 try:
2586 numClusters = len( json.loads( clusters[ 0 ] ) )
2587 except ( ValueError, TypeError ):
2588 main.log.exception( "Error parsing clusters[0]: " +
2589 repr( clusters[0] ) )
Jon Halla440e872016-03-31 15:15:50 -07002590 numClusters = "ERROR"
Jon Hall5cf14d52015-07-16 12:15:19 -07002591 clusterResults = main.FALSE
2592 if numClusters == 1:
2593 clusterResults = main.TRUE
2594 utilities.assert_equals(
2595 expect=1,
2596 actual=numClusters,
2597 onpass="ONOS shows 1 SCC",
2598 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2599
2600 topoResult = ( devicesResults and linksResults
2601 and hostsResults and consistentHostsResult
2602 and consistentClustersResult and clusterResults
2603 and ipResult and hostAttachmentResults )
2604
2605 topoResult = topoResult and int( count <= 2 )
2606 note = "note it takes about " + str( int( cliTime ) ) + \
2607 " seconds for the test to make all the cli calls to fetch " +\
2608 "the topology from each ONOS instance"
2609 main.log.info(
2610 "Very crass estimate for topology discovery/convergence( " +
2611 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2612 str( count ) + " tries" )
2613
2614 main.step( "Device information is correct" )
2615 utilities.assert_equals(
2616 expect=main.TRUE,
2617 actual=devicesResults,
2618 onpass="Device information is correct",
2619 onfail="Device information is incorrect" )
2620
2621 main.step( "Links are correct" )
2622 utilities.assert_equals(
2623 expect=main.TRUE,
2624 actual=linksResults,
2625 onpass="Link are correct",
2626 onfail="Links are incorrect" )
2627
Jon Halla440e872016-03-31 15:15:50 -07002628 main.step( "Hosts are correct" )
2629 utilities.assert_equals(
2630 expect=main.TRUE,
2631 actual=hostsResults,
2632 onpass="Hosts are correct",
2633 onfail="Hosts are incorrect" )
2634
Jon Hall5cf14d52015-07-16 12:15:19 -07002635 # FIXME: move this to an ONOS state case
2636 main.step( "Checking ONOS nodes" )
2637 nodesOutput = []
2638 nodeResults = main.TRUE
2639 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002640 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002641 t = main.Thread( target=main.CLIs[i].nodes,
Jon Hall5cf14d52015-07-16 12:15:19 -07002642 name="nodes-" + str( i ),
2643 args=[ ] )
2644 threads.append( t )
2645 t.start()
2646
2647 for t in threads:
2648 t.join()
2649 nodesOutput.append( t.result )
Jon Halla440e872016-03-31 15:15:50 -07002650 ips = [ main.nodes[node].ip_address for node in main.activeNodes ]
Jon Halle9b1fa32015-12-08 15:32:21 -08002651 ips.sort()
Jon Hall5cf14d52015-07-16 12:15:19 -07002652 for i in nodesOutput:
2653 try:
2654 current = json.loads( i )
Jon Halle9b1fa32015-12-08 15:32:21 -08002655 activeIps = []
2656 currentResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002657 for node in current:
Jon Hallbd182782016-03-28 16:42:22 -07002658 if node['state'] == 'READY':
Jon Halle9b1fa32015-12-08 15:32:21 -08002659 activeIps.append( node['ip'] )
2660 activeIps.sort()
2661 if ips == activeIps:
2662 currentResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002663 except ( ValueError, TypeError ):
2664 main.log.error( "Error parsing nodes output" )
2665 main.log.warn( repr( i ) )
Jon Halle9b1fa32015-12-08 15:32:21 -08002666 currentResult = main.FALSE
2667 nodeResults = nodeResults and currentResult
Jon Hall5cf14d52015-07-16 12:15:19 -07002668 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2669 onpass="Nodes check successful",
2670 onfail="Nodes check NOT successful" )
Jon Halla440e872016-03-31 15:15:50 -07002671 if not nodeResults:
2672 for cli in main.CLIs:
2673 main.log.debug( "{} components not ACTIVE: \n{}".format(
2674 cli.name,
2675 cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002676
2677 def CASE9( self, main ):
2678 """
2679 Link s3-s28 down
2680 """
2681 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002682 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002683 assert main, "main not defined"
2684 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002685 assert main.CLIs, "main.CLIs not defined"
2686 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002687 # NOTE: You should probably run a topology check after this
2688
2689 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2690
2691 description = "Turn off a link to ensure that Link Discovery " +\
2692 "is working properly"
2693 main.case( description )
2694
2695 main.step( "Kill Link between s3 and s28" )
2696 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
2697 main.log.info( "Waiting " + str( linkSleep ) +
2698 " seconds for link down to be discovered" )
2699 time.sleep( linkSleep )
2700 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
2701 onpass="Link down successful",
2702 onfail="Failed to bring link down" )
2703 # TODO do some sort of check here
2704
2705 def CASE10( self, main ):
2706 """
2707 Link s3-s28 up
2708 """
2709 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002710 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002711 assert main, "main not defined"
2712 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002713 assert main.CLIs, "main.CLIs not defined"
2714 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002715 # NOTE: You should probably run a topology check after this
2716
2717 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2718
2719 description = "Restore a link to ensure that Link Discovery is " + \
2720 "working properly"
2721 main.case( description )
2722
2723 main.step( "Bring link between s3 and s28 back up" )
2724 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
2725 main.log.info( "Waiting " + str( linkSleep ) +
2726 " seconds for link up to be discovered" )
2727 time.sleep( linkSleep )
2728 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
2729 onpass="Link up successful",
2730 onfail="Failed to bring link up" )
2731 # TODO do some sort of check here
2732
2733 def CASE11( self, main ):
2734 """
2735 Switch Down
2736 """
2737 # NOTE: You should probably run a topology check after this
2738 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002739 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002740 assert main, "main not defined"
2741 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002742 assert main.CLIs, "main.CLIs not defined"
2743 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002744
2745 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2746
2747 description = "Killing a switch to ensure it is discovered correctly"
Jon Halla440e872016-03-31 15:15:50 -07002748 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002749 main.case( description )
2750 switch = main.params[ 'kill' ][ 'switch' ]
2751 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2752
2753 # TODO: Make this switch parameterizable
2754 main.step( "Kill " + switch )
2755 main.log.info( "Deleting " + switch )
2756 main.Mininet1.delSwitch( switch )
2757 main.log.info( "Waiting " + str( switchSleep ) +
2758 " seconds for switch down to be discovered" )
2759 time.sleep( switchSleep )
Jon Halla440e872016-03-31 15:15:50 -07002760 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall5cf14d52015-07-16 12:15:19 -07002761 # Peek at the deleted switch
2762 main.log.warn( str( device ) )
2763 result = main.FALSE
2764 if device and device[ 'available' ] is False:
2765 result = main.TRUE
2766 utilities.assert_equals( expect=main.TRUE, actual=result,
2767 onpass="Kill switch successful",
2768 onfail="Failed to kill switch?" )
2769
2770 def CASE12( self, main ):
2771 """
2772 Switch Up
2773 """
2774 # NOTE: You should probably run a topology check after this
2775 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002776 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002777 assert main, "main not defined"
2778 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002779 assert main.CLIs, "main.CLIs not defined"
2780 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002781 assert ONOS1Port, "ONOS1Port not defined"
2782 assert ONOS2Port, "ONOS2Port not defined"
2783 assert ONOS3Port, "ONOS3Port not defined"
2784 assert ONOS4Port, "ONOS4Port not defined"
2785 assert ONOS5Port, "ONOS5Port not defined"
2786 assert ONOS6Port, "ONOS6Port not defined"
2787 assert ONOS7Port, "ONOS7Port not defined"
2788
2789 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2790 switch = main.params[ 'kill' ][ 'switch' ]
2791 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2792 links = main.params[ 'kill' ][ 'links' ].split()
Jon Halla440e872016-03-31 15:15:50 -07002793 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002794 description = "Adding a switch to ensure it is discovered correctly"
2795 main.case( description )
2796
2797 main.step( "Add back " + switch )
2798 main.Mininet1.addSwitch( switch, dpid=switchDPID )
2799 for peer in links:
2800 main.Mininet1.addLink( switch, peer )
Jon Halla440e872016-03-31 15:15:50 -07002801 ipList = [ node.ip_address for node in main.nodes ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002802 main.Mininet1.assignSwController( sw=switch, ip=ipList )
2803 main.log.info( "Waiting " + str( switchSleep ) +
2804 " seconds for switch up to be discovered" )
2805 time.sleep( switchSleep )
Jon Halla440e872016-03-31 15:15:50 -07002806 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall5cf14d52015-07-16 12:15:19 -07002807 # Peek at the deleted switch
2808 main.log.warn( str( device ) )
2809 result = main.FALSE
2810 if device and device[ 'available' ]:
2811 result = main.TRUE
2812 utilities.assert_equals( expect=main.TRUE, actual=result,
2813 onpass="add switch successful",
2814 onfail="Failed to add switch?" )
2815
2816 def CASE13( self, main ):
2817 """
2818 Clean up
2819 """
2820 import os
2821 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002822 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002823 assert main, "main not defined"
2824 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002825 assert main.CLIs, "main.CLIs not defined"
2826 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002827
2828 # printing colors to terminal
2829 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2830 'blue': '\033[94m', 'green': '\033[92m',
2831 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
2832 main.case( "Test Cleanup" )
2833 main.step( "Killing tcpdumps" )
2834 main.Mininet2.stopTcpdump()
2835
2836 testname = main.TEST
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002837 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall5cf14d52015-07-16 12:15:19 -07002838 main.step( "Copying MN pcap and ONOS log files to test station" )
2839 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
2840 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
Jon Hall96091e62015-09-21 17:34:17 -07002841 # NOTE: MN Pcap file is being saved to logdir.
2842 # We scp this file as MN and TestON aren't necessarily the same vm
2843
2844 # FIXME: To be replaced with a Jenkin's post script
Jon Hall5cf14d52015-07-16 12:15:19 -07002845 # TODO: Load these from params
2846 # NOTE: must end in /
2847 logFolder = "/opt/onos/log/"
2848 logFiles = [ "karaf.log", "karaf.log.1" ]
2849 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002850 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002851 for node in main.nodes:
Jon Hall6e709752016-02-01 13:38:46 -08002852 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002853 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2854 logFolder + f, dstName )
Jon Hall5cf14d52015-07-16 12:15:19 -07002855 # std*.log's
2856 # NOTE: must end in /
2857 logFolder = "/opt/onos/var/"
2858 logFiles = [ "stderr.log", "stdout.log" ]
2859 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002860 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002861 for node in main.nodes:
Jon Hall6e709752016-02-01 13:38:46 -08002862 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002863 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2864 logFolder + f, dstName )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002865 else:
2866 main.log.debug( "skipping saving log files" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002867
2868 main.step( "Stopping Mininet" )
2869 mnResult = main.Mininet1.stopNet()
2870 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2871 onpass="Mininet stopped",
2872 onfail="MN cleanup NOT successful" )
2873
2874 main.step( "Checking ONOS Logs for errors" )
Jon Halle1a3b752015-07-22 13:02:46 -07002875 for node in main.nodes:
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002876 main.log.debug( "Checking logs for errors on " + node.name + ":" )
2877 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002878
2879 try:
2880 timerLog = open( main.logdir + "/Timers.csv", 'w')
2881 main.log.error( ", ".join( labels ) + "\n" + ", ".join( data ) )
2882 timerLog.write( ", ".join( labels ) + "\n" + ", ".join( data ) )
2883 timerLog.close()
2884 except NameError, e:
2885 main.log.exception(e)
2886
2887 def CASE14( self, main ):
2888 """
2889 start election app on all onos nodes
2890 """
Jon Halle1a3b752015-07-22 13:02:46 -07002891 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002892 assert main, "main not defined"
2893 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002894 assert main.CLIs, "main.CLIs not defined"
2895 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002896
2897 main.case("Start Leadership Election app")
2898 main.step( "Install leadership election app" )
Jon Halla440e872016-03-31 15:15:50 -07002899 onosCli = main.CLIs[ main.activeNodes[0] ]
2900 appResult = onosCli.activateApp( "org.onosproject.election" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002901 utilities.assert_equals(
2902 expect=main.TRUE,
2903 actual=appResult,
2904 onpass="Election app installed",
2905 onfail="Something went wrong with installing Leadership election" )
2906
2907 main.step( "Run for election on each node" )
2908 leaderResult = main.TRUE
2909 leaders = []
Jon Halla440e872016-03-31 15:15:50 -07002910 for i in main.activeNodes:
2911 main.CLIs[i].electionTestRun()
2912 for i in main.activeNodes:
2913 cli = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07002914 leader = cli.electionTestLeader()
2915 if leader is None or leader == main.FALSE:
2916 main.log.error( cli.name + ": Leader for the election app " +
2917 "should be an ONOS node, instead got '" +
2918 str( leader ) + "'" )
2919 leaderResult = main.FALSE
2920 leaders.append( leader )
2921 utilities.assert_equals(
2922 expect=main.TRUE,
2923 actual=leaderResult,
2924 onpass="Successfully ran for leadership",
2925 onfail="Failed to run for leadership" )
2926
2927 main.step( "Check that each node shows the same leader" )
2928 sameLeader = main.TRUE
2929 if len( set( leaders ) ) != 1:
2930 sameLeader = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08002931 main.log.error( "Results of electionTestLeader is order of main.CLIs:" +
Jon Hall5cf14d52015-07-16 12:15:19 -07002932 str( leaders ) )
2933 utilities.assert_equals(
2934 expect=main.TRUE,
2935 actual=sameLeader,
2936 onpass="Leadership is consistent for the election topic",
2937 onfail="Nodes have different leaders" )
2938
2939 def CASE15( self, main ):
2940 """
2941 Check that Leadership Election is still functional
acsmars9475b1c2015-08-28 18:02:08 -07002942 15.1 Run election on each node
2943 15.2 Check that each node has the same leaders and candidates
2944 15.3 Find current leader and withdraw
2945 15.4 Check that a new node was elected leader
2946 15.5 Check that that new leader was the candidate of old leader
2947 15.6 Run for election on old leader
2948 15.7 Check that oldLeader is a candidate, and leader if only 1 node
2949 15.8 Make sure that the old leader was added to the candidate list
2950
2951 old and new variable prefixes refer to data from before vs after
2952 withdrawl and later before withdrawl vs after re-election
Jon Hall5cf14d52015-07-16 12:15:19 -07002953 """
2954 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002955 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002956 assert main, "main not defined"
2957 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002958 assert main.CLIs, "main.CLIs not defined"
2959 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002960
Jon Hall5cf14d52015-07-16 12:15:19 -07002961 description = "Check that Leadership Election is still functional"
2962 main.case( description )
Jon Halla440e872016-03-31 15:15:50 -07002963 # NOTE: Need to re-run after restarts since being a canidate is not persistant
acsmars9475b1c2015-08-28 18:02:08 -07002964
Jon Halla440e872016-03-31 15:15:50 -07002965 oldLeaders = [] # list of lists of each nodes' candidates before
2966 newLeaders = [] # list of lists of each nodes' candidates after
acsmars9475b1c2015-08-28 18:02:08 -07002967 oldLeader = '' # the old leader from oldLeaders, None if not same
2968 newLeader = '' # the new leaders fron newLoeaders, None if not same
2969 oldLeaderCLI = None # the CLI of the old leader used for re-electing
acsmars71adceb2015-08-31 15:09:26 -07002970 expectNoLeader = False # True when there is only one leader
2971 if main.numCtrls == 1:
2972 expectNoLeader = True
acsmars9475b1c2015-08-28 18:02:08 -07002973
Jon Hall5cf14d52015-07-16 12:15:19 -07002974 main.step( "Run for election on each node" )
acsmars9475b1c2015-08-28 18:02:08 -07002975 electionResult = main.TRUE
2976
Jon Halla440e872016-03-31 15:15:50 -07002977 for i in main.activeNodes: # run test election on each node
2978 if main.CLIs[i].electionTestRun() == main.FALSE:
acsmars9475b1c2015-08-28 18:02:08 -07002979 electionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002980 utilities.assert_equals(
2981 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07002982 actual=electionResult,
2983 onpass="All nodes successfully ran for leadership",
2984 onfail="At least one node failed to run for leadership" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002985
acsmars3a72bde2015-09-02 14:16:22 -07002986 if electionResult == main.FALSE:
2987 main.log.error(
2988 "Skipping Test Case because Election Test App isn't loaded" )
2989 main.skipCase()
2990
acsmars9475b1c2015-08-28 18:02:08 -07002991 main.step( "Check that each node shows the same leader and candidates" )
Jon Halla440e872016-03-31 15:15:50 -07002992 failMessage = "Nodes have different leaderboards"
2993 def consistentLeaderboards( nodes ):
2994 TOPIC = 'org.onosproject.election'
2995 # FIXME: use threads
2996 #FIXME: should we retry outside the function?
2997 for n in range( 5 ): # Retry in case election is still happening
2998 leaderList = []
2999 # Get all leaderboards
3000 for cli in nodes:
3001 leaderList.append( cli.specificLeaderCandidate( TOPIC ) )
3002 # Compare leaderboards
3003 result = all( i == leaderList[0] for i in leaderList ) and\
3004 leaderList is not None
3005 main.log.debug( leaderList )
3006 main.log.warn( result )
3007 if result:
3008 return ( result, leaderList )
3009 time.sleep(5) #TODO: paramerterize
3010 main.log.error( "Inconsistent leaderboards:" + str( leaderList ) )
3011 activeCLIs = [ main.CLIs[i] for i in main.activeNodes ]
3012 sameResult, oldLeaders = consistentLeaderboards( activeCLIs )
3013 if sameResult:
3014 oldLeader = oldLeaders[ 0 ][ 0 ]
3015 main.log.warn( oldLeader )
acsmars9475b1c2015-08-28 18:02:08 -07003016 else:
Jon Halla440e872016-03-31 15:15:50 -07003017 oldLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07003018 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07003019 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07003020 actual=sameResult,
Jon Halla440e872016-03-31 15:15:50 -07003021 onpass="Leaderboards are consistent for the election topic",
acsmars9475b1c2015-08-28 18:02:08 -07003022 onfail=failMessage )
Jon Hall5cf14d52015-07-16 12:15:19 -07003023
3024 main.step( "Find current leader and withdraw" )
acsmars9475b1c2015-08-28 18:02:08 -07003025 withdrawResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07003026 # do some sanity checking on leader before using it
acsmars9475b1c2015-08-28 18:02:08 -07003027 if oldLeader is None:
3028 main.log.error( "Leadership isn't consistent." )
3029 withdrawResult = main.FALSE
3030 # Get the CLI of the oldLeader
Jon Halla440e872016-03-31 15:15:50 -07003031 for i in main.activeNodes:
acsmars9475b1c2015-08-28 18:02:08 -07003032 if oldLeader == main.nodes[ i ].ip_address:
3033 oldLeaderCLI = main.CLIs[ i ]
Jon Hall5cf14d52015-07-16 12:15:19 -07003034 break
3035 else: # FOR/ELSE statement
3036 main.log.error( "Leader election, could not find current leader" )
3037 if oldLeader:
acsmars9475b1c2015-08-28 18:02:08 -07003038 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall5cf14d52015-07-16 12:15:19 -07003039 utilities.assert_equals(
3040 expect=main.TRUE,
3041 actual=withdrawResult,
3042 onpass="Node was withdrawn from election",
3043 onfail="Node was not withdrawn from election" )
3044
acsmars9475b1c2015-08-28 18:02:08 -07003045 main.step( "Check that a new node was elected leader" )
acsmars9475b1c2015-08-28 18:02:08 -07003046 failMessage = "Nodes have different leaders"
acsmars9475b1c2015-08-28 18:02:08 -07003047 # Get new leaders and candidates
Jon Halla440e872016-03-31 15:15:50 -07003048 newLeaderResult, newLeaders = consistentLeaderboards( activeCLIs )
3049 if newLeaders[ 0 ][ 0 ] == 'none':
3050 main.log.error( "No leader was elected on at least 1 node" )
3051 if not expectNoLeader:
3052 newLeaderResult = False
3053 if newLeaderResult:
3054 newLeader = newLeaders[ 0 ][ 0 ]
Jon Hall5cf14d52015-07-16 12:15:19 -07003055 else:
Jon Halla440e872016-03-31 15:15:50 -07003056 newLeader = None
acsmars71adceb2015-08-31 15:09:26 -07003057
acsmars9475b1c2015-08-28 18:02:08 -07003058 # Check that the new leader is not the older leader, which was withdrawn
3059 if newLeader == oldLeader:
Jon Halla440e872016-03-31 15:15:50 -07003060 newLeaderResult = False
Jon Hall6e709752016-02-01 13:38:46 -08003061 main.log.error( "All nodes still see old leader: " + str( oldLeader ) +
acsmars9475b1c2015-08-28 18:02:08 -07003062 " as the current leader" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003063 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07003064 expect=True,
acsmars9475b1c2015-08-28 18:02:08 -07003065 actual=newLeaderResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07003066 onpass="Leadership election passed",
3067 onfail="Something went wrong with Leadership election" )
3068
Jon Halla440e872016-03-31 15:15:50 -07003069 main.step( "Check that that new leader was the candidate of old leader" )
Jon Hall6e709752016-02-01 13:38:46 -08003070 # candidates[ 2 ] should become the top candidate after withdrawl
acsmars9475b1c2015-08-28 18:02:08 -07003071 correctCandidateResult = main.TRUE
acsmars71adceb2015-08-31 15:09:26 -07003072 if expectNoLeader:
3073 if newLeader == 'none':
3074 main.log.info( "No leader expected. None found. Pass" )
3075 correctCandidateResult = main.TRUE
3076 else:
3077 main.log.info( "Expected no leader, got: " + str( newLeader ) )
3078 correctCandidateResult = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003079 elif len( oldLeaders[0] ) >= 3:
3080 if newLeader == oldLeaders[ 0 ][ 2 ]:
3081 # correct leader was elected
3082 correctCandidateResult = main.TRUE
3083 else:
3084 correctCandidateResult = main.FALSE
3085 main.log.error( "Candidate {} was elected. {} should have had priority.".format(
3086 newLeader, oldLeaders[ 0 ][ 2 ] ) )
Jon Hall6e709752016-02-01 13:38:46 -08003087 else:
3088 main.log.warn( "Could not determine who should be the correct leader" )
Jon Halla440e872016-03-31 15:15:50 -07003089 main.log.debug( oldLeaders[ 0 ] )
Jon Hall6e709752016-02-01 13:38:46 -08003090 correctCandidateResult = main.FALSE
acsmars9475b1c2015-08-28 18:02:08 -07003091 utilities.assert_equals(
3092 expect=main.TRUE,
3093 actual=correctCandidateResult,
3094 onpass="Correct Candidate Elected",
3095 onfail="Incorrect Candidate Elected" )
3096
Jon Hall5cf14d52015-07-16 12:15:19 -07003097 main.step( "Run for election on old leader( just so everyone " +
3098 "is in the hat )" )
acsmars9475b1c2015-08-28 18:02:08 -07003099 if oldLeaderCLI is not None:
3100 runResult = oldLeaderCLI.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07003101 else:
acsmars9475b1c2015-08-28 18:02:08 -07003102 main.log.error( "No old leader to re-elect" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003103 runResult = main.FALSE
3104 utilities.assert_equals(
3105 expect=main.TRUE,
3106 actual=runResult,
3107 onpass="App re-ran for election",
3108 onfail="App failed to run for election" )
Jon Halla440e872016-03-31 15:15:50 -07003109
acsmars9475b1c2015-08-28 18:02:08 -07003110 main.step(
3111 "Check that oldLeader is a candidate, and leader if only 1 node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003112 # verify leader didn't just change
Jon Halla440e872016-03-31 15:15:50 -07003113 # Get new leaders and candidates
3114 reRunLeaders = []
3115 time.sleep( 5 ) # Paremterize
3116 positionResult, reRunLeaders = consistentLeaderboards( activeCLIs )
acsmars71adceb2015-08-31 15:09:26 -07003117
acsmars9475b1c2015-08-28 18:02:08 -07003118 # Check that the re-elected node is last on the candidate List
Jon Halla440e872016-03-31 15:15:50 -07003119 if oldLeader != reRunLeaders[ 0 ][ -1 ]:
3120 main.log.error( "Old Leader ({}) not in the proper position: {} ".format( str( oldLeader),
3121 str( reRunLeaders[ 0 ] ) ) )
acsmars9475b1c2015-08-28 18:02:08 -07003122 positionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07003123
3124 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07003125 expect=True,
acsmars9475b1c2015-08-28 18:02:08 -07003126 actual=positionResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07003127 onpass="Old leader successfully re-ran for election",
3128 onfail="Something went wrong with Leadership election after " +
3129 "the old leader re-ran for election" )
3130
3131 def CASE16( self, main ):
3132 """
3133 Install Distributed Primitives app
3134 """
3135 import time
Jon Halle1a3b752015-07-22 13:02:46 -07003136 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003137 assert main, "main not defined"
3138 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003139 assert main.CLIs, "main.CLIs not defined"
3140 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003141
3142 # Variables for the distributed primitives tests
3143 global pCounterName
Jon Hall5cf14d52015-07-16 12:15:19 -07003144 global pCounterValue
Jon Hall5cf14d52015-07-16 12:15:19 -07003145 global onosSet
3146 global onosSetName
3147 pCounterName = "TestON-Partitions"
Jon Hall5cf14d52015-07-16 12:15:19 -07003148 pCounterValue = 0
Jon Hall5cf14d52015-07-16 12:15:19 -07003149 onosSet = set([])
3150 onosSetName = "TestON-set"
3151
3152 description = "Install Primitives app"
3153 main.case( description )
3154 main.step( "Install Primitives app" )
3155 appName = "org.onosproject.distributedprimitives"
Jon Halla440e872016-03-31 15:15:50 -07003156 node = main.activeNodes[0]
3157 appResults = main.CLIs[node].activateApp( appName )
Jon Hall5cf14d52015-07-16 12:15:19 -07003158 utilities.assert_equals( expect=main.TRUE,
3159 actual=appResults,
3160 onpass="Primitives app activated",
3161 onfail="Primitives app not activated" )
3162 time.sleep( 5 ) # To allow all nodes to activate
3163
3164 def CASE17( self, main ):
3165 """
3166 Check for basic functionality with distributed primitives
3167 """
Jon Hall5cf14d52015-07-16 12:15:19 -07003168 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07003169 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003170 assert main, "main not defined"
3171 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003172 assert main.CLIs, "main.CLIs not defined"
3173 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003174 assert pCounterName, "pCounterName not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003175 assert onosSetName, "onosSetName not defined"
3176 # NOTE: assert fails if value is 0/None/Empty/False
3177 try:
3178 pCounterValue
3179 except NameError:
3180 main.log.error( "pCounterValue not defined, setting to 0" )
3181 pCounterValue = 0
3182 try:
Jon Hall5cf14d52015-07-16 12:15:19 -07003183 onosSet
3184 except NameError:
3185 main.log.error( "onosSet not defined, setting to empty Set" )
3186 onosSet = set([])
3187 # Variables for the distributed primitives tests. These are local only
3188 addValue = "a"
3189 addAllValue = "a b c d e f"
3190 retainValue = "c d e f"
3191
3192 description = "Check for basic functionality with distributed " +\
3193 "primitives"
3194 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07003195 main.caseExplanation = "Test the methods of the distributed " +\
3196 "primitives (counters and sets) throught the cli"
Jon Hall5cf14d52015-07-16 12:15:19 -07003197 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07003198 # Partitioned counters
3199 main.step( "Increment then get a default counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003200 pCounters = []
3201 threads = []
3202 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003203 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003204 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3205 name="counterAddAndGet-" + str( i ),
Jon Hall5cf14d52015-07-16 12:15:19 -07003206 args=[ pCounterName ] )
3207 pCounterValue += 1
3208 addedPValues.append( pCounterValue )
3209 threads.append( t )
3210 t.start()
3211
3212 for t in threads:
3213 t.join()
3214 pCounters.append( t.result )
3215 # Check that counter incremented numController times
3216 pCounterResults = True
3217 for i in addedPValues:
3218 tmpResult = i in pCounters
3219 pCounterResults = pCounterResults and tmpResult
3220 if not tmpResult:
3221 main.log.error( str( i ) + " is not in partitioned "
3222 "counter incremented results" )
3223 utilities.assert_equals( expect=True,
3224 actual=pCounterResults,
3225 onpass="Default counter incremented",
3226 onfail="Error incrementing default" +
3227 " counter" )
3228
Jon Halle1a3b752015-07-22 13:02:46 -07003229 main.step( "Get then Increment a default counter on each node" )
3230 pCounters = []
3231 threads = []
3232 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003233 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003234 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3235 name="counterGetAndAdd-" + str( i ),
3236 args=[ pCounterName ] )
3237 addedPValues.append( pCounterValue )
3238 pCounterValue += 1
3239 threads.append( t )
3240 t.start()
3241
3242 for t in threads:
3243 t.join()
3244 pCounters.append( t.result )
3245 # Check that counter incremented numController times
3246 pCounterResults = True
3247 for i in addedPValues:
3248 tmpResult = i in pCounters
3249 pCounterResults = pCounterResults and tmpResult
3250 if not tmpResult:
3251 main.log.error( str( i ) + " is not in partitioned "
3252 "counter incremented results" )
3253 utilities.assert_equals( expect=True,
3254 actual=pCounterResults,
3255 onpass="Default counter incremented",
3256 onfail="Error incrementing default" +
3257 " counter" )
3258
3259 main.step( "Counters we added have the correct values" )
3260 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3261 utilities.assert_equals( expect=main.TRUE,
3262 actual=incrementCheck,
3263 onpass="Added counters are correct",
3264 onfail="Added counters are incorrect" )
3265
3266 main.step( "Add -8 to then get a default counter on each node" )
3267 pCounters = []
3268 threads = []
3269 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003270 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003271 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3272 name="counterIncrement-" + str( i ),
3273 args=[ pCounterName ],
3274 kwargs={ "delta": -8 } )
3275 pCounterValue += -8
3276 addedPValues.append( pCounterValue )
3277 threads.append( t )
3278 t.start()
3279
3280 for t in threads:
3281 t.join()
3282 pCounters.append( t.result )
3283 # Check that counter incremented numController times
3284 pCounterResults = True
3285 for i in addedPValues:
3286 tmpResult = i in pCounters
3287 pCounterResults = pCounterResults and tmpResult
3288 if not tmpResult:
3289 main.log.error( str( i ) + " is not in partitioned "
3290 "counter incremented results" )
3291 utilities.assert_equals( expect=True,
3292 actual=pCounterResults,
3293 onpass="Default counter incremented",
3294 onfail="Error incrementing default" +
3295 " counter" )
3296
3297 main.step( "Add 5 to then get a default counter on each node" )
3298 pCounters = []
3299 threads = []
3300 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003301 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003302 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3303 name="counterIncrement-" + str( i ),
3304 args=[ pCounterName ],
3305 kwargs={ "delta": 5 } )
3306 pCounterValue += 5
3307 addedPValues.append( pCounterValue )
3308 threads.append( t )
3309 t.start()
3310
3311 for t in threads:
3312 t.join()
3313 pCounters.append( t.result )
3314 # Check that counter incremented numController times
3315 pCounterResults = True
3316 for i in addedPValues:
3317 tmpResult = i in pCounters
3318 pCounterResults = pCounterResults and tmpResult
3319 if not tmpResult:
3320 main.log.error( str( i ) + " is not in partitioned "
3321 "counter incremented results" )
3322 utilities.assert_equals( expect=True,
3323 actual=pCounterResults,
3324 onpass="Default counter incremented",
3325 onfail="Error incrementing default" +
3326 " counter" )
3327
3328 main.step( "Get then add 5 to a default counter on each node" )
3329 pCounters = []
3330 threads = []
3331 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003332 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003333 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3334 name="counterIncrement-" + str( i ),
3335 args=[ pCounterName ],
3336 kwargs={ "delta": 5 } )
3337 addedPValues.append( pCounterValue )
3338 pCounterValue += 5
3339 threads.append( t )
3340 t.start()
3341
3342 for t in threads:
3343 t.join()
3344 pCounters.append( t.result )
3345 # Check that counter incremented numController times
3346 pCounterResults = True
3347 for i in addedPValues:
3348 tmpResult = i in pCounters
3349 pCounterResults = pCounterResults and tmpResult
3350 if not tmpResult:
3351 main.log.error( str( i ) + " is not in partitioned "
3352 "counter incremented results" )
3353 utilities.assert_equals( expect=True,
3354 actual=pCounterResults,
3355 onpass="Default counter incremented",
3356 onfail="Error incrementing default" +
3357 " counter" )
3358
3359 main.step( "Counters we added have the correct values" )
3360 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3361 utilities.assert_equals( expect=main.TRUE,
3362 actual=incrementCheck,
3363 onpass="Added counters are correct",
3364 onfail="Added counters are incorrect" )
3365
Jon Hall5cf14d52015-07-16 12:15:19 -07003366 # DISTRIBUTED SETS
3367 main.step( "Distributed Set get" )
3368 size = len( onosSet )
3369 getResponses = []
3370 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003371 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003372 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003373 name="setTestGet-" + str( i ),
3374 args=[ onosSetName ] )
3375 threads.append( t )
3376 t.start()
3377 for t in threads:
3378 t.join()
3379 getResponses.append( t.result )
3380
3381 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003382 for i in range( len( main.activeNodes ) ):
3383 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003384 if isinstance( getResponses[ i ], list):
3385 current = set( getResponses[ i ] )
3386 if len( current ) == len( getResponses[ i ] ):
3387 # no repeats
3388 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003389 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003390 " has incorrect view" +
3391 " of set " + onosSetName + ":\n" +
3392 str( getResponses[ i ] ) )
3393 main.log.debug( "Expected: " + str( onosSet ) )
3394 main.log.debug( "Actual: " + str( current ) )
3395 getResults = main.FALSE
3396 else:
3397 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003398 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003399 " has repeat elements in" +
3400 " set " + onosSetName + ":\n" +
3401 str( getResponses[ i ] ) )
3402 getResults = main.FALSE
3403 elif getResponses[ i ] == main.ERROR:
3404 getResults = main.FALSE
3405 utilities.assert_equals( expect=main.TRUE,
3406 actual=getResults,
3407 onpass="Set elements are correct",
3408 onfail="Set elements are incorrect" )
3409
3410 main.step( "Distributed Set size" )
3411 sizeResponses = []
3412 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003413 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003414 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003415 name="setTestSize-" + str( i ),
3416 args=[ onosSetName ] )
3417 threads.append( t )
3418 t.start()
3419 for t in threads:
3420 t.join()
3421 sizeResponses.append( t.result )
3422
3423 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003424 for i in range( len( main.activeNodes ) ):
3425 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003426 if size != sizeResponses[ i ]:
3427 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003428 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003429 " expected a size of " + str( size ) +
3430 " for set " + onosSetName +
3431 " but got " + str( sizeResponses[ i ] ) )
3432 utilities.assert_equals( expect=main.TRUE,
3433 actual=sizeResults,
3434 onpass="Set sizes are correct",
3435 onfail="Set sizes are incorrect" )
3436
3437 main.step( "Distributed Set add()" )
3438 onosSet.add( addValue )
3439 addResponses = []
3440 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003441 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003442 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003443 name="setTestAdd-" + str( i ),
3444 args=[ onosSetName, addValue ] )
3445 threads.append( t )
3446 t.start()
3447 for t in threads:
3448 t.join()
3449 addResponses.append( t.result )
3450
3451 # main.TRUE = successfully changed the set
3452 # main.FALSE = action resulted in no change in set
3453 # main.ERROR - Some error in executing the function
3454 addResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003455 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003456 if addResponses[ i ] == main.TRUE:
3457 # All is well
3458 pass
3459 elif addResponses[ i ] == main.FALSE:
3460 # Already in set, probably fine
3461 pass
3462 elif addResponses[ i ] == main.ERROR:
3463 # Error in execution
3464 addResults = main.FALSE
3465 else:
3466 # unexpected result
3467 addResults = main.FALSE
3468 if addResults != main.TRUE:
3469 main.log.error( "Error executing set add" )
3470
3471 # Check if set is still correct
3472 size = len( onosSet )
3473 getResponses = []
3474 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003475 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003476 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003477 name="setTestGet-" + str( i ),
3478 args=[ onosSetName ] )
3479 threads.append( t )
3480 t.start()
3481 for t in threads:
3482 t.join()
3483 getResponses.append( t.result )
3484 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003485 for i in range( len( main.activeNodes ) ):
3486 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003487 if isinstance( getResponses[ i ], list):
3488 current = set( getResponses[ i ] )
3489 if len( current ) == len( getResponses[ i ] ):
3490 # no repeats
3491 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003492 main.log.error( "ONOS" + node + " has incorrect view" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003493 " of set " + onosSetName + ":\n" +
3494 str( getResponses[ i ] ) )
3495 main.log.debug( "Expected: " + str( onosSet ) )
3496 main.log.debug( "Actual: " + str( current ) )
3497 getResults = main.FALSE
3498 else:
3499 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003500 main.log.error( "ONOS" + node + " has repeat elements in" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003501 " set " + onosSetName + ":\n" +
3502 str( getResponses[ i ] ) )
3503 getResults = main.FALSE
3504 elif getResponses[ i ] == main.ERROR:
3505 getResults = main.FALSE
3506 sizeResponses = []
3507 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003508 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003509 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003510 name="setTestSize-" + str( i ),
3511 args=[ onosSetName ] )
3512 threads.append( t )
3513 t.start()
3514 for t in threads:
3515 t.join()
3516 sizeResponses.append( t.result )
3517 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003518 for i in range( len( main.activeNodes ) ):
3519 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003520 if size != sizeResponses[ i ]:
3521 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003522 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003523 " expected a size of " + str( size ) +
3524 " for set " + onosSetName +
3525 " but got " + str( sizeResponses[ i ] ) )
3526 addResults = addResults and getResults and sizeResults
3527 utilities.assert_equals( expect=main.TRUE,
3528 actual=addResults,
3529 onpass="Set add correct",
3530 onfail="Set add was incorrect" )
3531
3532 main.step( "Distributed Set addAll()" )
3533 onosSet.update( addAllValue.split() )
3534 addResponses = []
3535 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003536 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003537 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003538 name="setTestAddAll-" + str( i ),
3539 args=[ onosSetName, addAllValue ] )
3540 threads.append( t )
3541 t.start()
3542 for t in threads:
3543 t.join()
3544 addResponses.append( t.result )
3545
3546 # main.TRUE = successfully changed the set
3547 # main.FALSE = action resulted in no change in set
3548 # main.ERROR - Some error in executing the function
3549 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003550 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003551 if addResponses[ i ] == main.TRUE:
3552 # All is well
3553 pass
3554 elif addResponses[ i ] == main.FALSE:
3555 # Already in set, probably fine
3556 pass
3557 elif addResponses[ i ] == main.ERROR:
3558 # Error in execution
3559 addAllResults = main.FALSE
3560 else:
3561 # unexpected result
3562 addAllResults = main.FALSE
3563 if addAllResults != main.TRUE:
3564 main.log.error( "Error executing set addAll" )
3565
3566 # Check if set is still correct
3567 size = len( onosSet )
3568 getResponses = []
3569 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003570 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003571 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003572 name="setTestGet-" + str( i ),
3573 args=[ onosSetName ] )
3574 threads.append( t )
3575 t.start()
3576 for t in threads:
3577 t.join()
3578 getResponses.append( t.result )
3579 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003580 for i in range( len( main.activeNodes ) ):
3581 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003582 if isinstance( getResponses[ i ], list):
3583 current = set( getResponses[ i ] )
3584 if len( current ) == len( getResponses[ i ] ):
3585 # no repeats
3586 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003587 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003588 " has incorrect view" +
3589 " of set " + onosSetName + ":\n" +
3590 str( getResponses[ i ] ) )
3591 main.log.debug( "Expected: " + str( onosSet ) )
3592 main.log.debug( "Actual: " + str( current ) )
3593 getResults = main.FALSE
3594 else:
3595 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003596 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003597 " has repeat elements in" +
3598 " set " + onosSetName + ":\n" +
3599 str( getResponses[ i ] ) )
3600 getResults = main.FALSE
3601 elif getResponses[ i ] == main.ERROR:
3602 getResults = main.FALSE
3603 sizeResponses = []
3604 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003605 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003606 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003607 name="setTestSize-" + str( i ),
3608 args=[ onosSetName ] )
3609 threads.append( t )
3610 t.start()
3611 for t in threads:
3612 t.join()
3613 sizeResponses.append( t.result )
3614 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003615 for i in range( len( main.activeNodes ) ):
3616 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003617 if size != sizeResponses[ i ]:
3618 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003619 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003620 " expected a size of " + str( size ) +
3621 " for set " + onosSetName +
3622 " but got " + str( sizeResponses[ i ] ) )
3623 addAllResults = addAllResults and getResults and sizeResults
3624 utilities.assert_equals( expect=main.TRUE,
3625 actual=addAllResults,
3626 onpass="Set addAll correct",
3627 onfail="Set addAll was incorrect" )
3628
3629 main.step( "Distributed Set contains()" )
3630 containsResponses = []
3631 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003632 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003633 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003634 name="setContains-" + str( i ),
3635 args=[ onosSetName ],
3636 kwargs={ "values": addValue } )
3637 threads.append( t )
3638 t.start()
3639 for t in threads:
3640 t.join()
3641 # NOTE: This is the tuple
3642 containsResponses.append( t.result )
3643
3644 containsResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003645 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003646 if containsResponses[ i ] == main.ERROR:
3647 containsResults = main.FALSE
3648 else:
3649 containsResults = containsResults and\
3650 containsResponses[ i ][ 1 ]
3651 utilities.assert_equals( expect=main.TRUE,
3652 actual=containsResults,
3653 onpass="Set contains is functional",
3654 onfail="Set contains failed" )
3655
3656 main.step( "Distributed Set containsAll()" )
3657 containsAllResponses = []
3658 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003659 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003660 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003661 name="setContainsAll-" + str( i ),
3662 args=[ onosSetName ],
3663 kwargs={ "values": addAllValue } )
3664 threads.append( t )
3665 t.start()
3666 for t in threads:
3667 t.join()
3668 # NOTE: This is the tuple
3669 containsAllResponses.append( t.result )
3670
3671 containsAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003672 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003673 if containsResponses[ i ] == main.ERROR:
3674 containsResults = main.FALSE
3675 else:
3676 containsResults = containsResults and\
3677 containsResponses[ i ][ 1 ]
3678 utilities.assert_equals( expect=main.TRUE,
3679 actual=containsAllResults,
3680 onpass="Set containsAll is functional",
3681 onfail="Set containsAll failed" )
3682
3683 main.step( "Distributed Set remove()" )
3684 onosSet.remove( addValue )
3685 removeResponses = []
3686 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003687 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003688 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003689 name="setTestRemove-" + str( i ),
3690 args=[ onosSetName, addValue ] )
3691 threads.append( t )
3692 t.start()
3693 for t in threads:
3694 t.join()
3695 removeResponses.append( t.result )
3696
3697 # main.TRUE = successfully changed the set
3698 # main.FALSE = action resulted in no change in set
3699 # main.ERROR - Some error in executing the function
3700 removeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003701 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003702 if removeResponses[ i ] == main.TRUE:
3703 # All is well
3704 pass
3705 elif removeResponses[ i ] == main.FALSE:
3706 # not in set, probably fine
3707 pass
3708 elif removeResponses[ i ] == main.ERROR:
3709 # Error in execution
3710 removeResults = main.FALSE
3711 else:
3712 # unexpected result
3713 removeResults = main.FALSE
3714 if removeResults != main.TRUE:
3715 main.log.error( "Error executing set remove" )
3716
3717 # Check if set is still correct
3718 size = len( onosSet )
3719 getResponses = []
3720 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003721 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003722 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003723 name="setTestGet-" + str( i ),
3724 args=[ onosSetName ] )
3725 threads.append( t )
3726 t.start()
3727 for t in threads:
3728 t.join()
3729 getResponses.append( t.result )
3730 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003731 for i in range( len( main.activeNodes ) ):
3732 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003733 if isinstance( getResponses[ i ], list):
3734 current = set( getResponses[ i ] )
3735 if len( current ) == len( getResponses[ i ] ):
3736 # no repeats
3737 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003738 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003739 " has incorrect view" +
3740 " of set " + onosSetName + ":\n" +
3741 str( getResponses[ i ] ) )
3742 main.log.debug( "Expected: " + str( onosSet ) )
3743 main.log.debug( "Actual: " + str( current ) )
3744 getResults = main.FALSE
3745 else:
3746 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003747 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003748 " has repeat elements in" +
3749 " set " + onosSetName + ":\n" +
3750 str( getResponses[ i ] ) )
3751 getResults = main.FALSE
3752 elif getResponses[ i ] == main.ERROR:
3753 getResults = main.FALSE
3754 sizeResponses = []
3755 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003756 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003757 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003758 name="setTestSize-" + str( i ),
3759 args=[ onosSetName ] )
3760 threads.append( t )
3761 t.start()
3762 for t in threads:
3763 t.join()
3764 sizeResponses.append( t.result )
3765 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003766 for i in range( len( main.activeNodes ) ):
3767 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003768 if size != sizeResponses[ i ]:
3769 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003770 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003771 " expected a size of " + str( size ) +
3772 " for set " + onosSetName +
3773 " but got " + str( sizeResponses[ i ] ) )
3774 removeResults = removeResults and getResults and sizeResults
3775 utilities.assert_equals( expect=main.TRUE,
3776 actual=removeResults,
3777 onpass="Set remove correct",
3778 onfail="Set remove was incorrect" )
3779
3780 main.step( "Distributed Set removeAll()" )
3781 onosSet.difference_update( addAllValue.split() )
3782 removeAllResponses = []
3783 threads = []
3784 try:
Jon Halla440e872016-03-31 15:15:50 -07003785 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003786 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003787 name="setTestRemoveAll-" + str( i ),
3788 args=[ onosSetName, addAllValue ] )
3789 threads.append( t )
3790 t.start()
3791 for t in threads:
3792 t.join()
3793 removeAllResponses.append( t.result )
3794 except Exception, e:
3795 main.log.exception(e)
3796
3797 # main.TRUE = successfully changed the set
3798 # main.FALSE = action resulted in no change in set
3799 # main.ERROR - Some error in executing the function
3800 removeAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003801 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003802 if removeAllResponses[ i ] == main.TRUE:
3803 # All is well
3804 pass
3805 elif removeAllResponses[ i ] == main.FALSE:
3806 # not in set, probably fine
3807 pass
3808 elif removeAllResponses[ i ] == main.ERROR:
3809 # Error in execution
3810 removeAllResults = main.FALSE
3811 else:
3812 # unexpected result
3813 removeAllResults = main.FALSE
3814 if removeAllResults != main.TRUE:
3815 main.log.error( "Error executing set removeAll" )
3816
3817 # Check if set is still correct
3818 size = len( onosSet )
3819 getResponses = []
3820 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003821 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003822 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003823 name="setTestGet-" + str( i ),
3824 args=[ onosSetName ] )
3825 threads.append( t )
3826 t.start()
3827 for t in threads:
3828 t.join()
3829 getResponses.append( t.result )
3830 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003831 for i in range( len( main.activeNodes ) ):
3832 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003833 if isinstance( getResponses[ i ], list):
3834 current = set( getResponses[ i ] )
3835 if len( current ) == len( getResponses[ i ] ):
3836 # no repeats
3837 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003838 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003839 " has incorrect view" +
3840 " of set " + onosSetName + ":\n" +
3841 str( getResponses[ i ] ) )
3842 main.log.debug( "Expected: " + str( onosSet ) )
3843 main.log.debug( "Actual: " + str( current ) )
3844 getResults = main.FALSE
3845 else:
3846 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003847 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003848 " has repeat elements in" +
3849 " set " + onosSetName + ":\n" +
3850 str( getResponses[ i ] ) )
3851 getResults = main.FALSE
3852 elif getResponses[ i ] == main.ERROR:
3853 getResults = main.FALSE
3854 sizeResponses = []
3855 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003856 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003857 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003858 name="setTestSize-" + str( i ),
3859 args=[ onosSetName ] )
3860 threads.append( t )
3861 t.start()
3862 for t in threads:
3863 t.join()
3864 sizeResponses.append( t.result )
3865 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003866 for i in range( len( main.activeNodes ) ):
3867 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003868 if size != sizeResponses[ i ]:
3869 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003870 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003871 " expected a size of " + str( size ) +
3872 " for set " + onosSetName +
3873 " but got " + str( sizeResponses[ i ] ) )
3874 removeAllResults = removeAllResults and getResults and sizeResults
3875 utilities.assert_equals( expect=main.TRUE,
3876 actual=removeAllResults,
3877 onpass="Set removeAll correct",
3878 onfail="Set removeAll was incorrect" )
3879
3880 main.step( "Distributed Set addAll()" )
3881 onosSet.update( addAllValue.split() )
3882 addResponses = []
3883 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003884 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003885 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003886 name="setTestAddAll-" + str( i ),
3887 args=[ onosSetName, addAllValue ] )
3888 threads.append( t )
3889 t.start()
3890 for t in threads:
3891 t.join()
3892 addResponses.append( t.result )
3893
3894 # main.TRUE = successfully changed the set
3895 # main.FALSE = action resulted in no change in set
3896 # main.ERROR - Some error in executing the function
3897 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003898 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003899 if addResponses[ i ] == main.TRUE:
3900 # All is well
3901 pass
3902 elif addResponses[ i ] == main.FALSE:
3903 # Already in set, probably fine
3904 pass
3905 elif addResponses[ i ] == main.ERROR:
3906 # Error in execution
3907 addAllResults = main.FALSE
3908 else:
3909 # unexpected result
3910 addAllResults = main.FALSE
3911 if addAllResults != main.TRUE:
3912 main.log.error( "Error executing set addAll" )
3913
3914 # Check if set is still correct
3915 size = len( onosSet )
3916 getResponses = []
3917 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003918 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003919 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003920 name="setTestGet-" + str( i ),
3921 args=[ onosSetName ] )
3922 threads.append( t )
3923 t.start()
3924 for t in threads:
3925 t.join()
3926 getResponses.append( t.result )
3927 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003928 for i in range( len( main.activeNodes ) ):
3929 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003930 if isinstance( getResponses[ i ], list):
3931 current = set( getResponses[ i ] )
3932 if len( current ) == len( getResponses[ i ] ):
3933 # no repeats
3934 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003935 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003936 " has incorrect view" +
3937 " of set " + onosSetName + ":\n" +
3938 str( getResponses[ i ] ) )
3939 main.log.debug( "Expected: " + str( onosSet ) )
3940 main.log.debug( "Actual: " + str( current ) )
3941 getResults = main.FALSE
3942 else:
3943 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003944 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003945 " has repeat elements in" +
3946 " set " + onosSetName + ":\n" +
3947 str( getResponses[ i ] ) )
3948 getResults = main.FALSE
3949 elif getResponses[ i ] == main.ERROR:
3950 getResults = main.FALSE
3951 sizeResponses = []
3952 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003953 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003954 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003955 name="setTestSize-" + str( i ),
3956 args=[ onosSetName ] )
3957 threads.append( t )
3958 t.start()
3959 for t in threads:
3960 t.join()
3961 sizeResponses.append( t.result )
3962 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003963 for i in range( len( main.activeNodes ) ):
3964 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003965 if size != sizeResponses[ i ]:
3966 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003967 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003968 " expected a size of " + str( size ) +
3969 " for set " + onosSetName +
3970 " but got " + str( sizeResponses[ i ] ) )
3971 addAllResults = addAllResults and getResults and sizeResults
3972 utilities.assert_equals( expect=main.TRUE,
3973 actual=addAllResults,
3974 onpass="Set addAll correct",
3975 onfail="Set addAll was incorrect" )
3976
3977 main.step( "Distributed Set clear()" )
3978 onosSet.clear()
3979 clearResponses = []
3980 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003981 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003982 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003983 name="setTestClear-" + str( i ),
3984 args=[ onosSetName, " "], # Values doesn't matter
3985 kwargs={ "clear": True } )
3986 threads.append( t )
3987 t.start()
3988 for t in threads:
3989 t.join()
3990 clearResponses.append( t.result )
3991
3992 # main.TRUE = successfully changed the set
3993 # main.FALSE = action resulted in no change in set
3994 # main.ERROR - Some error in executing the function
3995 clearResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003996 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003997 if clearResponses[ i ] == main.TRUE:
3998 # All is well
3999 pass
4000 elif clearResponses[ i ] == main.FALSE:
4001 # Nothing set, probably fine
4002 pass
4003 elif clearResponses[ i ] == main.ERROR:
4004 # Error in execution
4005 clearResults = main.FALSE
4006 else:
4007 # unexpected result
4008 clearResults = main.FALSE
4009 if clearResults != main.TRUE:
4010 main.log.error( "Error executing set clear" )
4011
4012 # Check if set is still correct
4013 size = len( onosSet )
4014 getResponses = []
4015 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004016 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004017 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004018 name="setTestGet-" + str( i ),
4019 args=[ onosSetName ] )
4020 threads.append( t )
4021 t.start()
4022 for t in threads:
4023 t.join()
4024 getResponses.append( t.result )
4025 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004026 for i in range( len( main.activeNodes ) ):
4027 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004028 if isinstance( getResponses[ i ], list):
4029 current = set( getResponses[ i ] )
4030 if len( current ) == len( getResponses[ i ] ):
4031 # no repeats
4032 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08004033 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004034 " has incorrect view" +
4035 " of set " + onosSetName + ":\n" +
4036 str( getResponses[ i ] ) )
4037 main.log.debug( "Expected: " + str( onosSet ) )
4038 main.log.debug( "Actual: " + str( current ) )
4039 getResults = main.FALSE
4040 else:
4041 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08004042 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004043 " has repeat elements in" +
4044 " set " + onosSetName + ":\n" +
4045 str( getResponses[ i ] ) )
4046 getResults = main.FALSE
4047 elif getResponses[ i ] == main.ERROR:
4048 getResults = main.FALSE
4049 sizeResponses = []
4050 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004051 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004052 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004053 name="setTestSize-" + str( i ),
4054 args=[ onosSetName ] )
4055 threads.append( t )
4056 t.start()
4057 for t in threads:
4058 t.join()
4059 sizeResponses.append( t.result )
4060 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004061 for i in range( len( main.activeNodes ) ):
4062 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004063 if size != sizeResponses[ i ]:
4064 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08004065 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004066 " expected a size of " + str( size ) +
4067 " for set " + onosSetName +
4068 " but got " + str( sizeResponses[ i ] ) )
4069 clearResults = clearResults and getResults and sizeResults
4070 utilities.assert_equals( expect=main.TRUE,
4071 actual=clearResults,
4072 onpass="Set clear correct",
4073 onfail="Set clear was incorrect" )
4074
4075 main.step( "Distributed Set addAll()" )
4076 onosSet.update( addAllValue.split() )
4077 addResponses = []
4078 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004079 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004080 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004081 name="setTestAddAll-" + str( i ),
4082 args=[ onosSetName, addAllValue ] )
4083 threads.append( t )
4084 t.start()
4085 for t in threads:
4086 t.join()
4087 addResponses.append( t.result )
4088
4089 # main.TRUE = successfully changed the set
4090 # main.FALSE = action resulted in no change in set
4091 # main.ERROR - Some error in executing the function
4092 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004093 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004094 if addResponses[ i ] == main.TRUE:
4095 # All is well
4096 pass
4097 elif addResponses[ i ] == main.FALSE:
4098 # Already in set, probably fine
4099 pass
4100 elif addResponses[ i ] == main.ERROR:
4101 # Error in execution
4102 addAllResults = main.FALSE
4103 else:
4104 # unexpected result
4105 addAllResults = main.FALSE
4106 if addAllResults != main.TRUE:
4107 main.log.error( "Error executing set addAll" )
4108
4109 # Check if set is still correct
4110 size = len( onosSet )
4111 getResponses = []
4112 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004113 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004114 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004115 name="setTestGet-" + str( i ),
4116 args=[ onosSetName ] )
4117 threads.append( t )
4118 t.start()
4119 for t in threads:
4120 t.join()
4121 getResponses.append( t.result )
4122 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004123 for i in range( len( main.activeNodes ) ):
4124 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004125 if isinstance( getResponses[ i ], list):
4126 current = set( getResponses[ i ] )
4127 if len( current ) == len( getResponses[ i ] ):
4128 # no repeats
4129 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08004130 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004131 " has incorrect view" +
4132 " of set " + onosSetName + ":\n" +
4133 str( getResponses[ i ] ) )
4134 main.log.debug( "Expected: " + str( onosSet ) )
4135 main.log.debug( "Actual: " + str( current ) )
4136 getResults = main.FALSE
4137 else:
4138 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08004139 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004140 " has repeat elements in" +
4141 " set " + onosSetName + ":\n" +
4142 str( getResponses[ i ] ) )
4143 getResults = main.FALSE
4144 elif getResponses[ i ] == main.ERROR:
4145 getResults = main.FALSE
4146 sizeResponses = []
4147 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004148 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004149 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004150 name="setTestSize-" + str( i ),
4151 args=[ onosSetName ] )
4152 threads.append( t )
4153 t.start()
4154 for t in threads:
4155 t.join()
4156 sizeResponses.append( t.result )
4157 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004158 for i in range( len( main.activeNodes ) ):
4159 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004160 if size != sizeResponses[ i ]:
4161 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08004162 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004163 " expected a size of " + str( size ) +
4164 " for set " + onosSetName +
4165 " but got " + str( sizeResponses[ i ] ) )
4166 addAllResults = addAllResults and getResults and sizeResults
4167 utilities.assert_equals( expect=main.TRUE,
4168 actual=addAllResults,
4169 onpass="Set addAll correct",
4170 onfail="Set addAll was incorrect" )
4171
4172 main.step( "Distributed Set retain()" )
4173 onosSet.intersection_update( retainValue.split() )
4174 retainResponses = []
4175 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004176 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004177 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004178 name="setTestRetain-" + str( i ),
4179 args=[ onosSetName, retainValue ],
4180 kwargs={ "retain": True } )
4181 threads.append( t )
4182 t.start()
4183 for t in threads:
4184 t.join()
4185 retainResponses.append( t.result )
4186
4187 # main.TRUE = successfully changed the set
4188 # main.FALSE = action resulted in no change in set
4189 # main.ERROR - Some error in executing the function
4190 retainResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004191 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004192 if retainResponses[ i ] == main.TRUE:
4193 # All is well
4194 pass
4195 elif retainResponses[ i ] == main.FALSE:
4196 # Already in set, probably fine
4197 pass
4198 elif retainResponses[ i ] == main.ERROR:
4199 # Error in execution
4200 retainResults = main.FALSE
4201 else:
4202 # unexpected result
4203 retainResults = main.FALSE
4204 if retainResults != main.TRUE:
4205 main.log.error( "Error executing set retain" )
4206
4207 # Check if set is still correct
4208 size = len( onosSet )
4209 getResponses = []
4210 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004211 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004212 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004213 name="setTestGet-" + str( i ),
4214 args=[ onosSetName ] )
4215 threads.append( t )
4216 t.start()
4217 for t in threads:
4218 t.join()
4219 getResponses.append( t.result )
4220 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004221 for i in range( len( main.activeNodes ) ):
4222 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004223 if isinstance( getResponses[ i ], list):
4224 current = set( getResponses[ i ] )
4225 if len( current ) == len( getResponses[ i ] ):
4226 # no repeats
4227 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08004228 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004229 " has incorrect view" +
4230 " of set " + onosSetName + ":\n" +
4231 str( getResponses[ i ] ) )
4232 main.log.debug( "Expected: " + str( onosSet ) )
4233 main.log.debug( "Actual: " + str( current ) )
4234 getResults = main.FALSE
4235 else:
4236 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08004237 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004238 " has repeat elements in" +
4239 " set " + onosSetName + ":\n" +
4240 str( getResponses[ i ] ) )
4241 getResults = main.FALSE
4242 elif getResponses[ i ] == main.ERROR:
4243 getResults = main.FALSE
4244 sizeResponses = []
4245 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004246 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004247 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004248 name="setTestSize-" + str( i ),
4249 args=[ onosSetName ] )
4250 threads.append( t )
4251 t.start()
4252 for t in threads:
4253 t.join()
4254 sizeResponses.append( t.result )
4255 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004256 for i in range( len( main.activeNodes ) ):
4257 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004258 if size != sizeResponses[ i ]:
4259 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08004260 main.log.error( "ONOS" + node + " expected a size of " +
Jon Hall5cf14d52015-07-16 12:15:19 -07004261 str( size ) + " for set " + onosSetName +
4262 " but got " + str( sizeResponses[ i ] ) )
4263 retainResults = retainResults and getResults and sizeResults
4264 utilities.assert_equals( expect=main.TRUE,
4265 actual=retainResults,
4266 onpass="Set retain correct",
4267 onfail="Set retain was incorrect" )
4268
Jon Hall2a5002c2015-08-21 16:49:11 -07004269 # Transactional maps
4270 main.step( "Partitioned Transactional maps put" )
4271 tMapValue = "Testing"
4272 numKeys = 100
4273 putResult = True
Jon Halla440e872016-03-31 15:15:50 -07004274 node = main.activeNodes[0]
4275 putResponses = main.CLIs[node].transactionalMapPut( numKeys, tMapValue )
Jon Hall6e709752016-02-01 13:38:46 -08004276 if putResponses and len( putResponses ) == 100:
Jon Hall2a5002c2015-08-21 16:49:11 -07004277 for i in putResponses:
4278 if putResponses[ i ][ 'value' ] != tMapValue:
4279 putResult = False
4280 else:
4281 putResult = False
4282 if not putResult:
4283 main.log.debug( "Put response values: " + str( putResponses ) )
4284 utilities.assert_equals( expect=True,
4285 actual=putResult,
4286 onpass="Partitioned Transactional Map put successful",
4287 onfail="Partitioned Transactional Map put values are incorrect" )
4288
4289 main.step( "Partitioned Transactional maps get" )
4290 getCheck = True
4291 for n in range( 1, numKeys + 1 ):
4292 getResponses = []
4293 threads = []
4294 valueCheck = True
Jon Halla440e872016-03-31 15:15:50 -07004295 for i in main.activeNodes:
Jon Hall2a5002c2015-08-21 16:49:11 -07004296 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4297 name="TMap-get-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08004298 args=[ "Key" + str( n ) ] )
Jon Hall2a5002c2015-08-21 16:49:11 -07004299 threads.append( t )
4300 t.start()
4301 for t in threads:
4302 t.join()
4303 getResponses.append( t.result )
4304 for node in getResponses:
4305 if node != tMapValue:
4306 valueCheck = False
4307 if not valueCheck:
4308 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4309 main.log.warn( getResponses )
4310 getCheck = getCheck and valueCheck
4311 utilities.assert_equals( expect=True,
4312 actual=getCheck,
4313 onpass="Partitioned Transactional Map get values were correct",
4314 onfail="Partitioned Transactional Map values incorrect" )