blob: 6c2b01fc0c0b22788f564ca2cffd74dea5e2073b [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
Jon Halla440e872016-03-31 15:15:50 -0700243 main.step( "Checking ONOS nodes" )
244 nodesOutput = []
245 nodeResults = main.TRUE
246 threads = []
247 for i in main.activeNodes:
248 t = main.Thread( target=main.CLIs[i].nodes,
249 name="nodes-" + str( i ),
250 args=[ ] )
251 threads.append( t )
252 t.start()
253
254 for t in threads:
255 t.join()
256 nodesOutput.append( t.result )
257 ips = [ main.nodes[node].ip_address for node in main.activeNodes ]
258 ips.sort()
259 for i in nodesOutput:
260 try:
261 current = json.loads( i )
262 activeIps = []
263 currentResult = main.FALSE
264 for node in current:
265 if node['state'] == 'READY':
266 activeIps.append( node['ip'] )
267 activeIps.sort()
268 if ips == activeIps:
269 currentResult = main.TRUE
270 except ( ValueError, TypeError ):
271 main.log.error( "Error parsing nodes output" )
272 main.log.warn( repr( i ) )
273 currentResult = main.FALSE
274 nodeResults = nodeResults and currentResult
275 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
276 onpass="Nodes check successful",
277 onfail="Nodes check NOT successful" )
278
279 if not nodeResults:
280 for cli in main.CLIs:
281 main.log.debug( "{} components not ACTIVE: \n{}".format(
282 cli.name,
283 cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
284
Jon Hall85794ff2015-07-08 14:12:30 -0700285 if cliResults == main.FALSE:
286 main.log.error( "Failed to start ONOS, stopping test" )
287 main.cleanup()
288 main.exit()
289
Jon Hall172b7ba2016-04-07 18:12:20 -0700290 main.step( "Activate apps defined in the params file" )
291 # get data from the params
292 apps = main.params.get( 'apps' )
293 if apps:
294 apps = apps.split(',')
295 main.log.warn( apps )
296 activateResult = True
297 for app in apps:
298 main.CLIs[ 0 ].app( app, "Activate" )
299 # TODO: check this worked
300 time.sleep( 10 ) # wait for apps to activate
301 for app in apps:
302 state = main.CLIs[ 0 ].appStatus( app )
303 if state == "ACTIVE":
304 activateResult = activeResult and True
305 else:
306 main.log.error( "{} is in {} state".format( app, state ) )
307 activeResult = False
308 utilities.assert_equals( expect=True,
309 actual=activateResult,
310 onpass="Successfully activated apps",
311 onfail="Failed to activate apps" )
312 else:
313 main.log.warn( "No apps were specified to be loaded after startup" )
314
315 main.step( "Set ONOS configurations" )
316 config = main.params.get( 'ONOS_Configuration' )
317 if config:
318 main.log.debug( config )
319 checkResult = main.TRUE
320 for component in config:
321 for setting in config[component]:
322 value = config[component][setting]
323 check = main.CLIs[ 0 ].setCfg( component, setting, value )
324 main.log.info( "Value was changed? {}".format( main.TRUE == check ) )
325 checkResult = check and checkResult
326 utilities.assert_equals( expect=main.TRUE,
327 actual=checkResult,
328 onpass="Successfully set config",
329 onfail="Failed to set config" )
330 else:
331 main.log.warn( "No configurations were specified to be changed after startup" )
332
Jon Hall9d2dcad2016-04-08 10:15:20 -0700333 main.step( "App Ids check" )
334 appCheck = main.TRUE
335 threads = []
336 for i in main.activeNodes:
337 t = main.Thread( target=main.CLIs[i].appToIDCheck,
338 name="appToIDCheck-" + str( i ),
339 args=[] )
340 threads.append( t )
341 t.start()
342
343 for t in threads:
344 t.join()
345 appCheck = appCheck and t.result
346 if appCheck != main.TRUE:
347 node = main.activeNodes[0]
348 main.log.warn( main.CLIs[node].apps() )
349 main.log.warn( main.CLIs[node].appIDs() )
350 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
351 onpass="App Ids seem to be correct",
352 onfail="Something is wrong with app Ids" )
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"
Jon Hall9d2dcad2016-04-08 10:15:20 -0700921
922 main.step( "Check Intent state" )
923 installedCheck = True
924 # Print the intent states
925 intents = main.ONOScli1.intents()
926 intentStates = []
927 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
928 count = 0
929 # Iter through intents of a node
930 try:
931 for intent in json.loads( intents ):
932 state = intent.get( 'state', None )
933 if "INSTALLED" not in state:
934 installedCheck = False
935 intentId = intent.get( 'id', None )
936 intentStates.append( ( intentId, state ) )
937 except ( ValueError, TypeError ):
938 main.log.exception( "Error parsing intents." )
939 # Print states
940 intentStates.sort()
941 for i, s in intentStates:
942 count += 1
943 main.log.info( "%-6s%-15s%-15s" %
944 ( str( count ), str( i ), str( s ) ) )
945 utilities.assert_equals( expect=True, actual=installedCheck,
946 onpass="Intents are all INSTALLED",
947 onfail="Intents are not all in " +
948 "INSTALLED state" )
949
Jon Hall85794ff2015-07-08 14:12:30 -0700950 main.step( "Ping across added host intents" )
Jon Halla440e872016-03-31 15:15:50 -0700951 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall85794ff2015-07-08 14:12:30 -0700952 PingResult = main.TRUE
953 for i in range( 8, 18 ):
954 ping = main.Mininet1.pingHost( src="h" + str( i ),
955 target="h" + str( i + 10 ) )
956 PingResult = PingResult and ping
957 if ping == main.FALSE:
958 main.log.warn( "Ping failed between h" + str( i ) +
959 " and h" + str( i + 10 ) )
960 elif ping == main.TRUE:
961 main.log.info( "Ping test passed!" )
962 # Don't set PingResult or you'd override failures
963 if PingResult == main.FALSE:
964 main.log.error(
965 "Intents have not been installed correctly, pings failed." )
966 # TODO: pretty print
967 main.log.warn( "ONOS1 intents: " )
968 try:
Jon Halla440e872016-03-31 15:15:50 -0700969 tmpIntents = onosCli.intents()
Jon Hall85794ff2015-07-08 14:12:30 -0700970 main.log.warn( json.dumps( json.loads( tmpIntents ),
971 sort_keys=True,
972 indent=4,
973 separators=( ',', ': ' ) ) )
974 except ( ValueError, TypeError ):
975 main.log.warn( repr( tmpIntents ) )
976 utilities.assert_equals(
977 expect=main.TRUE,
978 actual=PingResult,
979 onpass="Intents have been installed correctly and pings work",
980 onfail="Intents have not been installed correctly, pings failed." )
981
Jon Hall85794ff2015-07-08 14:12:30 -0700982 main.step( "Check leadership of topics" )
Jon Halla440e872016-03-31 15:15:50 -0700983 leaders = onosCli.leaders()
Jon Hall85794ff2015-07-08 14:12:30 -0700984 topicCheck = main.TRUE
985 try:
986 if leaders:
987 parsedLeaders = json.loads( leaders )
988 main.log.warn( json.dumps( parsedLeaders,
989 sort_keys=True,
990 indent=4,
991 separators=( ',', ': ' ) ) )
992 # check for all intent partitions
993 # check for election
994 # TODO: Look at Devices as topics now that it uses this system
995 topics = []
996 for i in range( 14 ):
997 topics.append( "intent-partition-" + str( i ) )
998 # FIXME: this should only be after we start the app
999 # FIXME: topics.append( "org.onosproject.election" )
1000 # Print leaders output
1001 main.log.debug( topics )
1002 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1003 for topic in topics:
1004 if topic not in ONOStopics:
1005 main.log.error( "Error: " + topic +
1006 " not in leaders" )
1007 topicCheck = main.FALSE
1008 else:
1009 main.log.error( "leaders() returned None" )
1010 topicCheck = main.FALSE
1011 except ( ValueError, TypeError ):
1012 topicCheck = main.FALSE
1013 main.log.exception( "Error parsing leaders" )
1014 main.log.error( repr( leaders ) )
1015 # TODO: Check for a leader of these topics
Jon Halla440e872016-03-31 15:15:50 -07001016 # Check all nodes
1017 if topicCheck:
1018 for i in main.activeNodes:
1019 node = main.CLIs[i]
1020 response = node.leaders( jsonFormat=False)
1021 main.log.warn( str( node.name ) + " leaders output: \n" +
1022 str( response ) )
1023
Jon Hall85794ff2015-07-08 14:12:30 -07001024 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
1025 onpass="intent Partitions is in leaders",
1026 onfail="Some topics were lost " )
1027 # Print partitions
Jon Halla440e872016-03-31 15:15:50 -07001028 partitions = onosCli.partitions()
Jon Hall85794ff2015-07-08 14:12:30 -07001029 try:
1030 if partitions :
1031 parsedPartitions = json.loads( partitions )
1032 main.log.warn( json.dumps( parsedPartitions,
1033 sort_keys=True,
1034 indent=4,
1035 separators=( ',', ': ' ) ) )
1036 # TODO check for a leader in all paritions
1037 # TODO check for consistency among nodes
1038 else:
1039 main.log.error( "partitions() returned None" )
1040 except ( ValueError, TypeError ):
1041 main.log.exception( "Error parsing partitions" )
1042 main.log.error( repr( partitions ) )
1043 # Print Pending Map
Jon Halla440e872016-03-31 15:15:50 -07001044 pendingMap = onosCli.pendingMap()
Jon Hall85794ff2015-07-08 14:12:30 -07001045 try:
1046 if pendingMap :
1047 parsedPending = json.loads( pendingMap )
1048 main.log.warn( json.dumps( parsedPending,
1049 sort_keys=True,
1050 indent=4,
1051 separators=( ',', ': ' ) ) )
1052 # TODO check something here?
1053 else:
1054 main.log.error( "pendingMap() returned None" )
1055 except ( ValueError, TypeError ):
1056 main.log.exception( "Error parsing pending map" )
1057 main.log.error( repr( pendingMap ) )
1058
1059 if not installedCheck:
1060 main.log.info( "Waiting 60 seconds to see if the state of " +
1061 "intents change" )
1062 time.sleep( 60 )
1063 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -07001064 intents = onosCli.intents()
Jon Hall85794ff2015-07-08 14:12:30 -07001065 intentStates = []
1066 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
1067 count = 0
1068 # Iter through intents of a node
1069 try:
1070 for intent in json.loads( intents ):
1071 state = intent.get( 'state', None )
1072 if "INSTALLED" not in state:
1073 installedCheck = False
1074 intentId = intent.get( 'id', None )
1075 intentStates.append( ( intentId, state ) )
1076 except ( ValueError, TypeError ):
1077 main.log.exception( "Error parsing intents." )
1078 intentStates.sort()
1079 for i, s in intentStates:
1080 count += 1
1081 main.log.info( "%-6s%-15s%-15s" %
1082 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -07001083 leaders = onosCli.leaders()
Jon Hall85794ff2015-07-08 14:12:30 -07001084 try:
1085 missing = False
1086 if leaders:
1087 parsedLeaders = json.loads( leaders )
1088 main.log.warn( json.dumps( parsedLeaders,
1089 sort_keys=True,
1090 indent=4,
1091 separators=( ',', ': ' ) ) )
1092 # check for all intent partitions
1093 # check for election
1094 topics = []
1095 for i in range( 14 ):
1096 topics.append( "intent-partition-" + str( i ) )
1097 # FIXME: this should only be after we start the app
1098 topics.append( "org.onosproject.election" )
1099 main.log.debug( topics )
1100 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1101 for topic in topics:
1102 if topic not in ONOStopics:
1103 main.log.error( "Error: " + topic +
1104 " not in leaders" )
1105 missing = True
1106 else:
1107 main.log.error( "leaders() returned None" )
1108 except ( ValueError, TypeError ):
1109 main.log.exception( "Error parsing leaders" )
1110 main.log.error( repr( leaders ) )
1111 if missing:
Jon Halla440e872016-03-31 15:15:50 -07001112 for i in main.activeNodes:
1113 node = main.CLIs[i]
1114 response = node.leaders( jsonFormat=False)
1115 main.log.warn( str( node.name ) + " leaders output: \n" +
1116 str( response ) )
1117
1118 partitions = onosCli.partitions()
Jon Hall85794ff2015-07-08 14:12:30 -07001119 try:
1120 if partitions :
1121 parsedPartitions = json.loads( partitions )
1122 main.log.warn( json.dumps( parsedPartitions,
1123 sort_keys=True,
1124 indent=4,
1125 separators=( ',', ': ' ) ) )
1126 # TODO check for a leader in all paritions
1127 # TODO check for consistency among nodes
1128 else:
1129 main.log.error( "partitions() returned None" )
1130 except ( ValueError, TypeError ):
1131 main.log.exception( "Error parsing partitions" )
1132 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -07001133 pendingMap = onosCli.pendingMap()
Jon Hall85794ff2015-07-08 14:12:30 -07001134 try:
1135 if pendingMap :
1136 parsedPending = json.loads( pendingMap )
1137 main.log.warn( json.dumps( parsedPending,
1138 sort_keys=True,
1139 indent=4,
1140 separators=( ',', ': ' ) ) )
1141 # TODO check something here?
1142 else:
1143 main.log.error( "pendingMap() returned None" )
1144 except ( ValueError, TypeError ):
1145 main.log.exception( "Error parsing pending map" )
1146 main.log.error( repr( pendingMap ) )
1147 # Print flowrules
Jon Halla440e872016-03-31 15:15:50 -07001148 node = main.activeNodes[0]
1149 main.log.debug( main.CLIs[node].flows( jsonFormat=False ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001150 main.step( "Wait a minute then ping again" )
1151 # the wait is above
1152 PingResult = main.TRUE
1153 for i in range( 8, 18 ):
1154 ping = main.Mininet1.pingHost( src="h" + str( i ),
1155 target="h" + str( i + 10 ) )
1156 PingResult = PingResult and ping
1157 if ping == main.FALSE:
1158 main.log.warn( "Ping failed between h" + str( i ) +
1159 " and h" + str( i + 10 ) )
1160 elif ping == main.TRUE:
1161 main.log.info( "Ping test passed!" )
1162 # Don't set PingResult or you'd override failures
1163 if PingResult == main.FALSE:
1164 main.log.error(
1165 "Intents have not been installed correctly, pings failed." )
1166 # TODO: pretty print
1167 main.log.warn( "ONOS1 intents: " )
1168 try:
Jon Halla440e872016-03-31 15:15:50 -07001169 tmpIntents = onosCli.intents()
Jon Hall85794ff2015-07-08 14:12:30 -07001170 main.log.warn( json.dumps( json.loads( tmpIntents ),
1171 sort_keys=True,
1172 indent=4,
1173 separators=( ',', ': ' ) ) )
1174 except ( ValueError, TypeError ):
1175 main.log.warn( repr( tmpIntents ) )
1176 utilities.assert_equals(
1177 expect=main.TRUE,
1178 actual=PingResult,
1179 onpass="Intents have been installed correctly and pings work",
1180 onfail="Intents have not been installed correctly, pings failed." )
1181
1182 def CASE5( self, main ):
1183 """
1184 Reading state of ONOS
1185 """
1186 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001187 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001188 assert main, "main not defined"
1189 assert utilities.assert_equals, "utilities.assert_equals not defined"
1190
1191 main.case( "Setting up and gathering data for current state" )
1192 # The general idea for this test case is to pull the state of
1193 # ( intents,flows, topology,... ) from each ONOS node
1194 # We can then compare them with each other and also with past states
1195
1196 main.step( "Check that each switch has a master" )
1197 global mastershipState
1198 mastershipState = '[]'
1199
1200 # Assert that each device has a master
Jon Halla440e872016-03-31 15:15:50 -07001201 rolesNotNull = main.TRUE
1202 threads = []
1203 for i in main.activeNodes:
1204 t = main.Thread( target=main.CLIs[i].rolesNotNull,
1205 name="rolesNotNull-" + str( i ),
1206 args=[] )
1207 threads.append( t )
1208 t.start()
1209
1210 for t in threads:
1211 t.join()
1212 rolesNotNull = rolesNotNull and t.result
Jon Hall85794ff2015-07-08 14:12:30 -07001213 utilities.assert_equals(
1214 expect=main.TRUE,
1215 actual=rolesNotNull,
1216 onpass="Each device has a master",
1217 onfail="Some devices don't have a master assigned" )
1218
1219 main.step( "Get the Mastership of each switch" )
1220 ONOS1Mastership = main.ONOScli1.roles()
1221 # TODO: Make this a meaningful check
1222 if "Error" in ONOS1Mastership or not ONOS1Mastership:
1223 main.log.error( "Error in getting ONOS roles" )
1224 main.log.warn(
1225 "ONOS1 mastership response: " +
1226 repr( ONOS1Mastership ) )
1227 consistentMastership = main.FALSE
1228 else:
1229 mastershipState = ONOS1Mastership
1230 consistentMastership = main.TRUE
1231
1232 main.step( "Get the intents from each controller" )
1233 global intentState
1234 intentState = []
1235 ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
1236 intentCheck = main.FALSE
1237 if "Error" in ONOS1Intents or not ONOS1Intents:
1238 main.log.error( "Error in getting ONOS intents" )
1239 main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
1240 else:
1241 intentCheck = main.TRUE
1242
1243 main.step( "Get the flows from each controller" )
1244 global flowState
1245 flowState = []
1246 flowCheck = main.FALSE
1247 ONOS1Flows = main.ONOScli1.flows( jsonFormat=True )
1248 if "Error" in ONOS1Flows or not ONOS1Flows:
1249 main.log.error( "Error in getting ONOS flows" )
1250 main.log.warn( "ONOS1 flows repsponse: " + ONOS1Flows )
1251 else:
1252 # TODO: Do a better check, maybe compare flows on switches?
1253 flowState = ONOS1Flows
1254 flowCheck = main.TRUE
1255
1256 main.step( "Get the OF Table entries" )
1257 global flows
1258 flows = []
1259 for i in range( 1, 29 ):
GlennRC68467eb2015-11-16 18:01:01 -08001260 flows.append( main.Mininet1.getFlowTable( "s" + str( i ), version="1.3", debug=False ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001261 if flowCheck == main.FALSE:
1262 for table in flows:
1263 main.log.warn( table )
1264 # TODO: Compare switch flow tables with ONOS flow tables
1265
1266 main.step( "Collecting topology information from ONOS" )
1267 devices = []
1268 devices.append( main.ONOScli1.devices() )
1269 hosts = []
1270 hosts.append( json.loads( main.ONOScli1.hosts() ) )
1271 ports = []
1272 ports.append( main.ONOScli1.ports() )
1273 links = []
1274 links.append( main.ONOScli1.links() )
1275 clusters = []
1276 clusters.append( main.ONOScli1.clusters() )
1277
1278 main.step( "Each host has an IP address" )
1279 ipResult = main.TRUE
1280 for controller in range( 0, len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07001281 controllerStr = str( main.activeNodes[controller] + 1 )
1282 if hosts[ controller ]:
1283 for host in hosts[ controller ]:
1284 if not host.get( 'ipAddresses', [ ] ):
1285 main.log.error( "Error with host ips on controller" +
1286 controllerStr + ": " + str( host ) )
1287 ipResult = main.FALSE
Jon Hall85794ff2015-07-08 14:12:30 -07001288 utilities.assert_equals(
1289 expect=main.TRUE,
1290 actual=ipResult,
1291 onpass="The ips of the hosts aren't empty",
1292 onfail="The ip of at least one host is missing" )
1293
1294 # there should always only be one cluster
1295 main.step( "There is only one dataplane cluster" )
1296 try:
1297 numClusters = len( json.loads( clusters[ 0 ] ) )
1298 except ( ValueError, TypeError ):
1299 main.log.exception( "Error parsing clusters[0]: " +
1300 repr( clusters[ 0 ] ) )
Jon Hall6e709752016-02-01 13:38:46 -08001301 numClusters = "ERROR"
Jon Hall85794ff2015-07-08 14:12:30 -07001302 clusterResults = main.FALSE
1303 if numClusters == 1:
1304 clusterResults = main.TRUE
1305 utilities.assert_equals(
1306 expect=1,
1307 actual=numClusters,
1308 onpass="ONOS shows 1 SCC",
1309 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1310
1311 main.step( "Comparing ONOS topology to MN" )
1312 devicesResults = main.TRUE
1313 linksResults = main.TRUE
1314 hostsResults = main.TRUE
1315 mnSwitches = main.Mininet1.getSwitches()
1316 mnLinks = main.Mininet1.getLinks()
1317 mnHosts = main.Mininet1.getHosts()
Jon Halla440e872016-03-31 15:15:50 -07001318 for controller in main.activeNodes:
1319 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07001320 if devices[ controller ] and ports[ controller ] and\
1321 "Error" not in devices[ controller ] and\
1322 "Error" not in ports[ controller ]:
Jon Hall6e709752016-02-01 13:38:46 -08001323 currentDevicesResult = main.Mininet1.compareSwitches(
1324 mnSwitches,
1325 json.loads( devices[ controller ] ),
1326 json.loads( ports[ controller ] ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001327 else:
1328 currentDevicesResult = main.FALSE
1329 utilities.assert_equals( expect=main.TRUE,
1330 actual=currentDevicesResult,
1331 onpass="ONOS" + controllerStr +
1332 " Switches view is correct",
1333 onfail="ONOS" + controllerStr +
1334 " Switches view is incorrect" )
1335 if links[ controller ] and "Error" not in links[ controller ]:
1336 currentLinksResult = main.Mininet1.compareLinks(
1337 mnSwitches, mnLinks,
1338 json.loads( links[ controller ] ) )
1339 else:
1340 currentLinksResult = main.FALSE
1341 utilities.assert_equals( expect=main.TRUE,
1342 actual=currentLinksResult,
1343 onpass="ONOS" + controllerStr +
1344 " links view is correct",
1345 onfail="ONOS" + controllerStr +
1346 " links view is incorrect" )
1347
Jon Halla440e872016-03-31 15:15:50 -07001348 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall85794ff2015-07-08 14:12:30 -07001349 currentHostsResult = main.Mininet1.compareHosts(
1350 mnHosts,
1351 hosts[ controller ] )
1352 else:
1353 currentHostsResult = main.FALSE
1354 utilities.assert_equals( expect=main.TRUE,
1355 actual=currentHostsResult,
1356 onpass="ONOS" + controllerStr +
1357 " hosts exist in Mininet",
1358 onfail="ONOS" + controllerStr +
1359 " hosts don't match Mininet" )
1360
1361 devicesResults = devicesResults and currentDevicesResult
1362 linksResults = linksResults and currentLinksResult
1363 hostsResults = hostsResults and currentHostsResult
1364
1365 main.step( "Device information is correct" )
1366 utilities.assert_equals(
1367 expect=main.TRUE,
1368 actual=devicesResults,
1369 onpass="Device information is correct",
1370 onfail="Device information is incorrect" )
1371
1372 main.step( "Links are correct" )
1373 utilities.assert_equals(
1374 expect=main.TRUE,
1375 actual=linksResults,
1376 onpass="Link are correct",
1377 onfail="Links are incorrect" )
1378
1379 main.step( "Hosts are correct" )
1380 utilities.assert_equals(
1381 expect=main.TRUE,
1382 actual=hostsResults,
1383 onpass="Hosts are correct",
1384 onfail="Hosts are incorrect" )
1385
1386 def CASE6( self, main ):
1387 """
1388 The Failure case.
1389 """
1390 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001391 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001392 assert main, "main not defined"
1393 assert utilities.assert_equals, "utilities.assert_equals not defined"
1394
1395 # Reset non-persistent variables
1396 try:
1397 iCounterValue = 0
1398 except NameError:
1399 main.log.error( "iCounterValue not defined, setting to 0" )
1400 iCounterValue = 0
1401
1402 main.case( "Restart ONOS node" )
Jon Hall783bbf92015-07-23 14:33:19 -07001403 main.caseExplanation = "Killing ONOS process and restart cli " +\
Jon Hall85794ff2015-07-08 14:12:30 -07001404 "sessions once onos is up."
Jon Hall96091e62015-09-21 17:34:17 -07001405
1406 main.step( "Checking ONOS Logs for errors" )
1407 for node in main.nodes:
1408 main.log.debug( "Checking logs for errors on " + node.name + ":" )
1409 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
1410
Jon Hall85794ff2015-07-08 14:12:30 -07001411 main.step( "Killing ONOS processes" )
Jon Halle1a3b752015-07-22 13:02:46 -07001412 killResult = main.ONOSbench.onosKill( main.nodes[0].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -07001413 start = time.time()
1414 utilities.assert_equals( expect=main.TRUE, actual=killResult,
1415 onpass="ONOS Killed",
1416 onfail="Error killing ONOS" )
1417
1418 main.step( "Checking if ONOS is up yet" )
1419 count = 0
1420 while count < 10:
Jon Halle1a3b752015-07-22 13:02:46 -07001421 onos1Isup = main.ONOSbench.isup( main.nodes[0].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -07001422 if onos1Isup == main.TRUE:
1423 elapsed = time.time() - start
1424 break
1425 else:
1426 count = count + 1
1427 utilities.assert_equals( expect=main.TRUE, actual=onos1Isup,
1428 onpass="ONOS is back up",
1429 onfail="ONOS failed to start" )
1430
1431 main.log.step( "Starting ONOS CLI sessions" )
Jon Halle1a3b752015-07-22 13:02:46 -07001432 cliResults = main.ONOScli1.startOnosCli( main.nodes[0].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -07001433 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1434 onpass="ONOS cli startup successful",
1435 onfail="ONOS cli startup failed" )
1436
1437 if elapsed:
1438 main.log.info( "ESTIMATE: ONOS took %s seconds to restart" %
1439 str( elapsed ) )
1440 main.restartTime = elapsed
1441 else:
1442 main.restartTime = -1
1443 time.sleep( 5 )
1444 # rerun on election apps
1445 main.ONOScli1.electionTestRun()
1446
1447 def CASE7( self, main ):
1448 """
1449 Check state after ONOS failure
1450 """
1451 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001452 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001453 assert main, "main not defined"
1454 assert utilities.assert_equals, "utilities.assert_equals not defined"
1455 main.case( "Running ONOS Constant State Tests" )
Jon Hall6e709752016-02-01 13:38:46 -08001456
Jon Hall85794ff2015-07-08 14:12:30 -07001457 main.step( "Check that each switch has a master" )
1458 # Assert that each device has a master
Jon Halla440e872016-03-31 15:15:50 -07001459 rolesNotNull = main.TRUE
1460 threads = []
1461 for i in main.activeNodes:
1462 t = main.Thread( target=main.CLIs[i].rolesNotNull,
1463 name="rolesNotNull-" + str( i ),
1464 args=[ ] )
1465 threads.append( t )
1466 t.start()
1467
1468 for t in threads:
1469 t.join()
1470 rolesNotNull = rolesNotNull and t.result
Jon Hall85794ff2015-07-08 14:12:30 -07001471 utilities.assert_equals(
1472 expect=main.TRUE,
1473 actual=rolesNotNull,
1474 onpass="Each device has a master",
1475 onfail="Some devices don't have a master assigned" )
1476
1477 main.step( "Check if switch roles are consistent across all nodes" )
1478 ONOS1Mastership = main.ONOScli1.roles()
1479 # FIXME: Refactor this whole case for single instance
1480 if "Error" in ONOS1Mastership or not ONOS1Mastership:
1481 main.log.error( "Error in getting ONOS mastership" )
1482 main.log.warn( "ONOS1 mastership response: " +
1483 repr( ONOS1Mastership ) )
1484 consistentMastership = main.FALSE
1485 else:
1486 consistentMastership = main.TRUE
1487 utilities.assert_equals(
1488 expect=main.TRUE,
1489 actual=consistentMastership,
1490 onpass="Switch roles are consistent across all ONOS nodes",
1491 onfail="ONOS nodes have different views of switch roles" )
1492
1493 description2 = "Compare switch roles from before failure"
1494 main.step( description2 )
1495
1496 currentJson = json.loads( ONOS1Mastership )
1497 oldJson = json.loads( mastershipState )
1498 mastershipCheck = main.TRUE
1499 for i in range( 1, 29 ):
1500 switchDPID = str(
1501 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
1502
1503 current = [ switch[ 'master' ] for switch in currentJson
1504 if switchDPID in switch[ 'id' ] ]
1505 old = [ switch[ 'master' ] for switch in oldJson
1506 if switchDPID in switch[ 'id' ] ]
1507 if current == old:
1508 mastershipCheck = mastershipCheck and main.TRUE
1509 else:
1510 main.log.warn( "Mastership of switch %s changed" % switchDPID )
1511 mastershipCheck = main.FALSE
1512 utilities.assert_equals(
1513 expect=main.TRUE,
1514 actual=mastershipCheck,
1515 onpass="Mastership of Switches was not changed",
1516 onfail="Mastership of some switches changed" )
1517 mastershipCheck = mastershipCheck and consistentMastership
1518
1519 main.step( "Get the intents and compare across all nodes" )
1520 ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
1521 intentCheck = main.FALSE
1522 if "Error" in ONOS1Intents or not ONOS1Intents:
1523 main.log.error( "Error in getting ONOS intents" )
1524 main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
1525 else:
1526 intentCheck = main.TRUE
1527 utilities.assert_equals(
1528 expect=main.TRUE,
1529 actual=intentCheck,
1530 onpass="Intents are consistent across all ONOS nodes",
1531 onfail="ONOS nodes have different views of intents" )
1532 # Print the intent states
1533 intents = []
1534 intents.append( ONOS1Intents )
1535 intentStates = []
1536 for node in intents: # Iter through ONOS nodes
1537 nodeStates = []
1538 # Iter through intents of a node
1539 for intent in json.loads( node ):
1540 nodeStates.append( intent[ 'state' ] )
1541 intentStates.append( nodeStates )
1542 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1543 main.log.info( dict( out ) )
1544
1545 # NOTE: Store has no durability, so intents are lost across system
1546 # restarts
1547 """
1548 main.step( "Compare current intents with intents before the failure" )
1549 # NOTE: this requires case 5 to pass for intentState to be set.
1550 # maybe we should stop the test if that fails?
1551 sameIntents = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07001552 try:
1553 intentState
1554 except NameError:
1555 main.log.warn( "No previous intent state was saved" )
1556 else:
1557 if intentState and intentState == ONOSIntents[ 0 ]:
1558 sameIntents = main.TRUE
1559 main.log.info( "Intents are consistent with before failure" )
1560 # TODO: possibly the states have changed? we may need to figure out
1561 # what the acceptable states are
1562 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
1563 sameIntents = main.TRUE
1564 try:
1565 before = json.loads( intentState )
1566 after = json.loads( ONOSIntents[ 0 ] )
1567 for intent in before:
1568 if intent not in after:
1569 sameIntents = main.FALSE
1570 main.log.debug( "Intent is not currently in ONOS " +
1571 "(at least in the same form):" )
1572 main.log.debug( json.dumps( intent ) )
1573 except ( ValueError, TypeError ):
1574 main.log.exception( "Exception printing intents" )
1575 main.log.debug( repr( ONOSIntents[0] ) )
1576 main.log.debug( repr( intentState ) )
1577 if sameIntents == main.FALSE:
1578 try:
1579 main.log.debug( "ONOS intents before: " )
1580 main.log.debug( json.dumps( json.loads( intentState ),
1581 sort_keys=True, indent=4,
1582 separators=( ',', ': ' ) ) )
1583 main.log.debug( "Current ONOS intents: " )
1584 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1585 sort_keys=True, indent=4,
1586 separators=( ',', ': ' ) ) )
1587 except ( ValueError, TypeError ):
1588 main.log.exception( "Exception printing intents" )
1589 main.log.debug( repr( ONOSIntents[0] ) )
1590 main.log.debug( repr( intentState ) )
1591 utilities.assert_equals(
1592 expect=main.TRUE,
1593 actual=sameIntents,
1594 onpass="Intents are consistent with before failure",
1595 onfail="The Intents changed during failure" )
Jon Hall85794ff2015-07-08 14:12:30 -07001596 intentCheck = intentCheck and sameIntents
1597 """
1598 main.step( "Get the OF Table entries and compare to before " +
1599 "component failure" )
1600 FlowTables = main.TRUE
Jon Hall85794ff2015-07-08 14:12:30 -07001601 for i in range( 28 ):
1602 main.log.info( "Checking flow table on s" + str( i + 1 ) )
GlennRC68467eb2015-11-16 18:01:01 -08001603 tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
1604 FlowTables = FlowTables and main.Mininet1.flowTableComp( flows[i], tmpFlows )
Jon Hall85794ff2015-07-08 14:12:30 -07001605 if FlowTables == main.FALSE:
GlennRC68467eb2015-11-16 18:01:01 -08001606 main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001607 utilities.assert_equals(
1608 expect=main.TRUE,
1609 actual=FlowTables,
1610 onpass="No changes were found in the flow tables",
1611 onfail="Changes were found in the flow tables" )
1612
1613 main.step( "Leadership Election is still functional" )
1614 # Test of LeadershipElection
1615
Jon Halla440e872016-03-31 15:15:50 -07001616 leader = main.nodes[ main.activeNodes[ 0 ] ].ip_address
Jon Hall85794ff2015-07-08 14:12:30 -07001617 leaderResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001618 for controller in range( 1, main.numCtrls + 1 ):
Jon Hall85794ff2015-07-08 14:12:30 -07001619 # loop through ONOScli handlers
1620 node = getattr( main, ( 'ONOScli' + str( controller ) ) )
1621 leaderN = node.electionTestLeader()
1622 # verify leader is ONOS1
1623 # NOTE even though we restarted ONOS, it is the only one so onos 1
1624 # must be leader
1625 if leaderN == leader:
1626 # all is well
1627 pass
1628 elif leaderN == main.FALSE:
1629 # error in response
1630 main.log.error( "Something is wrong with " +
1631 "electionTestLeader function, check the" +
1632 " error logs" )
1633 leaderResult = main.FALSE
1634 elif leader != leaderN:
1635 leaderResult = main.FALSE
1636 main.log.error( "ONOS" + str( controller ) + " sees " +
1637 str( leaderN ) +
1638 " as the leader of the election app. " +
1639 "Leader should be " + str( leader ) )
1640 utilities.assert_equals(
1641 expect=main.TRUE,
1642 actual=leaderResult,
1643 onpass="Leadership election passed",
1644 onfail="Something went wrong with Leadership election" )
1645
1646 def CASE8( self, main ):
1647 """
1648 Compare topo
1649 """
1650 import json
1651 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001652 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001653 assert main, "main not defined"
1654 assert utilities.assert_equals, "utilities.assert_equals not defined"
1655
1656 main.case( "Compare ONOS Topology view to Mininet topology" )
Jon Hall783bbf92015-07-23 14:33:19 -07001657 main.caseExplanation = "Compare topology objects between Mininet" +\
Jon Hall85794ff2015-07-08 14:12:30 -07001658 " and ONOS"
Jon Hall85794ff2015-07-08 14:12:30 -07001659 topoResult = main.FALSE
1660 elapsed = 0
1661 count = 0
Jon Halle9b1fa32015-12-08 15:32:21 -08001662 main.step( "Comparing ONOS topology to MN topology" )
Jon Hall85794ff2015-07-08 14:12:30 -07001663 startTime = time.time()
1664 # Give time for Gossip to work
Jon Halle9b1fa32015-12-08 15:32:21 -08001665 while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
Jon Hall96091e62015-09-21 17:34:17 -07001666 devicesResults = main.TRUE
1667 linksResults = main.TRUE
1668 hostsResults = main.TRUE
1669 hostAttachmentResults = True
Jon Hall85794ff2015-07-08 14:12:30 -07001670 count += 1
1671 cliStart = time.time()
1672 devices = []
1673 devices.append( main.ONOScli1.devices() )
1674 hosts = []
1675 hosts.append( json.loads( main.ONOScli1.hosts() ) )
1676 ipResult = main.TRUE
1677 for controller in range( 0, len( hosts ) ):
1678 controllerStr = str( controller + 1 )
1679 for host in hosts[ controller ]:
1680 if host is None or host.get( 'ipAddresses', [] ) == []:
1681 main.log.error(
1682 "DEBUG:Error with host ips on controller" +
1683 controllerStr + ": " + str( host ) )
1684 ipResult = main.FALSE
1685 ports = []
1686 ports.append( main.ONOScli1.ports() )
1687 links = []
1688 links.append( main.ONOScli1.links() )
1689 clusters = []
1690 clusters.append( main.ONOScli1.clusters() )
1691
1692 elapsed = time.time() - startTime
1693 cliTime = time.time() - cliStart
1694 print "CLI time: " + str( cliTime )
1695
1696 mnSwitches = main.Mininet1.getSwitches()
1697 mnLinks = main.Mininet1.getLinks()
1698 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07001699 for controller in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07001700 controllerStr = str( controller + 1 )
1701 if devices[ controller ] and ports[ controller ] and\
1702 "Error" not in devices[ controller ] and\
1703 "Error" not in ports[ controller ]:
1704
Jon Hallc6793552016-01-19 14:18:37 -08001705 try:
1706 currentDevicesResult = main.Mininet1.compareSwitches(
1707 mnSwitches,
1708 json.loads( devices[ controller ] ),
1709 json.loads( ports[ controller ] ) )
1710 except ( TypeError, ValueError ) as e:
1711 main.log.exception( "Object not as expected; devices={!r}\nports={!r}".format(
1712 devices[ controller ], ports[ controller ] ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001713 else:
1714 currentDevicesResult = main.FALSE
1715 utilities.assert_equals( expect=main.TRUE,
1716 actual=currentDevicesResult,
1717 onpass="ONOS" + controllerStr +
1718 " Switches view is correct",
1719 onfail="ONOS" + controllerStr +
1720 " Switches view is incorrect" )
1721
1722 if links[ controller ] and "Error" not in links[ controller ]:
1723 currentLinksResult = main.Mininet1.compareLinks(
1724 mnSwitches, mnLinks,
1725 json.loads( links[ controller ] ) )
1726 else:
1727 currentLinksResult = main.FALSE
1728 utilities.assert_equals( expect=main.TRUE,
1729 actual=currentLinksResult,
1730 onpass="ONOS" + controllerStr +
1731 " links view is correct",
1732 onfail="ONOS" + controllerStr +
1733 " links view is incorrect" )
1734
1735 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1736 currentHostsResult = main.Mininet1.compareHosts(
1737 mnHosts,
1738 hosts[ controller ] )
1739 else:
1740 currentHostsResult = main.FALSE
1741 utilities.assert_equals( expect=main.TRUE,
1742 actual=currentHostsResult,
1743 onpass="ONOS" + controllerStr +
1744 " hosts exist in Mininet",
1745 onfail="ONOS" + controllerStr +
1746 " hosts don't match Mininet" )
1747 # CHECKING HOST ATTACHMENT POINTS
1748 hostAttachment = True
1749 zeroHosts = False
1750 # FIXME: topo-HA/obelisk specific mappings:
1751 # key is mac and value is dpid
1752 mappings = {}
1753 for i in range( 1, 29 ): # hosts 1 through 28
1754 # set up correct variables:
1755 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
1756 if i == 1:
1757 deviceId = "1000".zfill(16)
1758 elif i == 2:
1759 deviceId = "2000".zfill(16)
1760 elif i == 3:
1761 deviceId = "3000".zfill(16)
1762 elif i == 4:
1763 deviceId = "3004".zfill(16)
1764 elif i == 5:
1765 deviceId = "5000".zfill(16)
1766 elif i == 6:
1767 deviceId = "6000".zfill(16)
1768 elif i == 7:
1769 deviceId = "6007".zfill(16)
1770 elif i >= 8 and i <= 17:
1771 dpid = '3' + str( i ).zfill( 3 )
1772 deviceId = dpid.zfill(16)
1773 elif i >= 18 and i <= 27:
1774 dpid = '6' + str( i ).zfill( 3 )
1775 deviceId = dpid.zfill(16)
1776 elif i == 28:
1777 deviceId = "2800".zfill(16)
1778 mappings[ macId ] = deviceId
1779 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1780 if hosts[ controller ] == []:
1781 main.log.warn( "There are no hosts discovered" )
1782 zeroHosts = True
1783 else:
1784 for host in hosts[ controller ]:
1785 mac = None
1786 location = None
1787 device = None
1788 port = None
1789 try:
1790 mac = host.get( 'mac' )
1791 assert mac, "mac field could not be found for this host object"
1792
1793 location = host.get( 'location' )
1794 assert location, "location field could not be found for this host object"
1795
1796 # Trim the protocol identifier off deviceId
1797 device = str( location.get( 'elementId' ) ).split(':')[1]
1798 assert device, "elementId field could not be found for this host location object"
1799
1800 port = location.get( 'port' )
1801 assert port, "port field could not be found for this host location object"
1802
1803 # Now check if this matches where they should be
1804 if mac and device and port:
1805 if str( port ) != "1":
1806 main.log.error( "The attachment port is incorrect for " +
1807 "host " + str( mac ) +
1808 ". Expected: 1 Actual: " + str( port) )
1809 hostAttachment = False
1810 if device != mappings[ str( mac ) ]:
1811 main.log.error( "The attachment device is incorrect for " +
1812 "host " + str( mac ) +
1813 ". Expected: " + mappings[ str( mac ) ] +
1814 " Actual: " + device )
1815 hostAttachment = False
1816 else:
1817 hostAttachment = False
1818 except AssertionError:
1819 main.log.exception( "Json object not as expected" )
1820 main.log.error( repr( host ) )
1821 hostAttachment = False
1822 else:
1823 main.log.error( "No hosts json output or \"Error\"" +
1824 " in output. hosts = " +
1825 repr( hosts[ controller ] ) )
1826 if zeroHosts is False:
1827 hostAttachment = True
1828
Jon Hall85794ff2015-07-08 14:12:30 -07001829 devicesResults = devicesResults and currentDevicesResult
1830 linksResults = linksResults and currentLinksResult
1831 hostsResults = hostsResults and currentHostsResult
1832 hostAttachmentResults = hostAttachmentResults and\
1833 hostAttachment
1834
Jon Halla440e872016-03-31 15:15:50 -07001835 # "consistent" results don't make sense for single instance
Jon Hall85794ff2015-07-08 14:12:30 -07001836 # there should always only be one cluster
Jon Hall85794ff2015-07-08 14:12:30 -07001837 clusterResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07001838 try:
1839 numClusters = len( json.loads( clusters[ 0 ] ) )
1840 except ( ValueError, TypeError ):
1841 main.log.exception( "Error parsing clusters[0]: " +
1842 repr( clusters[0] ) )
1843 numClusters = "ERROR"
1844 clusterResults = main.FALSE
Jon Hall85794ff2015-07-08 14:12:30 -07001845 if numClusters == 1:
1846 clusterResults = main.TRUE
1847 utilities.assert_equals(
1848 expect=1,
1849 actual=numClusters,
1850 onpass="ONOS shows 1 SCC",
1851 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1852
1853 topoResult = ( devicesResults and linksResults
1854 and hostsResults and ipResult and clusterResults and
1855 hostAttachmentResults )
1856
1857 topoResult = topoResult and int( count <= 2 )
1858 note = "note it takes about " + str( int( cliTime ) ) + \
1859 " seconds for the test to make all the cli calls to fetch " +\
1860 "the topology from each ONOS instance"
1861 main.log.info(
1862 "Very crass estimate for topology discovery/convergence( " +
1863 str( note ) + " ): " + str( elapsed ) + " seconds, " +
1864 str( count ) + " tries" )
1865 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
1866 onpass="Topology Check Test successful",
1867 onfail="Topology Check Test NOT successful" )
1868
1869 def CASE9( self, main ):
1870 """
1871 Link s3-s28 down
1872 """
1873 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001874 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001875 assert main, "main not defined"
1876 assert utilities.assert_equals, "utilities.assert_equals not defined"
1877 # NOTE: You should probably run a topology check after this
1878
1879 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
1880
1881 description = "Turn off a link to ensure that Link Discovery " +\
1882 "is working properly"
1883 main.case( description )
1884
1885 main.step( "Kill Link between s3 and s28" )
1886 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
1887 main.log.info( "Waiting " + str( linkSleep ) +
1888 " seconds for link down to be discovered" )
1889 time.sleep( linkSleep )
1890 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
1891 onpass="Link down successful",
1892 onfail="Failed to bring link down" )
1893 # TODO do some sort of check here
1894
1895 def CASE10( self, main ):
1896 """
1897 Link s3-s28 up
1898 """
1899 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001900 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001901 assert main, "main not defined"
1902 assert utilities.assert_equals, "utilities.assert_equals not defined"
1903 # NOTE: You should probably run a topology check after this
1904
1905 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
1906
1907 description = "Restore a link to ensure that Link Discovery is " + \
1908 "working properly"
1909 main.case( description )
1910
1911 main.step( "Bring link between s3 and s28 back up" )
1912 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
1913 main.log.info( "Waiting " + str( linkSleep ) +
1914 " seconds for link up to be discovered" )
1915 time.sleep( linkSleep )
1916 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
1917 onpass="Link up successful",
1918 onfail="Failed to bring link up" )
1919 # TODO do some sort of check here
1920
1921 def CASE11( self, main ):
1922 """
1923 Switch Down
1924 """
1925 # NOTE: You should probably run a topology check after this
1926 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001927 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001928 assert main, "main not defined"
1929 assert utilities.assert_equals, "utilities.assert_equals not defined"
1930
1931 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
1932
1933 description = "Killing a switch to ensure it is discovered correctly"
Jon Halla440e872016-03-31 15:15:50 -07001934 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall85794ff2015-07-08 14:12:30 -07001935 main.case( description )
1936 switch = main.params[ 'kill' ][ 'switch' ]
1937 switchDPID = main.params[ 'kill' ][ 'dpid' ]
1938
1939 # TODO: Make this switch parameterizable
1940 main.step( "Kill " + switch )
1941 main.log.info( "Deleting " + switch )
1942 main.Mininet1.delSwitch( switch )
1943 main.log.info( "Waiting " + str( switchSleep ) +
1944 " seconds for switch down to be discovered" )
1945 time.sleep( switchSleep )
Jon Halla440e872016-03-31 15:15:50 -07001946 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall85794ff2015-07-08 14:12:30 -07001947 # Peek at the deleted switch
1948 main.log.warn( str( device ) )
1949 result = main.FALSE
1950 if device and device[ 'available' ] is False:
1951 result = main.TRUE
1952 utilities.assert_equals( expect=main.TRUE, actual=result,
1953 onpass="Kill switch successful",
1954 onfail="Failed to kill switch?" )
1955
1956 def CASE12( self, main ):
1957 """
1958 Switch Up
1959 """
1960 # NOTE: You should probably run a topology check after this
1961 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001962 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001963 assert main, "main not defined"
1964 assert utilities.assert_equals, "utilities.assert_equals not defined"
1965
1966 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
1967 switch = main.params[ 'kill' ][ 'switch' ]
1968 switchDPID = main.params[ 'kill' ][ 'dpid' ]
1969 links = main.params[ 'kill' ][ 'links' ].split()
Jon Halla440e872016-03-31 15:15:50 -07001970 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall85794ff2015-07-08 14:12:30 -07001971 description = "Adding a switch to ensure it is discovered correctly"
1972 main.case( description )
1973
1974 main.step( "Add back " + switch )
1975 main.Mininet1.addSwitch( switch, dpid=switchDPID )
1976 for peer in links:
1977 main.Mininet1.addLink( switch, peer )
Jon Halla440e872016-03-31 15:15:50 -07001978 ipList = [ node.ip_address for node in main.nodes ]
Jon Hall85794ff2015-07-08 14:12:30 -07001979 main.Mininet1.assignSwController( sw=switch, ip=ipList )
1980 main.log.info( "Waiting " + str( switchSleep ) +
1981 " seconds for switch up to be discovered" )
1982 time.sleep( switchSleep )
Jon Halla440e872016-03-31 15:15:50 -07001983 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall85794ff2015-07-08 14:12:30 -07001984 # Peek at the deleted switch
1985 main.log.warn( str( device ) )
1986 result = main.FALSE
1987 if device and device[ 'available' ]:
1988 result = main.TRUE
1989 utilities.assert_equals( expect=main.TRUE, actual=result,
1990 onpass="add switch successful",
1991 onfail="Failed to add switch?" )
1992
1993 def CASE13( self, main ):
1994 """
1995 Clean up
1996 """
1997 import os
1998 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001999 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002000 assert main, "main not defined"
2001 assert utilities.assert_equals, "utilities.assert_equals not defined"
2002 # printing colors to terminal
2003 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2004 'blue': '\033[94m', 'green': '\033[92m',
2005 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
2006 main.case( "Test Cleanup" )
2007 main.step( "Killing tcpdumps" )
2008 main.Mininet2.stopTcpdump()
2009
2010 testname = main.TEST
Jon Hall96091e62015-09-21 17:34:17 -07002011 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall85794ff2015-07-08 14:12:30 -07002012 main.step( "Copying MN pcap and ONOS log files to test station" )
2013 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
2014 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
Jon Hall96091e62015-09-21 17:34:17 -07002015 # NOTE: MN Pcap file is being saved to logdir.
2016 # We scp this file as MN and TestON aren't necessarily the same vm
2017
2018 # FIXME: To be replaced with a Jenkin's post script
Jon Hall85794ff2015-07-08 14:12:30 -07002019 # TODO: Load these from params
2020 # NOTE: must end in /
2021 logFolder = "/opt/onos/log/"
2022 logFiles = [ "karaf.log", "karaf.log.1" ]
2023 # NOTE: must end in /
Jon Hall85794ff2015-07-08 14:12:30 -07002024 for f in logFiles:
Jon Hall96091e62015-09-21 17:34:17 -07002025 for node in main.nodes:
Jon Halla440e872016-03-31 15:15:50 -07002026 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002027 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2028 logFolder + f, dstName )
Jon Hall85794ff2015-07-08 14:12:30 -07002029 # std*.log's
2030 # NOTE: must end in /
2031 logFolder = "/opt/onos/var/"
2032 logFiles = [ "stderr.log", "stdout.log" ]
2033 # NOTE: must end in /
Jon Hall85794ff2015-07-08 14:12:30 -07002034 for f in logFiles:
Jon Hall96091e62015-09-21 17:34:17 -07002035 for node in main.nodes:
Jon Halla440e872016-03-31 15:15:50 -07002036 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002037 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2038 logFolder + f, dstName )
2039 else:
2040 main.log.debug( "skipping saving log files" )
Jon Hall85794ff2015-07-08 14:12:30 -07002041
Jon Hall85794ff2015-07-08 14:12:30 -07002042 main.step( "Stopping Mininet" )
2043 mnResult = main.Mininet1.stopNet()
2044 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2045 onpass="Mininet stopped",
2046 onfail="MN cleanup NOT successful" )
2047
2048 main.step( "Checking ONOS Logs for errors" )
Jon Hall96091e62015-09-21 17:34:17 -07002049 for node in main.nodes:
2050 main.log.debug( "Checking logs for errors on " + node.name + ":" )
2051 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall85794ff2015-07-08 14:12:30 -07002052
2053 try:
2054 timerLog = open( main.logdir + "/Timers.csv", 'w')
2055 # Overwrite with empty line and close
2056 labels = "Gossip Intents, Restart"
2057 data = str( gossipTime ) + ", " + str( main.restartTime )
2058 timerLog.write( labels + "\n" + data )
2059 timerLog.close()
2060 except NameError, e:
2061 main.log.exception(e)
2062
2063 def CASE14( self, main ):
2064 """
2065 start election app on all onos nodes
2066 """
Jon Halle1a3b752015-07-22 13:02:46 -07002067 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002068 assert main, "main not defined"
2069 assert utilities.assert_equals, "utilities.assert_equals not defined"
2070
2071 main.case("Start Leadership Election app")
2072 main.step( "Install leadership election app" )
Jon Halla440e872016-03-31 15:15:50 -07002073 onosCli = main.CLIs[ main.activeNodes[0] ]
2074 appResult = onosCli.activateApp( "org.onosproject.election" )
Jon Hall85794ff2015-07-08 14:12:30 -07002075 utilities.assert_equals(
2076 expect=main.TRUE,
2077 actual=appResult,
2078 onpass="Election app installed",
2079 onfail="Something went wrong with installing Leadership election" )
2080
2081 main.step( "Run for election on each node" )
Jon Halla440e872016-03-31 15:15:50 -07002082 leaderResult = main.TRUE
2083 leaders = []
2084 for i in main.activeNodes:
2085 main.CLIs[i].electionTestRun()
2086 for i in main.activeNodes:
2087 cli = main.CLIs[i]
2088 leader = cli.electionTestLeader()
2089 if leader is None or leader == main.FALSE:
2090 main.log.error( cli.name + ": Leader for the election app " +
2091 "should be an ONOS node, instead got '" +
2092 str( leader ) + "'" )
2093 leaderResult = main.FALSE
2094 leaders.append( leader )
Jon Hall85794ff2015-07-08 14:12:30 -07002095 utilities.assert_equals(
2096 expect=main.TRUE,
2097 actual=leaderResult,
2098 onpass="Successfully ran for leadership",
2099 onfail="Failed to run for leadership" )
2100
2101 def CASE15( self, main ):
2102 """
2103 Check that Leadership Election is still functional
acsmars71adceb2015-08-31 15:09:26 -07002104 15.1 Run election on each node
2105 15.2 Check that each node has the same leaders and candidates
2106 15.3 Find current leader and withdraw
2107 15.4 Check that a new node was elected leader
2108 15.5 Check that that new leader was the candidate of old leader
2109 15.6 Run for election on old leader
2110 15.7 Check that oldLeader is a candidate, and leader if only 1 node
2111 15.8 Make sure that the old leader was added to the candidate list
2112
2113 old and new variable prefixes refer to data from before vs after
2114 withdrawl and later before withdrawl vs after re-election
Jon Hall85794ff2015-07-08 14:12:30 -07002115 """
acsmars71adceb2015-08-31 15:09:26 -07002116 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002117 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002118 assert main, "main not defined"
2119 assert utilities.assert_equals, "utilities.assert_equals not defined"
acsmars71adceb2015-08-31 15:09:26 -07002120 assert main.CLIs, "main.CLIs not defined"
2121 assert main.nodes, "main.nodes not defined"
2122
Jon Hall85794ff2015-07-08 14:12:30 -07002123 description = "Check that Leadership Election is still functional"
2124 main.case( description )
Jon Halla440e872016-03-31 15:15:50 -07002125 # NOTE: Need to re-run after restarts since being a canidate is not persistant
acsmars2c2fcdd2015-08-25 17:14:13 -07002126
Jon Halla440e872016-03-31 15:15:50 -07002127 oldLeaders = [] # list of lists of each nodes' candidates before
2128 newLeaders = [] # list of lists of each nodes' candidates after
acsmars71adceb2015-08-31 15:09:26 -07002129 oldLeader = '' # the old leader from oldLeaders, None if not same
2130 newLeader = '' # the new leaders fron newLoeaders, None if not same
2131 oldLeaderCLI = None # the CLI of the old leader used for re-electing
2132 expectNoLeader = False # True when there is only one leader
2133 if main.numCtrls == 1:
2134 expectNoLeader = True
acsmars2c2fcdd2015-08-25 17:14:13 -07002135
acsmars71adceb2015-08-31 15:09:26 -07002136 main.step( "Run for election on each node" )
2137 electionResult = main.TRUE
2138
Jon Halla440e872016-03-31 15:15:50 -07002139 for i in main.activeNodes: # run test election on each node
2140 if main.CLIs[i].electionTestRun() == main.FALSE:
acsmars71adceb2015-08-31 15:09:26 -07002141 electionResult = main.FALSE
acsmars71adceb2015-08-31 15:09:26 -07002142 utilities.assert_equals(
2143 expect=main.TRUE,
2144 actual=electionResult,
2145 onpass="All nodes successfully ran for leadership",
2146 onfail="At least one node failed to run for leadership" )
2147
acsmars3a72bde2015-09-02 14:16:22 -07002148 if electionResult == main.FALSE:
2149 main.log.error(
2150 "Skipping Test Case because Election Test App isn't loaded" )
2151 main.skipCase()
2152
acsmars71adceb2015-08-31 15:09:26 -07002153 main.step( "Check that each node shows the same leader and candidates" )
Jon Halla440e872016-03-31 15:15:50 -07002154 failMessage = "Nodes have different leaderboards"
2155 def consistentLeaderboards( nodes ):
2156 TOPIC = 'org.onosproject.election'
2157 # FIXME: use threads
2158 #FIXME: should we retry outside the function?
2159 for n in range( 5 ): # Retry in case election is still happening
2160 leaderList = []
2161 # Get all leaderboards
2162 for cli in nodes:
2163 leaderList.append( cli.specificLeaderCandidate( TOPIC ) )
2164 # Compare leaderboards
2165 result = all( i == leaderList[0] for i in leaderList ) and\
2166 leaderList is not None
2167 main.log.debug( leaderList )
2168 main.log.warn( result )
2169 if result:
2170 return ( result, leaderList )
2171 time.sleep(5) #TODO: paramerterize
2172 main.log.error( "Inconsistent leaderboards:" + str( leaderList ) )
2173 activeCLIs = [ main.CLIs[i] for i in main.activeNodes ]
2174 sameResult, oldLeaders = consistentLeaderboards( activeCLIs )
2175 if sameResult:
2176 oldLeader = oldLeaders[ 0 ][ 0 ]
2177 main.log.warn( oldLeader )
Jon Hall85794ff2015-07-08 14:12:30 -07002178 else:
Jon Halla440e872016-03-31 15:15:50 -07002179 oldLeader = None
acsmars71adceb2015-08-31 15:09:26 -07002180 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07002181 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07002182 actual=sameResult,
Jon Halla440e872016-03-31 15:15:50 -07002183 onpass="Leaderboards are consistent for the election topic",
acsmars71adceb2015-08-31 15:09:26 -07002184 onfail=failMessage )
2185
2186 main.step( "Find current leader and withdraw" )
2187 withdrawResult = main.TRUE
2188 # do some sanity checking on leader before using it
2189 if oldLeader is None:
2190 main.log.error( "Leadership isn't consistent." )
2191 withdrawResult = main.FALSE
2192 # Get the CLI of the oldLeader
Jon Halla440e872016-03-31 15:15:50 -07002193 for i in main.activeNodes:
acsmars71adceb2015-08-31 15:09:26 -07002194 if oldLeader == main.nodes[ i ].ip_address:
2195 oldLeaderCLI = main.CLIs[ i ]
2196 break
2197 else: # FOR/ELSE statement
2198 main.log.error( "Leader election, could not find current leader" )
Jon Hall85794ff2015-07-08 14:12:30 -07002199 if oldLeader:
acsmars71adceb2015-08-31 15:09:26 -07002200 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall85794ff2015-07-08 14:12:30 -07002201 utilities.assert_equals(
2202 expect=main.TRUE,
2203 actual=withdrawResult,
2204 onpass="Node was withdrawn from election",
2205 onfail="Node was not withdrawn from election" )
2206
acsmars71adceb2015-08-31 15:09:26 -07002207 main.step( "Check that a new node was elected leader" )
acsmars71adceb2015-08-31 15:09:26 -07002208 failMessage = "Nodes have different leaders"
acsmars71adceb2015-08-31 15:09:26 -07002209 # Get new leaders and candidates
Jon Halla440e872016-03-31 15:15:50 -07002210 newLeaderResult, newLeaders = consistentLeaderboards( activeCLIs )
2211 if newLeaders[ 0 ][ 0 ] == 'none':
2212 main.log.error( "No leader was elected on at least 1 node" )
2213 if not expectNoLeader:
2214 newLeaderResult = False
2215 if newLeaderResult:
2216 newLeader = newLeaders[ 0 ][ 0 ]
acsmars71adceb2015-08-31 15:09:26 -07002217 else:
Jon Halla440e872016-03-31 15:15:50 -07002218 newLeader = None
acsmars71adceb2015-08-31 15:09:26 -07002219
2220 # Check that the new leader is not the older leader, which was withdrawn
2221 if newLeader == oldLeader:
Jon Halla440e872016-03-31 15:15:50 -07002222 newLeaderResult = False
2223 main.log.error( "All nodes still see old leader: " + str( oldLeader ) +
acsmars71adceb2015-08-31 15:09:26 -07002224 " as the current leader" )
Jon Hall85794ff2015-07-08 14:12:30 -07002225 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07002226 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07002227 actual=newLeaderResult,
2228 onpass="Leadership election passed",
2229 onfail="Something went wrong with Leadership election" )
Jon Hall85794ff2015-07-08 14:12:30 -07002230
Jon Halla440e872016-03-31 15:15:50 -07002231 main.step( "Check that that new leader was the candidate of old leader" )
2232 # candidates[ 2 ] should become the top candidate after withdrawl
acsmars71adceb2015-08-31 15:09:26 -07002233 correctCandidateResult = main.TRUE
2234 if expectNoLeader:
2235 if newLeader == 'none':
2236 main.log.info( "No leader expected. None found. Pass" )
2237 correctCandidateResult = main.TRUE
2238 else:
2239 main.log.info( "Expected no leader, got: " + str( newLeader ) )
2240 correctCandidateResult = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002241 elif len( oldLeaders[0] ) >= 3:
2242 if newLeader == oldLeaders[ 0 ][ 2 ]:
2243 # correct leader was elected
2244 correctCandidateResult = main.TRUE
2245 else:
2246 correctCandidateResult = main.FALSE
2247 main.log.error( "Candidate {} was elected. {} should have had priority.".format(
2248 newLeader, oldLeaders[ 0 ][ 2 ] ) )
2249 else:
2250 main.log.warn( "Could not determine who should be the correct leader" )
2251 main.log.debug( oldLeaders[ 0 ] )
acsmars71adceb2015-08-31 15:09:26 -07002252 correctCandidateResult = main.FALSE
acsmars71adceb2015-08-31 15:09:26 -07002253 utilities.assert_equals(
2254 expect=main.TRUE,
2255 actual=correctCandidateResult,
2256 onpass="Correct Candidate Elected",
2257 onfail="Incorrect Candidate Elected" )
2258
Jon Hall85794ff2015-07-08 14:12:30 -07002259 main.step( "Run for election on old leader( just so everyone " +
2260 "is in the hat )" )
acsmars71adceb2015-08-31 15:09:26 -07002261 if oldLeaderCLI is not None:
2262 runResult = oldLeaderCLI.electionTestRun()
Jon Hall85794ff2015-07-08 14:12:30 -07002263 else:
acsmars71adceb2015-08-31 15:09:26 -07002264 main.log.error( "No old leader to re-elect" )
Jon Hall85794ff2015-07-08 14:12:30 -07002265 runResult = main.FALSE
2266 utilities.assert_equals(
2267 expect=main.TRUE,
2268 actual=runResult,
2269 onpass="App re-ran for election",
2270 onfail="App failed to run for election" )
Jon Halla440e872016-03-31 15:15:50 -07002271
acsmars71adceb2015-08-31 15:09:26 -07002272 main.step(
2273 "Check that oldLeader is a candidate, and leader if only 1 node" )
2274 # verify leader didn't just change
Jon Halla440e872016-03-31 15:15:50 -07002275 # Get new leaders and candidates
2276 reRunLeaders = []
2277 time.sleep( 5 ) # Paremterize
2278 positionResult, reRunLeaders = consistentLeaderboards( activeCLIs )
acsmars71adceb2015-08-31 15:09:26 -07002279
2280 # Check that the re-elected node is last on the candidate List
Jon Halla440e872016-03-31 15:15:50 -07002281 if oldLeader != reRunLeaders[ 0 ][ -1 ]:
2282 main.log.error( "Old Leader ({}) not in the proper position: {} ".format( str( oldLeader),
2283 str( reRunLeaders[ 0 ] ) ) )
acsmars71adceb2015-08-31 15:09:26 -07002284 positionResult = main.FALSE
Jon Hall85794ff2015-07-08 14:12:30 -07002285
2286 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07002287 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07002288 actual=positionResult,
Jon Hall85794ff2015-07-08 14:12:30 -07002289 onpass="Old leader successfully re-ran for election",
2290 onfail="Something went wrong with Leadership election after " +
2291 "the old leader re-ran for election" )
2292
2293 def CASE16( self, main ):
2294 """
2295 Install Distributed Primitives app
2296 """
Jon Halla440e872016-03-31 15:15:50 -07002297 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002298 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002299 assert main, "main not defined"
2300 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002301 assert main.CLIs, "main.CLIs not defined"
2302 assert main.nodes, "main.nodes not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002303
2304 # Variables for the distributed primitives tests
2305 global pCounterName
Jon Hall85794ff2015-07-08 14:12:30 -07002306 global pCounterValue
Jon Hall85794ff2015-07-08 14:12:30 -07002307 global onosSet
2308 global onosSetName
2309 pCounterName = "TestON-Partitions"
Jon Hall85794ff2015-07-08 14:12:30 -07002310 pCounterValue = 0
Jon Hall85794ff2015-07-08 14:12:30 -07002311 onosSet = set([])
2312 onosSetName = "TestON-set"
2313
2314 description = "Install Primitives app"
2315 main.case( description )
2316 main.step( "Install Primitives app" )
2317 appName = "org.onosproject.distributedprimitives"
Jon Halla440e872016-03-31 15:15:50 -07002318 node = main.activeNodes[0]
2319 appResults = main.CLIs[node].activateApp( appName )
Jon Hall85794ff2015-07-08 14:12:30 -07002320 utilities.assert_equals( expect=main.TRUE,
2321 actual=appResults,
2322 onpass="Primitives app activated",
2323 onfail="Primitives app not activated" )
Jon Halla440e872016-03-31 15:15:50 -07002324 time.sleep( 5 ) # To allow all nodes to activate
Jon Hall85794ff2015-07-08 14:12:30 -07002325
2326 def CASE17( self, main ):
2327 """
2328 Check for basic functionality with distributed primitives
2329 """
Jon Hall85794ff2015-07-08 14:12:30 -07002330 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07002331 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002332 assert main, "main not defined"
2333 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002334 assert main.CLIs, "main.CLIs not defined"
2335 assert main.nodes, "main.nodes not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002336 assert pCounterName, "pCounterName not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002337 assert onosSetName, "onosSetName not defined"
2338 # NOTE: assert fails if value is 0/None/Empty/False
2339 try:
2340 pCounterValue
2341 except NameError:
2342 main.log.error( "pCounterValue not defined, setting to 0" )
2343 pCounterValue = 0
2344 try:
Jon Hall85794ff2015-07-08 14:12:30 -07002345 onosSet
2346 except NameError:
2347 main.log.error( "onosSet not defined, setting to empty Set" )
2348 onosSet = set([])
2349 # Variables for the distributed primitives tests. These are local only
2350 addValue = "a"
2351 addAllValue = "a b c d e f"
2352 retainValue = "c d e f"
2353
2354 description = "Check for basic functionality with distributed " +\
2355 "primitives"
2356 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07002357 main.caseExplanation = "Test the methods of the distributed " +\
2358 "primitives (counters and sets) throught the cli"
Jon Hall85794ff2015-07-08 14:12:30 -07002359 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07002360 # Partitioned counters
2361 main.step( "Increment then get a default counter on each node" )
Jon Hall85794ff2015-07-08 14:12:30 -07002362 pCounters = []
2363 threads = []
2364 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07002365 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002366 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2367 name="counterAddAndGet-" + str( i ),
Jon Hall85794ff2015-07-08 14:12:30 -07002368 args=[ pCounterName ] )
2369 pCounterValue += 1
2370 addedPValues.append( pCounterValue )
2371 threads.append( t )
2372 t.start()
2373
2374 for t in threads:
2375 t.join()
2376 pCounters.append( t.result )
2377 # Check that counter incremented numController times
2378 pCounterResults = True
2379 for i in addedPValues:
2380 tmpResult = i in pCounters
2381 pCounterResults = pCounterResults and tmpResult
2382 if not tmpResult:
2383 main.log.error( str( i ) + " is not in partitioned "
2384 "counter incremented results" )
2385 utilities.assert_equals( expect=True,
2386 actual=pCounterResults,
2387 onpass="Default counter incremented",
2388 onfail="Error incrementing default" +
2389 " counter" )
2390
Jon Halle1a3b752015-07-22 13:02:46 -07002391 main.step( "Get then Increment a default counter on each node" )
2392 pCounters = []
2393 threads = []
2394 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07002395 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002396 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
2397 name="counterGetAndAdd-" + str( i ),
2398 args=[ pCounterName ] )
2399 addedPValues.append( pCounterValue )
2400 pCounterValue += 1
2401 threads.append( t )
2402 t.start()
2403
2404 for t in threads:
2405 t.join()
2406 pCounters.append( t.result )
2407 # Check that counter incremented numController times
2408 pCounterResults = True
2409 for i in addedPValues:
2410 tmpResult = i in pCounters
2411 pCounterResults = pCounterResults and tmpResult
2412 if not tmpResult:
2413 main.log.error( str( i ) + " is not in partitioned "
2414 "counter incremented results" )
2415 utilities.assert_equals( expect=True,
2416 actual=pCounterResults,
2417 onpass="Default counter incremented",
2418 onfail="Error incrementing default" +
2419 " counter" )
2420
2421 main.step( "Counters we added have the correct values" )
2422 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
2423 utilities.assert_equals( expect=main.TRUE,
2424 actual=incrementCheck,
2425 onpass="Added counters are correct",
2426 onfail="Added counters are incorrect" )
2427
2428 main.step( "Add -8 to then get a default counter on each node" )
2429 pCounters = []
2430 threads = []
2431 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07002432 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002433 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2434 name="counterIncrement-" + str( i ),
2435 args=[ pCounterName ],
2436 kwargs={ "delta": -8 } )
2437 pCounterValue += -8
2438 addedPValues.append( pCounterValue )
2439 threads.append( t )
2440 t.start()
2441
2442 for t in threads:
2443 t.join()
2444 pCounters.append( t.result )
2445 # Check that counter incremented numController times
2446 pCounterResults = True
2447 for i in addedPValues:
2448 tmpResult = i in pCounters
2449 pCounterResults = pCounterResults and tmpResult
2450 if not tmpResult:
2451 main.log.error( str( i ) + " is not in partitioned "
2452 "counter incremented results" )
2453 utilities.assert_equals( expect=True,
2454 actual=pCounterResults,
2455 onpass="Default counter incremented",
2456 onfail="Error incrementing default" +
2457 " counter" )
2458
2459 main.step( "Add 5 to then get a default counter on each node" )
2460 pCounters = []
2461 threads = []
2462 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07002463 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002464 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2465 name="counterIncrement-" + str( i ),
2466 args=[ pCounterName ],
2467 kwargs={ "delta": 5 } )
2468 pCounterValue += 5
2469 addedPValues.append( pCounterValue )
2470 threads.append( t )
2471 t.start()
2472
2473 for t in threads:
2474 t.join()
2475 pCounters.append( t.result )
2476 # Check that counter incremented numController times
2477 pCounterResults = True
2478 for i in addedPValues:
2479 tmpResult = i in pCounters
2480 pCounterResults = pCounterResults and tmpResult
2481 if not tmpResult:
2482 main.log.error( str( i ) + " is not in partitioned "
2483 "counter incremented results" )
2484 utilities.assert_equals( expect=True,
2485 actual=pCounterResults,
2486 onpass="Default counter incremented",
2487 onfail="Error incrementing default" +
2488 " counter" )
2489
2490 main.step( "Get then add 5 to a default counter on each node" )
2491 pCounters = []
2492 threads = []
2493 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07002494 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002495 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
2496 name="counterIncrement-" + str( i ),
2497 args=[ pCounterName ],
2498 kwargs={ "delta": 5 } )
2499 addedPValues.append( pCounterValue )
2500 pCounterValue += 5
2501 threads.append( t )
2502 t.start()
2503
2504 for t in threads:
2505 t.join()
2506 pCounters.append( t.result )
2507 # Check that counter incremented numController times
2508 pCounterResults = True
2509 for i in addedPValues:
2510 tmpResult = i in pCounters
2511 pCounterResults = pCounterResults and tmpResult
2512 if not tmpResult:
2513 main.log.error( str( i ) + " is not in partitioned "
2514 "counter incremented results" )
2515 utilities.assert_equals( expect=True,
2516 actual=pCounterResults,
2517 onpass="Default counter incremented",
2518 onfail="Error incrementing default" +
2519 " counter" )
2520
2521 main.step( "Counters we added have the correct values" )
2522 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
2523 utilities.assert_equals( expect=main.TRUE,
2524 actual=incrementCheck,
2525 onpass="Added counters are correct",
2526 onfail="Added counters are incorrect" )
2527
Jon Hall85794ff2015-07-08 14:12:30 -07002528 # DISTRIBUTED SETS
2529 main.step( "Distributed Set get" )
2530 size = len( onosSet )
2531 getResponses = []
2532 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002533 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002534 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002535 name="setTestGet-" + str( i ),
2536 args=[ onosSetName ] )
2537 threads.append( t )
2538 t.start()
2539 for t in threads:
2540 t.join()
2541 getResponses.append( t.result )
2542
2543 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002544 for i in range( len( main.activeNodes ) ):
2545 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002546 if isinstance( getResponses[ i ], list):
2547 current = set( getResponses[ i ] )
2548 if len( current ) == len( getResponses[ i ] ):
2549 # no repeats
2550 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07002551 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002552 " has incorrect view" +
2553 " of set " + onosSetName + ":\n" +
2554 str( getResponses[ i ] ) )
2555 main.log.debug( "Expected: " + str( onosSet ) )
2556 main.log.debug( "Actual: " + str( current ) )
2557 getResults = main.FALSE
2558 else:
2559 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07002560 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002561 " has repeat elements in" +
2562 " set " + onosSetName + ":\n" +
2563 str( getResponses[ i ] ) )
2564 getResults = main.FALSE
2565 elif getResponses[ i ] == main.ERROR:
2566 getResults = main.FALSE
2567 utilities.assert_equals( expect=main.TRUE,
2568 actual=getResults,
2569 onpass="Set elements are correct",
2570 onfail="Set elements are incorrect" )
2571
2572 main.step( "Distributed Set size" )
2573 sizeResponses = []
2574 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002575 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002576 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002577 name="setTestSize-" + str( i ),
2578 args=[ onosSetName ] )
2579 threads.append( t )
2580 t.start()
2581 for t in threads:
2582 t.join()
2583 sizeResponses.append( t.result )
2584
2585 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002586 for i in range( len( main.activeNodes ) ):
2587 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002588 if size != sizeResponses[ i ]:
2589 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002590 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002591 " expected a size of " + str( size ) +
2592 " for set " + onosSetName +
2593 " but got " + str( sizeResponses[ i ] ) )
2594 utilities.assert_equals( expect=main.TRUE,
2595 actual=sizeResults,
2596 onpass="Set sizes are correct",
2597 onfail="Set sizes are incorrect" )
2598
2599 main.step( "Distributed Set add()" )
2600 onosSet.add( addValue )
2601 addResponses = []
2602 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002603 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002604 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07002605 name="setTestAdd-" + str( i ),
2606 args=[ onosSetName, addValue ] )
2607 threads.append( t )
2608 t.start()
2609 for t in threads:
2610 t.join()
2611 addResponses.append( t.result )
2612
2613 # main.TRUE = successfully changed the set
2614 # main.FALSE = action resulted in no change in set
2615 # main.ERROR - Some error in executing the function
2616 addResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002617 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07002618 if addResponses[ i ] == main.TRUE:
2619 # All is well
2620 pass
2621 elif addResponses[ i ] == main.FALSE:
2622 # Already in set, probably fine
2623 pass
2624 elif addResponses[ i ] == main.ERROR:
2625 # Error in execution
2626 addResults = main.FALSE
2627 else:
2628 # unexpected result
2629 addResults = main.FALSE
2630 if addResults != main.TRUE:
2631 main.log.error( "Error executing set add" )
2632
2633 # Check if set is still correct
2634 size = len( onosSet )
2635 getResponses = []
2636 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002637 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002638 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002639 name="setTestGet-" + str( i ),
2640 args=[ onosSetName ] )
2641 threads.append( t )
2642 t.start()
2643 for t in threads:
2644 t.join()
2645 getResponses.append( t.result )
2646 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002647 for i in range( len( main.activeNodes ) ):
2648 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002649 if isinstance( getResponses[ i ], list):
2650 current = set( getResponses[ i ] )
2651 if len( current ) == len( getResponses[ i ] ):
2652 # no repeats
2653 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07002654 main.log.error( "ONOS" + node + " has incorrect view" +
Jon Hall85794ff2015-07-08 14:12:30 -07002655 " of set " + onosSetName + ":\n" +
2656 str( getResponses[ i ] ) )
2657 main.log.debug( "Expected: " + str( onosSet ) )
2658 main.log.debug( "Actual: " + str( current ) )
2659 getResults = main.FALSE
2660 else:
2661 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07002662 main.log.error( "ONOS" + node + " has repeat elements in" +
Jon Hall85794ff2015-07-08 14:12:30 -07002663 " set " + onosSetName + ":\n" +
2664 str( getResponses[ i ] ) )
2665 getResults = main.FALSE
2666 elif getResponses[ i ] == main.ERROR:
2667 getResults = main.FALSE
2668 sizeResponses = []
2669 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002670 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002671 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002672 name="setTestSize-" + str( i ),
2673 args=[ onosSetName ] )
2674 threads.append( t )
2675 t.start()
2676 for t in threads:
2677 t.join()
2678 sizeResponses.append( t.result )
2679 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002680 for i in range( len( main.activeNodes ) ):
2681 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002682 if size != sizeResponses[ i ]:
2683 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002684 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002685 " expected a size of " + str( size ) +
2686 " for set " + onosSetName +
2687 " but got " + str( sizeResponses[ i ] ) )
2688 addResults = addResults and getResults and sizeResults
2689 utilities.assert_equals( expect=main.TRUE,
2690 actual=addResults,
2691 onpass="Set add correct",
2692 onfail="Set add was incorrect" )
2693
2694 main.step( "Distributed Set addAll()" )
2695 onosSet.update( addAllValue.split() )
2696 addResponses = []
2697 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002698 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002699 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07002700 name="setTestAddAll-" + str( i ),
2701 args=[ onosSetName, addAllValue ] )
2702 threads.append( t )
2703 t.start()
2704 for t in threads:
2705 t.join()
2706 addResponses.append( t.result )
2707
2708 # main.TRUE = successfully changed the set
2709 # main.FALSE = action resulted in no change in set
2710 # main.ERROR - Some error in executing the function
2711 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002712 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07002713 if addResponses[ i ] == main.TRUE:
2714 # All is well
2715 pass
2716 elif addResponses[ i ] == main.FALSE:
2717 # Already in set, probably fine
2718 pass
2719 elif addResponses[ i ] == main.ERROR:
2720 # Error in execution
2721 addAllResults = main.FALSE
2722 else:
2723 # unexpected result
2724 addAllResults = main.FALSE
2725 if addAllResults != main.TRUE:
2726 main.log.error( "Error executing set addAll" )
2727
2728 # Check if set is still correct
2729 size = len( onosSet )
2730 getResponses = []
2731 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002732 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002733 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002734 name="setTestGet-" + str( i ),
2735 args=[ onosSetName ] )
2736 threads.append( t )
2737 t.start()
2738 for t in threads:
2739 t.join()
2740 getResponses.append( t.result )
2741 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002742 for i in range( len( main.activeNodes ) ):
2743 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002744 if isinstance( getResponses[ i ], list):
2745 current = set( getResponses[ i ] )
2746 if len( current ) == len( getResponses[ i ] ):
2747 # no repeats
2748 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07002749 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002750 " has incorrect view" +
2751 " of set " + onosSetName + ":\n" +
2752 str( getResponses[ i ] ) )
2753 main.log.debug( "Expected: " + str( onosSet ) )
2754 main.log.debug( "Actual: " + str( current ) )
2755 getResults = main.FALSE
2756 else:
2757 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07002758 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002759 " has repeat elements in" +
2760 " set " + onosSetName + ":\n" +
2761 str( getResponses[ i ] ) )
2762 getResults = main.FALSE
2763 elif getResponses[ i ] == main.ERROR:
2764 getResults = main.FALSE
2765 sizeResponses = []
2766 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002767 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002768 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002769 name="setTestSize-" + str( i ),
2770 args=[ onosSetName ] )
2771 threads.append( t )
2772 t.start()
2773 for t in threads:
2774 t.join()
2775 sizeResponses.append( t.result )
2776 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002777 for i in range( len( main.activeNodes ) ):
2778 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002779 if size != sizeResponses[ i ]:
2780 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002781 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002782 " expected a size of " + str( size ) +
2783 " for set " + onosSetName +
2784 " but got " + str( sizeResponses[ i ] ) )
2785 addAllResults = addAllResults and getResults and sizeResults
2786 utilities.assert_equals( expect=main.TRUE,
2787 actual=addAllResults,
2788 onpass="Set addAll correct",
2789 onfail="Set addAll was incorrect" )
2790
2791 main.step( "Distributed Set contains()" )
2792 containsResponses = []
2793 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002794 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002795 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002796 name="setContains-" + str( i ),
2797 args=[ onosSetName ],
2798 kwargs={ "values": addValue } )
2799 threads.append( t )
2800 t.start()
2801 for t in threads:
2802 t.join()
2803 # NOTE: This is the tuple
2804 containsResponses.append( t.result )
2805
2806 containsResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002807 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07002808 if containsResponses[ i ] == main.ERROR:
2809 containsResults = main.FALSE
2810 else:
2811 containsResults = containsResults and\
2812 containsResponses[ i ][ 1 ]
2813 utilities.assert_equals( expect=main.TRUE,
2814 actual=containsResults,
2815 onpass="Set contains is functional",
2816 onfail="Set contains failed" )
2817
2818 main.step( "Distributed Set containsAll()" )
2819 containsAllResponses = []
2820 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002821 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002822 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002823 name="setContainsAll-" + str( i ),
2824 args=[ onosSetName ],
2825 kwargs={ "values": addAllValue } )
2826 threads.append( t )
2827 t.start()
2828 for t in threads:
2829 t.join()
2830 # NOTE: This is the tuple
2831 containsAllResponses.append( t.result )
2832
2833 containsAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002834 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07002835 if containsResponses[ i ] == main.ERROR:
2836 containsResults = main.FALSE
2837 else:
2838 containsResults = containsResults and\
2839 containsResponses[ i ][ 1 ]
2840 utilities.assert_equals( expect=main.TRUE,
2841 actual=containsAllResults,
2842 onpass="Set containsAll is functional",
2843 onfail="Set containsAll failed" )
2844
2845 main.step( "Distributed Set remove()" )
2846 onosSet.remove( addValue )
2847 removeResponses = []
2848 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002849 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002850 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07002851 name="setTestRemove-" + str( i ),
2852 args=[ onosSetName, addValue ] )
2853 threads.append( t )
2854 t.start()
2855 for t in threads:
2856 t.join()
2857 removeResponses.append( t.result )
2858
2859 # main.TRUE = successfully changed the set
2860 # main.FALSE = action resulted in no change in set
2861 # main.ERROR - Some error in executing the function
2862 removeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002863 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07002864 if removeResponses[ i ] == main.TRUE:
2865 # All is well
2866 pass
2867 elif removeResponses[ i ] == main.FALSE:
2868 # not in set, probably fine
2869 pass
2870 elif removeResponses[ i ] == main.ERROR:
2871 # Error in execution
2872 removeResults = main.FALSE
2873 else:
2874 # unexpected result
2875 removeResults = main.FALSE
2876 if removeResults != main.TRUE:
2877 main.log.error( "Error executing set remove" )
2878
2879 # Check if set is still correct
2880 size = len( onosSet )
2881 getResponses = []
2882 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002883 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002884 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002885 name="setTestGet-" + str( i ),
2886 args=[ onosSetName ] )
2887 threads.append( t )
2888 t.start()
2889 for t in threads:
2890 t.join()
2891 getResponses.append( t.result )
2892 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002893 for i in range( len( main.activeNodes ) ):
2894 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002895 if isinstance( getResponses[ i ], list):
2896 current = set( getResponses[ i ] )
2897 if len( current ) == len( getResponses[ i ] ):
2898 # no repeats
2899 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07002900 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002901 " has incorrect view" +
2902 " of set " + onosSetName + ":\n" +
2903 str( getResponses[ i ] ) )
2904 main.log.debug( "Expected: " + str( onosSet ) )
2905 main.log.debug( "Actual: " + str( current ) )
2906 getResults = main.FALSE
2907 else:
2908 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07002909 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002910 " has repeat elements in" +
2911 " set " + onosSetName + ":\n" +
2912 str( getResponses[ i ] ) )
2913 getResults = main.FALSE
2914 elif getResponses[ i ] == main.ERROR:
2915 getResults = main.FALSE
2916 sizeResponses = []
2917 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002918 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002919 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002920 name="setTestSize-" + str( i ),
2921 args=[ onosSetName ] )
2922 threads.append( t )
2923 t.start()
2924 for t in threads:
2925 t.join()
2926 sizeResponses.append( t.result )
2927 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002928 for i in range( len( main.activeNodes ) ):
2929 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002930 if size != sizeResponses[ i ]:
2931 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002932 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002933 " expected a size of " + str( size ) +
2934 " for set " + onosSetName +
2935 " but got " + str( sizeResponses[ i ] ) )
2936 removeResults = removeResults and getResults and sizeResults
2937 utilities.assert_equals( expect=main.TRUE,
2938 actual=removeResults,
2939 onpass="Set remove correct",
2940 onfail="Set remove was incorrect" )
2941
2942 main.step( "Distributed Set removeAll()" )
2943 onosSet.difference_update( addAllValue.split() )
2944 removeAllResponses = []
2945 threads = []
2946 try:
Jon Halla440e872016-03-31 15:15:50 -07002947 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002948 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07002949 name="setTestRemoveAll-" + str( i ),
2950 args=[ onosSetName, addAllValue ] )
2951 threads.append( t )
2952 t.start()
2953 for t in threads:
2954 t.join()
2955 removeAllResponses.append( t.result )
2956 except Exception, e:
2957 main.log.exception(e)
2958
2959 # main.TRUE = successfully changed the set
2960 # main.FALSE = action resulted in no change in set
2961 # main.ERROR - Some error in executing the function
2962 removeAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002963 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07002964 if removeAllResponses[ i ] == main.TRUE:
2965 # All is well
2966 pass
2967 elif removeAllResponses[ i ] == main.FALSE:
2968 # not in set, probably fine
2969 pass
2970 elif removeAllResponses[ i ] == main.ERROR:
2971 # Error in execution
2972 removeAllResults = main.FALSE
2973 else:
2974 # unexpected result
2975 removeAllResults = main.FALSE
2976 if removeAllResults != main.TRUE:
2977 main.log.error( "Error executing set removeAll" )
2978
2979 # Check if set is still correct
2980 size = len( onosSet )
2981 getResponses = []
2982 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002983 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002984 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002985 name="setTestGet-" + str( i ),
2986 args=[ onosSetName ] )
2987 threads.append( t )
2988 t.start()
2989 for t in threads:
2990 t.join()
2991 getResponses.append( t.result )
2992 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002993 for i in range( len( main.activeNodes ) ):
2994 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002995 if isinstance( getResponses[ i ], list):
2996 current = set( getResponses[ i ] )
2997 if len( current ) == len( getResponses[ i ] ):
2998 # no repeats
2999 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07003000 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003001 " has incorrect view" +
3002 " of set " + onosSetName + ":\n" +
3003 str( getResponses[ i ] ) )
3004 main.log.debug( "Expected: " + str( onosSet ) )
3005 main.log.debug( "Actual: " + str( current ) )
3006 getResults = main.FALSE
3007 else:
3008 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003009 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003010 " has repeat elements in" +
3011 " set " + onosSetName + ":\n" +
3012 str( getResponses[ i ] ) )
3013 getResults = main.FALSE
3014 elif getResponses[ i ] == main.ERROR:
3015 getResults = main.FALSE
3016 sizeResponses = []
3017 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003018 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003019 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003020 name="setTestSize-" + str( i ),
3021 args=[ onosSetName ] )
3022 threads.append( t )
3023 t.start()
3024 for t in threads:
3025 t.join()
3026 sizeResponses.append( t.result )
3027 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003028 for i in range( len( main.activeNodes ) ):
3029 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003030 if size != sizeResponses[ i ]:
3031 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003032 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003033 " expected a size of " + str( size ) +
3034 " for set " + onosSetName +
3035 " but got " + str( sizeResponses[ i ] ) )
3036 removeAllResults = removeAllResults and getResults and sizeResults
3037 utilities.assert_equals( expect=main.TRUE,
3038 actual=removeAllResults,
3039 onpass="Set removeAll correct",
3040 onfail="Set removeAll was incorrect" )
3041
3042 main.step( "Distributed Set addAll()" )
3043 onosSet.update( addAllValue.split() )
3044 addResponses = []
3045 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003046 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003047 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07003048 name="setTestAddAll-" + str( i ),
3049 args=[ onosSetName, addAllValue ] )
3050 threads.append( t )
3051 t.start()
3052 for t in threads:
3053 t.join()
3054 addResponses.append( t.result )
3055
3056 # main.TRUE = successfully changed the set
3057 # main.FALSE = action resulted in no change in set
3058 # main.ERROR - Some error in executing the function
3059 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003060 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07003061 if addResponses[ i ] == main.TRUE:
3062 # All is well
3063 pass
3064 elif addResponses[ i ] == main.FALSE:
3065 # Already in set, probably fine
3066 pass
3067 elif addResponses[ i ] == main.ERROR:
3068 # Error in execution
3069 addAllResults = main.FALSE
3070 else:
3071 # unexpected result
3072 addAllResults = main.FALSE
3073 if addAllResults != main.TRUE:
3074 main.log.error( "Error executing set addAll" )
3075
3076 # Check if set is still correct
3077 size = len( onosSet )
3078 getResponses = []
3079 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003080 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003081 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003082 name="setTestGet-" + str( i ),
3083 args=[ onosSetName ] )
3084 threads.append( t )
3085 t.start()
3086 for t in threads:
3087 t.join()
3088 getResponses.append( t.result )
3089 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003090 for i in range( len( main.activeNodes ) ):
3091 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003092 if isinstance( getResponses[ i ], list):
3093 current = set( getResponses[ i ] )
3094 if len( current ) == len( getResponses[ i ] ):
3095 # no repeats
3096 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07003097 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003098 " has incorrect view" +
3099 " of set " + onosSetName + ":\n" +
3100 str( getResponses[ i ] ) )
3101 main.log.debug( "Expected: " + str( onosSet ) )
3102 main.log.debug( "Actual: " + str( current ) )
3103 getResults = main.FALSE
3104 else:
3105 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003106 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003107 " has repeat elements in" +
3108 " set " + onosSetName + ":\n" +
3109 str( getResponses[ i ] ) )
3110 getResults = main.FALSE
3111 elif getResponses[ i ] == main.ERROR:
3112 getResults = main.FALSE
3113 sizeResponses = []
3114 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003115 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003116 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003117 name="setTestSize-" + str( i ),
3118 args=[ onosSetName ] )
3119 threads.append( t )
3120 t.start()
3121 for t in threads:
3122 t.join()
3123 sizeResponses.append( t.result )
3124 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003125 for i in range( len( main.activeNodes ) ):
3126 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003127 if size != sizeResponses[ i ]:
3128 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003129 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003130 " expected a size of " + str( size ) +
3131 " for set " + onosSetName +
3132 " but got " + str( sizeResponses[ i ] ) )
3133 addAllResults = addAllResults and getResults and sizeResults
3134 utilities.assert_equals( expect=main.TRUE,
3135 actual=addAllResults,
3136 onpass="Set addAll correct",
3137 onfail="Set addAll was incorrect" )
3138
3139 main.step( "Distributed Set clear()" )
3140 onosSet.clear()
3141 clearResponses = []
3142 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003143 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003144 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07003145 name="setTestClear-" + str( i ),
3146 args=[ onosSetName, " "], # Values doesn't matter
3147 kwargs={ "clear": True } )
3148 threads.append( t )
3149 t.start()
3150 for t in threads:
3151 t.join()
3152 clearResponses.append( t.result )
3153
3154 # main.TRUE = successfully changed the set
3155 # main.FALSE = action resulted in no change in set
3156 # main.ERROR - Some error in executing the function
3157 clearResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003158 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07003159 if clearResponses[ i ] == main.TRUE:
3160 # All is well
3161 pass
3162 elif clearResponses[ i ] == main.FALSE:
3163 # Nothing set, probably fine
3164 pass
3165 elif clearResponses[ i ] == main.ERROR:
3166 # Error in execution
3167 clearResults = main.FALSE
3168 else:
3169 # unexpected result
3170 clearResults = main.FALSE
3171 if clearResults != main.TRUE:
3172 main.log.error( "Error executing set clear" )
3173
3174 # Check if set is still correct
3175 size = len( onosSet )
3176 getResponses = []
3177 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003178 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003179 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003180 name="setTestGet-" + str( i ),
3181 args=[ onosSetName ] )
3182 threads.append( t )
3183 t.start()
3184 for t in threads:
3185 t.join()
3186 getResponses.append( t.result )
3187 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003188 for i in range( len( main.activeNodes ) ):
3189 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003190 if isinstance( getResponses[ i ], list):
3191 current = set( getResponses[ i ] )
3192 if len( current ) == len( getResponses[ i ] ):
3193 # no repeats
3194 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07003195 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003196 " has incorrect view" +
3197 " of set " + onosSetName + ":\n" +
3198 str( getResponses[ i ] ) )
3199 main.log.debug( "Expected: " + str( onosSet ) )
3200 main.log.debug( "Actual: " + str( current ) )
3201 getResults = main.FALSE
3202 else:
3203 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003204 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003205 " has repeat elements in" +
3206 " set " + onosSetName + ":\n" +
3207 str( getResponses[ i ] ) )
3208 getResults = main.FALSE
3209 elif getResponses[ i ] == main.ERROR:
3210 getResults = main.FALSE
3211 sizeResponses = []
3212 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003213 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003214 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003215 name="setTestSize-" + str( i ),
3216 args=[ onosSetName ] )
3217 threads.append( t )
3218 t.start()
3219 for t in threads:
3220 t.join()
3221 sizeResponses.append( t.result )
3222 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003223 for i in range( len( main.activeNodes ) ):
3224 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003225 if size != sizeResponses[ i ]:
3226 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003227 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003228 " expected a size of " + str( size ) +
3229 " for set " + onosSetName +
3230 " but got " + str( sizeResponses[ i ] ) )
3231 clearResults = clearResults and getResults and sizeResults
3232 utilities.assert_equals( expect=main.TRUE,
3233 actual=clearResults,
3234 onpass="Set clear correct",
3235 onfail="Set clear was incorrect" )
3236
3237 main.step( "Distributed Set addAll()" )
3238 onosSet.update( addAllValue.split() )
3239 addResponses = []
3240 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003241 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003242 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07003243 name="setTestAddAll-" + str( i ),
3244 args=[ onosSetName, addAllValue ] )
3245 threads.append( t )
3246 t.start()
3247 for t in threads:
3248 t.join()
3249 addResponses.append( t.result )
3250
3251 # main.TRUE = successfully changed the set
3252 # main.FALSE = action resulted in no change in set
3253 # main.ERROR - Some error in executing the function
3254 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003255 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07003256 if addResponses[ i ] == main.TRUE:
3257 # All is well
3258 pass
3259 elif addResponses[ i ] == main.FALSE:
3260 # Already in set, probably fine
3261 pass
3262 elif addResponses[ i ] == main.ERROR:
3263 # Error in execution
3264 addAllResults = main.FALSE
3265 else:
3266 # unexpected result
3267 addAllResults = main.FALSE
3268 if addAllResults != main.TRUE:
3269 main.log.error( "Error executing set addAll" )
3270
3271 # Check if set is still correct
3272 size = len( onosSet )
3273 getResponses = []
3274 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003275 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003276 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003277 name="setTestGet-" + str( i ),
3278 args=[ onosSetName ] )
3279 threads.append( t )
3280 t.start()
3281 for t in threads:
3282 t.join()
3283 getResponses.append( t.result )
3284 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003285 for i in range( len( main.activeNodes ) ):
3286 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003287 if isinstance( getResponses[ i ], list):
3288 current = set( getResponses[ i ] )
3289 if len( current ) == len( getResponses[ i ] ):
3290 # no repeats
3291 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07003292 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003293 " has incorrect view" +
3294 " of set " + onosSetName + ":\n" +
3295 str( getResponses[ i ] ) )
3296 main.log.debug( "Expected: " + str( onosSet ) )
3297 main.log.debug( "Actual: " + str( current ) )
3298 getResults = main.FALSE
3299 else:
3300 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003301 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003302 " has repeat elements in" +
3303 " set " + onosSetName + ":\n" +
3304 str( getResponses[ i ] ) )
3305 getResults = main.FALSE
3306 elif getResponses[ i ] == main.ERROR:
3307 getResults = main.FALSE
3308 sizeResponses = []
3309 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003310 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003311 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003312 name="setTestSize-" + str( i ),
3313 args=[ onosSetName ] )
3314 threads.append( t )
3315 t.start()
3316 for t in threads:
3317 t.join()
3318 sizeResponses.append( t.result )
3319 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003320 for i in range( len( main.activeNodes ) ):
3321 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003322 if size != sizeResponses[ i ]:
3323 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003324 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003325 " expected a size of " + str( size ) +
3326 " for set " + onosSetName +
3327 " but got " + str( sizeResponses[ i ] ) )
3328 addAllResults = addAllResults and getResults and sizeResults
3329 utilities.assert_equals( expect=main.TRUE,
3330 actual=addAllResults,
3331 onpass="Set addAll correct",
3332 onfail="Set addAll was incorrect" )
3333
3334 main.step( "Distributed Set retain()" )
3335 onosSet.intersection_update( retainValue.split() )
3336 retainResponses = []
3337 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003338 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003339 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07003340 name="setTestRetain-" + str( i ),
3341 args=[ onosSetName, retainValue ],
3342 kwargs={ "retain": True } )
3343 threads.append( t )
3344 t.start()
3345 for t in threads:
3346 t.join()
3347 retainResponses.append( t.result )
3348
3349 # main.TRUE = successfully changed the set
3350 # main.FALSE = action resulted in no change in set
3351 # main.ERROR - Some error in executing the function
3352 retainResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003353 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07003354 if retainResponses[ i ] == main.TRUE:
3355 # All is well
3356 pass
3357 elif retainResponses[ i ] == main.FALSE:
3358 # Already in set, probably fine
3359 pass
3360 elif retainResponses[ i ] == main.ERROR:
3361 # Error in execution
3362 retainResults = main.FALSE
3363 else:
3364 # unexpected result
3365 retainResults = main.FALSE
3366 if retainResults != main.TRUE:
3367 main.log.error( "Error executing set retain" )
3368
3369 # Check if set is still correct
3370 size = len( onosSet )
3371 getResponses = []
3372 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003373 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003374 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003375 name="setTestGet-" + str( i ),
3376 args=[ onosSetName ] )
3377 threads.append( t )
3378 t.start()
3379 for t in threads:
3380 t.join()
3381 getResponses.append( t.result )
3382 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003383 for i in range( len( main.activeNodes ) ):
3384 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003385 if isinstance( getResponses[ i ], list):
3386 current = set( getResponses[ i ] )
3387 if len( current ) == len( getResponses[ i ] ):
3388 # no repeats
3389 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07003390 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003391 " has incorrect view" +
3392 " of set " + onosSetName + ":\n" +
3393 str( getResponses[ i ] ) )
3394 main.log.debug( "Expected: " + str( onosSet ) )
3395 main.log.debug( "Actual: " + str( current ) )
3396 getResults = main.FALSE
3397 else:
3398 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003399 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003400 " has repeat elements in" +
3401 " set " + onosSetName + ":\n" +
3402 str( getResponses[ i ] ) )
3403 getResults = main.FALSE
3404 elif getResponses[ i ] == main.ERROR:
3405 getResults = main.FALSE
3406 sizeResponses = []
3407 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003408 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003409 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003410 name="setTestSize-" + str( i ),
3411 args=[ onosSetName ] )
3412 threads.append( t )
3413 t.start()
3414 for t in threads:
3415 t.join()
3416 sizeResponses.append( t.result )
3417 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003418 for i in range( len( main.activeNodes ) ):
3419 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003420 if size != sizeResponses[ i ]:
3421 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003422 main.log.error( "ONOS" + node + " expected a size of " +
Jon Hall85794ff2015-07-08 14:12:30 -07003423 str( size ) + " for set " + onosSetName +
3424 " but got " + str( sizeResponses[ i ] ) )
3425 retainResults = retainResults and getResults and sizeResults
3426 utilities.assert_equals( expect=main.TRUE,
3427 actual=retainResults,
3428 onpass="Set retain correct",
3429 onfail="Set retain was incorrect" )
3430
Jon Hall2a5002c2015-08-21 16:49:11 -07003431 # Transactional maps
3432 main.step( "Partitioned Transactional maps put" )
3433 tMapValue = "Testing"
3434 numKeys = 100
3435 putResult = True
Jon Halla440e872016-03-31 15:15:50 -07003436 node = main.activeNodes[0]
3437 putResponses = main.CLIs[node].transactionalMapPut( numKeys, tMapValue )
3438 if putResponses and len( putResponses ) == 100:
Jon Hall2a5002c2015-08-21 16:49:11 -07003439 for i in putResponses:
3440 if putResponses[ i ][ 'value' ] != tMapValue:
3441 putResult = False
3442 else:
3443 putResult = False
3444 if not putResult:
3445 main.log.debug( "Put response values: " + str( putResponses ) )
3446 utilities.assert_equals( expect=True,
3447 actual=putResult,
3448 onpass="Partitioned Transactional Map put successful",
3449 onfail="Partitioned Transactional Map put values are incorrect" )
3450
3451 main.step( "Partitioned Transactional maps get" )
3452 getCheck = True
3453 for n in range( 1, numKeys + 1 ):
3454 getResponses = []
3455 threads = []
3456 valueCheck = True
Jon Halla440e872016-03-31 15:15:50 -07003457 for i in main.activeNodes:
Jon Hall2a5002c2015-08-21 16:49:11 -07003458 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
3459 name="TMap-get-" + str( i ),
Jon Halla440e872016-03-31 15:15:50 -07003460 args=[ "Key" + str( n ) ] )
Jon Hall2a5002c2015-08-21 16:49:11 -07003461 threads.append( t )
3462 t.start()
3463 for t in threads:
3464 t.join()
3465 getResponses.append( t.result )
3466 for node in getResponses:
3467 if node != tMapValue:
3468 valueCheck = False
3469 if not valueCheck:
3470 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
3471 main.log.warn( getResponses )
3472 getCheck = getCheck and valueCheck
3473 utilities.assert_equals( expect=True,
3474 actual=getCheck,
3475 onpass="Partitioned Transactional Map get values were correct",
3476 onfail="Partitioned Transactional Map values incorrect" )