blob: a3865db17d169385d1117d8f41b8db9e373a952d [file] [log] [blame]
Jon Hall85794ff2015-07-08 14:12:30 -07001"""
2Description: This test is to determine if a single
3 instance ONOS 'cluster' can handle a restart
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 HAsingleInstanceRestart:
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 Hall85794ff2015-07-08 14:12:30 -070053 main.log.info( "ONOS Single node cluster restart " +
54 "HA test - initialization" )
55 main.case( "Setting up test environment" )
Jon Hall783bbf92015-07-23 14:33:19 -070056 main.caseExplanation = "Setup the test environment including " +\
Jon Hall85794ff2015-07-08 14:12:30 -070057 "installing ONOS, starting Mininet and ONOS" +\
58 "cli sessions."
Jon Hall85794ff2015-07-08 14:12:30 -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 )
Jon Hall85794ff2015-07-08 14:12:30 -070071
Jon Halle1a3b752015-07-22 13:02:46 -070072 try:
Jon Halla440e872016-03-31 15:15:50 -070073 from tests.HAsanity.dependencies.Counters import Counters
74 main.Counters = Counters()
Jon Halle1a3b752015-07-22 13:02:46 -070075 except Exception as e:
76 main.log.exception( e )
77 main.cleanup()
78 main.exit()
79
80 main.CLIs = []
81 main.nodes = []
Jon Hall5cf14d52015-07-16 12:15:19 -070082 ipList = []
83 for i in range( 1, int( main.ONOSbench.maxNodes ) + 1 ):
84 try:
Jon Halle1a3b752015-07-22 13:02:46 -070085 main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
86 main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
87 ipList.append( main.nodes[ -1 ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -070088 except AttributeError:
89 break
Jon Hall85794ff2015-07-08 14:12:30 -070090
Jon Hall5cf14d52015-07-16 12:15:19 -070091 main.step( "Create cell file" )
92 cellAppString = main.params[ 'ENV' ][ 'appString' ]
93 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
94 main.Mininet1.ip_address,
95 cellAppString, ipList )
Jon Hall85794ff2015-07-08 14:12:30 -070096 main.step( "Applying cell variable to environment" )
97 cellResult = main.ONOSbench.setCell( cellName )
98 verifyResult = main.ONOSbench.verifyCell()
99
100 # FIXME:this is short term fix
101 main.log.info( "Removing raft logs" )
102 main.ONOSbench.onosRemoveRaftLogs()
103
104 main.log.info( "Uninstalling ONOS" )
Jon Halle1a3b752015-07-22 13:02:46 -0700105 for node in main.nodes:
Jon Hall85794ff2015-07-08 14:12:30 -0700106 main.ONOSbench.onosUninstall( node.ip_address )
107
108 # Make sure ONOS is DEAD
109 main.log.info( "Killing any ONOS processes" )
110 killResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700111 for node in main.nodes:
Jon Hall85794ff2015-07-08 14:12:30 -0700112 killed = main.ONOSbench.onosKill( node.ip_address )
113 killResults = killResults and killed
114
115 cleanInstallResult = main.TRUE
116 gitPullResult = main.TRUE
117
118 main.step( "Starting Mininet" )
119 # scp topo file to mininet
120 # TODO: move to params?
121 topoName = "obelisk.py"
122 filePath = main.ONOSbench.home + "/tools/test/topos/"
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700123 main.ONOSbench.scp( main.Mininet1,
124 filePath + topoName,
125 main.Mininet1.home,
126 direction="to" )
Jon Hall85794ff2015-07-08 14:12:30 -0700127 mnResult = main.Mininet1.startNet( )
128 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
129 onpass="Mininet Started",
130 onfail="Error starting Mininet" )
131
132 main.step( "Git checkout and pull " + gitBranch )
133 if PULLCODE:
134 main.ONOSbench.gitCheckout( gitBranch )
135 gitPullResult = main.ONOSbench.gitPull()
136 # values of 1 or 3 are good
137 utilities.assert_lesser( expect=0, actual=gitPullResult,
138 onpass="Git pull successful",
139 onfail="Git pull failed" )
140 main.ONOSbench.getVersion( report=True )
141
142 main.step( "Using mvn clean install" )
143 cleanInstallResult = main.TRUE
144 if PULLCODE and gitPullResult == main.TRUE:
145 cleanInstallResult = main.ONOSbench.cleanInstall()
146 else:
147 main.log.warn( "Did not pull new code so skipping mvn " +
148 "clean install" )
149 utilities.assert_equals( expect=main.TRUE,
150 actual=cleanInstallResult,
151 onpass="MCI successful",
152 onfail="MCI failed" )
153 # GRAPHS
154 # NOTE: important params here:
155 # job = name of Jenkins job
156 # Plot Name = Plot-HA, only can be used if multiple plots
157 # index = The number of the graph under plot name
Jon Hall5cf14d52015-07-16 12:15:19 -0700158 job = "HAsingleInstanceRestart"
Jon Hall85794ff2015-07-08 14:12:30 -0700159 plotName = "Plot-HA"
Jon Hall843f8bc2016-03-18 14:28:13 -0700160 index = "2"
Jon Hall85794ff2015-07-08 14:12:30 -0700161 graphs = '<ac:structured-macro ac:name="html">\n'
162 graphs += '<ac:plain-text-body><![CDATA[\n'
163 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
Jon Halla9845df2016-01-15 14:55:58 -0800164 '/plot/' + plotName + '/getPlot?index=' + index +\
Jon Hall85794ff2015-07-08 14:12:30 -0700165 '&width=500&height=300"' +\
166 'noborder="0" width="500" height="300" scrolling="yes" ' +\
167 'seamless="seamless"></iframe>\n'
168 graphs += ']]></ac:plain-text-body>\n'
169 graphs += '</ac:structured-macro>\n'
170 main.log.wiki(graphs)
171
Jon Halle1a3b752015-07-22 13:02:46 -0700172 main.CLIs = []
173 main.nodes = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700174 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700175 for i in range( 1, main.numCtrls + 1 ):
176 main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
177 main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
178 ipList.append( main.nodes[ -1 ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -0700179
180 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, "SingleHA",
181 main.Mininet1.ip_address,
182 cellAppString, ipList[ 0 ] )
Jon Hall85794ff2015-07-08 14:12:30 -0700183 cellResult = main.ONOSbench.setCell( "SingleHA" )
184 verifyResult = main.ONOSbench.verifyCell()
185 main.step( "Creating ONOS package" )
186 packageResult = main.ONOSbench.onosPackage()
187 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
188 onpass="ONOS package successful",
189 onfail="ONOS package failed" )
190
191 main.step( "Installing ONOS package" )
Jon Halla440e872016-03-31 15:15:50 -0700192 onosInstallResult = main.TRUE
193 for node in main.nodes:
194 tmpResult = main.ONOSbench.onosInstall( options="-f",
195 node=node.ip_address )
196 onosInstallResult = onosInstallResult and tmpResult
Jon Hall85794ff2015-07-08 14:12:30 -0700197 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
198 onpass="ONOS install successful",
199 onfail="ONOS install failed" )
200
201 main.step( "Checking if ONOS is up yet" )
202 for i in range( 2 ):
Jon Halla440e872016-03-31 15:15:50 -0700203 onosIsupResult = main.TRUE
204 for node in main.nodes:
205 started = main.ONOSbench.isup( node.ip_address )
206 if not started:
207 main.log.error( node.name + " hasn't started" )
208 onosIsupResult = onosIsupResult and started
209 if onosIsupResult == main.TRUE:
Jon Hall85794ff2015-07-08 14:12:30 -0700210 break
Jon Halla440e872016-03-31 15:15:50 -0700211 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
Jon Hall85794ff2015-07-08 14:12:30 -0700212 onpass="ONOS startup successful",
213 onfail="ONOS startup failed" )
214
215 main.log.step( "Starting ONOS CLI sessions" )
Jon Halla440e872016-03-31 15:15:50 -0700216 cliResults = main.TRUE
217 threads = []
218 for i in range( main.numCtrls ):
219 t = main.Thread( target=main.CLIs[i].startOnosCli,
220 name="startOnosCli-" + str( i ),
221 args=[main.nodes[i].ip_address] )
222 threads.append( t )
223 t.start()
224
225 for t in threads:
226 t.join()
227 cliResults = cliResults and t.result
Jon Hall85794ff2015-07-08 14:12:30 -0700228 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
229 onpass="ONOS cli startup successful",
230 onfail="ONOS cli startup failed" )
231
Jon Halla440e872016-03-31 15:15:50 -0700232 # Create a list of active nodes for use when some nodes are stopped
233 main.activeNodes = [ i for i in range( 0, len( main.CLIs ) ) ]
234
Jon Hall85794ff2015-07-08 14:12:30 -0700235 if main.params[ 'tcpdump' ].lower() == "true":
236 main.step( "Start Packet Capture MN" )
237 main.Mininet2.startTcpdump(
238 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
239 + "-MN.pcap",
240 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
241 port=main.params[ 'MNtcpdump' ][ 'port' ] )
242
243 main.step( "App Ids check" )
Jon Halla440e872016-03-31 15:15:50 -0700244 appCheck = main.TRUE
245 threads = []
246 for i in main.activeNodes:
247 t = main.Thread( target=main.CLIs[i].appToIDCheck,
248 name="appToIDCheck-" + str( i ),
249 args=[] )
250 threads.append( t )
251 t.start()
252
253 for t in threads:
254 t.join()
255 appCheck = appCheck and t.result
Jon Hall85794ff2015-07-08 14:12:30 -0700256 if appCheck != main.TRUE:
Jon Halla440e872016-03-31 15:15:50 -0700257 node = main.activeNodes[0]
258 main.log.warn( main.CLIs[node].apps() )
259 main.log.warn( main.CLIs[node].appIDs() )
Jon Hall85794ff2015-07-08 14:12:30 -0700260 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
261 onpass="App Ids seem to be correct",
262 onfail="Something is wrong with app Ids" )
263
Jon Halla440e872016-03-31 15:15:50 -0700264 main.step( "Checking ONOS nodes" )
265 nodesOutput = []
266 nodeResults = main.TRUE
267 threads = []
268 for i in main.activeNodes:
269 t = main.Thread( target=main.CLIs[i].nodes,
270 name="nodes-" + str( i ),
271 args=[ ] )
272 threads.append( t )
273 t.start()
274
275 for t in threads:
276 t.join()
277 nodesOutput.append( t.result )
278 ips = [ main.nodes[node].ip_address for node in main.activeNodes ]
279 ips.sort()
280 for i in nodesOutput:
281 try:
282 current = json.loads( i )
283 activeIps = []
284 currentResult = main.FALSE
285 for node in current:
286 if node['state'] == 'READY':
287 activeIps.append( node['ip'] )
288 activeIps.sort()
289 if ips == activeIps:
290 currentResult = main.TRUE
291 except ( ValueError, TypeError ):
292 main.log.error( "Error parsing nodes output" )
293 main.log.warn( repr( i ) )
294 currentResult = main.FALSE
295 nodeResults = nodeResults and currentResult
296 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
297 onpass="Nodes check successful",
298 onfail="Nodes check NOT successful" )
299
300 if not nodeResults:
301 for cli in main.CLIs:
302 main.log.debug( "{} components not ACTIVE: \n{}".format(
303 cli.name,
304 cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
305
Jon Hall85794ff2015-07-08 14:12:30 -0700306 if cliResults == main.FALSE:
307 main.log.error( "Failed to start ONOS, stopping test" )
308 main.cleanup()
309 main.exit()
310
Jon Hall172b7ba2016-04-07 18:12:20 -0700311 main.step( "Activate apps defined in the params file" )
312 # get data from the params
313 apps = main.params.get( 'apps' )
314 if apps:
315 apps = apps.split(',')
316 main.log.warn( apps )
317 activateResult = True
318 for app in apps:
319 main.CLIs[ 0 ].app( app, "Activate" )
320 # TODO: check this worked
321 time.sleep( 10 ) # wait for apps to activate
322 for app in apps:
323 state = main.CLIs[ 0 ].appStatus( app )
324 if state == "ACTIVE":
325 activateResult = activeResult and True
326 else:
327 main.log.error( "{} is in {} state".format( app, state ) )
328 activeResult = False
329 utilities.assert_equals( expect=True,
330 actual=activateResult,
331 onpass="Successfully activated apps",
332 onfail="Failed to activate apps" )
333 else:
334 main.log.warn( "No apps were specified to be loaded after startup" )
335
336 main.step( "Set ONOS configurations" )
337 config = main.params.get( 'ONOS_Configuration' )
338 if config:
339 main.log.debug( config )
340 checkResult = main.TRUE
341 for component in config:
342 for setting in config[component]:
343 value = config[component][setting]
344 check = main.CLIs[ 0 ].setCfg( component, setting, value )
345 main.log.info( "Value was changed? {}".format( main.TRUE == check ) )
346 checkResult = check and checkResult
347 utilities.assert_equals( expect=main.TRUE,
348 actual=checkResult,
349 onpass="Successfully set config",
350 onfail="Failed to set config" )
351 else:
352 main.log.warn( "No configurations were specified to be changed after startup" )
353
Jon Hall85794ff2015-07-08 14:12:30 -0700354 def CASE2( self, main ):
355 """
356 Assign devices to controllers
357 """
358 import re
Jon Halle1a3b752015-07-22 13:02:46 -0700359 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700360 assert main, "main not defined"
361 assert utilities.assert_equals, "utilities.assert_equals not defined"
362
363 main.case( "Assigning devices to controllers" )
Jon Hall783bbf92015-07-23 14:33:19 -0700364 main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700365 "and check that an ONOS node becomes the " +\
366 "master of the device."
367 main.step( "Assign switches to controllers" )
368
369 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700370 for i in range( main.numCtrls ):
371 ipList.append( main.nodes[ i ].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -0700372 swList = []
373 for i in range( 1, 29 ):
374 swList.append( "s" + str( i ) )
375 main.Mininet1.assignSwController( sw=swList, ip=ipList )
376
377 mastershipCheck = main.TRUE
378 for i in range( 1, 29 ):
379 response = main.Mininet1.getSwController( "s" + str( i ) )
380 try:
381 main.log.info( str( response ) )
382 except Exception:
383 main.log.info( repr( response ) )
Jon Halla440e872016-03-31 15:15:50 -0700384 for node in main.nodes:
385 if re.search( "tcp:" + node.ip_address, response ):
386 mastershipCheck = mastershipCheck and main.TRUE
387 else:
388 main.log.error( "Error, node " + node.ip_address + " is " +
389 "not in the list of controllers s" +
390 str( i ) + " is connecting to." )
391 mastershipCheck = main.FALSE
Jon Hall85794ff2015-07-08 14:12:30 -0700392 utilities.assert_equals(
393 expect=main.TRUE,
394 actual=mastershipCheck,
395 onpass="Switch mastership assigned correctly",
396 onfail="Switches not assigned correctly to controllers" )
397
398 def CASE21( self, main ):
399 """
400 Assign mastership to controllers
401 """
Jon Halle1a3b752015-07-22 13:02:46 -0700402 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700403 assert main, "main not defined"
404 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700405 assert main.CLIs, "main.CLIs not defined"
406 assert main.nodes, "main.nodes not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700407
408 main.case( "Assigning Controller roles for switches" )
Jon Hall783bbf92015-07-23 14:33:19 -0700409 main.caseExplanation = "Check that ONOS is connected to each " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700410 "device. Then manually assign" +\
411 " mastership to specific ONOS nodes using" +\
412 " 'device-role'"
413 main.step( "Assign mastership of switches to specific controllers" )
Jon Halla440e872016-03-31 15:15:50 -0700414 # Manually assign mastership to the controller we want
Jon Hall85794ff2015-07-08 14:12:30 -0700415 roleCall = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -0700416
417 ipList = [ ]
418 deviceList = []
419 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall85794ff2015-07-08 14:12:30 -0700420 try:
Jon Halla440e872016-03-31 15:15:50 -0700421 # Assign mastership to specific controllers. This assignment was
422 # determined for a 7 node cluser, but will work with any sized
423 # cluster
Jon Hall85794ff2015-07-08 14:12:30 -0700424 for i in range( 1, 29 ): # switches 1 through 28
Jon Hall85794ff2015-07-08 14:12:30 -0700425 # set up correct variables:
426 if i == 1:
Jon Halla440e872016-03-31 15:15:50 -0700427 c = 0
428 ip = main.nodes[ c ].ip_address # ONOS1
429 deviceId = onosCli.getDevice( "1000" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700430 elif i == 2:
Jon Halla440e872016-03-31 15:15:50 -0700431 c = 1 % main.numCtrls
432 ip = main.nodes[ c ].ip_address # ONOS2
433 deviceId = onosCli.getDevice( "2000" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700434 elif i == 3:
Jon Halla440e872016-03-31 15:15:50 -0700435 c = 1 % main.numCtrls
436 ip = main.nodes[ c ].ip_address # ONOS2
437 deviceId = onosCli.getDevice( "3000" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700438 elif i == 4:
Jon Halla440e872016-03-31 15:15:50 -0700439 c = 3 % main.numCtrls
440 ip = main.nodes[ c ].ip_address # ONOS4
441 deviceId = onosCli.getDevice( "3004" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700442 elif i == 5:
Jon Halla440e872016-03-31 15:15:50 -0700443 c = 2 % main.numCtrls
444 ip = main.nodes[ c ].ip_address # ONOS3
445 deviceId = onosCli.getDevice( "5000" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700446 elif i == 6:
Jon Halla440e872016-03-31 15:15:50 -0700447 c = 2 % main.numCtrls
448 ip = main.nodes[ c ].ip_address # ONOS3
449 deviceId = onosCli.getDevice( "6000" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700450 elif i == 7:
Jon Halla440e872016-03-31 15:15:50 -0700451 c = 5 % main.numCtrls
452 ip = main.nodes[ c ].ip_address # ONOS6
453 deviceId = onosCli.getDevice( "6007" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700454 elif i >= 8 and i <= 17:
Jon Halla440e872016-03-31 15:15:50 -0700455 c = 4 % main.numCtrls
456 ip = main.nodes[ c ].ip_address # ONOS5
Jon Hall85794ff2015-07-08 14:12:30 -0700457 dpid = '3' + str( i ).zfill( 3 )
Jon Halla440e872016-03-31 15:15:50 -0700458 deviceId = onosCli.getDevice( dpid ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700459 elif i >= 18 and i <= 27:
Jon Halla440e872016-03-31 15:15:50 -0700460 c = 6 % main.numCtrls
461 ip = main.nodes[ c ].ip_address # ONOS7
Jon Hall85794ff2015-07-08 14:12:30 -0700462 dpid = '6' + str( i ).zfill( 3 )
Jon Halla440e872016-03-31 15:15:50 -0700463 deviceId = onosCli.getDevice( dpid ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700464 elif i == 28:
Jon Halla440e872016-03-31 15:15:50 -0700465 c = 0
466 ip = main.nodes[ c ].ip_address # ONOS1
467 deviceId = onosCli.getDevice( "2800" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700468 else:
469 main.log.error( "You didn't write an else statement for " +
470 "switch s" + str( i ) )
Jon Halla440e872016-03-31 15:15:50 -0700471 roleCall = main.FALSE
Jon Hall85794ff2015-07-08 14:12:30 -0700472 # Assign switch
473 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
474 # TODO: make this controller dynamic
Jon Halla440e872016-03-31 15:15:50 -0700475 roleCall = roleCall and onosCli.deviceRole( deviceId, ip )
476 ipList.append( ip )
477 deviceList.append( deviceId )
Jon Hall85794ff2015-07-08 14:12:30 -0700478 except ( AttributeError, AssertionError ):
479 main.log.exception( "Something is wrong with ONOS device view" )
Jon Halla440e872016-03-31 15:15:50 -0700480 main.log.info( onosCli.devices() )
Jon Hall85794ff2015-07-08 14:12:30 -0700481 utilities.assert_equals(
482 expect=main.TRUE,
483 actual=roleCall,
484 onpass="Re-assigned switch mastership to designated controller",
485 onfail="Something wrong with deviceRole calls" )
486
487 main.step( "Check mastership was correctly assigned" )
Jon Halla440e872016-03-31 15:15:50 -0700488 roleCheck = main.TRUE
489 # NOTE: This is due to the fact that device mastership change is not
490 # atomic and is actually a multi step process
491 time.sleep( 5 )
492 for i in range( len( ipList ) ):
493 ip = ipList[i]
494 deviceId = deviceList[i]
495 # Check assignment
496 master = onosCli.getRole( deviceId ).get( 'master' )
497 if ip in master:
498 roleCheck = roleCheck and main.TRUE
499 else:
500 roleCheck = roleCheck and main.FALSE
501 main.log.error( "Error, controller " + ip + " is not" +
502 " master " + "of device " +
503 str( deviceId ) + ". Master is " +
504 repr( master ) + "." )
Jon Hall85794ff2015-07-08 14:12:30 -0700505 utilities.assert_equals(
506 expect=main.TRUE,
507 actual=roleCheck,
508 onpass="Switches were successfully reassigned to designated " +
509 "controller",
510 onfail="Switches were not successfully reassigned" )
511
512 def CASE3( self, main ):
513 """
514 Assign intents
515 """
516 import time
517 import json
Jon Halle1a3b752015-07-22 13:02:46 -0700518 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700519 assert main, "main not defined"
520 assert utilities.assert_equals, "utilities.assert_equals not defined"
521 # NOTE: we must reinstall intents until we have a persistant intent
522 # datastore!
523 main.case( "Adding host Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700524 main.caseExplanation = "Discover hosts by using pingall then " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700525 "assign predetermined host-to-host intents." +\
526 " After installation, check that the intent" +\
527 " is distributed to all nodes and the state" +\
528 " is INSTALLED"
529
530 # install onos-app-fwd
531 main.step( "Install reactive forwarding app" )
Jon Halla440e872016-03-31 15:15:50 -0700532 onosCli = main.CLIs[ main.activeNodes[0] ]
533 installResults = onosCli.activateApp( "org.onosproject.fwd" )
Jon Hall85794ff2015-07-08 14:12:30 -0700534 utilities.assert_equals( expect=main.TRUE, actual=installResults,
535 onpass="Install fwd successful",
536 onfail="Install fwd failed" )
537
538 main.step( "Check app ids" )
Jon Halla440e872016-03-31 15:15:50 -0700539 appCheck = main.TRUE
540 threads = []
541 for i in main.activeNodes:
542 t = main.Thread( target=main.CLIs[i].appToIDCheck,
543 name="appToIDCheck-" + str( i ),
544 args=[] )
545 threads.append( t )
546 t.start()
547
548 for t in threads:
549 t.join()
550 appCheck = appCheck and t.result
Jon Hall85794ff2015-07-08 14:12:30 -0700551 if appCheck != main.TRUE:
Jon Halla440e872016-03-31 15:15:50 -0700552 main.log.warn( onosCli.apps() )
553 main.log.warn( onosCli.appIDs() )
Jon Hall85794ff2015-07-08 14:12:30 -0700554 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
555 onpass="App Ids seem to be correct",
556 onfail="Something is wrong with app Ids" )
557
558 main.step( "Discovering Hosts( Via pingall for now )" )
559 # FIXME: Once we have a host discovery mechanism, use that instead
560 # REACTIVE FWD test
561 pingResult = main.FALSE
Jon Hall96091e62015-09-21 17:34:17 -0700562 passMsg = "Reactive Pingall test passed"
563 time1 = time.time()
564 pingResult = main.Mininet1.pingall()
565 time2 = time.time()
566 if not pingResult:
567 main.log.warn("First pingall failed. Trying again...")
Jon Hall85794ff2015-07-08 14:12:30 -0700568 pingResult = main.Mininet1.pingall()
Jon Hall96091e62015-09-21 17:34:17 -0700569 passMsg += " on the second try"
570 utilities.assert_equals(
571 expect=main.TRUE,
572 actual=pingResult,
573 onpass= passMsg,
574 onfail="Reactive Pingall failed, " +
575 "one or more ping pairs failed" )
576 main.log.info( "Time for pingall: %2f seconds" %
577 ( time2 - time1 ) )
Jon Hall85794ff2015-07-08 14:12:30 -0700578 # timeout for fwd flows
579 time.sleep( 11 )
580 # uninstall onos-app-fwd
581 main.step( "Uninstall reactive forwarding app" )
Jon Halla440e872016-03-31 15:15:50 -0700582 node = main.activeNodes[0]
583 uninstallResult = main.CLIs[node].deactivateApp( "org.onosproject.fwd" )
Jon Hall85794ff2015-07-08 14:12:30 -0700584 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
585 onpass="Uninstall fwd successful",
586 onfail="Uninstall fwd failed" )
587
588 main.step( "Check app ids" )
Jon Halla440e872016-03-31 15:15:50 -0700589 threads = []
590 appCheck2 = main.TRUE
591 for i in main.activeNodes:
592 t = main.Thread( target=main.CLIs[i].appToIDCheck,
593 name="appToIDCheck-" + str( i ),
594 args=[] )
595 threads.append( t )
596 t.start()
597
598 for t in threads:
599 t.join()
600 appCheck2 = appCheck2 and t.result
Jon Hall85794ff2015-07-08 14:12:30 -0700601 if appCheck2 != main.TRUE:
Jon Halla440e872016-03-31 15:15:50 -0700602 node = main.activeNodes[0]
603 main.log.warn( main.CLIs[node].apps() )
604 main.log.warn( main.CLIs[node].appIDs() )
Jon Hall85794ff2015-07-08 14:12:30 -0700605 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
606 onpass="App Ids seem to be correct",
607 onfail="Something is wrong with app Ids" )
608
609 main.step( "Add host intents via cli" )
610 intentIds = []
Jon Halla440e872016-03-31 15:15:50 -0700611 # TODO: move the host numbers to params
612 # Maybe look at all the paths we ping?
Jon Hall85794ff2015-07-08 14:12:30 -0700613 intentAddResult = True
614 hostResult = main.TRUE
615 for i in range( 8, 18 ):
616 main.log.info( "Adding host intent between h" + str( i ) +
617 " and h" + str( i + 10 ) )
618 host1 = "00:00:00:00:00:" + \
619 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
620 host2 = "00:00:00:00:00:" + \
621 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
622 # NOTE: getHost can return None
Jon Halla440e872016-03-31 15:15:50 -0700623 host1Dict = onosCli.getHost( host1 )
624 host2Dict = onosCli.getHost( host2 )
Jon Hall85794ff2015-07-08 14:12:30 -0700625 host1Id = None
626 host2Id = None
627 if host1Dict and host2Dict:
628 host1Id = host1Dict.get( 'id', None )
629 host2Id = host2Dict.get( 'id', None )
630 if host1Id and host2Id:
Jon Halla440e872016-03-31 15:15:50 -0700631 nodeNum = ( i % len( main.activeNodes ) )
632 node = main.activeNodes[nodeNum]
633 tmpId = main.CLIs[node].addHostIntent( host1Id, host2Id )
Jon Hall85794ff2015-07-08 14:12:30 -0700634 if tmpId:
635 main.log.info( "Added intent with id: " + tmpId )
636 intentIds.append( tmpId )
637 else:
638 main.log.error( "addHostIntent returned: " +
639 repr( tmpId ) )
640 else:
641 main.log.error( "Error, getHost() failed for h" + str( i ) +
642 " and/or h" + str( i + 10 ) )
Jon Halla440e872016-03-31 15:15:50 -0700643 node = main.activeNodes[0]
644 hosts = main.CLIs[node].hosts()
Jon Hall85794ff2015-07-08 14:12:30 -0700645 main.log.warn( "Hosts output: " )
646 try:
647 main.log.warn( json.dumps( json.loads( hosts ),
648 sort_keys=True,
649 indent=4,
650 separators=( ',', ': ' ) ) )
651 except ( ValueError, TypeError ):
652 main.log.warn( repr( hosts ) )
653 hostResult = main.FALSE
654 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
655 onpass="Found a host id for each host",
656 onfail="Error looking up host ids" )
657
658 intentStart = time.time()
Jon Halla440e872016-03-31 15:15:50 -0700659 onosIds = onosCli.getAllIntentsId()
Jon Hall85794ff2015-07-08 14:12:30 -0700660 main.log.info( "Submitted intents: " + str( intentIds ) )
661 main.log.info( "Intents in ONOS: " + str( onosIds ) )
662 for intent in intentIds:
663 if intent in onosIds:
664 pass # intent submitted is in onos
665 else:
666 intentAddResult = False
667 if intentAddResult:
668 intentStop = time.time()
669 else:
670 intentStop = None
671 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -0700672 intents = onosCli.intents()
Jon Hall85794ff2015-07-08 14:12:30 -0700673 intentStates = []
674 installedCheck = True
675 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
676 count = 0
677 try:
678 for intent in json.loads( intents ):
679 state = intent.get( 'state', None )
680 if "INSTALLED" not in state:
681 installedCheck = False
682 intentId = intent.get( 'id', None )
683 intentStates.append( ( intentId, state ) )
684 except ( ValueError, TypeError ):
685 main.log.exception( "Error parsing intents" )
686 # add submitted intents not in the store
687 tmplist = [ i for i, s in intentStates ]
688 missingIntents = False
689 for i in intentIds:
690 if i not in tmplist:
691 intentStates.append( ( i, " - " ) )
692 missingIntents = True
693 intentStates.sort()
694 for i, s in intentStates:
695 count += 1
696 main.log.info( "%-6s%-15s%-15s" %
697 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -0700698 leaders = onosCli.leaders()
Jon Hall85794ff2015-07-08 14:12:30 -0700699 try:
700 missing = False
701 if leaders:
702 parsedLeaders = json.loads( leaders )
703 main.log.warn( json.dumps( parsedLeaders,
704 sort_keys=True,
705 indent=4,
706 separators=( ',', ': ' ) ) )
707 # check for all intent partitions
708 topics = []
709 for i in range( 14 ):
710 topics.append( "intent-partition-" + str( i ) )
711 main.log.debug( topics )
712 ONOStopics = [ j['topic'] for j in parsedLeaders ]
713 for topic in topics:
714 if topic not in ONOStopics:
715 main.log.error( "Error: " + topic +
716 " not in leaders" )
717 missing = True
718 else:
719 main.log.error( "leaders() returned None" )
720 except ( ValueError, TypeError ):
721 main.log.exception( "Error parsing leaders" )
722 main.log.error( repr( leaders ) )
723 # Check all nodes
724 if missing:
Jon Halla440e872016-03-31 15:15:50 -0700725 for i in main.activeNodes:
726 response = main.CLIs[i].leaders( jsonFormat=False)
727 main.log.warn( str( main.CLIs[i].name ) + " leaders output: \n" +
728 str( response ) )
Jon Hall85794ff2015-07-08 14:12:30 -0700729
Jon Halla440e872016-03-31 15:15:50 -0700730 partitions = onosCli.partitions()
Jon Hall85794ff2015-07-08 14:12:30 -0700731 try:
732 if partitions :
733 parsedPartitions = json.loads( partitions )
734 main.log.warn( json.dumps( parsedPartitions,
735 sort_keys=True,
736 indent=4,
737 separators=( ',', ': ' ) ) )
738 # TODO check for a leader in all paritions
739 # TODO check for consistency among nodes
740 else:
741 main.log.error( "partitions() returned None" )
742 except ( ValueError, TypeError ):
743 main.log.exception( "Error parsing partitions" )
744 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -0700745 pendingMap = onosCli.pendingMap()
Jon Hall85794ff2015-07-08 14:12:30 -0700746 try:
747 if pendingMap :
748 parsedPending = json.loads( pendingMap )
749 main.log.warn( json.dumps( parsedPending,
750 sort_keys=True,
751 indent=4,
752 separators=( ',', ': ' ) ) )
753 # TODO check something here?
754 else:
755 main.log.error( "pendingMap() returned None" )
756 except ( ValueError, TypeError ):
757 main.log.exception( "Error parsing pending map" )
758 main.log.error( repr( pendingMap ) )
759
760 intentAddResult = bool( intentAddResult and not missingIntents and
761 installedCheck )
762 if not intentAddResult:
763 main.log.error( "Error in pushing host intents to ONOS" )
764
765 main.step( "Intent Anti-Entropy dispersion" )
Jon Halla440e872016-03-31 15:15:50 -0700766 for j in range(100):
Jon Hall85794ff2015-07-08 14:12:30 -0700767 correct = True
768 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Halla440e872016-03-31 15:15:50 -0700769 for i in main.activeNodes:
Jon Hall85794ff2015-07-08 14:12:30 -0700770 onosIds = []
Jon Halla440e872016-03-31 15:15:50 -0700771 ids = main.CLIs[i].getAllIntentsId()
Jon Hall85794ff2015-07-08 14:12:30 -0700772 onosIds.append( ids )
Jon Halla440e872016-03-31 15:15:50 -0700773 main.log.debug( "Intents in " + main.CLIs[i].name + ": " +
Jon Hall85794ff2015-07-08 14:12:30 -0700774 str( sorted( onosIds ) ) )
775 if sorted( ids ) != sorted( intentIds ):
776 main.log.warn( "Set of intent IDs doesn't match" )
777 correct = False
778 break
779 else:
Jon Halla440e872016-03-31 15:15:50 -0700780 intents = json.loads( main.CLIs[i].intents() )
Jon Hall85794ff2015-07-08 14:12:30 -0700781 for intent in intents:
782 if intent[ 'state' ] != "INSTALLED":
783 main.log.warn( "Intent " + intent[ 'id' ] +
784 " is " + intent[ 'state' ] )
785 correct = False
786 break
787 if correct:
788 break
789 else:
790 time.sleep(1)
791 if not intentStop:
792 intentStop = time.time()
793 global gossipTime
794 gossipTime = intentStop - intentStart
795 main.log.info( "It took about " + str( gossipTime ) +
796 " seconds for all intents to appear in each node" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700797 gossipPeriod = int( main.params['timers']['gossip'] )
Jon Halla440e872016-03-31 15:15:50 -0700798 maxGossipTime = gossipPeriod * len( main.activeNodes )
Jon Hall85794ff2015-07-08 14:12:30 -0700799 utilities.assert_greater_equals(
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700800 expect=maxGossipTime, actual=gossipTime,
Jon Hall85794ff2015-07-08 14:12:30 -0700801 onpass="ECM anti-entropy for intents worked within " +
802 "expected time",
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700803 onfail="Intent ECM anti-entropy took too long. " +
804 "Expected time:{}, Actual time:{}".format( maxGossipTime,
805 gossipTime ) )
806 if gossipTime <= maxGossipTime:
Jon Hall85794ff2015-07-08 14:12:30 -0700807 intentAddResult = True
808
809 if not intentAddResult or "key" in pendingMap:
810 import time
811 installedCheck = True
812 main.log.info( "Sleeping 60 seconds to see if intents are found" )
813 time.sleep( 60 )
Jon Halla440e872016-03-31 15:15:50 -0700814 onosIds = onosCli.getAllIntentsId()
Jon Hall85794ff2015-07-08 14:12:30 -0700815 main.log.info( "Submitted intents: " + str( intentIds ) )
816 main.log.info( "Intents in ONOS: " + str( onosIds ) )
817 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -0700818 intents = onosCli.intents()
Jon Hall85794ff2015-07-08 14:12:30 -0700819 intentStates = []
820 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
821 count = 0
822 try:
823 for intent in json.loads( intents ):
824 # Iter through intents of a node
825 state = intent.get( 'state', None )
826 if "INSTALLED" not in state:
827 installedCheck = False
828 intentId = intent.get( 'id', None )
829 intentStates.append( ( intentId, state ) )
830 except ( ValueError, TypeError ):
831 main.log.exception( "Error parsing intents" )
832 # add submitted intents not in the store
833 tmplist = [ i for i, s in intentStates ]
834 for i in intentIds:
835 if i not in tmplist:
836 intentStates.append( ( i, " - " ) )
837 intentStates.sort()
838 for i, s in intentStates:
839 count += 1
840 main.log.info( "%-6s%-15s%-15s" %
841 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -0700842 leaders = onosCli.leaders()
Jon Hall85794ff2015-07-08 14:12:30 -0700843 try:
844 missing = False
845 if leaders:
846 parsedLeaders = json.loads( leaders )
847 main.log.warn( json.dumps( parsedLeaders,
848 sort_keys=True,
849 indent=4,
850 separators=( ',', ': ' ) ) )
851 # check for all intent partitions
852 # check for election
853 topics = []
854 for i in range( 14 ):
855 topics.append( "intent-partition-" + str( i ) )
856 # FIXME: this should only be after we start the app
857 topics.append( "org.onosproject.election" )
858 main.log.debug( topics )
859 ONOStopics = [ j['topic'] for j in parsedLeaders ]
860 for topic in topics:
861 if topic not in ONOStopics:
862 main.log.error( "Error: " + topic +
863 " not in leaders" )
864 missing = True
865 else:
866 main.log.error( "leaders() returned None" )
867 except ( ValueError, TypeError ):
868 main.log.exception( "Error parsing leaders" )
869 main.log.error( repr( leaders ) )
870 # Check all nodes
871 if missing:
Jon Halla440e872016-03-31 15:15:50 -0700872 for i in main.activeNodes:
873 node = main.CLIs[i]
874 response = node.leaders( jsonFormat=False)
875 main.log.warn( str( node.name ) + " leaders output: \n" +
876 str( response ) )
877
878 partitions = onosCli.partitions()
Jon Hall85794ff2015-07-08 14:12:30 -0700879 try:
880 if partitions :
881 parsedPartitions = json.loads( partitions )
882 main.log.warn( json.dumps( parsedPartitions,
883 sort_keys=True,
884 indent=4,
885 separators=( ',', ': ' ) ) )
886 # TODO check for a leader in all paritions
887 # TODO check for consistency among nodes
888 else:
889 main.log.error( "partitions() returned None" )
890 except ( ValueError, TypeError ):
891 main.log.exception( "Error parsing partitions" )
892 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -0700893 pendingMap = onosCli.pendingMap()
Jon Hall85794ff2015-07-08 14:12:30 -0700894 try:
895 if pendingMap :
896 parsedPending = json.loads( pendingMap )
897 main.log.warn( json.dumps( parsedPending,
898 sort_keys=True,
899 indent=4,
900 separators=( ',', ': ' ) ) )
901 # TODO check something here?
902 else:
903 main.log.error( "pendingMap() returned None" )
904 except ( ValueError, TypeError ):
905 main.log.exception( "Error parsing pending map" )
906 main.log.error( repr( pendingMap ) )
907
908 def CASE4( self, main ):
909 """
910 Ping across added host intents
911 """
912 import json
913 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700914 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700915 assert main, "main not defined"
916 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halla440e872016-03-31 15:15:50 -0700917 main.case( "Verify connectivity by sending traffic across Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700918 main.caseExplanation = "Ping across added host intents to check " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700919 "functionality and check the state of " +\
920 "the intent"
921 main.step( "Ping across added host intents" )
Jon Halla440e872016-03-31 15:15:50 -0700922 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall85794ff2015-07-08 14:12:30 -0700923 PingResult = main.TRUE
924 for i in range( 8, 18 ):
925 ping = main.Mininet1.pingHost( src="h" + str( i ),
926 target="h" + str( i + 10 ) )
927 PingResult = PingResult and ping
928 if ping == main.FALSE:
929 main.log.warn( "Ping failed between h" + str( i ) +
930 " and h" + str( i + 10 ) )
931 elif ping == main.TRUE:
932 main.log.info( "Ping test passed!" )
933 # Don't set PingResult or you'd override failures
934 if PingResult == main.FALSE:
935 main.log.error(
936 "Intents have not been installed correctly, pings failed." )
937 # TODO: pretty print
938 main.log.warn( "ONOS1 intents: " )
939 try:
Jon Halla440e872016-03-31 15:15:50 -0700940 tmpIntents = onosCli.intents()
Jon Hall85794ff2015-07-08 14:12:30 -0700941 main.log.warn( json.dumps( json.loads( tmpIntents ),
942 sort_keys=True,
943 indent=4,
944 separators=( ',', ': ' ) ) )
945 except ( ValueError, TypeError ):
946 main.log.warn( repr( tmpIntents ) )
947 utilities.assert_equals(
948 expect=main.TRUE,
949 actual=PingResult,
950 onpass="Intents have been installed correctly and pings work",
951 onfail="Intents have not been installed correctly, pings failed." )
952
953 main.step( "Check Intent state" )
954 installedCheck = True
955 # Print the intent states
956 intents = main.ONOScli1.intents()
957 intentStates = []
958 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
959 count = 0
960 # Iter through intents of a node
961 try:
962 for intent in json.loads( intents ):
963 state = intent.get( 'state', None )
964 if "INSTALLED" not in state:
965 installedCheck = False
966 intentId = intent.get( 'id', None )
967 intentStates.append( ( intentId, state ) )
968 except ( ValueError, TypeError ):
969 main.log.exception( "Error parsing intents." )
970 # Print states
971 intentStates.sort()
972 for i, s in intentStates:
973 count += 1
974 main.log.info( "%-6s%-15s%-15s" %
975 ( str( count ), str( i ), str( s ) ) )
976 utilities.assert_equals( expect=True, actual=installedCheck,
977 onpass="Intents are all INSTALLED",
978 onfail="Intents are not all in " +
979 "INSTALLED state" )
980
981 main.step( "Check leadership of topics" )
Jon Halla440e872016-03-31 15:15:50 -0700982 leaders = onosCli.leaders()
Jon Hall85794ff2015-07-08 14:12:30 -0700983 topicCheck = main.TRUE
984 try:
985 if leaders:
986 parsedLeaders = json.loads( leaders )
987 main.log.warn( json.dumps( parsedLeaders,
988 sort_keys=True,
989 indent=4,
990 separators=( ',', ': ' ) ) )
991 # check for all intent partitions
992 # check for election
993 # TODO: Look at Devices as topics now that it uses this system
994 topics = []
995 for i in range( 14 ):
996 topics.append( "intent-partition-" + str( i ) )
997 # FIXME: this should only be after we start the app
998 # FIXME: topics.append( "org.onosproject.election" )
999 # Print leaders output
1000 main.log.debug( topics )
1001 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1002 for topic in topics:
1003 if topic not in ONOStopics:
1004 main.log.error( "Error: " + topic +
1005 " not in leaders" )
1006 topicCheck = main.FALSE
1007 else:
1008 main.log.error( "leaders() returned None" )
1009 topicCheck = main.FALSE
1010 except ( ValueError, TypeError ):
1011 topicCheck = main.FALSE
1012 main.log.exception( "Error parsing leaders" )
1013 main.log.error( repr( leaders ) )
1014 # TODO: Check for a leader of these topics
Jon Halla440e872016-03-31 15:15:50 -07001015 # Check all nodes
1016 if topicCheck:
1017 for i in main.activeNodes:
1018 node = main.CLIs[i]
1019 response = node.leaders( jsonFormat=False)
1020 main.log.warn( str( node.name ) + " leaders output: \n" +
1021 str( response ) )
1022
Jon Hall85794ff2015-07-08 14:12:30 -07001023 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
1024 onpass="intent Partitions is in leaders",
1025 onfail="Some topics were lost " )
1026 # Print partitions
Jon Halla440e872016-03-31 15:15:50 -07001027 partitions = onosCli.partitions()
Jon Hall85794ff2015-07-08 14:12:30 -07001028 try:
1029 if partitions :
1030 parsedPartitions = json.loads( partitions )
1031 main.log.warn( json.dumps( parsedPartitions,
1032 sort_keys=True,
1033 indent=4,
1034 separators=( ',', ': ' ) ) )
1035 # TODO check for a leader in all paritions
1036 # TODO check for consistency among nodes
1037 else:
1038 main.log.error( "partitions() returned None" )
1039 except ( ValueError, TypeError ):
1040 main.log.exception( "Error parsing partitions" )
1041 main.log.error( repr( partitions ) )
1042 # Print Pending Map
Jon Halla440e872016-03-31 15:15:50 -07001043 pendingMap = onosCli.pendingMap()
Jon Hall85794ff2015-07-08 14:12:30 -07001044 try:
1045 if pendingMap :
1046 parsedPending = json.loads( pendingMap )
1047 main.log.warn( json.dumps( parsedPending,
1048 sort_keys=True,
1049 indent=4,
1050 separators=( ',', ': ' ) ) )
1051 # TODO check something here?
1052 else:
1053 main.log.error( "pendingMap() returned None" )
1054 except ( ValueError, TypeError ):
1055 main.log.exception( "Error parsing pending map" )
1056 main.log.error( repr( pendingMap ) )
1057
1058 if not installedCheck:
1059 main.log.info( "Waiting 60 seconds to see if the state of " +
1060 "intents change" )
1061 time.sleep( 60 )
1062 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -07001063 intents = onosCli.intents()
Jon Hall85794ff2015-07-08 14:12:30 -07001064 intentStates = []
1065 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
1066 count = 0
1067 # Iter through intents of a node
1068 try:
1069 for intent in json.loads( intents ):
1070 state = intent.get( 'state', None )
1071 if "INSTALLED" not in state:
1072 installedCheck = False
1073 intentId = intent.get( 'id', None )
1074 intentStates.append( ( intentId, state ) )
1075 except ( ValueError, TypeError ):
1076 main.log.exception( "Error parsing intents." )
1077 intentStates.sort()
1078 for i, s in intentStates:
1079 count += 1
1080 main.log.info( "%-6s%-15s%-15s" %
1081 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -07001082 leaders = onosCli.leaders()
Jon Hall85794ff2015-07-08 14:12:30 -07001083 try:
1084 missing = False
1085 if leaders:
1086 parsedLeaders = json.loads( leaders )
1087 main.log.warn( json.dumps( parsedLeaders,
1088 sort_keys=True,
1089 indent=4,
1090 separators=( ',', ': ' ) ) )
1091 # check for all intent partitions
1092 # check for election
1093 topics = []
1094 for i in range( 14 ):
1095 topics.append( "intent-partition-" + str( i ) )
1096 # FIXME: this should only be after we start the app
1097 topics.append( "org.onosproject.election" )
1098 main.log.debug( topics )
1099 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1100 for topic in topics:
1101 if topic not in ONOStopics:
1102 main.log.error( "Error: " + topic +
1103 " not in leaders" )
1104 missing = True
1105 else:
1106 main.log.error( "leaders() returned None" )
1107 except ( ValueError, TypeError ):
1108 main.log.exception( "Error parsing leaders" )
1109 main.log.error( repr( leaders ) )
1110 if missing:
Jon Halla440e872016-03-31 15:15:50 -07001111 for i in main.activeNodes:
1112 node = main.CLIs[i]
1113 response = node.leaders( jsonFormat=False)
1114 main.log.warn( str( node.name ) + " leaders output: \n" +
1115 str( response ) )
1116
1117 partitions = onosCli.partitions()
Jon Hall85794ff2015-07-08 14:12:30 -07001118 try:
1119 if partitions :
1120 parsedPartitions = json.loads( partitions )
1121 main.log.warn( json.dumps( parsedPartitions,
1122 sort_keys=True,
1123 indent=4,
1124 separators=( ',', ': ' ) ) )
1125 # TODO check for a leader in all paritions
1126 # TODO check for consistency among nodes
1127 else:
1128 main.log.error( "partitions() returned None" )
1129 except ( ValueError, TypeError ):
1130 main.log.exception( "Error parsing partitions" )
1131 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -07001132 pendingMap = onosCli.pendingMap()
Jon Hall85794ff2015-07-08 14:12:30 -07001133 try:
1134 if pendingMap :
1135 parsedPending = json.loads( pendingMap )
1136 main.log.warn( json.dumps( parsedPending,
1137 sort_keys=True,
1138 indent=4,
1139 separators=( ',', ': ' ) ) )
1140 # TODO check something here?
1141 else:
1142 main.log.error( "pendingMap() returned None" )
1143 except ( ValueError, TypeError ):
1144 main.log.exception( "Error parsing pending map" )
1145 main.log.error( repr( pendingMap ) )
1146 # Print flowrules
Jon Halla440e872016-03-31 15:15:50 -07001147 node = main.activeNodes[0]
1148 main.log.debug( main.CLIs[node].flows( jsonFormat=False ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001149 main.step( "Wait a minute then ping again" )
1150 # the wait is above
1151 PingResult = main.TRUE
1152 for i in range( 8, 18 ):
1153 ping = main.Mininet1.pingHost( src="h" + str( i ),
1154 target="h" + str( i + 10 ) )
1155 PingResult = PingResult and ping
1156 if ping == main.FALSE:
1157 main.log.warn( "Ping failed between h" + str( i ) +
1158 " and h" + str( i + 10 ) )
1159 elif ping == main.TRUE:
1160 main.log.info( "Ping test passed!" )
1161 # Don't set PingResult or you'd override failures
1162 if PingResult == main.FALSE:
1163 main.log.error(
1164 "Intents have not been installed correctly, pings failed." )
1165 # TODO: pretty print
1166 main.log.warn( "ONOS1 intents: " )
1167 try:
Jon Halla440e872016-03-31 15:15:50 -07001168 tmpIntents = onosCli.intents()
Jon Hall85794ff2015-07-08 14:12:30 -07001169 main.log.warn( json.dumps( json.loads( tmpIntents ),
1170 sort_keys=True,
1171 indent=4,
1172 separators=( ',', ': ' ) ) )
1173 except ( ValueError, TypeError ):
1174 main.log.warn( repr( tmpIntents ) )
1175 utilities.assert_equals(
1176 expect=main.TRUE,
1177 actual=PingResult,
1178 onpass="Intents have been installed correctly and pings work",
1179 onfail="Intents have not been installed correctly, pings failed." )
1180
1181 def CASE5( self, main ):
1182 """
1183 Reading state of ONOS
1184 """
1185 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001186 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001187 assert main, "main not defined"
1188 assert utilities.assert_equals, "utilities.assert_equals not defined"
1189
1190 main.case( "Setting up and gathering data for current state" )
1191 # The general idea for this test case is to pull the state of
1192 # ( intents,flows, topology,... ) from each ONOS node
1193 # We can then compare them with each other and also with past states
1194
1195 main.step( "Check that each switch has a master" )
1196 global mastershipState
1197 mastershipState = '[]'
1198
1199 # Assert that each device has a master
Jon Halla440e872016-03-31 15:15:50 -07001200 rolesNotNull = main.TRUE
1201 threads = []
1202 for i in main.activeNodes:
1203 t = main.Thread( target=main.CLIs[i].rolesNotNull,
1204 name="rolesNotNull-" + str( i ),
1205 args=[] )
1206 threads.append( t )
1207 t.start()
1208
1209 for t in threads:
1210 t.join()
1211 rolesNotNull = rolesNotNull and t.result
Jon Hall85794ff2015-07-08 14:12:30 -07001212 utilities.assert_equals(
1213 expect=main.TRUE,
1214 actual=rolesNotNull,
1215 onpass="Each device has a master",
1216 onfail="Some devices don't have a master assigned" )
1217
1218 main.step( "Get the Mastership of each switch" )
1219 ONOS1Mastership = main.ONOScli1.roles()
1220 # TODO: Make this a meaningful check
1221 if "Error" in ONOS1Mastership or not ONOS1Mastership:
1222 main.log.error( "Error in getting ONOS roles" )
1223 main.log.warn(
1224 "ONOS1 mastership response: " +
1225 repr( ONOS1Mastership ) )
1226 consistentMastership = main.FALSE
1227 else:
1228 mastershipState = ONOS1Mastership
1229 consistentMastership = main.TRUE
1230
1231 main.step( "Get the intents from each controller" )
1232 global intentState
1233 intentState = []
1234 ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
1235 intentCheck = main.FALSE
1236 if "Error" in ONOS1Intents or not ONOS1Intents:
1237 main.log.error( "Error in getting ONOS intents" )
1238 main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
1239 else:
1240 intentCheck = main.TRUE
1241
1242 main.step( "Get the flows from each controller" )
1243 global flowState
1244 flowState = []
1245 flowCheck = main.FALSE
1246 ONOS1Flows = main.ONOScli1.flows( jsonFormat=True )
1247 if "Error" in ONOS1Flows or not ONOS1Flows:
1248 main.log.error( "Error in getting ONOS flows" )
1249 main.log.warn( "ONOS1 flows repsponse: " + ONOS1Flows )
1250 else:
1251 # TODO: Do a better check, maybe compare flows on switches?
1252 flowState = ONOS1Flows
1253 flowCheck = main.TRUE
1254
1255 main.step( "Get the OF Table entries" )
1256 global flows
1257 flows = []
1258 for i in range( 1, 29 ):
GlennRC68467eb2015-11-16 18:01:01 -08001259 flows.append( main.Mininet1.getFlowTable( "s" + str( i ), version="1.3", debug=False ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001260 if flowCheck == main.FALSE:
1261 for table in flows:
1262 main.log.warn( table )
1263 # TODO: Compare switch flow tables with ONOS flow tables
1264
1265 main.step( "Collecting topology information from ONOS" )
1266 devices = []
1267 devices.append( main.ONOScli1.devices() )
1268 hosts = []
1269 hosts.append( json.loads( main.ONOScli1.hosts() ) )
1270 ports = []
1271 ports.append( main.ONOScli1.ports() )
1272 links = []
1273 links.append( main.ONOScli1.links() )
1274 clusters = []
1275 clusters.append( main.ONOScli1.clusters() )
1276
1277 main.step( "Each host has an IP address" )
1278 ipResult = main.TRUE
1279 for controller in range( 0, len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07001280 controllerStr = str( main.activeNodes[controller] + 1 )
1281 if hosts[ controller ]:
1282 for host in hosts[ controller ]:
1283 if not host.get( 'ipAddresses', [ ] ):
1284 main.log.error( "Error with host ips on controller" +
1285 controllerStr + ": " + str( host ) )
1286 ipResult = main.FALSE
Jon Hall85794ff2015-07-08 14:12:30 -07001287 utilities.assert_equals(
1288 expect=main.TRUE,
1289 actual=ipResult,
1290 onpass="The ips of the hosts aren't empty",
1291 onfail="The ip of at least one host is missing" )
1292
1293 # there should always only be one cluster
1294 main.step( "There is only one dataplane cluster" )
1295 try:
1296 numClusters = len( json.loads( clusters[ 0 ] ) )
1297 except ( ValueError, TypeError ):
1298 main.log.exception( "Error parsing clusters[0]: " +
1299 repr( clusters[ 0 ] ) )
Jon Hall6e709752016-02-01 13:38:46 -08001300 numClusters = "ERROR"
Jon Hall85794ff2015-07-08 14:12:30 -07001301 clusterResults = main.FALSE
1302 if numClusters == 1:
1303 clusterResults = main.TRUE
1304 utilities.assert_equals(
1305 expect=1,
1306 actual=numClusters,
1307 onpass="ONOS shows 1 SCC",
1308 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1309
1310 main.step( "Comparing ONOS topology to MN" )
1311 devicesResults = main.TRUE
1312 linksResults = main.TRUE
1313 hostsResults = main.TRUE
1314 mnSwitches = main.Mininet1.getSwitches()
1315 mnLinks = main.Mininet1.getLinks()
1316 mnHosts = main.Mininet1.getHosts()
Jon Halla440e872016-03-31 15:15:50 -07001317 for controller in main.activeNodes:
1318 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07001319 if devices[ controller ] and ports[ controller ] and\
1320 "Error" not in devices[ controller ] and\
1321 "Error" not in ports[ controller ]:
Jon Hall6e709752016-02-01 13:38:46 -08001322 currentDevicesResult = main.Mininet1.compareSwitches(
1323 mnSwitches,
1324 json.loads( devices[ controller ] ),
1325 json.loads( ports[ controller ] ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001326 else:
1327 currentDevicesResult = main.FALSE
1328 utilities.assert_equals( expect=main.TRUE,
1329 actual=currentDevicesResult,
1330 onpass="ONOS" + controllerStr +
1331 " Switches view is correct",
1332 onfail="ONOS" + controllerStr +
1333 " Switches view is incorrect" )
1334 if links[ controller ] and "Error" not in links[ controller ]:
1335 currentLinksResult = main.Mininet1.compareLinks(
1336 mnSwitches, mnLinks,
1337 json.loads( links[ controller ] ) )
1338 else:
1339 currentLinksResult = main.FALSE
1340 utilities.assert_equals( expect=main.TRUE,
1341 actual=currentLinksResult,
1342 onpass="ONOS" + controllerStr +
1343 " links view is correct",
1344 onfail="ONOS" + controllerStr +
1345 " links view is incorrect" )
1346
Jon Halla440e872016-03-31 15:15:50 -07001347 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall85794ff2015-07-08 14:12:30 -07001348 currentHostsResult = main.Mininet1.compareHosts(
1349 mnHosts,
1350 hosts[ controller ] )
1351 else:
1352 currentHostsResult = main.FALSE
1353 utilities.assert_equals( expect=main.TRUE,
1354 actual=currentHostsResult,
1355 onpass="ONOS" + controllerStr +
1356 " hosts exist in Mininet",
1357 onfail="ONOS" + controllerStr +
1358 " hosts don't match Mininet" )
1359
1360 devicesResults = devicesResults and currentDevicesResult
1361 linksResults = linksResults and currentLinksResult
1362 hostsResults = hostsResults and currentHostsResult
1363
1364 main.step( "Device information is correct" )
1365 utilities.assert_equals(
1366 expect=main.TRUE,
1367 actual=devicesResults,
1368 onpass="Device information is correct",
1369 onfail="Device information is incorrect" )
1370
1371 main.step( "Links are correct" )
1372 utilities.assert_equals(
1373 expect=main.TRUE,
1374 actual=linksResults,
1375 onpass="Link are correct",
1376 onfail="Links are incorrect" )
1377
1378 main.step( "Hosts are correct" )
1379 utilities.assert_equals(
1380 expect=main.TRUE,
1381 actual=hostsResults,
1382 onpass="Hosts are correct",
1383 onfail="Hosts are incorrect" )
1384
1385 def CASE6( self, main ):
1386 """
1387 The Failure case.
1388 """
1389 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001390 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001391 assert main, "main not defined"
1392 assert utilities.assert_equals, "utilities.assert_equals not defined"
1393
1394 # Reset non-persistent variables
1395 try:
1396 iCounterValue = 0
1397 except NameError:
1398 main.log.error( "iCounterValue not defined, setting to 0" )
1399 iCounterValue = 0
1400
1401 main.case( "Restart ONOS node" )
Jon Hall783bbf92015-07-23 14:33:19 -07001402 main.caseExplanation = "Killing ONOS process and restart cli " +\
Jon Hall85794ff2015-07-08 14:12:30 -07001403 "sessions once onos is up."
Jon Hall96091e62015-09-21 17:34:17 -07001404
1405 main.step( "Checking ONOS Logs for errors" )
1406 for node in main.nodes:
1407 main.log.debug( "Checking logs for errors on " + node.name + ":" )
1408 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
1409
Jon Hall85794ff2015-07-08 14:12:30 -07001410 main.step( "Killing ONOS processes" )
Jon Halle1a3b752015-07-22 13:02:46 -07001411 killResult = main.ONOSbench.onosKill( main.nodes[0].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -07001412 start = time.time()
1413 utilities.assert_equals( expect=main.TRUE, actual=killResult,
1414 onpass="ONOS Killed",
1415 onfail="Error killing ONOS" )
1416
1417 main.step( "Checking if ONOS is up yet" )
1418 count = 0
1419 while count < 10:
Jon Halle1a3b752015-07-22 13:02:46 -07001420 onos1Isup = main.ONOSbench.isup( main.nodes[0].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -07001421 if onos1Isup == main.TRUE:
1422 elapsed = time.time() - start
1423 break
1424 else:
1425 count = count + 1
1426 utilities.assert_equals( expect=main.TRUE, actual=onos1Isup,
1427 onpass="ONOS is back up",
1428 onfail="ONOS failed to start" )
1429
1430 main.log.step( "Starting ONOS CLI sessions" )
Jon Halle1a3b752015-07-22 13:02:46 -07001431 cliResults = main.ONOScli1.startOnosCli( main.nodes[0].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -07001432 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1433 onpass="ONOS cli startup successful",
1434 onfail="ONOS cli startup failed" )
1435
1436 if elapsed:
1437 main.log.info( "ESTIMATE: ONOS took %s seconds to restart" %
1438 str( elapsed ) )
1439 main.restartTime = elapsed
1440 else:
1441 main.restartTime = -1
1442 time.sleep( 5 )
1443 # rerun on election apps
1444 main.ONOScli1.electionTestRun()
1445
1446 def CASE7( self, main ):
1447 """
1448 Check state after ONOS failure
1449 """
1450 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001451 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001452 assert main, "main not defined"
1453 assert utilities.assert_equals, "utilities.assert_equals not defined"
1454 main.case( "Running ONOS Constant State Tests" )
Jon Hall6e709752016-02-01 13:38:46 -08001455
Jon Hall85794ff2015-07-08 14:12:30 -07001456 main.step( "Check that each switch has a master" )
1457 # Assert that each device has a master
Jon Halla440e872016-03-31 15:15:50 -07001458 rolesNotNull = main.TRUE
1459 threads = []
1460 for i in main.activeNodes:
1461 t = main.Thread( target=main.CLIs[i].rolesNotNull,
1462 name="rolesNotNull-" + str( i ),
1463 args=[ ] )
1464 threads.append( t )
1465 t.start()
1466
1467 for t in threads:
1468 t.join()
1469 rolesNotNull = rolesNotNull and t.result
Jon Hall85794ff2015-07-08 14:12:30 -07001470 utilities.assert_equals(
1471 expect=main.TRUE,
1472 actual=rolesNotNull,
1473 onpass="Each device has a master",
1474 onfail="Some devices don't have a master assigned" )
1475
1476 main.step( "Check if switch roles are consistent across all nodes" )
1477 ONOS1Mastership = main.ONOScli1.roles()
1478 # FIXME: Refactor this whole case for single instance
1479 if "Error" in ONOS1Mastership or not ONOS1Mastership:
1480 main.log.error( "Error in getting ONOS mastership" )
1481 main.log.warn( "ONOS1 mastership response: " +
1482 repr( ONOS1Mastership ) )
1483 consistentMastership = main.FALSE
1484 else:
1485 consistentMastership = main.TRUE
1486 utilities.assert_equals(
1487 expect=main.TRUE,
1488 actual=consistentMastership,
1489 onpass="Switch roles are consistent across all ONOS nodes",
1490 onfail="ONOS nodes have different views of switch roles" )
1491
1492 description2 = "Compare switch roles from before failure"
1493 main.step( description2 )
1494
1495 currentJson = json.loads( ONOS1Mastership )
1496 oldJson = json.loads( mastershipState )
1497 mastershipCheck = main.TRUE
1498 for i in range( 1, 29 ):
1499 switchDPID = str(
1500 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
1501
1502 current = [ switch[ 'master' ] for switch in currentJson
1503 if switchDPID in switch[ 'id' ] ]
1504 old = [ switch[ 'master' ] for switch in oldJson
1505 if switchDPID in switch[ 'id' ] ]
1506 if current == old:
1507 mastershipCheck = mastershipCheck and main.TRUE
1508 else:
1509 main.log.warn( "Mastership of switch %s changed" % switchDPID )
1510 mastershipCheck = main.FALSE
1511 utilities.assert_equals(
1512 expect=main.TRUE,
1513 actual=mastershipCheck,
1514 onpass="Mastership of Switches was not changed",
1515 onfail="Mastership of some switches changed" )
1516 mastershipCheck = mastershipCheck and consistentMastership
1517
1518 main.step( "Get the intents and compare across all nodes" )
1519 ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
1520 intentCheck = main.FALSE
1521 if "Error" in ONOS1Intents or not ONOS1Intents:
1522 main.log.error( "Error in getting ONOS intents" )
1523 main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
1524 else:
1525 intentCheck = main.TRUE
1526 utilities.assert_equals(
1527 expect=main.TRUE,
1528 actual=intentCheck,
1529 onpass="Intents are consistent across all ONOS nodes",
1530 onfail="ONOS nodes have different views of intents" )
1531 # Print the intent states
1532 intents = []
1533 intents.append( ONOS1Intents )
1534 intentStates = []
1535 for node in intents: # Iter through ONOS nodes
1536 nodeStates = []
1537 # Iter through intents of a node
1538 for intent in json.loads( node ):
1539 nodeStates.append( intent[ 'state' ] )
1540 intentStates.append( nodeStates )
1541 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1542 main.log.info( dict( out ) )
1543
1544 # NOTE: Store has no durability, so intents are lost across system
1545 # restarts
1546 """
1547 main.step( "Compare current intents with intents before the failure" )
1548 # NOTE: this requires case 5 to pass for intentState to be set.
1549 # maybe we should stop the test if that fails?
1550 sameIntents = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07001551 try:
1552 intentState
1553 except NameError:
1554 main.log.warn( "No previous intent state was saved" )
1555 else:
1556 if intentState and intentState == ONOSIntents[ 0 ]:
1557 sameIntents = main.TRUE
1558 main.log.info( "Intents are consistent with before failure" )
1559 # TODO: possibly the states have changed? we may need to figure out
1560 # what the acceptable states are
1561 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
1562 sameIntents = main.TRUE
1563 try:
1564 before = json.loads( intentState )
1565 after = json.loads( ONOSIntents[ 0 ] )
1566 for intent in before:
1567 if intent not in after:
1568 sameIntents = main.FALSE
1569 main.log.debug( "Intent is not currently in ONOS " +
1570 "(at least in the same form):" )
1571 main.log.debug( json.dumps( intent ) )
1572 except ( ValueError, TypeError ):
1573 main.log.exception( "Exception printing intents" )
1574 main.log.debug( repr( ONOSIntents[0] ) )
1575 main.log.debug( repr( intentState ) )
1576 if sameIntents == main.FALSE:
1577 try:
1578 main.log.debug( "ONOS intents before: " )
1579 main.log.debug( json.dumps( json.loads( intentState ),
1580 sort_keys=True, indent=4,
1581 separators=( ',', ': ' ) ) )
1582 main.log.debug( "Current ONOS intents: " )
1583 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1584 sort_keys=True, indent=4,
1585 separators=( ',', ': ' ) ) )
1586 except ( ValueError, TypeError ):
1587 main.log.exception( "Exception printing intents" )
1588 main.log.debug( repr( ONOSIntents[0] ) )
1589 main.log.debug( repr( intentState ) )
1590 utilities.assert_equals(
1591 expect=main.TRUE,
1592 actual=sameIntents,
1593 onpass="Intents are consistent with before failure",
1594 onfail="The Intents changed during failure" )
Jon Hall85794ff2015-07-08 14:12:30 -07001595 intentCheck = intentCheck and sameIntents
1596 """
1597 main.step( "Get the OF Table entries and compare to before " +
1598 "component failure" )
1599 FlowTables = main.TRUE
Jon Hall85794ff2015-07-08 14:12:30 -07001600 for i in range( 28 ):
1601 main.log.info( "Checking flow table on s" + str( i + 1 ) )
GlennRC68467eb2015-11-16 18:01:01 -08001602 tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
1603 FlowTables = FlowTables and main.Mininet1.flowTableComp( flows[i], tmpFlows )
Jon Hall85794ff2015-07-08 14:12:30 -07001604 if FlowTables == main.FALSE:
GlennRC68467eb2015-11-16 18:01:01 -08001605 main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001606 utilities.assert_equals(
1607 expect=main.TRUE,
1608 actual=FlowTables,
1609 onpass="No changes were found in the flow tables",
1610 onfail="Changes were found in the flow tables" )
1611
1612 main.step( "Leadership Election is still functional" )
1613 # Test of LeadershipElection
1614
Jon Halla440e872016-03-31 15:15:50 -07001615 leader = main.nodes[ main.activeNodes[ 0 ] ].ip_address
Jon Hall85794ff2015-07-08 14:12:30 -07001616 leaderResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001617 for controller in range( 1, main.numCtrls + 1 ):
Jon Hall85794ff2015-07-08 14:12:30 -07001618 # loop through ONOScli handlers
1619 node = getattr( main, ( 'ONOScli' + str( controller ) ) )
1620 leaderN = node.electionTestLeader()
1621 # verify leader is ONOS1
1622 # NOTE even though we restarted ONOS, it is the only one so onos 1
1623 # must be leader
1624 if leaderN == leader:
1625 # all is well
1626 pass
1627 elif leaderN == main.FALSE:
1628 # error in response
1629 main.log.error( "Something is wrong with " +
1630 "electionTestLeader function, check the" +
1631 " error logs" )
1632 leaderResult = main.FALSE
1633 elif leader != leaderN:
1634 leaderResult = main.FALSE
1635 main.log.error( "ONOS" + str( controller ) + " sees " +
1636 str( leaderN ) +
1637 " as the leader of the election app. " +
1638 "Leader should be " + str( leader ) )
1639 utilities.assert_equals(
1640 expect=main.TRUE,
1641 actual=leaderResult,
1642 onpass="Leadership election passed",
1643 onfail="Something went wrong with Leadership election" )
1644
1645 def CASE8( self, main ):
1646 """
1647 Compare topo
1648 """
1649 import json
1650 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001651 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001652 assert main, "main not defined"
1653 assert utilities.assert_equals, "utilities.assert_equals not defined"
1654
1655 main.case( "Compare ONOS Topology view to Mininet topology" )
Jon Hall783bbf92015-07-23 14:33:19 -07001656 main.caseExplanation = "Compare topology objects between Mininet" +\
Jon Hall85794ff2015-07-08 14:12:30 -07001657 " and ONOS"
Jon Hall85794ff2015-07-08 14:12:30 -07001658 topoResult = main.FALSE
1659 elapsed = 0
1660 count = 0
Jon Halle9b1fa32015-12-08 15:32:21 -08001661 main.step( "Comparing ONOS topology to MN topology" )
Jon Hall85794ff2015-07-08 14:12:30 -07001662 startTime = time.time()
1663 # Give time for Gossip to work
Jon Halle9b1fa32015-12-08 15:32:21 -08001664 while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
Jon Hall96091e62015-09-21 17:34:17 -07001665 devicesResults = main.TRUE
1666 linksResults = main.TRUE
1667 hostsResults = main.TRUE
1668 hostAttachmentResults = True
Jon Hall85794ff2015-07-08 14:12:30 -07001669 count += 1
1670 cliStart = time.time()
1671 devices = []
1672 devices.append( main.ONOScli1.devices() )
1673 hosts = []
1674 hosts.append( json.loads( main.ONOScli1.hosts() ) )
1675 ipResult = main.TRUE
1676 for controller in range( 0, len( hosts ) ):
1677 controllerStr = str( controller + 1 )
1678 for host in hosts[ controller ]:
1679 if host is None or host.get( 'ipAddresses', [] ) == []:
1680 main.log.error(
1681 "DEBUG:Error with host ips on controller" +
1682 controllerStr + ": " + str( host ) )
1683 ipResult = main.FALSE
1684 ports = []
1685 ports.append( main.ONOScli1.ports() )
1686 links = []
1687 links.append( main.ONOScli1.links() )
1688 clusters = []
1689 clusters.append( main.ONOScli1.clusters() )
1690
1691 elapsed = time.time() - startTime
1692 cliTime = time.time() - cliStart
1693 print "CLI time: " + str( cliTime )
1694
1695 mnSwitches = main.Mininet1.getSwitches()
1696 mnLinks = main.Mininet1.getLinks()
1697 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07001698 for controller in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07001699 controllerStr = str( controller + 1 )
1700 if devices[ controller ] and ports[ controller ] and\
1701 "Error" not in devices[ controller ] and\
1702 "Error" not in ports[ controller ]:
1703
Jon Hallc6793552016-01-19 14:18:37 -08001704 try:
1705 currentDevicesResult = main.Mininet1.compareSwitches(
1706 mnSwitches,
1707 json.loads( devices[ controller ] ),
1708 json.loads( ports[ controller ] ) )
1709 except ( TypeError, ValueError ) as e:
1710 main.log.exception( "Object not as expected; devices={!r}\nports={!r}".format(
1711 devices[ controller ], ports[ controller ] ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001712 else:
1713 currentDevicesResult = main.FALSE
1714 utilities.assert_equals( expect=main.TRUE,
1715 actual=currentDevicesResult,
1716 onpass="ONOS" + controllerStr +
1717 " Switches view is correct",
1718 onfail="ONOS" + controllerStr +
1719 " Switches view is incorrect" )
1720
1721 if links[ controller ] and "Error" not in links[ controller ]:
1722 currentLinksResult = main.Mininet1.compareLinks(
1723 mnSwitches, mnLinks,
1724 json.loads( links[ controller ] ) )
1725 else:
1726 currentLinksResult = main.FALSE
1727 utilities.assert_equals( expect=main.TRUE,
1728 actual=currentLinksResult,
1729 onpass="ONOS" + controllerStr +
1730 " links view is correct",
1731 onfail="ONOS" + controllerStr +
1732 " links view is incorrect" )
1733
1734 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1735 currentHostsResult = main.Mininet1.compareHosts(
1736 mnHosts,
1737 hosts[ controller ] )
1738 else:
1739 currentHostsResult = main.FALSE
1740 utilities.assert_equals( expect=main.TRUE,
1741 actual=currentHostsResult,
1742 onpass="ONOS" + controllerStr +
1743 " hosts exist in Mininet",
1744 onfail="ONOS" + controllerStr +
1745 " hosts don't match Mininet" )
1746 # CHECKING HOST ATTACHMENT POINTS
1747 hostAttachment = True
1748 zeroHosts = False
1749 # FIXME: topo-HA/obelisk specific mappings:
1750 # key is mac and value is dpid
1751 mappings = {}
1752 for i in range( 1, 29 ): # hosts 1 through 28
1753 # set up correct variables:
1754 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
1755 if i == 1:
1756 deviceId = "1000".zfill(16)
1757 elif i == 2:
1758 deviceId = "2000".zfill(16)
1759 elif i == 3:
1760 deviceId = "3000".zfill(16)
1761 elif i == 4:
1762 deviceId = "3004".zfill(16)
1763 elif i == 5:
1764 deviceId = "5000".zfill(16)
1765 elif i == 6:
1766 deviceId = "6000".zfill(16)
1767 elif i == 7:
1768 deviceId = "6007".zfill(16)
1769 elif i >= 8 and i <= 17:
1770 dpid = '3' + str( i ).zfill( 3 )
1771 deviceId = dpid.zfill(16)
1772 elif i >= 18 and i <= 27:
1773 dpid = '6' + str( i ).zfill( 3 )
1774 deviceId = dpid.zfill(16)
1775 elif i == 28:
1776 deviceId = "2800".zfill(16)
1777 mappings[ macId ] = deviceId
1778 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1779 if hosts[ controller ] == []:
1780 main.log.warn( "There are no hosts discovered" )
1781 zeroHosts = True
1782 else:
1783 for host in hosts[ controller ]:
1784 mac = None
1785 location = None
1786 device = None
1787 port = None
1788 try:
1789 mac = host.get( 'mac' )
1790 assert mac, "mac field could not be found for this host object"
1791
1792 location = host.get( 'location' )
1793 assert location, "location field could not be found for this host object"
1794
1795 # Trim the protocol identifier off deviceId
1796 device = str( location.get( 'elementId' ) ).split(':')[1]
1797 assert device, "elementId field could not be found for this host location object"
1798
1799 port = location.get( 'port' )
1800 assert port, "port field could not be found for this host location object"
1801
1802 # Now check if this matches where they should be
1803 if mac and device and port:
1804 if str( port ) != "1":
1805 main.log.error( "The attachment port is incorrect for " +
1806 "host " + str( mac ) +
1807 ". Expected: 1 Actual: " + str( port) )
1808 hostAttachment = False
1809 if device != mappings[ str( mac ) ]:
1810 main.log.error( "The attachment device is incorrect for " +
1811 "host " + str( mac ) +
1812 ". Expected: " + mappings[ str( mac ) ] +
1813 " Actual: " + device )
1814 hostAttachment = False
1815 else:
1816 hostAttachment = False
1817 except AssertionError:
1818 main.log.exception( "Json object not as expected" )
1819 main.log.error( repr( host ) )
1820 hostAttachment = False
1821 else:
1822 main.log.error( "No hosts json output or \"Error\"" +
1823 " in output. hosts = " +
1824 repr( hosts[ controller ] ) )
1825 if zeroHosts is False:
1826 hostAttachment = True
1827
Jon Hall85794ff2015-07-08 14:12:30 -07001828 devicesResults = devicesResults and currentDevicesResult
1829 linksResults = linksResults and currentLinksResult
1830 hostsResults = hostsResults and currentHostsResult
1831 hostAttachmentResults = hostAttachmentResults and\
1832 hostAttachment
1833
Jon Halla440e872016-03-31 15:15:50 -07001834 # "consistent" results don't make sense for single instance
Jon Hall85794ff2015-07-08 14:12:30 -07001835 # there should always only be one cluster
Jon Hall85794ff2015-07-08 14:12:30 -07001836 clusterResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07001837 try:
1838 numClusters = len( json.loads( clusters[ 0 ] ) )
1839 except ( ValueError, TypeError ):
1840 main.log.exception( "Error parsing clusters[0]: " +
1841 repr( clusters[0] ) )
1842 numClusters = "ERROR"
1843 clusterResults = main.FALSE
Jon Hall85794ff2015-07-08 14:12:30 -07001844 if numClusters == 1:
1845 clusterResults = main.TRUE
1846 utilities.assert_equals(
1847 expect=1,
1848 actual=numClusters,
1849 onpass="ONOS shows 1 SCC",
1850 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1851
1852 topoResult = ( devicesResults and linksResults
1853 and hostsResults and ipResult and clusterResults and
1854 hostAttachmentResults )
1855
1856 topoResult = topoResult and int( count <= 2 )
1857 note = "note it takes about " + str( int( cliTime ) ) + \
1858 " seconds for the test to make all the cli calls to fetch " +\
1859 "the topology from each ONOS instance"
1860 main.log.info(
1861 "Very crass estimate for topology discovery/convergence( " +
1862 str( note ) + " ): " + str( elapsed ) + " seconds, " +
1863 str( count ) + " tries" )
1864 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
1865 onpass="Topology Check Test successful",
1866 onfail="Topology Check Test NOT successful" )
1867
1868 def CASE9( self, main ):
1869 """
1870 Link s3-s28 down
1871 """
1872 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001873 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001874 assert main, "main not defined"
1875 assert utilities.assert_equals, "utilities.assert_equals not defined"
1876 # NOTE: You should probably run a topology check after this
1877
1878 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
1879
1880 description = "Turn off a link to ensure that Link Discovery " +\
1881 "is working properly"
1882 main.case( description )
1883
1884 main.step( "Kill Link between s3 and s28" )
1885 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
1886 main.log.info( "Waiting " + str( linkSleep ) +
1887 " seconds for link down to be discovered" )
1888 time.sleep( linkSleep )
1889 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
1890 onpass="Link down successful",
1891 onfail="Failed to bring link down" )
1892 # TODO do some sort of check here
1893
1894 def CASE10( self, main ):
1895 """
1896 Link s3-s28 up
1897 """
1898 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001899 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001900 assert main, "main not defined"
1901 assert utilities.assert_equals, "utilities.assert_equals not defined"
1902 # NOTE: You should probably run a topology check after this
1903
1904 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
1905
1906 description = "Restore a link to ensure that Link Discovery is " + \
1907 "working properly"
1908 main.case( description )
1909
1910 main.step( "Bring link between s3 and s28 back up" )
1911 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
1912 main.log.info( "Waiting " + str( linkSleep ) +
1913 " seconds for link up to be discovered" )
1914 time.sleep( linkSleep )
1915 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
1916 onpass="Link up successful",
1917 onfail="Failed to bring link up" )
1918 # TODO do some sort of check here
1919
1920 def CASE11( self, main ):
1921 """
1922 Switch Down
1923 """
1924 # NOTE: You should probably run a topology check after this
1925 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001926 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001927 assert main, "main not defined"
1928 assert utilities.assert_equals, "utilities.assert_equals not defined"
1929
1930 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
1931
1932 description = "Killing a switch to ensure it is discovered correctly"
Jon Halla440e872016-03-31 15:15:50 -07001933 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall85794ff2015-07-08 14:12:30 -07001934 main.case( description )
1935 switch = main.params[ 'kill' ][ 'switch' ]
1936 switchDPID = main.params[ 'kill' ][ 'dpid' ]
1937
1938 # TODO: Make this switch parameterizable
1939 main.step( "Kill " + switch )
1940 main.log.info( "Deleting " + switch )
1941 main.Mininet1.delSwitch( switch )
1942 main.log.info( "Waiting " + str( switchSleep ) +
1943 " seconds for switch down to be discovered" )
1944 time.sleep( switchSleep )
Jon Halla440e872016-03-31 15:15:50 -07001945 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall85794ff2015-07-08 14:12:30 -07001946 # Peek at the deleted switch
1947 main.log.warn( str( device ) )
1948 result = main.FALSE
1949 if device and device[ 'available' ] is False:
1950 result = main.TRUE
1951 utilities.assert_equals( expect=main.TRUE, actual=result,
1952 onpass="Kill switch successful",
1953 onfail="Failed to kill switch?" )
1954
1955 def CASE12( self, main ):
1956 """
1957 Switch Up
1958 """
1959 # NOTE: You should probably run a topology check after this
1960 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001961 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001962 assert main, "main not defined"
1963 assert utilities.assert_equals, "utilities.assert_equals not defined"
1964
1965 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
1966 switch = main.params[ 'kill' ][ 'switch' ]
1967 switchDPID = main.params[ 'kill' ][ 'dpid' ]
1968 links = main.params[ 'kill' ][ 'links' ].split()
Jon Halla440e872016-03-31 15:15:50 -07001969 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall85794ff2015-07-08 14:12:30 -07001970 description = "Adding a switch to ensure it is discovered correctly"
1971 main.case( description )
1972
1973 main.step( "Add back " + switch )
1974 main.Mininet1.addSwitch( switch, dpid=switchDPID )
1975 for peer in links:
1976 main.Mininet1.addLink( switch, peer )
Jon Halla440e872016-03-31 15:15:50 -07001977 ipList = [ node.ip_address for node in main.nodes ]
Jon Hall85794ff2015-07-08 14:12:30 -07001978 main.Mininet1.assignSwController( sw=switch, ip=ipList )
1979 main.log.info( "Waiting " + str( switchSleep ) +
1980 " seconds for switch up to be discovered" )
1981 time.sleep( switchSleep )
Jon Halla440e872016-03-31 15:15:50 -07001982 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall85794ff2015-07-08 14:12:30 -07001983 # Peek at the deleted switch
1984 main.log.warn( str( device ) )
1985 result = main.FALSE
1986 if device and device[ 'available' ]:
1987 result = main.TRUE
1988 utilities.assert_equals( expect=main.TRUE, actual=result,
1989 onpass="add switch successful",
1990 onfail="Failed to add switch?" )
1991
1992 def CASE13( self, main ):
1993 """
1994 Clean up
1995 """
1996 import os
1997 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001998 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001999 assert main, "main not defined"
2000 assert utilities.assert_equals, "utilities.assert_equals not defined"
2001 # printing colors to terminal
2002 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2003 'blue': '\033[94m', 'green': '\033[92m',
2004 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
2005 main.case( "Test Cleanup" )
2006 main.step( "Killing tcpdumps" )
2007 main.Mininet2.stopTcpdump()
2008
2009 testname = main.TEST
Jon Hall96091e62015-09-21 17:34:17 -07002010 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall85794ff2015-07-08 14:12:30 -07002011 main.step( "Copying MN pcap and ONOS log files to test station" )
2012 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
2013 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
Jon Hall96091e62015-09-21 17:34:17 -07002014 # NOTE: MN Pcap file is being saved to logdir.
2015 # We scp this file as MN and TestON aren't necessarily the same vm
2016
2017 # FIXME: To be replaced with a Jenkin's post script
Jon Hall85794ff2015-07-08 14:12:30 -07002018 # TODO: Load these from params
2019 # NOTE: must end in /
2020 logFolder = "/opt/onos/log/"
2021 logFiles = [ "karaf.log", "karaf.log.1" ]
2022 # NOTE: must end in /
Jon Hall85794ff2015-07-08 14:12:30 -07002023 for f in logFiles:
Jon Hall96091e62015-09-21 17:34:17 -07002024 for node in main.nodes:
Jon Halla440e872016-03-31 15:15:50 -07002025 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002026 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2027 logFolder + f, dstName )
Jon Hall85794ff2015-07-08 14:12:30 -07002028 # std*.log's
2029 # NOTE: must end in /
2030 logFolder = "/opt/onos/var/"
2031 logFiles = [ "stderr.log", "stdout.log" ]
2032 # NOTE: must end in /
Jon Hall85794ff2015-07-08 14:12:30 -07002033 for f in logFiles:
Jon Hall96091e62015-09-21 17:34:17 -07002034 for node in main.nodes:
Jon Halla440e872016-03-31 15:15:50 -07002035 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002036 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2037 logFolder + f, dstName )
2038 else:
2039 main.log.debug( "skipping saving log files" )
Jon Hall85794ff2015-07-08 14:12:30 -07002040
Jon Hall85794ff2015-07-08 14:12:30 -07002041 main.step( "Stopping Mininet" )
2042 mnResult = main.Mininet1.stopNet()
2043 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2044 onpass="Mininet stopped",
2045 onfail="MN cleanup NOT successful" )
2046
2047 main.step( "Checking ONOS Logs for errors" )
Jon Hall96091e62015-09-21 17:34:17 -07002048 for node in main.nodes:
2049 main.log.debug( "Checking logs for errors on " + node.name + ":" )
2050 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall85794ff2015-07-08 14:12:30 -07002051
2052 try:
2053 timerLog = open( main.logdir + "/Timers.csv", 'w')
2054 # Overwrite with empty line and close
2055 labels = "Gossip Intents, Restart"
2056 data = str( gossipTime ) + ", " + str( main.restartTime )
2057 timerLog.write( labels + "\n" + data )
2058 timerLog.close()
2059 except NameError, e:
2060 main.log.exception(e)
2061
2062 def CASE14( self, main ):
2063 """
2064 start election app on all onos nodes
2065 """
Jon Halle1a3b752015-07-22 13:02:46 -07002066 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002067 assert main, "main not defined"
2068 assert utilities.assert_equals, "utilities.assert_equals not defined"
2069
2070 main.case("Start Leadership Election app")
2071 main.step( "Install leadership election app" )
Jon Halla440e872016-03-31 15:15:50 -07002072 onosCli = main.CLIs[ main.activeNodes[0] ]
2073 appResult = onosCli.activateApp( "org.onosproject.election" )
Jon Hall85794ff2015-07-08 14:12:30 -07002074 utilities.assert_equals(
2075 expect=main.TRUE,
2076 actual=appResult,
2077 onpass="Election app installed",
2078 onfail="Something went wrong with installing Leadership election" )
2079
2080 main.step( "Run for election on each node" )
Jon Halla440e872016-03-31 15:15:50 -07002081 leaderResult = main.TRUE
2082 leaders = []
2083 for i in main.activeNodes:
2084 main.CLIs[i].electionTestRun()
2085 for i in main.activeNodes:
2086 cli = main.CLIs[i]
2087 leader = cli.electionTestLeader()
2088 if leader is None or leader == main.FALSE:
2089 main.log.error( cli.name + ": Leader for the election app " +
2090 "should be an ONOS node, instead got '" +
2091 str( leader ) + "'" )
2092 leaderResult = main.FALSE
2093 leaders.append( leader )
Jon Hall85794ff2015-07-08 14:12:30 -07002094 utilities.assert_equals(
2095 expect=main.TRUE,
2096 actual=leaderResult,
2097 onpass="Successfully ran for leadership",
2098 onfail="Failed to run for leadership" )
2099
2100 def CASE15( self, main ):
2101 """
2102 Check that Leadership Election is still functional
acsmars71adceb2015-08-31 15:09:26 -07002103 15.1 Run election on each node
2104 15.2 Check that each node has the same leaders and candidates
2105 15.3 Find current leader and withdraw
2106 15.4 Check that a new node was elected leader
2107 15.5 Check that that new leader was the candidate of old leader
2108 15.6 Run for election on old leader
2109 15.7 Check that oldLeader is a candidate, and leader if only 1 node
2110 15.8 Make sure that the old leader was added to the candidate list
2111
2112 old and new variable prefixes refer to data from before vs after
2113 withdrawl and later before withdrawl vs after re-election
Jon Hall85794ff2015-07-08 14:12:30 -07002114 """
acsmars71adceb2015-08-31 15:09:26 -07002115 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002116 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002117 assert main, "main not defined"
2118 assert utilities.assert_equals, "utilities.assert_equals not defined"
acsmars71adceb2015-08-31 15:09:26 -07002119 assert main.CLIs, "main.CLIs not defined"
2120 assert main.nodes, "main.nodes not defined"
2121
Jon Hall85794ff2015-07-08 14:12:30 -07002122 description = "Check that Leadership Election is still functional"
2123 main.case( description )
Jon Halla440e872016-03-31 15:15:50 -07002124 # NOTE: Need to re-run after restarts since being a canidate is not persistant
acsmars2c2fcdd2015-08-25 17:14:13 -07002125
Jon Halla440e872016-03-31 15:15:50 -07002126 oldLeaders = [] # list of lists of each nodes' candidates before
2127 newLeaders = [] # list of lists of each nodes' candidates after
acsmars71adceb2015-08-31 15:09:26 -07002128 oldLeader = '' # the old leader from oldLeaders, None if not same
2129 newLeader = '' # the new leaders fron newLoeaders, None if not same
2130 oldLeaderCLI = None # the CLI of the old leader used for re-electing
2131 expectNoLeader = False # True when there is only one leader
2132 if main.numCtrls == 1:
2133 expectNoLeader = True
acsmars2c2fcdd2015-08-25 17:14:13 -07002134
acsmars71adceb2015-08-31 15:09:26 -07002135 main.step( "Run for election on each node" )
2136 electionResult = main.TRUE
2137
Jon Halla440e872016-03-31 15:15:50 -07002138 for i in main.activeNodes: # run test election on each node
2139 if main.CLIs[i].electionTestRun() == main.FALSE:
acsmars71adceb2015-08-31 15:09:26 -07002140 electionResult = main.FALSE
acsmars71adceb2015-08-31 15:09:26 -07002141 utilities.assert_equals(
2142 expect=main.TRUE,
2143 actual=electionResult,
2144 onpass="All nodes successfully ran for leadership",
2145 onfail="At least one node failed to run for leadership" )
2146
acsmars3a72bde2015-09-02 14:16:22 -07002147 if electionResult == main.FALSE:
2148 main.log.error(
2149 "Skipping Test Case because Election Test App isn't loaded" )
2150 main.skipCase()
2151
acsmars71adceb2015-08-31 15:09:26 -07002152 main.step( "Check that each node shows the same leader and candidates" )
Jon Halla440e872016-03-31 15:15:50 -07002153 failMessage = "Nodes have different leaderboards"
2154 def consistentLeaderboards( nodes ):
2155 TOPIC = 'org.onosproject.election'
2156 # FIXME: use threads
2157 #FIXME: should we retry outside the function?
2158 for n in range( 5 ): # Retry in case election is still happening
2159 leaderList = []
2160 # Get all leaderboards
2161 for cli in nodes:
2162 leaderList.append( cli.specificLeaderCandidate( TOPIC ) )
2163 # Compare leaderboards
2164 result = all( i == leaderList[0] for i in leaderList ) and\
2165 leaderList is not None
2166 main.log.debug( leaderList )
2167 main.log.warn( result )
2168 if result:
2169 return ( result, leaderList )
2170 time.sleep(5) #TODO: paramerterize
2171 main.log.error( "Inconsistent leaderboards:" + str( leaderList ) )
2172 activeCLIs = [ main.CLIs[i] for i in main.activeNodes ]
2173 sameResult, oldLeaders = consistentLeaderboards( activeCLIs )
2174 if sameResult:
2175 oldLeader = oldLeaders[ 0 ][ 0 ]
2176 main.log.warn( oldLeader )
Jon Hall85794ff2015-07-08 14:12:30 -07002177 else:
Jon Halla440e872016-03-31 15:15:50 -07002178 oldLeader = None
acsmars71adceb2015-08-31 15:09:26 -07002179 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07002180 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07002181 actual=sameResult,
Jon Halla440e872016-03-31 15:15:50 -07002182 onpass="Leaderboards are consistent for the election topic",
acsmars71adceb2015-08-31 15:09:26 -07002183 onfail=failMessage )
2184
2185 main.step( "Find current leader and withdraw" )
2186 withdrawResult = main.TRUE
2187 # do some sanity checking on leader before using it
2188 if oldLeader is None:
2189 main.log.error( "Leadership isn't consistent." )
2190 withdrawResult = main.FALSE
2191 # Get the CLI of the oldLeader
Jon Halla440e872016-03-31 15:15:50 -07002192 for i in main.activeNodes:
acsmars71adceb2015-08-31 15:09:26 -07002193 if oldLeader == main.nodes[ i ].ip_address:
2194 oldLeaderCLI = main.CLIs[ i ]
2195 break
2196 else: # FOR/ELSE statement
2197 main.log.error( "Leader election, could not find current leader" )
Jon Hall85794ff2015-07-08 14:12:30 -07002198 if oldLeader:
acsmars71adceb2015-08-31 15:09:26 -07002199 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall85794ff2015-07-08 14:12:30 -07002200 utilities.assert_equals(
2201 expect=main.TRUE,
2202 actual=withdrawResult,
2203 onpass="Node was withdrawn from election",
2204 onfail="Node was not withdrawn from election" )
2205
acsmars71adceb2015-08-31 15:09:26 -07002206 main.step( "Check that a new node was elected leader" )
acsmars71adceb2015-08-31 15:09:26 -07002207 failMessage = "Nodes have different leaders"
acsmars71adceb2015-08-31 15:09:26 -07002208 # Get new leaders and candidates
Jon Halla440e872016-03-31 15:15:50 -07002209 newLeaderResult, newLeaders = consistentLeaderboards( activeCLIs )
2210 if newLeaders[ 0 ][ 0 ] == 'none':
2211 main.log.error( "No leader was elected on at least 1 node" )
2212 if not expectNoLeader:
2213 newLeaderResult = False
2214 if newLeaderResult:
2215 newLeader = newLeaders[ 0 ][ 0 ]
acsmars71adceb2015-08-31 15:09:26 -07002216 else:
Jon Halla440e872016-03-31 15:15:50 -07002217 newLeader = None
acsmars71adceb2015-08-31 15:09:26 -07002218
2219 # Check that the new leader is not the older leader, which was withdrawn
2220 if newLeader == oldLeader:
Jon Halla440e872016-03-31 15:15:50 -07002221 newLeaderResult = False
2222 main.log.error( "All nodes still see old leader: " + str( oldLeader ) +
acsmars71adceb2015-08-31 15:09:26 -07002223 " as the current leader" )
Jon Hall85794ff2015-07-08 14:12:30 -07002224 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07002225 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07002226 actual=newLeaderResult,
2227 onpass="Leadership election passed",
2228 onfail="Something went wrong with Leadership election" )
Jon Hall85794ff2015-07-08 14:12:30 -07002229
Jon Halla440e872016-03-31 15:15:50 -07002230 main.step( "Check that that new leader was the candidate of old leader" )
2231 # candidates[ 2 ] should become the top candidate after withdrawl
acsmars71adceb2015-08-31 15:09:26 -07002232 correctCandidateResult = main.TRUE
2233 if expectNoLeader:
2234 if newLeader == 'none':
2235 main.log.info( "No leader expected. None found. Pass" )
2236 correctCandidateResult = main.TRUE
2237 else:
2238 main.log.info( "Expected no leader, got: " + str( newLeader ) )
2239 correctCandidateResult = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002240 elif len( oldLeaders[0] ) >= 3:
2241 if newLeader == oldLeaders[ 0 ][ 2 ]:
2242 # correct leader was elected
2243 correctCandidateResult = main.TRUE
2244 else:
2245 correctCandidateResult = main.FALSE
2246 main.log.error( "Candidate {} was elected. {} should have had priority.".format(
2247 newLeader, oldLeaders[ 0 ][ 2 ] ) )
2248 else:
2249 main.log.warn( "Could not determine who should be the correct leader" )
2250 main.log.debug( oldLeaders[ 0 ] )
acsmars71adceb2015-08-31 15:09:26 -07002251 correctCandidateResult = main.FALSE
acsmars71adceb2015-08-31 15:09:26 -07002252 utilities.assert_equals(
2253 expect=main.TRUE,
2254 actual=correctCandidateResult,
2255 onpass="Correct Candidate Elected",
2256 onfail="Incorrect Candidate Elected" )
2257
Jon Hall85794ff2015-07-08 14:12:30 -07002258 main.step( "Run for election on old leader( just so everyone " +
2259 "is in the hat )" )
acsmars71adceb2015-08-31 15:09:26 -07002260 if oldLeaderCLI is not None:
2261 runResult = oldLeaderCLI.electionTestRun()
Jon Hall85794ff2015-07-08 14:12:30 -07002262 else:
acsmars71adceb2015-08-31 15:09:26 -07002263 main.log.error( "No old leader to re-elect" )
Jon Hall85794ff2015-07-08 14:12:30 -07002264 runResult = main.FALSE
2265 utilities.assert_equals(
2266 expect=main.TRUE,
2267 actual=runResult,
2268 onpass="App re-ran for election",
2269 onfail="App failed to run for election" )
Jon Halla440e872016-03-31 15:15:50 -07002270
acsmars71adceb2015-08-31 15:09:26 -07002271 main.step(
2272 "Check that oldLeader is a candidate, and leader if only 1 node" )
2273 # verify leader didn't just change
Jon Halla440e872016-03-31 15:15:50 -07002274 # Get new leaders and candidates
2275 reRunLeaders = []
2276 time.sleep( 5 ) # Paremterize
2277 positionResult, reRunLeaders = consistentLeaderboards( activeCLIs )
acsmars71adceb2015-08-31 15:09:26 -07002278
2279 # Check that the re-elected node is last on the candidate List
Jon Halla440e872016-03-31 15:15:50 -07002280 if oldLeader != reRunLeaders[ 0 ][ -1 ]:
2281 main.log.error( "Old Leader ({}) not in the proper position: {} ".format( str( oldLeader),
2282 str( reRunLeaders[ 0 ] ) ) )
acsmars71adceb2015-08-31 15:09:26 -07002283 positionResult = main.FALSE
Jon Hall85794ff2015-07-08 14:12:30 -07002284
2285 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07002286 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07002287 actual=positionResult,
Jon Hall85794ff2015-07-08 14:12:30 -07002288 onpass="Old leader successfully re-ran for election",
2289 onfail="Something went wrong with Leadership election after " +
2290 "the old leader re-ran for election" )
2291
2292 def CASE16( self, main ):
2293 """
2294 Install Distributed Primitives app
2295 """
Jon Halla440e872016-03-31 15:15:50 -07002296 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002297 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002298 assert main, "main not defined"
2299 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002300 assert main.CLIs, "main.CLIs not defined"
2301 assert main.nodes, "main.nodes not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002302
2303 # Variables for the distributed primitives tests
2304 global pCounterName
Jon Hall85794ff2015-07-08 14:12:30 -07002305 global pCounterValue
Jon Hall85794ff2015-07-08 14:12:30 -07002306 global onosSet
2307 global onosSetName
2308 pCounterName = "TestON-Partitions"
Jon Hall85794ff2015-07-08 14:12:30 -07002309 pCounterValue = 0
Jon Hall85794ff2015-07-08 14:12:30 -07002310 onosSet = set([])
2311 onosSetName = "TestON-set"
2312
2313 description = "Install Primitives app"
2314 main.case( description )
2315 main.step( "Install Primitives app" )
2316 appName = "org.onosproject.distributedprimitives"
Jon Halla440e872016-03-31 15:15:50 -07002317 node = main.activeNodes[0]
2318 appResults = main.CLIs[node].activateApp( appName )
Jon Hall85794ff2015-07-08 14:12:30 -07002319 utilities.assert_equals( expect=main.TRUE,
2320 actual=appResults,
2321 onpass="Primitives app activated",
2322 onfail="Primitives app not activated" )
Jon Halla440e872016-03-31 15:15:50 -07002323 time.sleep( 5 ) # To allow all nodes to activate
Jon Hall85794ff2015-07-08 14:12:30 -07002324
2325 def CASE17( self, main ):
2326 """
2327 Check for basic functionality with distributed primitives
2328 """
Jon Hall85794ff2015-07-08 14:12:30 -07002329 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07002330 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002331 assert main, "main not defined"
2332 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002333 assert main.CLIs, "main.CLIs not defined"
2334 assert main.nodes, "main.nodes not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002335 assert pCounterName, "pCounterName not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002336 assert onosSetName, "onosSetName not defined"
2337 # NOTE: assert fails if value is 0/None/Empty/False
2338 try:
2339 pCounterValue
2340 except NameError:
2341 main.log.error( "pCounterValue not defined, setting to 0" )
2342 pCounterValue = 0
2343 try:
Jon Hall85794ff2015-07-08 14:12:30 -07002344 onosSet
2345 except NameError:
2346 main.log.error( "onosSet not defined, setting to empty Set" )
2347 onosSet = set([])
2348 # Variables for the distributed primitives tests. These are local only
2349 addValue = "a"
2350 addAllValue = "a b c d e f"
2351 retainValue = "c d e f"
2352
2353 description = "Check for basic functionality with distributed " +\
2354 "primitives"
2355 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07002356 main.caseExplanation = "Test the methods of the distributed " +\
2357 "primitives (counters and sets) throught the cli"
Jon Hall85794ff2015-07-08 14:12:30 -07002358 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07002359 # Partitioned counters
2360 main.step( "Increment then get a default counter on each node" )
Jon Hall85794ff2015-07-08 14:12:30 -07002361 pCounters = []
2362 threads = []
2363 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07002364 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002365 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2366 name="counterAddAndGet-" + str( i ),
Jon Hall85794ff2015-07-08 14:12:30 -07002367 args=[ pCounterName ] )
2368 pCounterValue += 1
2369 addedPValues.append( pCounterValue )
2370 threads.append( t )
2371 t.start()
2372
2373 for t in threads:
2374 t.join()
2375 pCounters.append( t.result )
2376 # Check that counter incremented numController times
2377 pCounterResults = True
2378 for i in addedPValues:
2379 tmpResult = i in pCounters
2380 pCounterResults = pCounterResults and tmpResult
2381 if not tmpResult:
2382 main.log.error( str( i ) + " is not in partitioned "
2383 "counter incremented results" )
2384 utilities.assert_equals( expect=True,
2385 actual=pCounterResults,
2386 onpass="Default counter incremented",
2387 onfail="Error incrementing default" +
2388 " counter" )
2389
Jon Halle1a3b752015-07-22 13:02:46 -07002390 main.step( "Get then Increment a default counter on each node" )
2391 pCounters = []
2392 threads = []
2393 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07002394 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002395 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
2396 name="counterGetAndAdd-" + str( i ),
2397 args=[ pCounterName ] )
2398 addedPValues.append( pCounterValue )
2399 pCounterValue += 1
2400 threads.append( t )
2401 t.start()
2402
2403 for t in threads:
2404 t.join()
2405 pCounters.append( t.result )
2406 # Check that counter incremented numController times
2407 pCounterResults = True
2408 for i in addedPValues:
2409 tmpResult = i in pCounters
2410 pCounterResults = pCounterResults and tmpResult
2411 if not tmpResult:
2412 main.log.error( str( i ) + " is not in partitioned "
2413 "counter incremented results" )
2414 utilities.assert_equals( expect=True,
2415 actual=pCounterResults,
2416 onpass="Default counter incremented",
2417 onfail="Error incrementing default" +
2418 " counter" )
2419
2420 main.step( "Counters we added have the correct values" )
2421 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
2422 utilities.assert_equals( expect=main.TRUE,
2423 actual=incrementCheck,
2424 onpass="Added counters are correct",
2425 onfail="Added counters are incorrect" )
2426
2427 main.step( "Add -8 to then get a default counter on each node" )
2428 pCounters = []
2429 threads = []
2430 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07002431 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002432 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2433 name="counterIncrement-" + str( i ),
2434 args=[ pCounterName ],
2435 kwargs={ "delta": -8 } )
2436 pCounterValue += -8
2437 addedPValues.append( pCounterValue )
2438 threads.append( t )
2439 t.start()
2440
2441 for t in threads:
2442 t.join()
2443 pCounters.append( t.result )
2444 # Check that counter incremented numController times
2445 pCounterResults = True
2446 for i in addedPValues:
2447 tmpResult = i in pCounters
2448 pCounterResults = pCounterResults and tmpResult
2449 if not tmpResult:
2450 main.log.error( str( i ) + " is not in partitioned "
2451 "counter incremented results" )
2452 utilities.assert_equals( expect=True,
2453 actual=pCounterResults,
2454 onpass="Default counter incremented",
2455 onfail="Error incrementing default" +
2456 " counter" )
2457
2458 main.step( "Add 5 to then get a default counter on each node" )
2459 pCounters = []
2460 threads = []
2461 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07002462 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002463 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2464 name="counterIncrement-" + str( i ),
2465 args=[ pCounterName ],
2466 kwargs={ "delta": 5 } )
2467 pCounterValue += 5
2468 addedPValues.append( pCounterValue )
2469 threads.append( t )
2470 t.start()
2471
2472 for t in threads:
2473 t.join()
2474 pCounters.append( t.result )
2475 # Check that counter incremented numController times
2476 pCounterResults = True
2477 for i in addedPValues:
2478 tmpResult = i in pCounters
2479 pCounterResults = pCounterResults and tmpResult
2480 if not tmpResult:
2481 main.log.error( str( i ) + " is not in partitioned "
2482 "counter incremented results" )
2483 utilities.assert_equals( expect=True,
2484 actual=pCounterResults,
2485 onpass="Default counter incremented",
2486 onfail="Error incrementing default" +
2487 " counter" )
2488
2489 main.step( "Get then add 5 to a default counter on each node" )
2490 pCounters = []
2491 threads = []
2492 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07002493 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002494 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
2495 name="counterIncrement-" + str( i ),
2496 args=[ pCounterName ],
2497 kwargs={ "delta": 5 } )
2498 addedPValues.append( pCounterValue )
2499 pCounterValue += 5
2500 threads.append( t )
2501 t.start()
2502
2503 for t in threads:
2504 t.join()
2505 pCounters.append( t.result )
2506 # Check that counter incremented numController times
2507 pCounterResults = True
2508 for i in addedPValues:
2509 tmpResult = i in pCounters
2510 pCounterResults = pCounterResults and tmpResult
2511 if not tmpResult:
2512 main.log.error( str( i ) + " is not in partitioned "
2513 "counter incremented results" )
2514 utilities.assert_equals( expect=True,
2515 actual=pCounterResults,
2516 onpass="Default counter incremented",
2517 onfail="Error incrementing default" +
2518 " counter" )
2519
2520 main.step( "Counters we added have the correct values" )
2521 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
2522 utilities.assert_equals( expect=main.TRUE,
2523 actual=incrementCheck,
2524 onpass="Added counters are correct",
2525 onfail="Added counters are incorrect" )
2526
Jon Hall85794ff2015-07-08 14:12:30 -07002527 # DISTRIBUTED SETS
2528 main.step( "Distributed Set get" )
2529 size = len( onosSet )
2530 getResponses = []
2531 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002532 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002533 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002534 name="setTestGet-" + str( i ),
2535 args=[ onosSetName ] )
2536 threads.append( t )
2537 t.start()
2538 for t in threads:
2539 t.join()
2540 getResponses.append( t.result )
2541
2542 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002543 for i in range( len( main.activeNodes ) ):
2544 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002545 if isinstance( getResponses[ i ], list):
2546 current = set( getResponses[ i ] )
2547 if len( current ) == len( getResponses[ i ] ):
2548 # no repeats
2549 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07002550 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002551 " has incorrect view" +
2552 " of set " + onosSetName + ":\n" +
2553 str( getResponses[ i ] ) )
2554 main.log.debug( "Expected: " + str( onosSet ) )
2555 main.log.debug( "Actual: " + str( current ) )
2556 getResults = main.FALSE
2557 else:
2558 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07002559 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002560 " has repeat elements in" +
2561 " set " + onosSetName + ":\n" +
2562 str( getResponses[ i ] ) )
2563 getResults = main.FALSE
2564 elif getResponses[ i ] == main.ERROR:
2565 getResults = main.FALSE
2566 utilities.assert_equals( expect=main.TRUE,
2567 actual=getResults,
2568 onpass="Set elements are correct",
2569 onfail="Set elements are incorrect" )
2570
2571 main.step( "Distributed Set size" )
2572 sizeResponses = []
2573 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002574 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002575 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002576 name="setTestSize-" + str( i ),
2577 args=[ onosSetName ] )
2578 threads.append( t )
2579 t.start()
2580 for t in threads:
2581 t.join()
2582 sizeResponses.append( t.result )
2583
2584 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002585 for i in range( len( main.activeNodes ) ):
2586 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002587 if size != sizeResponses[ i ]:
2588 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002589 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002590 " expected a size of " + str( size ) +
2591 " for set " + onosSetName +
2592 " but got " + str( sizeResponses[ i ] ) )
2593 utilities.assert_equals( expect=main.TRUE,
2594 actual=sizeResults,
2595 onpass="Set sizes are correct",
2596 onfail="Set sizes are incorrect" )
2597
2598 main.step( "Distributed Set add()" )
2599 onosSet.add( addValue )
2600 addResponses = []
2601 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002602 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002603 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07002604 name="setTestAdd-" + str( i ),
2605 args=[ onosSetName, addValue ] )
2606 threads.append( t )
2607 t.start()
2608 for t in threads:
2609 t.join()
2610 addResponses.append( t.result )
2611
2612 # main.TRUE = successfully changed the set
2613 # main.FALSE = action resulted in no change in set
2614 # main.ERROR - Some error in executing the function
2615 addResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002616 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07002617 if addResponses[ i ] == main.TRUE:
2618 # All is well
2619 pass
2620 elif addResponses[ i ] == main.FALSE:
2621 # Already in set, probably fine
2622 pass
2623 elif addResponses[ i ] == main.ERROR:
2624 # Error in execution
2625 addResults = main.FALSE
2626 else:
2627 # unexpected result
2628 addResults = main.FALSE
2629 if addResults != main.TRUE:
2630 main.log.error( "Error executing set add" )
2631
2632 # Check if set is still correct
2633 size = len( onosSet )
2634 getResponses = []
2635 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002636 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002637 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002638 name="setTestGet-" + str( i ),
2639 args=[ onosSetName ] )
2640 threads.append( t )
2641 t.start()
2642 for t in threads:
2643 t.join()
2644 getResponses.append( t.result )
2645 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002646 for i in range( len( main.activeNodes ) ):
2647 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002648 if isinstance( getResponses[ i ], list):
2649 current = set( getResponses[ i ] )
2650 if len( current ) == len( getResponses[ i ] ):
2651 # no repeats
2652 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07002653 main.log.error( "ONOS" + node + " has incorrect view" +
Jon Hall85794ff2015-07-08 14:12:30 -07002654 " of set " + onosSetName + ":\n" +
2655 str( getResponses[ i ] ) )
2656 main.log.debug( "Expected: " + str( onosSet ) )
2657 main.log.debug( "Actual: " + str( current ) )
2658 getResults = main.FALSE
2659 else:
2660 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07002661 main.log.error( "ONOS" + node + " has repeat elements in" +
Jon Hall85794ff2015-07-08 14:12:30 -07002662 " set " + onosSetName + ":\n" +
2663 str( getResponses[ i ] ) )
2664 getResults = main.FALSE
2665 elif getResponses[ i ] == main.ERROR:
2666 getResults = main.FALSE
2667 sizeResponses = []
2668 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002669 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002670 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002671 name="setTestSize-" + str( i ),
2672 args=[ onosSetName ] )
2673 threads.append( t )
2674 t.start()
2675 for t in threads:
2676 t.join()
2677 sizeResponses.append( t.result )
2678 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002679 for i in range( len( main.activeNodes ) ):
2680 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002681 if size != sizeResponses[ i ]:
2682 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002683 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002684 " expected a size of " + str( size ) +
2685 " for set " + onosSetName +
2686 " but got " + str( sizeResponses[ i ] ) )
2687 addResults = addResults and getResults and sizeResults
2688 utilities.assert_equals( expect=main.TRUE,
2689 actual=addResults,
2690 onpass="Set add correct",
2691 onfail="Set add was incorrect" )
2692
2693 main.step( "Distributed Set addAll()" )
2694 onosSet.update( addAllValue.split() )
2695 addResponses = []
2696 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002697 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002698 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07002699 name="setTestAddAll-" + str( i ),
2700 args=[ onosSetName, addAllValue ] )
2701 threads.append( t )
2702 t.start()
2703 for t in threads:
2704 t.join()
2705 addResponses.append( t.result )
2706
2707 # main.TRUE = successfully changed the set
2708 # main.FALSE = action resulted in no change in set
2709 # main.ERROR - Some error in executing the function
2710 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002711 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07002712 if addResponses[ i ] == main.TRUE:
2713 # All is well
2714 pass
2715 elif addResponses[ i ] == main.FALSE:
2716 # Already in set, probably fine
2717 pass
2718 elif addResponses[ i ] == main.ERROR:
2719 # Error in execution
2720 addAllResults = main.FALSE
2721 else:
2722 # unexpected result
2723 addAllResults = main.FALSE
2724 if addAllResults != main.TRUE:
2725 main.log.error( "Error executing set addAll" )
2726
2727 # Check if set is still correct
2728 size = len( onosSet )
2729 getResponses = []
2730 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002731 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002732 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002733 name="setTestGet-" + str( i ),
2734 args=[ onosSetName ] )
2735 threads.append( t )
2736 t.start()
2737 for t in threads:
2738 t.join()
2739 getResponses.append( t.result )
2740 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002741 for i in range( len( main.activeNodes ) ):
2742 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002743 if isinstance( getResponses[ i ], list):
2744 current = set( getResponses[ i ] )
2745 if len( current ) == len( getResponses[ i ] ):
2746 # no repeats
2747 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07002748 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002749 " has incorrect view" +
2750 " of set " + onosSetName + ":\n" +
2751 str( getResponses[ i ] ) )
2752 main.log.debug( "Expected: " + str( onosSet ) )
2753 main.log.debug( "Actual: " + str( current ) )
2754 getResults = main.FALSE
2755 else:
2756 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07002757 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002758 " has repeat elements in" +
2759 " set " + onosSetName + ":\n" +
2760 str( getResponses[ i ] ) )
2761 getResults = main.FALSE
2762 elif getResponses[ i ] == main.ERROR:
2763 getResults = main.FALSE
2764 sizeResponses = []
2765 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002766 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002767 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002768 name="setTestSize-" + str( i ),
2769 args=[ onosSetName ] )
2770 threads.append( t )
2771 t.start()
2772 for t in threads:
2773 t.join()
2774 sizeResponses.append( t.result )
2775 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002776 for i in range( len( main.activeNodes ) ):
2777 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002778 if size != sizeResponses[ i ]:
2779 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002780 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002781 " expected a size of " + str( size ) +
2782 " for set " + onosSetName +
2783 " but got " + str( sizeResponses[ i ] ) )
2784 addAllResults = addAllResults and getResults and sizeResults
2785 utilities.assert_equals( expect=main.TRUE,
2786 actual=addAllResults,
2787 onpass="Set addAll correct",
2788 onfail="Set addAll was incorrect" )
2789
2790 main.step( "Distributed Set contains()" )
2791 containsResponses = []
2792 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002793 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002794 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002795 name="setContains-" + str( i ),
2796 args=[ onosSetName ],
2797 kwargs={ "values": addValue } )
2798 threads.append( t )
2799 t.start()
2800 for t in threads:
2801 t.join()
2802 # NOTE: This is the tuple
2803 containsResponses.append( t.result )
2804
2805 containsResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002806 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07002807 if containsResponses[ i ] == main.ERROR:
2808 containsResults = main.FALSE
2809 else:
2810 containsResults = containsResults and\
2811 containsResponses[ i ][ 1 ]
2812 utilities.assert_equals( expect=main.TRUE,
2813 actual=containsResults,
2814 onpass="Set contains is functional",
2815 onfail="Set contains failed" )
2816
2817 main.step( "Distributed Set containsAll()" )
2818 containsAllResponses = []
2819 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002820 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002821 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002822 name="setContainsAll-" + str( i ),
2823 args=[ onosSetName ],
2824 kwargs={ "values": addAllValue } )
2825 threads.append( t )
2826 t.start()
2827 for t in threads:
2828 t.join()
2829 # NOTE: This is the tuple
2830 containsAllResponses.append( t.result )
2831
2832 containsAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002833 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07002834 if containsResponses[ i ] == main.ERROR:
2835 containsResults = main.FALSE
2836 else:
2837 containsResults = containsResults and\
2838 containsResponses[ i ][ 1 ]
2839 utilities.assert_equals( expect=main.TRUE,
2840 actual=containsAllResults,
2841 onpass="Set containsAll is functional",
2842 onfail="Set containsAll failed" )
2843
2844 main.step( "Distributed Set remove()" )
2845 onosSet.remove( addValue )
2846 removeResponses = []
2847 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002848 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002849 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07002850 name="setTestRemove-" + str( i ),
2851 args=[ onosSetName, addValue ] )
2852 threads.append( t )
2853 t.start()
2854 for t in threads:
2855 t.join()
2856 removeResponses.append( t.result )
2857
2858 # main.TRUE = successfully changed the set
2859 # main.FALSE = action resulted in no change in set
2860 # main.ERROR - Some error in executing the function
2861 removeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002862 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07002863 if removeResponses[ i ] == main.TRUE:
2864 # All is well
2865 pass
2866 elif removeResponses[ i ] == main.FALSE:
2867 # not in set, probably fine
2868 pass
2869 elif removeResponses[ i ] == main.ERROR:
2870 # Error in execution
2871 removeResults = main.FALSE
2872 else:
2873 # unexpected result
2874 removeResults = main.FALSE
2875 if removeResults != main.TRUE:
2876 main.log.error( "Error executing set remove" )
2877
2878 # Check if set is still correct
2879 size = len( onosSet )
2880 getResponses = []
2881 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002882 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002883 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002884 name="setTestGet-" + str( i ),
2885 args=[ onosSetName ] )
2886 threads.append( t )
2887 t.start()
2888 for t in threads:
2889 t.join()
2890 getResponses.append( t.result )
2891 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002892 for i in range( len( main.activeNodes ) ):
2893 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002894 if isinstance( getResponses[ i ], list):
2895 current = set( getResponses[ i ] )
2896 if len( current ) == len( getResponses[ i ] ):
2897 # no repeats
2898 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07002899 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002900 " has incorrect view" +
2901 " of set " + onosSetName + ":\n" +
2902 str( getResponses[ i ] ) )
2903 main.log.debug( "Expected: " + str( onosSet ) )
2904 main.log.debug( "Actual: " + str( current ) )
2905 getResults = main.FALSE
2906 else:
2907 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07002908 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002909 " has repeat elements in" +
2910 " set " + onosSetName + ":\n" +
2911 str( getResponses[ i ] ) )
2912 getResults = main.FALSE
2913 elif getResponses[ i ] == main.ERROR:
2914 getResults = main.FALSE
2915 sizeResponses = []
2916 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002917 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002918 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002919 name="setTestSize-" + str( i ),
2920 args=[ onosSetName ] )
2921 threads.append( t )
2922 t.start()
2923 for t in threads:
2924 t.join()
2925 sizeResponses.append( t.result )
2926 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002927 for i in range( len( main.activeNodes ) ):
2928 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002929 if size != sizeResponses[ i ]:
2930 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002931 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002932 " expected a size of " + str( size ) +
2933 " for set " + onosSetName +
2934 " but got " + str( sizeResponses[ i ] ) )
2935 removeResults = removeResults and getResults and sizeResults
2936 utilities.assert_equals( expect=main.TRUE,
2937 actual=removeResults,
2938 onpass="Set remove correct",
2939 onfail="Set remove was incorrect" )
2940
2941 main.step( "Distributed Set removeAll()" )
2942 onosSet.difference_update( addAllValue.split() )
2943 removeAllResponses = []
2944 threads = []
2945 try:
Jon Halla440e872016-03-31 15:15:50 -07002946 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002947 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07002948 name="setTestRemoveAll-" + str( i ),
2949 args=[ onosSetName, addAllValue ] )
2950 threads.append( t )
2951 t.start()
2952 for t in threads:
2953 t.join()
2954 removeAllResponses.append( t.result )
2955 except Exception, e:
2956 main.log.exception(e)
2957
2958 # main.TRUE = successfully changed the set
2959 # main.FALSE = action resulted in no change in set
2960 # main.ERROR - Some error in executing the function
2961 removeAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002962 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07002963 if removeAllResponses[ i ] == main.TRUE:
2964 # All is well
2965 pass
2966 elif removeAllResponses[ i ] == main.FALSE:
2967 # not in set, probably fine
2968 pass
2969 elif removeAllResponses[ i ] == main.ERROR:
2970 # Error in execution
2971 removeAllResults = main.FALSE
2972 else:
2973 # unexpected result
2974 removeAllResults = main.FALSE
2975 if removeAllResults != main.TRUE:
2976 main.log.error( "Error executing set removeAll" )
2977
2978 # Check if set is still correct
2979 size = len( onosSet )
2980 getResponses = []
2981 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002982 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002983 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002984 name="setTestGet-" + str( i ),
2985 args=[ onosSetName ] )
2986 threads.append( t )
2987 t.start()
2988 for t in threads:
2989 t.join()
2990 getResponses.append( t.result )
2991 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002992 for i in range( len( main.activeNodes ) ):
2993 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002994 if isinstance( getResponses[ i ], list):
2995 current = set( getResponses[ i ] )
2996 if len( current ) == len( getResponses[ i ] ):
2997 # no repeats
2998 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07002999 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003000 " has incorrect view" +
3001 " of set " + onosSetName + ":\n" +
3002 str( getResponses[ i ] ) )
3003 main.log.debug( "Expected: " + str( onosSet ) )
3004 main.log.debug( "Actual: " + str( current ) )
3005 getResults = main.FALSE
3006 else:
3007 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003008 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003009 " has repeat elements in" +
3010 " set " + onosSetName + ":\n" +
3011 str( getResponses[ i ] ) )
3012 getResults = main.FALSE
3013 elif getResponses[ i ] == main.ERROR:
3014 getResults = main.FALSE
3015 sizeResponses = []
3016 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003017 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003018 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003019 name="setTestSize-" + str( i ),
3020 args=[ onosSetName ] )
3021 threads.append( t )
3022 t.start()
3023 for t in threads:
3024 t.join()
3025 sizeResponses.append( t.result )
3026 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003027 for i in range( len( main.activeNodes ) ):
3028 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003029 if size != sizeResponses[ i ]:
3030 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003031 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003032 " expected a size of " + str( size ) +
3033 " for set " + onosSetName +
3034 " but got " + str( sizeResponses[ i ] ) )
3035 removeAllResults = removeAllResults and getResults and sizeResults
3036 utilities.assert_equals( expect=main.TRUE,
3037 actual=removeAllResults,
3038 onpass="Set removeAll correct",
3039 onfail="Set removeAll was incorrect" )
3040
3041 main.step( "Distributed Set addAll()" )
3042 onosSet.update( addAllValue.split() )
3043 addResponses = []
3044 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003045 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003046 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07003047 name="setTestAddAll-" + str( i ),
3048 args=[ onosSetName, addAllValue ] )
3049 threads.append( t )
3050 t.start()
3051 for t in threads:
3052 t.join()
3053 addResponses.append( t.result )
3054
3055 # main.TRUE = successfully changed the set
3056 # main.FALSE = action resulted in no change in set
3057 # main.ERROR - Some error in executing the function
3058 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003059 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07003060 if addResponses[ i ] == main.TRUE:
3061 # All is well
3062 pass
3063 elif addResponses[ i ] == main.FALSE:
3064 # Already in set, probably fine
3065 pass
3066 elif addResponses[ i ] == main.ERROR:
3067 # Error in execution
3068 addAllResults = main.FALSE
3069 else:
3070 # unexpected result
3071 addAllResults = main.FALSE
3072 if addAllResults != main.TRUE:
3073 main.log.error( "Error executing set addAll" )
3074
3075 # Check if set is still correct
3076 size = len( onosSet )
3077 getResponses = []
3078 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003079 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003080 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003081 name="setTestGet-" + str( i ),
3082 args=[ onosSetName ] )
3083 threads.append( t )
3084 t.start()
3085 for t in threads:
3086 t.join()
3087 getResponses.append( t.result )
3088 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003089 for i in range( len( main.activeNodes ) ):
3090 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003091 if isinstance( getResponses[ i ], list):
3092 current = set( getResponses[ i ] )
3093 if len( current ) == len( getResponses[ i ] ):
3094 # no repeats
3095 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07003096 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003097 " has incorrect view" +
3098 " of set " + onosSetName + ":\n" +
3099 str( getResponses[ i ] ) )
3100 main.log.debug( "Expected: " + str( onosSet ) )
3101 main.log.debug( "Actual: " + str( current ) )
3102 getResults = main.FALSE
3103 else:
3104 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003105 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003106 " has repeat elements in" +
3107 " set " + onosSetName + ":\n" +
3108 str( getResponses[ i ] ) )
3109 getResults = main.FALSE
3110 elif getResponses[ i ] == main.ERROR:
3111 getResults = main.FALSE
3112 sizeResponses = []
3113 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003114 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003115 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003116 name="setTestSize-" + str( i ),
3117 args=[ onosSetName ] )
3118 threads.append( t )
3119 t.start()
3120 for t in threads:
3121 t.join()
3122 sizeResponses.append( t.result )
3123 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003124 for i in range( len( main.activeNodes ) ):
3125 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003126 if size != sizeResponses[ i ]:
3127 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003128 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003129 " expected a size of " + str( size ) +
3130 " for set " + onosSetName +
3131 " but got " + str( sizeResponses[ i ] ) )
3132 addAllResults = addAllResults and getResults and sizeResults
3133 utilities.assert_equals( expect=main.TRUE,
3134 actual=addAllResults,
3135 onpass="Set addAll correct",
3136 onfail="Set addAll was incorrect" )
3137
3138 main.step( "Distributed Set clear()" )
3139 onosSet.clear()
3140 clearResponses = []
3141 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003142 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003143 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07003144 name="setTestClear-" + str( i ),
3145 args=[ onosSetName, " "], # Values doesn't matter
3146 kwargs={ "clear": True } )
3147 threads.append( t )
3148 t.start()
3149 for t in threads:
3150 t.join()
3151 clearResponses.append( t.result )
3152
3153 # main.TRUE = successfully changed the set
3154 # main.FALSE = action resulted in no change in set
3155 # main.ERROR - Some error in executing the function
3156 clearResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003157 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07003158 if clearResponses[ i ] == main.TRUE:
3159 # All is well
3160 pass
3161 elif clearResponses[ i ] == main.FALSE:
3162 # Nothing set, probably fine
3163 pass
3164 elif clearResponses[ i ] == main.ERROR:
3165 # Error in execution
3166 clearResults = main.FALSE
3167 else:
3168 # unexpected result
3169 clearResults = main.FALSE
3170 if clearResults != main.TRUE:
3171 main.log.error( "Error executing set clear" )
3172
3173 # Check if set is still correct
3174 size = len( onosSet )
3175 getResponses = []
3176 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003177 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003178 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003179 name="setTestGet-" + str( i ),
3180 args=[ onosSetName ] )
3181 threads.append( t )
3182 t.start()
3183 for t in threads:
3184 t.join()
3185 getResponses.append( t.result )
3186 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003187 for i in range( len( main.activeNodes ) ):
3188 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003189 if isinstance( getResponses[ i ], list):
3190 current = set( getResponses[ i ] )
3191 if len( current ) == len( getResponses[ i ] ):
3192 # no repeats
3193 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07003194 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003195 " has incorrect view" +
3196 " of set " + onosSetName + ":\n" +
3197 str( getResponses[ i ] ) )
3198 main.log.debug( "Expected: " + str( onosSet ) )
3199 main.log.debug( "Actual: " + str( current ) )
3200 getResults = main.FALSE
3201 else:
3202 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003203 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003204 " has repeat elements in" +
3205 " set " + onosSetName + ":\n" +
3206 str( getResponses[ i ] ) )
3207 getResults = main.FALSE
3208 elif getResponses[ i ] == main.ERROR:
3209 getResults = main.FALSE
3210 sizeResponses = []
3211 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003212 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003213 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003214 name="setTestSize-" + str( i ),
3215 args=[ onosSetName ] )
3216 threads.append( t )
3217 t.start()
3218 for t in threads:
3219 t.join()
3220 sizeResponses.append( t.result )
3221 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003222 for i in range( len( main.activeNodes ) ):
3223 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003224 if size != sizeResponses[ i ]:
3225 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003226 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003227 " expected a size of " + str( size ) +
3228 " for set " + onosSetName +
3229 " but got " + str( sizeResponses[ i ] ) )
3230 clearResults = clearResults and getResults and sizeResults
3231 utilities.assert_equals( expect=main.TRUE,
3232 actual=clearResults,
3233 onpass="Set clear correct",
3234 onfail="Set clear was incorrect" )
3235
3236 main.step( "Distributed Set addAll()" )
3237 onosSet.update( addAllValue.split() )
3238 addResponses = []
3239 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003240 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003241 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07003242 name="setTestAddAll-" + str( i ),
3243 args=[ onosSetName, addAllValue ] )
3244 threads.append( t )
3245 t.start()
3246 for t in threads:
3247 t.join()
3248 addResponses.append( t.result )
3249
3250 # main.TRUE = successfully changed the set
3251 # main.FALSE = action resulted in no change in set
3252 # main.ERROR - Some error in executing the function
3253 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003254 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07003255 if addResponses[ i ] == main.TRUE:
3256 # All is well
3257 pass
3258 elif addResponses[ i ] == main.FALSE:
3259 # Already in set, probably fine
3260 pass
3261 elif addResponses[ i ] == main.ERROR:
3262 # Error in execution
3263 addAllResults = main.FALSE
3264 else:
3265 # unexpected result
3266 addAllResults = main.FALSE
3267 if addAllResults != main.TRUE:
3268 main.log.error( "Error executing set addAll" )
3269
3270 # Check if set is still correct
3271 size = len( onosSet )
3272 getResponses = []
3273 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003274 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003275 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003276 name="setTestGet-" + str( i ),
3277 args=[ onosSetName ] )
3278 threads.append( t )
3279 t.start()
3280 for t in threads:
3281 t.join()
3282 getResponses.append( t.result )
3283 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003284 for i in range( len( main.activeNodes ) ):
3285 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003286 if isinstance( getResponses[ i ], list):
3287 current = set( getResponses[ i ] )
3288 if len( current ) == len( getResponses[ i ] ):
3289 # no repeats
3290 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07003291 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003292 " has incorrect view" +
3293 " of set " + onosSetName + ":\n" +
3294 str( getResponses[ i ] ) )
3295 main.log.debug( "Expected: " + str( onosSet ) )
3296 main.log.debug( "Actual: " + str( current ) )
3297 getResults = main.FALSE
3298 else:
3299 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003300 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003301 " has repeat elements in" +
3302 " set " + onosSetName + ":\n" +
3303 str( getResponses[ i ] ) )
3304 getResults = main.FALSE
3305 elif getResponses[ i ] == main.ERROR:
3306 getResults = main.FALSE
3307 sizeResponses = []
3308 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003309 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003310 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003311 name="setTestSize-" + str( i ),
3312 args=[ onosSetName ] )
3313 threads.append( t )
3314 t.start()
3315 for t in threads:
3316 t.join()
3317 sizeResponses.append( t.result )
3318 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003319 for i in range( len( main.activeNodes ) ):
3320 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003321 if size != sizeResponses[ i ]:
3322 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003323 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003324 " expected a size of " + str( size ) +
3325 " for set " + onosSetName +
3326 " but got " + str( sizeResponses[ i ] ) )
3327 addAllResults = addAllResults and getResults and sizeResults
3328 utilities.assert_equals( expect=main.TRUE,
3329 actual=addAllResults,
3330 onpass="Set addAll correct",
3331 onfail="Set addAll was incorrect" )
3332
3333 main.step( "Distributed Set retain()" )
3334 onosSet.intersection_update( retainValue.split() )
3335 retainResponses = []
3336 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003337 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003338 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07003339 name="setTestRetain-" + str( i ),
3340 args=[ onosSetName, retainValue ],
3341 kwargs={ "retain": True } )
3342 threads.append( t )
3343 t.start()
3344 for t in threads:
3345 t.join()
3346 retainResponses.append( t.result )
3347
3348 # main.TRUE = successfully changed the set
3349 # main.FALSE = action resulted in no change in set
3350 # main.ERROR - Some error in executing the function
3351 retainResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003352 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07003353 if retainResponses[ i ] == main.TRUE:
3354 # All is well
3355 pass
3356 elif retainResponses[ i ] == main.FALSE:
3357 # Already in set, probably fine
3358 pass
3359 elif retainResponses[ i ] == main.ERROR:
3360 # Error in execution
3361 retainResults = main.FALSE
3362 else:
3363 # unexpected result
3364 retainResults = main.FALSE
3365 if retainResults != main.TRUE:
3366 main.log.error( "Error executing set retain" )
3367
3368 # Check if set is still correct
3369 size = len( onosSet )
3370 getResponses = []
3371 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003372 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003373 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003374 name="setTestGet-" + str( i ),
3375 args=[ onosSetName ] )
3376 threads.append( t )
3377 t.start()
3378 for t in threads:
3379 t.join()
3380 getResponses.append( t.result )
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 Hall85794ff2015-07-08 14:12:30 -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 Halla440e872016-03-31 15:15:50 -07003389 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -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 Halla440e872016-03-31 15:15:50 -07003398 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -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 sizeResponses = []
3406 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003407 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003408 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003409 name="setTestSize-" + str( i ),
3410 args=[ onosSetName ] )
3411 threads.append( t )
3412 t.start()
3413 for t in threads:
3414 t.join()
3415 sizeResponses.append( t.result )
3416 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003417 for i in range( len( main.activeNodes ) ):
3418 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003419 if size != sizeResponses[ i ]:
3420 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003421 main.log.error( "ONOS" + node + " expected a size of " +
Jon Hall85794ff2015-07-08 14:12:30 -07003422 str( size ) + " for set " + onosSetName +
3423 " but got " + str( sizeResponses[ i ] ) )
3424 retainResults = retainResults and getResults and sizeResults
3425 utilities.assert_equals( expect=main.TRUE,
3426 actual=retainResults,
3427 onpass="Set retain correct",
3428 onfail="Set retain was incorrect" )
3429
Jon Hall2a5002c2015-08-21 16:49:11 -07003430 # Transactional maps
3431 main.step( "Partitioned Transactional maps put" )
3432 tMapValue = "Testing"
3433 numKeys = 100
3434 putResult = True
Jon Halla440e872016-03-31 15:15:50 -07003435 node = main.activeNodes[0]
3436 putResponses = main.CLIs[node].transactionalMapPut( numKeys, tMapValue )
3437 if putResponses and len( putResponses ) == 100:
Jon Hall2a5002c2015-08-21 16:49:11 -07003438 for i in putResponses:
3439 if putResponses[ i ][ 'value' ] != tMapValue:
3440 putResult = False
3441 else:
3442 putResult = False
3443 if not putResult:
3444 main.log.debug( "Put response values: " + str( putResponses ) )
3445 utilities.assert_equals( expect=True,
3446 actual=putResult,
3447 onpass="Partitioned Transactional Map put successful",
3448 onfail="Partitioned Transactional Map put values are incorrect" )
3449
3450 main.step( "Partitioned Transactional maps get" )
3451 getCheck = True
3452 for n in range( 1, numKeys + 1 ):
3453 getResponses = []
3454 threads = []
3455 valueCheck = True
Jon Halla440e872016-03-31 15:15:50 -07003456 for i in main.activeNodes:
Jon Hall2a5002c2015-08-21 16:49:11 -07003457 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
3458 name="TMap-get-" + str( i ),
Jon Halla440e872016-03-31 15:15:50 -07003459 args=[ "Key" + str( n ) ] )
Jon Hall2a5002c2015-08-21 16:49:11 -07003460 threads.append( t )
3461 t.start()
3462 for t in threads:
3463 t.join()
3464 getResponses.append( t.result )
3465 for node in getResponses:
3466 if node != tMapValue:
3467 valueCheck = False
3468 if not valueCheck:
3469 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
3470 main.log.warn( getResponses )
3471 getCheck = getCheck and valueCheck
3472 utilities.assert_equals( expect=True,
3473 actual=getCheck,
3474 onpass="Partitioned Transactional Map get values were correct",
3475 onfail="Partitioned Transactional Map values incorrect" )