blob: 44b402f4108ddc040232a281280ef6d5535e48ab [file] [log] [blame]
Jon Hall85794ff2015-07-08 14:12:30 -07001"""
2Description: This test is to determine if a single
3 instance ONOS 'cluster' can handle a restart
4
5List of test cases:
6CASE1: Compile ONOS and push it to the test machines
7CASE2: Assign devices to controllers
8CASE21: Assign mastership to controllers
9CASE3: Assign intents
10CASE4: Ping across added host intents
11CASE5: Reading state of ONOS
12CASE6: The Failure case.
13CASE7: Check state after control plane failure
14CASE8: Compare topo
15CASE9: Link s3-s28 down
16CASE10: Link s3-s28 up
17CASE11: Switch down
18CASE12: Switch up
19CASE13: Clean up
20CASE14: start election app on all onos nodes
21CASE15: Check that Leadership Election is still functional
22CASE16: Install Distributed Primitives app
23CASE17: Check for basic functionality with distributed primitives
24"""
25
26
27class HAsingleInstanceRestart:
28
29 def __init__( self ):
30 self.default = ''
31
32 def CASE1( self, main ):
33 """
34 CASE1 is to compile ONOS and push it to the test machines
35
36 Startup sequence:
37 cell <name>
38 onos-verify-cell
39 NOTE: temporary - onos-remove-raft-logs
40 onos-uninstall
41 start mininet
42 git pull
43 mvn clean install
44 onos-package
45 onos-install -f
46 onos-wait-for-start
47 start cli sessions
48 start tcpdump
49 """
Jon Halle1a3b752015-07-22 13:02:46 -070050 import imp
Jon Hallf3d16e72015-12-16 17:45:08 -080051 import time
Jon Halla440e872016-03-31 15:15:50 -070052 import json
Jon Hall85794ff2015-07-08 14:12:30 -070053 main.log.info( "ONOS Single node cluster restart " +
54 "HA test - initialization" )
55 main.case( "Setting up test environment" )
Jon Hall783bbf92015-07-23 14:33:19 -070056 main.caseExplanation = "Setup the test environment including " +\
Jon Hall85794ff2015-07-08 14:12:30 -070057 "installing ONOS, starting Mininet and ONOS" +\
58 "cli sessions."
Jon Hall85794ff2015-07-08 14:12:30 -070059
60 # load some variables from the params file
61 PULLCODE = False
62 if main.params[ 'Git' ] == 'True':
63 PULLCODE = True
64 gitBranch = main.params[ 'branch' ]
65 cellName = main.params[ 'ENV' ][ 'cellName' ]
66
Jon Halle1a3b752015-07-22 13:02:46 -070067 main.numCtrls = int( main.params[ 'num_controllers' ] )
Jon Hall5cf14d52015-07-16 12:15:19 -070068 if main.ONOSbench.maxNodes:
Jon Halle1a3b752015-07-22 13:02:46 -070069 if main.ONOSbench.maxNodes < main.numCtrls:
70 main.numCtrls = int( main.ONOSbench.maxNodes )
Jon Hall85794ff2015-07-08 14:12:30 -070071
Jon Halle1a3b752015-07-22 13:02:46 -070072 try:
Jon Halla440e872016-03-31 15:15:50 -070073 from tests.HAsanity.dependencies.Counters import Counters
74 main.Counters = Counters()
Jon Halle1a3b752015-07-22 13:02:46 -070075 except Exception as e:
76 main.log.exception( e )
77 main.cleanup()
78 main.exit()
79
80 main.CLIs = []
81 main.nodes = []
Jon Hall5cf14d52015-07-16 12:15:19 -070082 ipList = []
83 for i in range( 1, int( main.ONOSbench.maxNodes ) + 1 ):
84 try:
Jon Halle1a3b752015-07-22 13:02:46 -070085 main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
86 main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
87 ipList.append( main.nodes[ -1 ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -070088 except AttributeError:
89 break
Jon Hall85794ff2015-07-08 14:12:30 -070090
Jon Hall5cf14d52015-07-16 12:15:19 -070091 main.step( "Create cell file" )
92 cellAppString = main.params[ 'ENV' ][ 'appString' ]
93 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
94 main.Mininet1.ip_address,
95 cellAppString, ipList )
Jon Hall85794ff2015-07-08 14:12:30 -070096 main.step( "Applying cell variable to environment" )
97 cellResult = main.ONOSbench.setCell( cellName )
98 verifyResult = main.ONOSbench.verifyCell()
99
100 # FIXME:this is short term fix
101 main.log.info( "Removing raft logs" )
102 main.ONOSbench.onosRemoveRaftLogs()
103
104 main.log.info( "Uninstalling ONOS" )
Jon Halle1a3b752015-07-22 13:02:46 -0700105 for node in main.nodes:
Jon Hall85794ff2015-07-08 14:12:30 -0700106 main.ONOSbench.onosUninstall( node.ip_address )
107
108 # Make sure ONOS is DEAD
109 main.log.info( "Killing any ONOS processes" )
110 killResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700111 for node in main.nodes:
Jon Hall85794ff2015-07-08 14:12:30 -0700112 killed = main.ONOSbench.onosKill( node.ip_address )
113 killResults = killResults and killed
114
115 cleanInstallResult = main.TRUE
116 gitPullResult = main.TRUE
117
118 main.step( "Starting Mininet" )
119 # scp topo file to mininet
120 # TODO: move to params?
121 topoName = "obelisk.py"
122 filePath = main.ONOSbench.home + "/tools/test/topos/"
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700123 main.ONOSbench.scp( main.Mininet1,
124 filePath + topoName,
125 main.Mininet1.home,
126 direction="to" )
Jon Hall85794ff2015-07-08 14:12:30 -0700127 mnResult = main.Mininet1.startNet( )
128 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
129 onpass="Mininet Started",
130 onfail="Error starting Mininet" )
131
132 main.step( "Git checkout and pull " + gitBranch )
133 if PULLCODE:
134 main.ONOSbench.gitCheckout( gitBranch )
135 gitPullResult = main.ONOSbench.gitPull()
136 # values of 1 or 3 are good
137 utilities.assert_lesser( expect=0, actual=gitPullResult,
138 onpass="Git pull successful",
139 onfail="Git pull failed" )
140 main.ONOSbench.getVersion( report=True )
141
142 main.step( "Using mvn clean install" )
143 cleanInstallResult = main.TRUE
144 if PULLCODE and gitPullResult == main.TRUE:
145 cleanInstallResult = main.ONOSbench.cleanInstall()
146 else:
147 main.log.warn( "Did not pull new code so skipping mvn " +
148 "clean install" )
149 utilities.assert_equals( expect=main.TRUE,
150 actual=cleanInstallResult,
151 onpass="MCI successful",
152 onfail="MCI failed" )
153 # GRAPHS
154 # NOTE: important params here:
155 # job = name of Jenkins job
156 # Plot Name = Plot-HA, only can be used if multiple plots
157 # index = The number of the graph under plot name
Jon Hall5cf14d52015-07-16 12:15:19 -0700158 job = "HAsingleInstanceRestart"
Jon Hall85794ff2015-07-08 14:12:30 -0700159 plotName = "Plot-HA"
Jon Hall843f8bc2016-03-18 14:28:13 -0700160 index = "2"
Jon Hall85794ff2015-07-08 14:12:30 -0700161 graphs = '<ac:structured-macro ac:name="html">\n'
162 graphs += '<ac:plain-text-body><![CDATA[\n'
163 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
Jon Halla9845df2016-01-15 14:55:58 -0800164 '/plot/' + plotName + '/getPlot?index=' + index +\
Jon Hall85794ff2015-07-08 14:12:30 -0700165 '&width=500&height=300"' +\
166 'noborder="0" width="500" height="300" scrolling="yes" ' +\
167 'seamless="seamless"></iframe>\n'
168 graphs += ']]></ac:plain-text-body>\n'
169 graphs += '</ac:structured-macro>\n'
170 main.log.wiki(graphs)
171
Jon Halle1a3b752015-07-22 13:02:46 -0700172 main.CLIs = []
173 main.nodes = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700174 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700175 for i in range( 1, main.numCtrls + 1 ):
176 main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
177 main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
178 ipList.append( main.nodes[ -1 ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -0700179
180 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, "SingleHA",
181 main.Mininet1.ip_address,
182 cellAppString, ipList[ 0 ] )
Jon Hall85794ff2015-07-08 14:12:30 -0700183 cellResult = main.ONOSbench.setCell( "SingleHA" )
184 verifyResult = main.ONOSbench.verifyCell()
185 main.step( "Creating ONOS package" )
186 packageResult = main.ONOSbench.onosPackage()
187 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
188 onpass="ONOS package successful",
189 onfail="ONOS package failed" )
190
191 main.step( "Installing ONOS package" )
Jon Halla440e872016-03-31 15:15:50 -0700192 onosInstallResult = main.TRUE
193 for node in main.nodes:
194 tmpResult = main.ONOSbench.onosInstall( options="-f",
195 node=node.ip_address )
196 onosInstallResult = onosInstallResult and tmpResult
Jon Hall85794ff2015-07-08 14:12:30 -0700197 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
198 onpass="ONOS install successful",
199 onfail="ONOS install failed" )
200
201 main.step( "Checking if ONOS is up yet" )
202 for i in range( 2 ):
Jon Halla440e872016-03-31 15:15:50 -0700203 onosIsupResult = main.TRUE
204 for node in main.nodes:
205 started = main.ONOSbench.isup( node.ip_address )
206 if not started:
207 main.log.error( node.name + " hasn't started" )
208 onosIsupResult = onosIsupResult and started
209 if onosIsupResult == main.TRUE:
Jon Hall85794ff2015-07-08 14:12:30 -0700210 break
Jon Halla440e872016-03-31 15:15:50 -0700211 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
Jon Hall85794ff2015-07-08 14:12:30 -0700212 onpass="ONOS startup successful",
213 onfail="ONOS startup failed" )
214
215 main.log.step( "Starting ONOS CLI sessions" )
Jon Halla440e872016-03-31 15:15:50 -0700216 cliResults = main.TRUE
217 threads = []
218 for i in range( main.numCtrls ):
219 t = main.Thread( target=main.CLIs[i].startOnosCli,
220 name="startOnosCli-" + str( i ),
221 args=[main.nodes[i].ip_address] )
222 threads.append( t )
223 t.start()
224
225 for t in threads:
226 t.join()
227 cliResults = cliResults and t.result
Jon Hall85794ff2015-07-08 14:12:30 -0700228 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
229 onpass="ONOS cli startup successful",
230 onfail="ONOS cli startup failed" )
231
Jon Halla440e872016-03-31 15:15:50 -0700232 # Create a list of active nodes for use when some nodes are stopped
233 main.activeNodes = [ i for i in range( 0, len( main.CLIs ) ) ]
234
Jon Hall85794ff2015-07-08 14:12:30 -0700235 if main.params[ 'tcpdump' ].lower() == "true":
236 main.step( "Start Packet Capture MN" )
237 main.Mininet2.startTcpdump(
238 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
239 + "-MN.pcap",
240 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
241 port=main.params[ 'MNtcpdump' ][ 'port' ] )
242
243 main.step( "App Ids check" )
Jon Halla440e872016-03-31 15:15:50 -0700244 appCheck = main.TRUE
245 threads = []
246 for i in main.activeNodes:
247 t = main.Thread( target=main.CLIs[i].appToIDCheck,
248 name="appToIDCheck-" + str( i ),
249 args=[] )
250 threads.append( t )
251 t.start()
252
253 for t in threads:
254 t.join()
255 appCheck = appCheck and t.result
Jon Hall85794ff2015-07-08 14:12:30 -0700256 if appCheck != main.TRUE:
Jon Halla440e872016-03-31 15:15:50 -0700257 node = main.activeNodes[0]
258 main.log.warn( main.CLIs[node].apps() )
259 main.log.warn( main.CLIs[node].appIDs() )
Jon Hall85794ff2015-07-08 14:12:30 -0700260 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
261 onpass="App Ids seem to be correct",
262 onfail="Something is wrong with app Ids" )
263
Jon Halla440e872016-03-31 15:15:50 -0700264 main.step( "Checking ONOS nodes" )
265 nodesOutput = []
266 nodeResults = main.TRUE
267 threads = []
268 for i in main.activeNodes:
269 t = main.Thread( target=main.CLIs[i].nodes,
270 name="nodes-" + str( i ),
271 args=[ ] )
272 threads.append( t )
273 t.start()
274
275 for t in threads:
276 t.join()
277 nodesOutput.append( t.result )
278 ips = [ main.nodes[node].ip_address for node in main.activeNodes ]
279 ips.sort()
280 for i in nodesOutput:
281 try:
282 current = json.loads( i )
283 activeIps = []
284 currentResult = main.FALSE
285 for node in current:
286 if node['state'] == 'READY':
287 activeIps.append( node['ip'] )
288 activeIps.sort()
289 if ips == activeIps:
290 currentResult = main.TRUE
291 except ( ValueError, TypeError ):
292 main.log.error( "Error parsing nodes output" )
293 main.log.warn( repr( i ) )
294 currentResult = main.FALSE
295 nodeResults = nodeResults and currentResult
296 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
297 onpass="Nodes check successful",
298 onfail="Nodes check NOT successful" )
299
300 if not nodeResults:
301 for cli in main.CLIs:
302 main.log.debug( "{} components not ACTIVE: \n{}".format(
303 cli.name,
304 cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
305
Jon Hall85794ff2015-07-08 14:12:30 -0700306 if cliResults == main.FALSE:
307 main.log.error( "Failed to start ONOS, stopping test" )
308 main.cleanup()
309 main.exit()
310
311 def CASE2( self, main ):
312 """
313 Assign devices to controllers
314 """
315 import re
Jon Halle1a3b752015-07-22 13:02:46 -0700316 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700317 assert main, "main not defined"
318 assert utilities.assert_equals, "utilities.assert_equals not defined"
319
320 main.case( "Assigning devices to controllers" )
Jon Hall783bbf92015-07-23 14:33:19 -0700321 main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700322 "and check that an ONOS node becomes the " +\
323 "master of the device."
324 main.step( "Assign switches to controllers" )
325
326 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700327 for i in range( main.numCtrls ):
328 ipList.append( main.nodes[ i ].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -0700329 swList = []
330 for i in range( 1, 29 ):
331 swList.append( "s" + str( i ) )
332 main.Mininet1.assignSwController( sw=swList, ip=ipList )
333
334 mastershipCheck = main.TRUE
335 for i in range( 1, 29 ):
336 response = main.Mininet1.getSwController( "s" + str( i ) )
337 try:
338 main.log.info( str( response ) )
339 except Exception:
340 main.log.info( repr( response ) )
Jon Halla440e872016-03-31 15:15:50 -0700341 for node in main.nodes:
342 if re.search( "tcp:" + node.ip_address, response ):
343 mastershipCheck = mastershipCheck and main.TRUE
344 else:
345 main.log.error( "Error, node " + node.ip_address + " is " +
346 "not in the list of controllers s" +
347 str( i ) + " is connecting to." )
348 mastershipCheck = main.FALSE
Jon Hall85794ff2015-07-08 14:12:30 -0700349 utilities.assert_equals(
350 expect=main.TRUE,
351 actual=mastershipCheck,
352 onpass="Switch mastership assigned correctly",
353 onfail="Switches not assigned correctly to controllers" )
354
355 def CASE21( self, main ):
356 """
357 Assign mastership to controllers
358 """
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"
Jon Halle1a3b752015-07-22 13:02:46 -0700362 assert main.CLIs, "main.CLIs not defined"
363 assert main.nodes, "main.nodes not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700364
365 main.case( "Assigning Controller roles for switches" )
Jon Hall783bbf92015-07-23 14:33:19 -0700366 main.caseExplanation = "Check that ONOS is connected to each " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700367 "device. Then manually assign" +\
368 " mastership to specific ONOS nodes using" +\
369 " 'device-role'"
370 main.step( "Assign mastership of switches to specific controllers" )
Jon Halla440e872016-03-31 15:15:50 -0700371 # Manually assign mastership to the controller we want
Jon Hall85794ff2015-07-08 14:12:30 -0700372 roleCall = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -0700373
374 ipList = [ ]
375 deviceList = []
376 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall85794ff2015-07-08 14:12:30 -0700377 try:
Jon Halla440e872016-03-31 15:15:50 -0700378 # Assign mastership to specific controllers. This assignment was
379 # determined for a 7 node cluser, but will work with any sized
380 # cluster
Jon Hall85794ff2015-07-08 14:12:30 -0700381 for i in range( 1, 29 ): # switches 1 through 28
Jon Hall85794ff2015-07-08 14:12:30 -0700382 # set up correct variables:
383 if i == 1:
Jon Halla440e872016-03-31 15:15:50 -0700384 c = 0
385 ip = main.nodes[ c ].ip_address # ONOS1
386 deviceId = onosCli.getDevice( "1000" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700387 elif i == 2:
Jon Halla440e872016-03-31 15:15:50 -0700388 c = 1 % main.numCtrls
389 ip = main.nodes[ c ].ip_address # ONOS2
390 deviceId = onosCli.getDevice( "2000" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700391 elif i == 3:
Jon Halla440e872016-03-31 15:15:50 -0700392 c = 1 % main.numCtrls
393 ip = main.nodes[ c ].ip_address # ONOS2
394 deviceId = onosCli.getDevice( "3000" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700395 elif i == 4:
Jon Halla440e872016-03-31 15:15:50 -0700396 c = 3 % main.numCtrls
397 ip = main.nodes[ c ].ip_address # ONOS4
398 deviceId = onosCli.getDevice( "3004" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700399 elif i == 5:
Jon Halla440e872016-03-31 15:15:50 -0700400 c = 2 % main.numCtrls
401 ip = main.nodes[ c ].ip_address # ONOS3
402 deviceId = onosCli.getDevice( "5000" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700403 elif i == 6:
Jon Halla440e872016-03-31 15:15:50 -0700404 c = 2 % main.numCtrls
405 ip = main.nodes[ c ].ip_address # ONOS3
406 deviceId = onosCli.getDevice( "6000" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700407 elif i == 7:
Jon Halla440e872016-03-31 15:15:50 -0700408 c = 5 % main.numCtrls
409 ip = main.nodes[ c ].ip_address # ONOS6
410 deviceId = onosCli.getDevice( "6007" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700411 elif i >= 8 and i <= 17:
Jon Halla440e872016-03-31 15:15:50 -0700412 c = 4 % main.numCtrls
413 ip = main.nodes[ c ].ip_address # ONOS5
Jon Hall85794ff2015-07-08 14:12:30 -0700414 dpid = '3' + str( i ).zfill( 3 )
Jon Halla440e872016-03-31 15:15:50 -0700415 deviceId = onosCli.getDevice( dpid ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700416 elif i >= 18 and i <= 27:
Jon Halla440e872016-03-31 15:15:50 -0700417 c = 6 % main.numCtrls
418 ip = main.nodes[ c ].ip_address # ONOS7
Jon Hall85794ff2015-07-08 14:12:30 -0700419 dpid = '6' + str( i ).zfill( 3 )
Jon Halla440e872016-03-31 15:15:50 -0700420 deviceId = onosCli.getDevice( dpid ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700421 elif i == 28:
Jon Halla440e872016-03-31 15:15:50 -0700422 c = 0
423 ip = main.nodes[ c ].ip_address # ONOS1
424 deviceId = onosCli.getDevice( "2800" ).get( 'id' )
Jon Hall85794ff2015-07-08 14:12:30 -0700425 else:
426 main.log.error( "You didn't write an else statement for " +
427 "switch s" + str( i ) )
Jon Halla440e872016-03-31 15:15:50 -0700428 roleCall = main.FALSE
Jon Hall85794ff2015-07-08 14:12:30 -0700429 # Assign switch
430 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
431 # TODO: make this controller dynamic
Jon Halla440e872016-03-31 15:15:50 -0700432 roleCall = roleCall and onosCli.deviceRole( deviceId, ip )
433 ipList.append( ip )
434 deviceList.append( deviceId )
Jon Hall85794ff2015-07-08 14:12:30 -0700435 except ( AttributeError, AssertionError ):
436 main.log.exception( "Something is wrong with ONOS device view" )
Jon Halla440e872016-03-31 15:15:50 -0700437 main.log.info( onosCli.devices() )
Jon Hall85794ff2015-07-08 14:12:30 -0700438 utilities.assert_equals(
439 expect=main.TRUE,
440 actual=roleCall,
441 onpass="Re-assigned switch mastership to designated controller",
442 onfail="Something wrong with deviceRole calls" )
443
444 main.step( "Check mastership was correctly assigned" )
Jon Halla440e872016-03-31 15:15:50 -0700445 roleCheck = main.TRUE
446 # NOTE: This is due to the fact that device mastership change is not
447 # atomic and is actually a multi step process
448 time.sleep( 5 )
449 for i in range( len( ipList ) ):
450 ip = ipList[i]
451 deviceId = deviceList[i]
452 # Check assignment
453 master = onosCli.getRole( deviceId ).get( 'master' )
454 if ip in master:
455 roleCheck = roleCheck and main.TRUE
456 else:
457 roleCheck = roleCheck and main.FALSE
458 main.log.error( "Error, controller " + ip + " is not" +
459 " master " + "of device " +
460 str( deviceId ) + ". Master is " +
461 repr( master ) + "." )
Jon Hall85794ff2015-07-08 14:12:30 -0700462 utilities.assert_equals(
463 expect=main.TRUE,
464 actual=roleCheck,
465 onpass="Switches were successfully reassigned to designated " +
466 "controller",
467 onfail="Switches were not successfully reassigned" )
468
469 def CASE3( self, main ):
470 """
471 Assign intents
472 """
473 import time
474 import json
Jon Halle1a3b752015-07-22 13:02:46 -0700475 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700476 assert main, "main not defined"
477 assert utilities.assert_equals, "utilities.assert_equals not defined"
478 # NOTE: we must reinstall intents until we have a persistant intent
479 # datastore!
480 main.case( "Adding host Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700481 main.caseExplanation = "Discover hosts by using pingall then " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700482 "assign predetermined host-to-host intents." +\
483 " After installation, check that the intent" +\
484 " is distributed to all nodes and the state" +\
485 " is INSTALLED"
486
487 # install onos-app-fwd
488 main.step( "Install reactive forwarding app" )
Jon Halla440e872016-03-31 15:15:50 -0700489 onosCli = main.CLIs[ main.activeNodes[0] ]
490 installResults = onosCli.activateApp( "org.onosproject.fwd" )
Jon Hall85794ff2015-07-08 14:12:30 -0700491 utilities.assert_equals( expect=main.TRUE, actual=installResults,
492 onpass="Install fwd successful",
493 onfail="Install fwd failed" )
494
495 main.step( "Check app ids" )
Jon Halla440e872016-03-31 15:15:50 -0700496 appCheck = main.TRUE
497 threads = []
498 for i in main.activeNodes:
499 t = main.Thread( target=main.CLIs[i].appToIDCheck,
500 name="appToIDCheck-" + str( i ),
501 args=[] )
502 threads.append( t )
503 t.start()
504
505 for t in threads:
506 t.join()
507 appCheck = appCheck and t.result
Jon Hall85794ff2015-07-08 14:12:30 -0700508 if appCheck != main.TRUE:
Jon Halla440e872016-03-31 15:15:50 -0700509 main.log.warn( onosCli.apps() )
510 main.log.warn( onosCli.appIDs() )
Jon Hall85794ff2015-07-08 14:12:30 -0700511 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
512 onpass="App Ids seem to be correct",
513 onfail="Something is wrong with app Ids" )
514
515 main.step( "Discovering Hosts( Via pingall for now )" )
516 # FIXME: Once we have a host discovery mechanism, use that instead
517 # REACTIVE FWD test
518 pingResult = main.FALSE
Jon Hall96091e62015-09-21 17:34:17 -0700519 passMsg = "Reactive Pingall test passed"
520 time1 = time.time()
521 pingResult = main.Mininet1.pingall()
522 time2 = time.time()
523 if not pingResult:
524 main.log.warn("First pingall failed. Trying again...")
Jon Hall85794ff2015-07-08 14:12:30 -0700525 pingResult = main.Mininet1.pingall()
Jon Hall96091e62015-09-21 17:34:17 -0700526 passMsg += " on the second try"
527 utilities.assert_equals(
528 expect=main.TRUE,
529 actual=pingResult,
530 onpass= passMsg,
531 onfail="Reactive Pingall failed, " +
532 "one or more ping pairs failed" )
533 main.log.info( "Time for pingall: %2f seconds" %
534 ( time2 - time1 ) )
Jon Hall85794ff2015-07-08 14:12:30 -0700535 # timeout for fwd flows
536 time.sleep( 11 )
537 # uninstall onos-app-fwd
538 main.step( "Uninstall reactive forwarding app" )
Jon Halla440e872016-03-31 15:15:50 -0700539 node = main.activeNodes[0]
540 uninstallResult = main.CLIs[node].deactivateApp( "org.onosproject.fwd" )
Jon Hall85794ff2015-07-08 14:12:30 -0700541 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
542 onpass="Uninstall fwd successful",
543 onfail="Uninstall fwd failed" )
544
545 main.step( "Check app ids" )
Jon Halla440e872016-03-31 15:15:50 -0700546 threads = []
547 appCheck2 = main.TRUE
548 for i in main.activeNodes:
549 t = main.Thread( target=main.CLIs[i].appToIDCheck,
550 name="appToIDCheck-" + str( i ),
551 args=[] )
552 threads.append( t )
553 t.start()
554
555 for t in threads:
556 t.join()
557 appCheck2 = appCheck2 and t.result
Jon Hall85794ff2015-07-08 14:12:30 -0700558 if appCheck2 != main.TRUE:
Jon Halla440e872016-03-31 15:15:50 -0700559 node = main.activeNodes[0]
560 main.log.warn( main.CLIs[node].apps() )
561 main.log.warn( main.CLIs[node].appIDs() )
Jon Hall85794ff2015-07-08 14:12:30 -0700562 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
563 onpass="App Ids seem to be correct",
564 onfail="Something is wrong with app Ids" )
565
566 main.step( "Add host intents via cli" )
567 intentIds = []
Jon Halla440e872016-03-31 15:15:50 -0700568 # TODO: move the host numbers to params
569 # Maybe look at all the paths we ping?
Jon Hall85794ff2015-07-08 14:12:30 -0700570 intentAddResult = True
571 hostResult = main.TRUE
572 for i in range( 8, 18 ):
573 main.log.info( "Adding host intent between h" + str( i ) +
574 " and h" + str( i + 10 ) )
575 host1 = "00:00:00:00:00:" + \
576 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
577 host2 = "00:00:00:00:00:" + \
578 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
579 # NOTE: getHost can return None
Jon Halla440e872016-03-31 15:15:50 -0700580 host1Dict = onosCli.getHost( host1 )
581 host2Dict = onosCli.getHost( host2 )
Jon Hall85794ff2015-07-08 14:12:30 -0700582 host1Id = None
583 host2Id = None
584 if host1Dict and host2Dict:
585 host1Id = host1Dict.get( 'id', None )
586 host2Id = host2Dict.get( 'id', None )
587 if host1Id and host2Id:
Jon Halla440e872016-03-31 15:15:50 -0700588 nodeNum = ( i % len( main.activeNodes ) )
589 node = main.activeNodes[nodeNum]
590 tmpId = main.CLIs[node].addHostIntent( host1Id, host2Id )
Jon Hall85794ff2015-07-08 14:12:30 -0700591 if tmpId:
592 main.log.info( "Added intent with id: " + tmpId )
593 intentIds.append( tmpId )
594 else:
595 main.log.error( "addHostIntent returned: " +
596 repr( tmpId ) )
597 else:
598 main.log.error( "Error, getHost() failed for h" + str( i ) +
599 " and/or h" + str( i + 10 ) )
Jon Halla440e872016-03-31 15:15:50 -0700600 node = main.activeNodes[0]
601 hosts = main.CLIs[node].hosts()
Jon Hall85794ff2015-07-08 14:12:30 -0700602 main.log.warn( "Hosts output: " )
603 try:
604 main.log.warn( json.dumps( json.loads( hosts ),
605 sort_keys=True,
606 indent=4,
607 separators=( ',', ': ' ) ) )
608 except ( ValueError, TypeError ):
609 main.log.warn( repr( hosts ) )
610 hostResult = main.FALSE
611 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
612 onpass="Found a host id for each host",
613 onfail="Error looking up host ids" )
614
615 intentStart = time.time()
Jon Halla440e872016-03-31 15:15:50 -0700616 onosIds = onosCli.getAllIntentsId()
Jon Hall85794ff2015-07-08 14:12:30 -0700617 main.log.info( "Submitted intents: " + str( intentIds ) )
618 main.log.info( "Intents in ONOS: " + str( onosIds ) )
619 for intent in intentIds:
620 if intent in onosIds:
621 pass # intent submitted is in onos
622 else:
623 intentAddResult = False
624 if intentAddResult:
625 intentStop = time.time()
626 else:
627 intentStop = None
628 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -0700629 intents = onosCli.intents()
Jon Hall85794ff2015-07-08 14:12:30 -0700630 intentStates = []
631 installedCheck = True
632 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
633 count = 0
634 try:
635 for intent in json.loads( intents ):
636 state = intent.get( 'state', None )
637 if "INSTALLED" not in state:
638 installedCheck = False
639 intentId = intent.get( 'id', None )
640 intentStates.append( ( intentId, state ) )
641 except ( ValueError, TypeError ):
642 main.log.exception( "Error parsing intents" )
643 # add submitted intents not in the store
644 tmplist = [ i for i, s in intentStates ]
645 missingIntents = False
646 for i in intentIds:
647 if i not in tmplist:
648 intentStates.append( ( i, " - " ) )
649 missingIntents = True
650 intentStates.sort()
651 for i, s in intentStates:
652 count += 1
653 main.log.info( "%-6s%-15s%-15s" %
654 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -0700655 leaders = onosCli.leaders()
Jon Hall85794ff2015-07-08 14:12:30 -0700656 try:
657 missing = False
658 if leaders:
659 parsedLeaders = json.loads( leaders )
660 main.log.warn( json.dumps( parsedLeaders,
661 sort_keys=True,
662 indent=4,
663 separators=( ',', ': ' ) ) )
664 # check for all intent partitions
665 topics = []
666 for i in range( 14 ):
667 topics.append( "intent-partition-" + str( i ) )
668 main.log.debug( topics )
669 ONOStopics = [ j['topic'] for j in parsedLeaders ]
670 for topic in topics:
671 if topic not in ONOStopics:
672 main.log.error( "Error: " + topic +
673 " not in leaders" )
674 missing = True
675 else:
676 main.log.error( "leaders() returned None" )
677 except ( ValueError, TypeError ):
678 main.log.exception( "Error parsing leaders" )
679 main.log.error( repr( leaders ) )
680 # Check all nodes
681 if missing:
Jon Halla440e872016-03-31 15:15:50 -0700682 for i in main.activeNodes:
683 response = main.CLIs[i].leaders( jsonFormat=False)
684 main.log.warn( str( main.CLIs[i].name ) + " leaders output: \n" +
685 str( response ) )
Jon Hall85794ff2015-07-08 14:12:30 -0700686
Jon Halla440e872016-03-31 15:15:50 -0700687 partitions = onosCli.partitions()
Jon Hall85794ff2015-07-08 14:12:30 -0700688 try:
689 if partitions :
690 parsedPartitions = json.loads( partitions )
691 main.log.warn( json.dumps( parsedPartitions,
692 sort_keys=True,
693 indent=4,
694 separators=( ',', ': ' ) ) )
695 # TODO check for a leader in all paritions
696 # TODO check for consistency among nodes
697 else:
698 main.log.error( "partitions() returned None" )
699 except ( ValueError, TypeError ):
700 main.log.exception( "Error parsing partitions" )
701 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -0700702 pendingMap = onosCli.pendingMap()
Jon Hall85794ff2015-07-08 14:12:30 -0700703 try:
704 if pendingMap :
705 parsedPending = json.loads( pendingMap )
706 main.log.warn( json.dumps( parsedPending,
707 sort_keys=True,
708 indent=4,
709 separators=( ',', ': ' ) ) )
710 # TODO check something here?
711 else:
712 main.log.error( "pendingMap() returned None" )
713 except ( ValueError, TypeError ):
714 main.log.exception( "Error parsing pending map" )
715 main.log.error( repr( pendingMap ) )
716
717 intentAddResult = bool( intentAddResult and not missingIntents and
718 installedCheck )
719 if not intentAddResult:
720 main.log.error( "Error in pushing host intents to ONOS" )
721
722 main.step( "Intent Anti-Entropy dispersion" )
Jon Halla440e872016-03-31 15:15:50 -0700723 for j in range(100):
Jon Hall85794ff2015-07-08 14:12:30 -0700724 correct = True
725 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Halla440e872016-03-31 15:15:50 -0700726 for i in main.activeNodes:
Jon Hall85794ff2015-07-08 14:12:30 -0700727 onosIds = []
Jon Halla440e872016-03-31 15:15:50 -0700728 ids = main.CLIs[i].getAllIntentsId()
Jon Hall85794ff2015-07-08 14:12:30 -0700729 onosIds.append( ids )
Jon Halla440e872016-03-31 15:15:50 -0700730 main.log.debug( "Intents in " + main.CLIs[i].name + ": " +
Jon Hall85794ff2015-07-08 14:12:30 -0700731 str( sorted( onosIds ) ) )
732 if sorted( ids ) != sorted( intentIds ):
733 main.log.warn( "Set of intent IDs doesn't match" )
734 correct = False
735 break
736 else:
Jon Halla440e872016-03-31 15:15:50 -0700737 intents = json.loads( main.CLIs[i].intents() )
Jon Hall85794ff2015-07-08 14:12:30 -0700738 for intent in intents:
739 if intent[ 'state' ] != "INSTALLED":
740 main.log.warn( "Intent " + intent[ 'id' ] +
741 " is " + intent[ 'state' ] )
742 correct = False
743 break
744 if correct:
745 break
746 else:
747 time.sleep(1)
748 if not intentStop:
749 intentStop = time.time()
750 global gossipTime
751 gossipTime = intentStop - intentStart
752 main.log.info( "It took about " + str( gossipTime ) +
753 " seconds for all intents to appear in each node" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700754 gossipPeriod = int( main.params['timers']['gossip'] )
Jon Halla440e872016-03-31 15:15:50 -0700755 maxGossipTime = gossipPeriod * len( main.activeNodes )
Jon Hall85794ff2015-07-08 14:12:30 -0700756 utilities.assert_greater_equals(
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700757 expect=maxGossipTime, actual=gossipTime,
Jon Hall85794ff2015-07-08 14:12:30 -0700758 onpass="ECM anti-entropy for intents worked within " +
759 "expected time",
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700760 onfail="Intent ECM anti-entropy took too long. " +
761 "Expected time:{}, Actual time:{}".format( maxGossipTime,
762 gossipTime ) )
763 if gossipTime <= maxGossipTime:
Jon Hall85794ff2015-07-08 14:12:30 -0700764 intentAddResult = True
765
766 if not intentAddResult or "key" in pendingMap:
767 import time
768 installedCheck = True
769 main.log.info( "Sleeping 60 seconds to see if intents are found" )
770 time.sleep( 60 )
Jon Halla440e872016-03-31 15:15:50 -0700771 onosIds = onosCli.getAllIntentsId()
Jon Hall85794ff2015-07-08 14:12:30 -0700772 main.log.info( "Submitted intents: " + str( intentIds ) )
773 main.log.info( "Intents in ONOS: " + str( onosIds ) )
774 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -0700775 intents = onosCli.intents()
Jon Hall85794ff2015-07-08 14:12:30 -0700776 intentStates = []
777 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
778 count = 0
779 try:
780 for intent in json.loads( intents ):
781 # Iter through intents of a node
782 state = intent.get( 'state', None )
783 if "INSTALLED" not in state:
784 installedCheck = False
785 intentId = intent.get( 'id', None )
786 intentStates.append( ( intentId, state ) )
787 except ( ValueError, TypeError ):
788 main.log.exception( "Error parsing intents" )
789 # add submitted intents not in the store
790 tmplist = [ i for i, s in intentStates ]
791 for i in intentIds:
792 if i not in tmplist:
793 intentStates.append( ( i, " - " ) )
794 intentStates.sort()
795 for i, s in intentStates:
796 count += 1
797 main.log.info( "%-6s%-15s%-15s" %
798 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -0700799 leaders = onosCli.leaders()
Jon Hall85794ff2015-07-08 14:12:30 -0700800 try:
801 missing = False
802 if leaders:
803 parsedLeaders = json.loads( leaders )
804 main.log.warn( json.dumps( parsedLeaders,
805 sort_keys=True,
806 indent=4,
807 separators=( ',', ': ' ) ) )
808 # check for all intent partitions
809 # check for election
810 topics = []
811 for i in range( 14 ):
812 topics.append( "intent-partition-" + str( i ) )
813 # FIXME: this should only be after we start the app
814 topics.append( "org.onosproject.election" )
815 main.log.debug( topics )
816 ONOStopics = [ j['topic'] for j in parsedLeaders ]
817 for topic in topics:
818 if topic not in ONOStopics:
819 main.log.error( "Error: " + topic +
820 " not in leaders" )
821 missing = True
822 else:
823 main.log.error( "leaders() returned None" )
824 except ( ValueError, TypeError ):
825 main.log.exception( "Error parsing leaders" )
826 main.log.error( repr( leaders ) )
827 # Check all nodes
828 if missing:
Jon Halla440e872016-03-31 15:15:50 -0700829 for i in main.activeNodes:
830 node = main.CLIs[i]
831 response = node.leaders( jsonFormat=False)
832 main.log.warn( str( node.name ) + " leaders output: \n" +
833 str( response ) )
834
835 partitions = onosCli.partitions()
Jon Hall85794ff2015-07-08 14:12:30 -0700836 try:
837 if partitions :
838 parsedPartitions = json.loads( partitions )
839 main.log.warn( json.dumps( parsedPartitions,
840 sort_keys=True,
841 indent=4,
842 separators=( ',', ': ' ) ) )
843 # TODO check for a leader in all paritions
844 # TODO check for consistency among nodes
845 else:
846 main.log.error( "partitions() returned None" )
847 except ( ValueError, TypeError ):
848 main.log.exception( "Error parsing partitions" )
849 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -0700850 pendingMap = onosCli.pendingMap()
Jon Hall85794ff2015-07-08 14:12:30 -0700851 try:
852 if pendingMap :
853 parsedPending = json.loads( pendingMap )
854 main.log.warn( json.dumps( parsedPending,
855 sort_keys=True,
856 indent=4,
857 separators=( ',', ': ' ) ) )
858 # TODO check something here?
859 else:
860 main.log.error( "pendingMap() returned None" )
861 except ( ValueError, TypeError ):
862 main.log.exception( "Error parsing pending map" )
863 main.log.error( repr( pendingMap ) )
864
865 def CASE4( self, main ):
866 """
867 Ping across added host intents
868 """
869 import json
870 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700871 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700872 assert main, "main not defined"
873 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halla440e872016-03-31 15:15:50 -0700874 main.case( "Verify connectivity by sending traffic across Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700875 main.caseExplanation = "Ping across added host intents to check " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700876 "functionality and check the state of " +\
877 "the intent"
878 main.step( "Ping across added host intents" )
Jon Halla440e872016-03-31 15:15:50 -0700879 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall85794ff2015-07-08 14:12:30 -0700880 PingResult = main.TRUE
881 for i in range( 8, 18 ):
882 ping = main.Mininet1.pingHost( src="h" + str( i ),
883 target="h" + str( i + 10 ) )
884 PingResult = PingResult and ping
885 if ping == main.FALSE:
886 main.log.warn( "Ping failed between h" + str( i ) +
887 " and h" + str( i + 10 ) )
888 elif ping == main.TRUE:
889 main.log.info( "Ping test passed!" )
890 # Don't set PingResult or you'd override failures
891 if PingResult == main.FALSE:
892 main.log.error(
893 "Intents have not been installed correctly, pings failed." )
894 # TODO: pretty print
895 main.log.warn( "ONOS1 intents: " )
896 try:
Jon Halla440e872016-03-31 15:15:50 -0700897 tmpIntents = onosCli.intents()
Jon Hall85794ff2015-07-08 14:12:30 -0700898 main.log.warn( json.dumps( json.loads( tmpIntents ),
899 sort_keys=True,
900 indent=4,
901 separators=( ',', ': ' ) ) )
902 except ( ValueError, TypeError ):
903 main.log.warn( repr( tmpIntents ) )
904 utilities.assert_equals(
905 expect=main.TRUE,
906 actual=PingResult,
907 onpass="Intents have been installed correctly and pings work",
908 onfail="Intents have not been installed correctly, pings failed." )
909
910 main.step( "Check Intent state" )
911 installedCheck = True
912 # Print the intent states
913 intents = main.ONOScli1.intents()
914 intentStates = []
915 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
916 count = 0
917 # Iter through intents of a node
918 try:
919 for intent in json.loads( intents ):
920 state = intent.get( 'state', None )
921 if "INSTALLED" not in state:
922 installedCheck = False
923 intentId = intent.get( 'id', None )
924 intentStates.append( ( intentId, state ) )
925 except ( ValueError, TypeError ):
926 main.log.exception( "Error parsing intents." )
927 # Print states
928 intentStates.sort()
929 for i, s in intentStates:
930 count += 1
931 main.log.info( "%-6s%-15s%-15s" %
932 ( str( count ), str( i ), str( s ) ) )
933 utilities.assert_equals( expect=True, actual=installedCheck,
934 onpass="Intents are all INSTALLED",
935 onfail="Intents are not all in " +
936 "INSTALLED state" )
937
938 main.step( "Check leadership of topics" )
Jon Halla440e872016-03-31 15:15:50 -0700939 leaders = onosCli.leaders()
Jon Hall85794ff2015-07-08 14:12:30 -0700940 topicCheck = main.TRUE
941 try:
942 if leaders:
943 parsedLeaders = json.loads( leaders )
944 main.log.warn( json.dumps( parsedLeaders,
945 sort_keys=True,
946 indent=4,
947 separators=( ',', ': ' ) ) )
948 # check for all intent partitions
949 # check for election
950 # TODO: Look at Devices as topics now that it uses this system
951 topics = []
952 for i in range( 14 ):
953 topics.append( "intent-partition-" + str( i ) )
954 # FIXME: this should only be after we start the app
955 # FIXME: topics.append( "org.onosproject.election" )
956 # Print leaders output
957 main.log.debug( topics )
958 ONOStopics = [ j['topic'] for j in parsedLeaders ]
959 for topic in topics:
960 if topic not in ONOStopics:
961 main.log.error( "Error: " + topic +
962 " not in leaders" )
963 topicCheck = main.FALSE
964 else:
965 main.log.error( "leaders() returned None" )
966 topicCheck = main.FALSE
967 except ( ValueError, TypeError ):
968 topicCheck = main.FALSE
969 main.log.exception( "Error parsing leaders" )
970 main.log.error( repr( leaders ) )
971 # TODO: Check for a leader of these topics
Jon Halla440e872016-03-31 15:15:50 -0700972 # Check all nodes
973 if topicCheck:
974 for i in main.activeNodes:
975 node = main.CLIs[i]
976 response = node.leaders( jsonFormat=False)
977 main.log.warn( str( node.name ) + " leaders output: \n" +
978 str( response ) )
979
Jon Hall85794ff2015-07-08 14:12:30 -0700980 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
981 onpass="intent Partitions is in leaders",
982 onfail="Some topics were lost " )
983 # Print partitions
Jon Halla440e872016-03-31 15:15:50 -0700984 partitions = onosCli.partitions()
Jon Hall85794ff2015-07-08 14:12:30 -0700985 try:
986 if partitions :
987 parsedPartitions = json.loads( partitions )
988 main.log.warn( json.dumps( parsedPartitions,
989 sort_keys=True,
990 indent=4,
991 separators=( ',', ': ' ) ) )
992 # TODO check for a leader in all paritions
993 # TODO check for consistency among nodes
994 else:
995 main.log.error( "partitions() returned None" )
996 except ( ValueError, TypeError ):
997 main.log.exception( "Error parsing partitions" )
998 main.log.error( repr( partitions ) )
999 # Print Pending Map
Jon Halla440e872016-03-31 15:15:50 -07001000 pendingMap = onosCli.pendingMap()
Jon Hall85794ff2015-07-08 14:12:30 -07001001 try:
1002 if pendingMap :
1003 parsedPending = json.loads( pendingMap )
1004 main.log.warn( json.dumps( parsedPending,
1005 sort_keys=True,
1006 indent=4,
1007 separators=( ',', ': ' ) ) )
1008 # TODO check something here?
1009 else:
1010 main.log.error( "pendingMap() returned None" )
1011 except ( ValueError, TypeError ):
1012 main.log.exception( "Error parsing pending map" )
1013 main.log.error( repr( pendingMap ) )
1014
1015 if not installedCheck:
1016 main.log.info( "Waiting 60 seconds to see if the state of " +
1017 "intents change" )
1018 time.sleep( 60 )
1019 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -07001020 intents = onosCli.intents()
Jon Hall85794ff2015-07-08 14:12:30 -07001021 intentStates = []
1022 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
1023 count = 0
1024 # Iter through intents of a node
1025 try:
1026 for intent in json.loads( intents ):
1027 state = intent.get( 'state', None )
1028 if "INSTALLED" not in state:
1029 installedCheck = False
1030 intentId = intent.get( 'id', None )
1031 intentStates.append( ( intentId, state ) )
1032 except ( ValueError, TypeError ):
1033 main.log.exception( "Error parsing intents." )
1034 intentStates.sort()
1035 for i, s in intentStates:
1036 count += 1
1037 main.log.info( "%-6s%-15s%-15s" %
1038 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -07001039 leaders = onosCli.leaders()
Jon Hall85794ff2015-07-08 14:12:30 -07001040 try:
1041 missing = False
1042 if leaders:
1043 parsedLeaders = json.loads( leaders )
1044 main.log.warn( json.dumps( parsedLeaders,
1045 sort_keys=True,
1046 indent=4,
1047 separators=( ',', ': ' ) ) )
1048 # check for all intent partitions
1049 # check for election
1050 topics = []
1051 for i in range( 14 ):
1052 topics.append( "intent-partition-" + str( i ) )
1053 # FIXME: this should only be after we start the app
1054 topics.append( "org.onosproject.election" )
1055 main.log.debug( topics )
1056 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1057 for topic in topics:
1058 if topic not in ONOStopics:
1059 main.log.error( "Error: " + topic +
1060 " not in leaders" )
1061 missing = True
1062 else:
1063 main.log.error( "leaders() returned None" )
1064 except ( ValueError, TypeError ):
1065 main.log.exception( "Error parsing leaders" )
1066 main.log.error( repr( leaders ) )
1067 if missing:
Jon Halla440e872016-03-31 15:15:50 -07001068 for i in main.activeNodes:
1069 node = main.CLIs[i]
1070 response = node.leaders( jsonFormat=False)
1071 main.log.warn( str( node.name ) + " leaders output: \n" +
1072 str( response ) )
1073
1074 partitions = onosCli.partitions()
Jon Hall85794ff2015-07-08 14:12:30 -07001075 try:
1076 if partitions :
1077 parsedPartitions = json.loads( partitions )
1078 main.log.warn( json.dumps( parsedPartitions,
1079 sort_keys=True,
1080 indent=4,
1081 separators=( ',', ': ' ) ) )
1082 # TODO check for a leader in all paritions
1083 # TODO check for consistency among nodes
1084 else:
1085 main.log.error( "partitions() returned None" )
1086 except ( ValueError, TypeError ):
1087 main.log.exception( "Error parsing partitions" )
1088 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -07001089 pendingMap = onosCli.pendingMap()
Jon Hall85794ff2015-07-08 14:12:30 -07001090 try:
1091 if pendingMap :
1092 parsedPending = json.loads( pendingMap )
1093 main.log.warn( json.dumps( parsedPending,
1094 sort_keys=True,
1095 indent=4,
1096 separators=( ',', ': ' ) ) )
1097 # TODO check something here?
1098 else:
1099 main.log.error( "pendingMap() returned None" )
1100 except ( ValueError, TypeError ):
1101 main.log.exception( "Error parsing pending map" )
1102 main.log.error( repr( pendingMap ) )
1103 # Print flowrules
Jon Halla440e872016-03-31 15:15:50 -07001104 node = main.activeNodes[0]
1105 main.log.debug( main.CLIs[node].flows( jsonFormat=False ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001106 main.step( "Wait a minute then ping again" )
1107 # the wait is above
1108 PingResult = main.TRUE
1109 for i in range( 8, 18 ):
1110 ping = main.Mininet1.pingHost( src="h" + str( i ),
1111 target="h" + str( i + 10 ) )
1112 PingResult = PingResult and ping
1113 if ping == main.FALSE:
1114 main.log.warn( "Ping failed between h" + str( i ) +
1115 " and h" + str( i + 10 ) )
1116 elif ping == main.TRUE:
1117 main.log.info( "Ping test passed!" )
1118 # Don't set PingResult or you'd override failures
1119 if PingResult == main.FALSE:
1120 main.log.error(
1121 "Intents have not been installed correctly, pings failed." )
1122 # TODO: pretty print
1123 main.log.warn( "ONOS1 intents: " )
1124 try:
Jon Halla440e872016-03-31 15:15:50 -07001125 tmpIntents = onosCli.intents()
Jon Hall85794ff2015-07-08 14:12:30 -07001126 main.log.warn( json.dumps( json.loads( tmpIntents ),
1127 sort_keys=True,
1128 indent=4,
1129 separators=( ',', ': ' ) ) )
1130 except ( ValueError, TypeError ):
1131 main.log.warn( repr( tmpIntents ) )
1132 utilities.assert_equals(
1133 expect=main.TRUE,
1134 actual=PingResult,
1135 onpass="Intents have been installed correctly and pings work",
1136 onfail="Intents have not been installed correctly, pings failed." )
1137
1138 def CASE5( self, main ):
1139 """
1140 Reading state of ONOS
1141 """
1142 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001143 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001144 assert main, "main not defined"
1145 assert utilities.assert_equals, "utilities.assert_equals not defined"
1146
1147 main.case( "Setting up and gathering data for current state" )
1148 # The general idea for this test case is to pull the state of
1149 # ( intents,flows, topology,... ) from each ONOS node
1150 # We can then compare them with each other and also with past states
1151
1152 main.step( "Check that each switch has a master" )
1153 global mastershipState
1154 mastershipState = '[]'
1155
1156 # Assert that each device has a master
Jon Halla440e872016-03-31 15:15:50 -07001157 rolesNotNull = main.TRUE
1158 threads = []
1159 for i in main.activeNodes:
1160 t = main.Thread( target=main.CLIs[i].rolesNotNull,
1161 name="rolesNotNull-" + str( i ),
1162 args=[] )
1163 threads.append( t )
1164 t.start()
1165
1166 for t in threads:
1167 t.join()
1168 rolesNotNull = rolesNotNull and t.result
Jon Hall85794ff2015-07-08 14:12:30 -07001169 utilities.assert_equals(
1170 expect=main.TRUE,
1171 actual=rolesNotNull,
1172 onpass="Each device has a master",
1173 onfail="Some devices don't have a master assigned" )
1174
1175 main.step( "Get the Mastership of each switch" )
1176 ONOS1Mastership = main.ONOScli1.roles()
1177 # TODO: Make this a meaningful check
1178 if "Error" in ONOS1Mastership or not ONOS1Mastership:
1179 main.log.error( "Error in getting ONOS roles" )
1180 main.log.warn(
1181 "ONOS1 mastership response: " +
1182 repr( ONOS1Mastership ) )
1183 consistentMastership = main.FALSE
1184 else:
1185 mastershipState = ONOS1Mastership
1186 consistentMastership = main.TRUE
1187
1188 main.step( "Get the intents from each controller" )
1189 global intentState
1190 intentState = []
1191 ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
1192 intentCheck = main.FALSE
1193 if "Error" in ONOS1Intents or not ONOS1Intents:
1194 main.log.error( "Error in getting ONOS intents" )
1195 main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
1196 else:
1197 intentCheck = main.TRUE
1198
1199 main.step( "Get the flows from each controller" )
1200 global flowState
1201 flowState = []
1202 flowCheck = main.FALSE
1203 ONOS1Flows = main.ONOScli1.flows( jsonFormat=True )
1204 if "Error" in ONOS1Flows or not ONOS1Flows:
1205 main.log.error( "Error in getting ONOS flows" )
1206 main.log.warn( "ONOS1 flows repsponse: " + ONOS1Flows )
1207 else:
1208 # TODO: Do a better check, maybe compare flows on switches?
1209 flowState = ONOS1Flows
1210 flowCheck = main.TRUE
1211
1212 main.step( "Get the OF Table entries" )
1213 global flows
1214 flows = []
1215 for i in range( 1, 29 ):
GlennRC68467eb2015-11-16 18:01:01 -08001216 flows.append( main.Mininet1.getFlowTable( "s" + str( i ), version="1.3", debug=False ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001217 if flowCheck == main.FALSE:
1218 for table in flows:
1219 main.log.warn( table )
1220 # TODO: Compare switch flow tables with ONOS flow tables
1221
1222 main.step( "Collecting topology information from ONOS" )
1223 devices = []
1224 devices.append( main.ONOScli1.devices() )
1225 hosts = []
1226 hosts.append( json.loads( main.ONOScli1.hosts() ) )
1227 ports = []
1228 ports.append( main.ONOScli1.ports() )
1229 links = []
1230 links.append( main.ONOScli1.links() )
1231 clusters = []
1232 clusters.append( main.ONOScli1.clusters() )
1233
1234 main.step( "Each host has an IP address" )
1235 ipResult = main.TRUE
1236 for controller in range( 0, len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07001237 controllerStr = str( main.activeNodes[controller] + 1 )
1238 if hosts[ controller ]:
1239 for host in hosts[ controller ]:
1240 if not host.get( 'ipAddresses', [ ] ):
1241 main.log.error( "Error with host ips on controller" +
1242 controllerStr + ": " + str( host ) )
1243 ipResult = main.FALSE
Jon Hall85794ff2015-07-08 14:12:30 -07001244 utilities.assert_equals(
1245 expect=main.TRUE,
1246 actual=ipResult,
1247 onpass="The ips of the hosts aren't empty",
1248 onfail="The ip of at least one host is missing" )
1249
1250 # there should always only be one cluster
1251 main.step( "There is only one dataplane cluster" )
1252 try:
1253 numClusters = len( json.loads( clusters[ 0 ] ) )
1254 except ( ValueError, TypeError ):
1255 main.log.exception( "Error parsing clusters[0]: " +
1256 repr( clusters[ 0 ] ) )
Jon Hall6e709752016-02-01 13:38:46 -08001257 numClusters = "ERROR"
Jon Hall85794ff2015-07-08 14:12:30 -07001258 clusterResults = main.FALSE
1259 if numClusters == 1:
1260 clusterResults = main.TRUE
1261 utilities.assert_equals(
1262 expect=1,
1263 actual=numClusters,
1264 onpass="ONOS shows 1 SCC",
1265 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1266
1267 main.step( "Comparing ONOS topology to MN" )
1268 devicesResults = main.TRUE
1269 linksResults = main.TRUE
1270 hostsResults = main.TRUE
1271 mnSwitches = main.Mininet1.getSwitches()
1272 mnLinks = main.Mininet1.getLinks()
1273 mnHosts = main.Mininet1.getHosts()
Jon Halla440e872016-03-31 15:15:50 -07001274 for controller in main.activeNodes:
1275 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07001276 if devices[ controller ] and ports[ controller ] and\
1277 "Error" not in devices[ controller ] and\
1278 "Error" not in ports[ controller ]:
Jon Hall6e709752016-02-01 13:38:46 -08001279 currentDevicesResult = main.Mininet1.compareSwitches(
1280 mnSwitches,
1281 json.loads( devices[ controller ] ),
1282 json.loads( ports[ controller ] ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001283 else:
1284 currentDevicesResult = main.FALSE
1285 utilities.assert_equals( expect=main.TRUE,
1286 actual=currentDevicesResult,
1287 onpass="ONOS" + controllerStr +
1288 " Switches view is correct",
1289 onfail="ONOS" + controllerStr +
1290 " Switches view is incorrect" )
1291 if links[ controller ] and "Error" not in links[ controller ]:
1292 currentLinksResult = main.Mininet1.compareLinks(
1293 mnSwitches, mnLinks,
1294 json.loads( links[ controller ] ) )
1295 else:
1296 currentLinksResult = main.FALSE
1297 utilities.assert_equals( expect=main.TRUE,
1298 actual=currentLinksResult,
1299 onpass="ONOS" + controllerStr +
1300 " links view is correct",
1301 onfail="ONOS" + controllerStr +
1302 " links view is incorrect" )
1303
Jon Halla440e872016-03-31 15:15:50 -07001304 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall85794ff2015-07-08 14:12:30 -07001305 currentHostsResult = main.Mininet1.compareHosts(
1306 mnHosts,
1307 hosts[ controller ] )
1308 else:
1309 currentHostsResult = main.FALSE
1310 utilities.assert_equals( expect=main.TRUE,
1311 actual=currentHostsResult,
1312 onpass="ONOS" + controllerStr +
1313 " hosts exist in Mininet",
1314 onfail="ONOS" + controllerStr +
1315 " hosts don't match Mininet" )
1316
1317 devicesResults = devicesResults and currentDevicesResult
1318 linksResults = linksResults and currentLinksResult
1319 hostsResults = hostsResults and currentHostsResult
1320
1321 main.step( "Device information is correct" )
1322 utilities.assert_equals(
1323 expect=main.TRUE,
1324 actual=devicesResults,
1325 onpass="Device information is correct",
1326 onfail="Device information is incorrect" )
1327
1328 main.step( "Links are correct" )
1329 utilities.assert_equals(
1330 expect=main.TRUE,
1331 actual=linksResults,
1332 onpass="Link are correct",
1333 onfail="Links are incorrect" )
1334
1335 main.step( "Hosts are correct" )
1336 utilities.assert_equals(
1337 expect=main.TRUE,
1338 actual=hostsResults,
1339 onpass="Hosts are correct",
1340 onfail="Hosts are incorrect" )
1341
1342 def CASE6( self, main ):
1343 """
1344 The Failure case.
1345 """
1346 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001347 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001348 assert main, "main not defined"
1349 assert utilities.assert_equals, "utilities.assert_equals not defined"
1350
1351 # Reset non-persistent variables
1352 try:
1353 iCounterValue = 0
1354 except NameError:
1355 main.log.error( "iCounterValue not defined, setting to 0" )
1356 iCounterValue = 0
1357
1358 main.case( "Restart ONOS node" )
Jon Hall783bbf92015-07-23 14:33:19 -07001359 main.caseExplanation = "Killing ONOS process and restart cli " +\
Jon Hall85794ff2015-07-08 14:12:30 -07001360 "sessions once onos is up."
Jon Hall96091e62015-09-21 17:34:17 -07001361
1362 main.step( "Checking ONOS Logs for errors" )
1363 for node in main.nodes:
1364 main.log.debug( "Checking logs for errors on " + node.name + ":" )
1365 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
1366
Jon Hall85794ff2015-07-08 14:12:30 -07001367 main.step( "Killing ONOS processes" )
Jon Halle1a3b752015-07-22 13:02:46 -07001368 killResult = main.ONOSbench.onosKill( main.nodes[0].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -07001369 start = time.time()
1370 utilities.assert_equals( expect=main.TRUE, actual=killResult,
1371 onpass="ONOS Killed",
1372 onfail="Error killing ONOS" )
1373
1374 main.step( "Checking if ONOS is up yet" )
1375 count = 0
1376 while count < 10:
Jon Halle1a3b752015-07-22 13:02:46 -07001377 onos1Isup = main.ONOSbench.isup( main.nodes[0].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -07001378 if onos1Isup == main.TRUE:
1379 elapsed = time.time() - start
1380 break
1381 else:
1382 count = count + 1
1383 utilities.assert_equals( expect=main.TRUE, actual=onos1Isup,
1384 onpass="ONOS is back up",
1385 onfail="ONOS failed to start" )
1386
1387 main.log.step( "Starting ONOS CLI sessions" )
Jon Halle1a3b752015-07-22 13:02:46 -07001388 cliResults = main.ONOScli1.startOnosCli( main.nodes[0].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -07001389 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1390 onpass="ONOS cli startup successful",
1391 onfail="ONOS cli startup failed" )
1392
1393 if elapsed:
1394 main.log.info( "ESTIMATE: ONOS took %s seconds to restart" %
1395 str( elapsed ) )
1396 main.restartTime = elapsed
1397 else:
1398 main.restartTime = -1
1399 time.sleep( 5 )
1400 # rerun on election apps
1401 main.ONOScli1.electionTestRun()
1402
1403 def CASE7( self, main ):
1404 """
1405 Check state after ONOS failure
1406 """
1407 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001408 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001409 assert main, "main not defined"
1410 assert utilities.assert_equals, "utilities.assert_equals not defined"
1411 main.case( "Running ONOS Constant State Tests" )
Jon Hall6e709752016-02-01 13:38:46 -08001412
Jon Hall85794ff2015-07-08 14:12:30 -07001413 main.step( "Check that each switch has a master" )
1414 # Assert that each device has a master
Jon Halla440e872016-03-31 15:15:50 -07001415 rolesNotNull = main.TRUE
1416 threads = []
1417 for i in main.activeNodes:
1418 t = main.Thread( target=main.CLIs[i].rolesNotNull,
1419 name="rolesNotNull-" + str( i ),
1420 args=[ ] )
1421 threads.append( t )
1422 t.start()
1423
1424 for t in threads:
1425 t.join()
1426 rolesNotNull = rolesNotNull and t.result
Jon Hall85794ff2015-07-08 14:12:30 -07001427 utilities.assert_equals(
1428 expect=main.TRUE,
1429 actual=rolesNotNull,
1430 onpass="Each device has a master",
1431 onfail="Some devices don't have a master assigned" )
1432
1433 main.step( "Check if switch roles are consistent across all nodes" )
1434 ONOS1Mastership = main.ONOScli1.roles()
1435 # FIXME: Refactor this whole case for single instance
1436 if "Error" in ONOS1Mastership or not ONOS1Mastership:
1437 main.log.error( "Error in getting ONOS mastership" )
1438 main.log.warn( "ONOS1 mastership response: " +
1439 repr( ONOS1Mastership ) )
1440 consistentMastership = main.FALSE
1441 else:
1442 consistentMastership = main.TRUE
1443 utilities.assert_equals(
1444 expect=main.TRUE,
1445 actual=consistentMastership,
1446 onpass="Switch roles are consistent across all ONOS nodes",
1447 onfail="ONOS nodes have different views of switch roles" )
1448
1449 description2 = "Compare switch roles from before failure"
1450 main.step( description2 )
1451
1452 currentJson = json.loads( ONOS1Mastership )
1453 oldJson = json.loads( mastershipState )
1454 mastershipCheck = main.TRUE
1455 for i in range( 1, 29 ):
1456 switchDPID = str(
1457 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
1458
1459 current = [ switch[ 'master' ] for switch in currentJson
1460 if switchDPID in switch[ 'id' ] ]
1461 old = [ switch[ 'master' ] for switch in oldJson
1462 if switchDPID in switch[ 'id' ] ]
1463 if current == old:
1464 mastershipCheck = mastershipCheck and main.TRUE
1465 else:
1466 main.log.warn( "Mastership of switch %s changed" % switchDPID )
1467 mastershipCheck = main.FALSE
1468 utilities.assert_equals(
1469 expect=main.TRUE,
1470 actual=mastershipCheck,
1471 onpass="Mastership of Switches was not changed",
1472 onfail="Mastership of some switches changed" )
1473 mastershipCheck = mastershipCheck and consistentMastership
1474
1475 main.step( "Get the intents and compare across all nodes" )
1476 ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
1477 intentCheck = main.FALSE
1478 if "Error" in ONOS1Intents or not ONOS1Intents:
1479 main.log.error( "Error in getting ONOS intents" )
1480 main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
1481 else:
1482 intentCheck = main.TRUE
1483 utilities.assert_equals(
1484 expect=main.TRUE,
1485 actual=intentCheck,
1486 onpass="Intents are consistent across all ONOS nodes",
1487 onfail="ONOS nodes have different views of intents" )
1488 # Print the intent states
1489 intents = []
1490 intents.append( ONOS1Intents )
1491 intentStates = []
1492 for node in intents: # Iter through ONOS nodes
1493 nodeStates = []
1494 # Iter through intents of a node
1495 for intent in json.loads( node ):
1496 nodeStates.append( intent[ 'state' ] )
1497 intentStates.append( nodeStates )
1498 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1499 main.log.info( dict( out ) )
1500
1501 # NOTE: Store has no durability, so intents are lost across system
1502 # restarts
1503 """
1504 main.step( "Compare current intents with intents before the failure" )
1505 # NOTE: this requires case 5 to pass for intentState to be set.
1506 # maybe we should stop the test if that fails?
1507 sameIntents = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07001508 try:
1509 intentState
1510 except NameError:
1511 main.log.warn( "No previous intent state was saved" )
1512 else:
1513 if intentState and intentState == ONOSIntents[ 0 ]:
1514 sameIntents = main.TRUE
1515 main.log.info( "Intents are consistent with before failure" )
1516 # TODO: possibly the states have changed? we may need to figure out
1517 # what the acceptable states are
1518 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
1519 sameIntents = main.TRUE
1520 try:
1521 before = json.loads( intentState )
1522 after = json.loads( ONOSIntents[ 0 ] )
1523 for intent in before:
1524 if intent not in after:
1525 sameIntents = main.FALSE
1526 main.log.debug( "Intent is not currently in ONOS " +
1527 "(at least in the same form):" )
1528 main.log.debug( json.dumps( intent ) )
1529 except ( ValueError, TypeError ):
1530 main.log.exception( "Exception printing intents" )
1531 main.log.debug( repr( ONOSIntents[0] ) )
1532 main.log.debug( repr( intentState ) )
1533 if sameIntents == main.FALSE:
1534 try:
1535 main.log.debug( "ONOS intents before: " )
1536 main.log.debug( json.dumps( json.loads( intentState ),
1537 sort_keys=True, indent=4,
1538 separators=( ',', ': ' ) ) )
1539 main.log.debug( "Current ONOS intents: " )
1540 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1541 sort_keys=True, indent=4,
1542 separators=( ',', ': ' ) ) )
1543 except ( ValueError, TypeError ):
1544 main.log.exception( "Exception printing intents" )
1545 main.log.debug( repr( ONOSIntents[0] ) )
1546 main.log.debug( repr( intentState ) )
1547 utilities.assert_equals(
1548 expect=main.TRUE,
1549 actual=sameIntents,
1550 onpass="Intents are consistent with before failure",
1551 onfail="The Intents changed during failure" )
Jon Hall85794ff2015-07-08 14:12:30 -07001552 intentCheck = intentCheck and sameIntents
1553 """
1554 main.step( "Get the OF Table entries and compare to before " +
1555 "component failure" )
1556 FlowTables = main.TRUE
Jon Hall85794ff2015-07-08 14:12:30 -07001557 for i in range( 28 ):
1558 main.log.info( "Checking flow table on s" + str( i + 1 ) )
GlennRC68467eb2015-11-16 18:01:01 -08001559 tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
1560 FlowTables = FlowTables and main.Mininet1.flowTableComp( flows[i], tmpFlows )
Jon Hall85794ff2015-07-08 14:12:30 -07001561 if FlowTables == main.FALSE:
GlennRC68467eb2015-11-16 18:01:01 -08001562 main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001563 utilities.assert_equals(
1564 expect=main.TRUE,
1565 actual=FlowTables,
1566 onpass="No changes were found in the flow tables",
1567 onfail="Changes were found in the flow tables" )
1568
1569 main.step( "Leadership Election is still functional" )
1570 # Test of LeadershipElection
1571
Jon Halla440e872016-03-31 15:15:50 -07001572 leader = main.nodes[ main.activeNodes[ 0 ] ].ip_address
Jon Hall85794ff2015-07-08 14:12:30 -07001573 leaderResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001574 for controller in range( 1, main.numCtrls + 1 ):
Jon Hall85794ff2015-07-08 14:12:30 -07001575 # loop through ONOScli handlers
1576 node = getattr( main, ( 'ONOScli' + str( controller ) ) )
1577 leaderN = node.electionTestLeader()
1578 # verify leader is ONOS1
1579 # NOTE even though we restarted ONOS, it is the only one so onos 1
1580 # must be leader
1581 if leaderN == leader:
1582 # all is well
1583 pass
1584 elif leaderN == main.FALSE:
1585 # error in response
1586 main.log.error( "Something is wrong with " +
1587 "electionTestLeader function, check the" +
1588 " error logs" )
1589 leaderResult = main.FALSE
1590 elif leader != leaderN:
1591 leaderResult = main.FALSE
1592 main.log.error( "ONOS" + str( controller ) + " sees " +
1593 str( leaderN ) +
1594 " as the leader of the election app. " +
1595 "Leader should be " + str( leader ) )
1596 utilities.assert_equals(
1597 expect=main.TRUE,
1598 actual=leaderResult,
1599 onpass="Leadership election passed",
1600 onfail="Something went wrong with Leadership election" )
1601
1602 def CASE8( self, main ):
1603 """
1604 Compare topo
1605 """
1606 import json
1607 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001608 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001609 assert main, "main not defined"
1610 assert utilities.assert_equals, "utilities.assert_equals not defined"
1611
1612 main.case( "Compare ONOS Topology view to Mininet topology" )
Jon Hall783bbf92015-07-23 14:33:19 -07001613 main.caseExplanation = "Compare topology objects between Mininet" +\
Jon Hall85794ff2015-07-08 14:12:30 -07001614 " and ONOS"
Jon Hall85794ff2015-07-08 14:12:30 -07001615 topoResult = main.FALSE
1616 elapsed = 0
1617 count = 0
Jon Halle9b1fa32015-12-08 15:32:21 -08001618 main.step( "Comparing ONOS topology to MN topology" )
Jon Hall85794ff2015-07-08 14:12:30 -07001619 startTime = time.time()
1620 # Give time for Gossip to work
Jon Halle9b1fa32015-12-08 15:32:21 -08001621 while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
Jon Hall96091e62015-09-21 17:34:17 -07001622 devicesResults = main.TRUE
1623 linksResults = main.TRUE
1624 hostsResults = main.TRUE
1625 hostAttachmentResults = True
Jon Hall85794ff2015-07-08 14:12:30 -07001626 count += 1
1627 cliStart = time.time()
1628 devices = []
1629 devices.append( main.ONOScli1.devices() )
1630 hosts = []
1631 hosts.append( json.loads( main.ONOScli1.hosts() ) )
1632 ipResult = main.TRUE
1633 for controller in range( 0, len( hosts ) ):
1634 controllerStr = str( controller + 1 )
1635 for host in hosts[ controller ]:
1636 if host is None or host.get( 'ipAddresses', [] ) == []:
1637 main.log.error(
1638 "DEBUG:Error with host ips on controller" +
1639 controllerStr + ": " + str( host ) )
1640 ipResult = main.FALSE
1641 ports = []
1642 ports.append( main.ONOScli1.ports() )
1643 links = []
1644 links.append( main.ONOScli1.links() )
1645 clusters = []
1646 clusters.append( main.ONOScli1.clusters() )
1647
1648 elapsed = time.time() - startTime
1649 cliTime = time.time() - cliStart
1650 print "CLI time: " + str( cliTime )
1651
1652 mnSwitches = main.Mininet1.getSwitches()
1653 mnLinks = main.Mininet1.getLinks()
1654 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07001655 for controller in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07001656 controllerStr = str( controller + 1 )
1657 if devices[ controller ] and ports[ controller ] and\
1658 "Error" not in devices[ controller ] and\
1659 "Error" not in ports[ controller ]:
1660
Jon Hallc6793552016-01-19 14:18:37 -08001661 try:
1662 currentDevicesResult = main.Mininet1.compareSwitches(
1663 mnSwitches,
1664 json.loads( devices[ controller ] ),
1665 json.loads( ports[ controller ] ) )
1666 except ( TypeError, ValueError ) as e:
1667 main.log.exception( "Object not as expected; devices={!r}\nports={!r}".format(
1668 devices[ controller ], ports[ controller ] ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001669 else:
1670 currentDevicesResult = main.FALSE
1671 utilities.assert_equals( expect=main.TRUE,
1672 actual=currentDevicesResult,
1673 onpass="ONOS" + controllerStr +
1674 " Switches view is correct",
1675 onfail="ONOS" + controllerStr +
1676 " Switches view is incorrect" )
1677
1678 if links[ controller ] and "Error" not in links[ controller ]:
1679 currentLinksResult = main.Mininet1.compareLinks(
1680 mnSwitches, mnLinks,
1681 json.loads( links[ controller ] ) )
1682 else:
1683 currentLinksResult = main.FALSE
1684 utilities.assert_equals( expect=main.TRUE,
1685 actual=currentLinksResult,
1686 onpass="ONOS" + controllerStr +
1687 " links view is correct",
1688 onfail="ONOS" + controllerStr +
1689 " links view is incorrect" )
1690
1691 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1692 currentHostsResult = main.Mininet1.compareHosts(
1693 mnHosts,
1694 hosts[ controller ] )
1695 else:
1696 currentHostsResult = main.FALSE
1697 utilities.assert_equals( expect=main.TRUE,
1698 actual=currentHostsResult,
1699 onpass="ONOS" + controllerStr +
1700 " hosts exist in Mininet",
1701 onfail="ONOS" + controllerStr +
1702 " hosts don't match Mininet" )
1703 # CHECKING HOST ATTACHMENT POINTS
1704 hostAttachment = True
1705 zeroHosts = False
1706 # FIXME: topo-HA/obelisk specific mappings:
1707 # key is mac and value is dpid
1708 mappings = {}
1709 for i in range( 1, 29 ): # hosts 1 through 28
1710 # set up correct variables:
1711 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
1712 if i == 1:
1713 deviceId = "1000".zfill(16)
1714 elif i == 2:
1715 deviceId = "2000".zfill(16)
1716 elif i == 3:
1717 deviceId = "3000".zfill(16)
1718 elif i == 4:
1719 deviceId = "3004".zfill(16)
1720 elif i == 5:
1721 deviceId = "5000".zfill(16)
1722 elif i == 6:
1723 deviceId = "6000".zfill(16)
1724 elif i == 7:
1725 deviceId = "6007".zfill(16)
1726 elif i >= 8 and i <= 17:
1727 dpid = '3' + str( i ).zfill( 3 )
1728 deviceId = dpid.zfill(16)
1729 elif i >= 18 and i <= 27:
1730 dpid = '6' + str( i ).zfill( 3 )
1731 deviceId = dpid.zfill(16)
1732 elif i == 28:
1733 deviceId = "2800".zfill(16)
1734 mappings[ macId ] = deviceId
1735 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1736 if hosts[ controller ] == []:
1737 main.log.warn( "There are no hosts discovered" )
1738 zeroHosts = True
1739 else:
1740 for host in hosts[ controller ]:
1741 mac = None
1742 location = None
1743 device = None
1744 port = None
1745 try:
1746 mac = host.get( 'mac' )
1747 assert mac, "mac field could not be found for this host object"
1748
1749 location = host.get( 'location' )
1750 assert location, "location field could not be found for this host object"
1751
1752 # Trim the protocol identifier off deviceId
1753 device = str( location.get( 'elementId' ) ).split(':')[1]
1754 assert device, "elementId field could not be found for this host location object"
1755
1756 port = location.get( 'port' )
1757 assert port, "port field could not be found for this host location object"
1758
1759 # Now check if this matches where they should be
1760 if mac and device and port:
1761 if str( port ) != "1":
1762 main.log.error( "The attachment port is incorrect for " +
1763 "host " + str( mac ) +
1764 ". Expected: 1 Actual: " + str( port) )
1765 hostAttachment = False
1766 if device != mappings[ str( mac ) ]:
1767 main.log.error( "The attachment device is incorrect for " +
1768 "host " + str( mac ) +
1769 ". Expected: " + mappings[ str( mac ) ] +
1770 " Actual: " + device )
1771 hostAttachment = False
1772 else:
1773 hostAttachment = False
1774 except AssertionError:
1775 main.log.exception( "Json object not as expected" )
1776 main.log.error( repr( host ) )
1777 hostAttachment = False
1778 else:
1779 main.log.error( "No hosts json output or \"Error\"" +
1780 " in output. hosts = " +
1781 repr( hosts[ controller ] ) )
1782 if zeroHosts is False:
1783 hostAttachment = True
1784
Jon Hall85794ff2015-07-08 14:12:30 -07001785 devicesResults = devicesResults and currentDevicesResult
1786 linksResults = linksResults and currentLinksResult
1787 hostsResults = hostsResults and currentHostsResult
1788 hostAttachmentResults = hostAttachmentResults and\
1789 hostAttachment
1790
Jon Halla440e872016-03-31 15:15:50 -07001791 # "consistent" results don't make sense for single instance
Jon Hall85794ff2015-07-08 14:12:30 -07001792 # there should always only be one cluster
Jon Hall85794ff2015-07-08 14:12:30 -07001793 clusterResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07001794 try:
1795 numClusters = len( json.loads( clusters[ 0 ] ) )
1796 except ( ValueError, TypeError ):
1797 main.log.exception( "Error parsing clusters[0]: " +
1798 repr( clusters[0] ) )
1799 numClusters = "ERROR"
1800 clusterResults = main.FALSE
Jon Hall85794ff2015-07-08 14:12:30 -07001801 if numClusters == 1:
1802 clusterResults = main.TRUE
1803 utilities.assert_equals(
1804 expect=1,
1805 actual=numClusters,
1806 onpass="ONOS shows 1 SCC",
1807 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1808
1809 topoResult = ( devicesResults and linksResults
1810 and hostsResults and ipResult and clusterResults and
1811 hostAttachmentResults )
1812
1813 topoResult = topoResult and int( count <= 2 )
1814 note = "note it takes about " + str( int( cliTime ) ) + \
1815 " seconds for the test to make all the cli calls to fetch " +\
1816 "the topology from each ONOS instance"
1817 main.log.info(
1818 "Very crass estimate for topology discovery/convergence( " +
1819 str( note ) + " ): " + str( elapsed ) + " seconds, " +
1820 str( count ) + " tries" )
1821 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
1822 onpass="Topology Check Test successful",
1823 onfail="Topology Check Test NOT successful" )
1824
1825 def CASE9( self, main ):
1826 """
1827 Link s3-s28 down
1828 """
1829 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001830 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001831 assert main, "main not defined"
1832 assert utilities.assert_equals, "utilities.assert_equals not defined"
1833 # NOTE: You should probably run a topology check after this
1834
1835 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
1836
1837 description = "Turn off a link to ensure that Link Discovery " +\
1838 "is working properly"
1839 main.case( description )
1840
1841 main.step( "Kill Link between s3 and s28" )
1842 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
1843 main.log.info( "Waiting " + str( linkSleep ) +
1844 " seconds for link down to be discovered" )
1845 time.sleep( linkSleep )
1846 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
1847 onpass="Link down successful",
1848 onfail="Failed to bring link down" )
1849 # TODO do some sort of check here
1850
1851 def CASE10( self, main ):
1852 """
1853 Link s3-s28 up
1854 """
1855 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001856 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001857 assert main, "main not defined"
1858 assert utilities.assert_equals, "utilities.assert_equals not defined"
1859 # NOTE: You should probably run a topology check after this
1860
1861 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
1862
1863 description = "Restore a link to ensure that Link Discovery is " + \
1864 "working properly"
1865 main.case( description )
1866
1867 main.step( "Bring link between s3 and s28 back up" )
1868 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
1869 main.log.info( "Waiting " + str( linkSleep ) +
1870 " seconds for link up to be discovered" )
1871 time.sleep( linkSleep )
1872 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
1873 onpass="Link up successful",
1874 onfail="Failed to bring link up" )
1875 # TODO do some sort of check here
1876
1877 def CASE11( self, main ):
1878 """
1879 Switch Down
1880 """
1881 # NOTE: You should probably run a topology check after this
1882 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001883 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001884 assert main, "main not defined"
1885 assert utilities.assert_equals, "utilities.assert_equals not defined"
1886
1887 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
1888
1889 description = "Killing a switch to ensure it is discovered correctly"
Jon Halla440e872016-03-31 15:15:50 -07001890 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall85794ff2015-07-08 14:12:30 -07001891 main.case( description )
1892 switch = main.params[ 'kill' ][ 'switch' ]
1893 switchDPID = main.params[ 'kill' ][ 'dpid' ]
1894
1895 # TODO: Make this switch parameterizable
1896 main.step( "Kill " + switch )
1897 main.log.info( "Deleting " + switch )
1898 main.Mininet1.delSwitch( switch )
1899 main.log.info( "Waiting " + str( switchSleep ) +
1900 " seconds for switch down to be discovered" )
1901 time.sleep( switchSleep )
Jon Halla440e872016-03-31 15:15:50 -07001902 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall85794ff2015-07-08 14:12:30 -07001903 # Peek at the deleted switch
1904 main.log.warn( str( device ) )
1905 result = main.FALSE
1906 if device and device[ 'available' ] is False:
1907 result = main.TRUE
1908 utilities.assert_equals( expect=main.TRUE, actual=result,
1909 onpass="Kill switch successful",
1910 onfail="Failed to kill switch?" )
1911
1912 def CASE12( self, main ):
1913 """
1914 Switch Up
1915 """
1916 # NOTE: You should probably run a topology check after this
1917 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001918 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001919 assert main, "main not defined"
1920 assert utilities.assert_equals, "utilities.assert_equals not defined"
1921
1922 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
1923 switch = main.params[ 'kill' ][ 'switch' ]
1924 switchDPID = main.params[ 'kill' ][ 'dpid' ]
1925 links = main.params[ 'kill' ][ 'links' ].split()
Jon Halla440e872016-03-31 15:15:50 -07001926 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall85794ff2015-07-08 14:12:30 -07001927 description = "Adding a switch to ensure it is discovered correctly"
1928 main.case( description )
1929
1930 main.step( "Add back " + switch )
1931 main.Mininet1.addSwitch( switch, dpid=switchDPID )
1932 for peer in links:
1933 main.Mininet1.addLink( switch, peer )
Jon Halla440e872016-03-31 15:15:50 -07001934 ipList = [ node.ip_address for node in main.nodes ]
Jon Hall85794ff2015-07-08 14:12:30 -07001935 main.Mininet1.assignSwController( sw=switch, ip=ipList )
1936 main.log.info( "Waiting " + str( switchSleep ) +
1937 " seconds for switch up to be discovered" )
1938 time.sleep( switchSleep )
Jon Halla440e872016-03-31 15:15:50 -07001939 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall85794ff2015-07-08 14:12:30 -07001940 # Peek at the deleted switch
1941 main.log.warn( str( device ) )
1942 result = main.FALSE
1943 if device and device[ 'available' ]:
1944 result = main.TRUE
1945 utilities.assert_equals( expect=main.TRUE, actual=result,
1946 onpass="add switch successful",
1947 onfail="Failed to add switch?" )
1948
1949 def CASE13( self, main ):
1950 """
1951 Clean up
1952 """
1953 import os
1954 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001955 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001956 assert main, "main not defined"
1957 assert utilities.assert_equals, "utilities.assert_equals not defined"
1958 # printing colors to terminal
1959 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
1960 'blue': '\033[94m', 'green': '\033[92m',
1961 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
1962 main.case( "Test Cleanup" )
1963 main.step( "Killing tcpdumps" )
1964 main.Mininet2.stopTcpdump()
1965
1966 testname = main.TEST
Jon Hall96091e62015-09-21 17:34:17 -07001967 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall85794ff2015-07-08 14:12:30 -07001968 main.step( "Copying MN pcap and ONOS log files to test station" )
1969 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
1970 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
Jon Hall96091e62015-09-21 17:34:17 -07001971 # NOTE: MN Pcap file is being saved to logdir.
1972 # We scp this file as MN and TestON aren't necessarily the same vm
1973
1974 # FIXME: To be replaced with a Jenkin's post script
Jon Hall85794ff2015-07-08 14:12:30 -07001975 # TODO: Load these from params
1976 # NOTE: must end in /
1977 logFolder = "/opt/onos/log/"
1978 logFiles = [ "karaf.log", "karaf.log.1" ]
1979 # NOTE: must end in /
Jon Hall85794ff2015-07-08 14:12:30 -07001980 for f in logFiles:
Jon Hall96091e62015-09-21 17:34:17 -07001981 for node in main.nodes:
Jon Halla440e872016-03-31 15:15:50 -07001982 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07001983 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
1984 logFolder + f, dstName )
Jon Hall85794ff2015-07-08 14:12:30 -07001985 # std*.log's
1986 # NOTE: must end in /
1987 logFolder = "/opt/onos/var/"
1988 logFiles = [ "stderr.log", "stdout.log" ]
1989 # NOTE: must end in /
Jon Hall85794ff2015-07-08 14:12:30 -07001990 for f in logFiles:
Jon Hall96091e62015-09-21 17:34:17 -07001991 for node in main.nodes:
Jon Halla440e872016-03-31 15:15:50 -07001992 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07001993 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
1994 logFolder + f, dstName )
1995 else:
1996 main.log.debug( "skipping saving log files" )
Jon Hall85794ff2015-07-08 14:12:30 -07001997
Jon Hall85794ff2015-07-08 14:12:30 -07001998 main.step( "Stopping Mininet" )
1999 mnResult = main.Mininet1.stopNet()
2000 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2001 onpass="Mininet stopped",
2002 onfail="MN cleanup NOT successful" )
2003
2004 main.step( "Checking ONOS Logs for errors" )
Jon Hall96091e62015-09-21 17:34:17 -07002005 for node in main.nodes:
2006 main.log.debug( "Checking logs for errors on " + node.name + ":" )
2007 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall85794ff2015-07-08 14:12:30 -07002008
2009 try:
2010 timerLog = open( main.logdir + "/Timers.csv", 'w')
2011 # Overwrite with empty line and close
2012 labels = "Gossip Intents, Restart"
2013 data = str( gossipTime ) + ", " + str( main.restartTime )
2014 timerLog.write( labels + "\n" + data )
2015 timerLog.close()
2016 except NameError, e:
2017 main.log.exception(e)
2018
2019 def CASE14( self, main ):
2020 """
2021 start election app on all onos nodes
2022 """
Jon Halle1a3b752015-07-22 13:02:46 -07002023 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002024 assert main, "main not defined"
2025 assert utilities.assert_equals, "utilities.assert_equals not defined"
2026
2027 main.case("Start Leadership Election app")
2028 main.step( "Install leadership election app" )
Jon Halla440e872016-03-31 15:15:50 -07002029 onosCli = main.CLIs[ main.activeNodes[0] ]
2030 appResult = onosCli.activateApp( "org.onosproject.election" )
Jon Hall85794ff2015-07-08 14:12:30 -07002031 utilities.assert_equals(
2032 expect=main.TRUE,
2033 actual=appResult,
2034 onpass="Election app installed",
2035 onfail="Something went wrong with installing Leadership election" )
2036
2037 main.step( "Run for election on each node" )
Jon Halla440e872016-03-31 15:15:50 -07002038 leaderResult = main.TRUE
2039 leaders = []
2040 for i in main.activeNodes:
2041 main.CLIs[i].electionTestRun()
2042 for i in main.activeNodes:
2043 cli = main.CLIs[i]
2044 leader = cli.electionTestLeader()
2045 if leader is None or leader == main.FALSE:
2046 main.log.error( cli.name + ": Leader for the election app " +
2047 "should be an ONOS node, instead got '" +
2048 str( leader ) + "'" )
2049 leaderResult = main.FALSE
2050 leaders.append( leader )
Jon Hall85794ff2015-07-08 14:12:30 -07002051 utilities.assert_equals(
2052 expect=main.TRUE,
2053 actual=leaderResult,
2054 onpass="Successfully ran for leadership",
2055 onfail="Failed to run for leadership" )
2056
2057 def CASE15( self, main ):
2058 """
2059 Check that Leadership Election is still functional
acsmars71adceb2015-08-31 15:09:26 -07002060 15.1 Run election on each node
2061 15.2 Check that each node has the same leaders and candidates
2062 15.3 Find current leader and withdraw
2063 15.4 Check that a new node was elected leader
2064 15.5 Check that that new leader was the candidate of old leader
2065 15.6 Run for election on old leader
2066 15.7 Check that oldLeader is a candidate, and leader if only 1 node
2067 15.8 Make sure that the old leader was added to the candidate list
2068
2069 old and new variable prefixes refer to data from before vs after
2070 withdrawl and later before withdrawl vs after re-election
Jon Hall85794ff2015-07-08 14:12:30 -07002071 """
acsmars71adceb2015-08-31 15:09:26 -07002072 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002073 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002074 assert main, "main not defined"
2075 assert utilities.assert_equals, "utilities.assert_equals not defined"
acsmars71adceb2015-08-31 15:09:26 -07002076 assert main.CLIs, "main.CLIs not defined"
2077 assert main.nodes, "main.nodes not defined"
2078
Jon Hall85794ff2015-07-08 14:12:30 -07002079 description = "Check that Leadership Election is still functional"
2080 main.case( description )
Jon Halla440e872016-03-31 15:15:50 -07002081 # NOTE: Need to re-run after restarts since being a canidate is not persistant
acsmars2c2fcdd2015-08-25 17:14:13 -07002082
Jon Halla440e872016-03-31 15:15:50 -07002083 oldLeaders = [] # list of lists of each nodes' candidates before
2084 newLeaders = [] # list of lists of each nodes' candidates after
acsmars71adceb2015-08-31 15:09:26 -07002085 oldLeader = '' # the old leader from oldLeaders, None if not same
2086 newLeader = '' # the new leaders fron newLoeaders, None if not same
2087 oldLeaderCLI = None # the CLI of the old leader used for re-electing
2088 expectNoLeader = False # True when there is only one leader
2089 if main.numCtrls == 1:
2090 expectNoLeader = True
acsmars2c2fcdd2015-08-25 17:14:13 -07002091
acsmars71adceb2015-08-31 15:09:26 -07002092 main.step( "Run for election on each node" )
2093 electionResult = main.TRUE
2094
Jon Halla440e872016-03-31 15:15:50 -07002095 for i in main.activeNodes: # run test election on each node
2096 if main.CLIs[i].electionTestRun() == main.FALSE:
acsmars71adceb2015-08-31 15:09:26 -07002097 electionResult = main.FALSE
acsmars71adceb2015-08-31 15:09:26 -07002098 utilities.assert_equals(
2099 expect=main.TRUE,
2100 actual=electionResult,
2101 onpass="All nodes successfully ran for leadership",
2102 onfail="At least one node failed to run for leadership" )
2103
acsmars3a72bde2015-09-02 14:16:22 -07002104 if electionResult == main.FALSE:
2105 main.log.error(
2106 "Skipping Test Case because Election Test App isn't loaded" )
2107 main.skipCase()
2108
acsmars71adceb2015-08-31 15:09:26 -07002109 main.step( "Check that each node shows the same leader and candidates" )
Jon Halla440e872016-03-31 15:15:50 -07002110 failMessage = "Nodes have different leaderboards"
2111 def consistentLeaderboards( nodes ):
2112 TOPIC = 'org.onosproject.election'
2113 # FIXME: use threads
2114 #FIXME: should we retry outside the function?
2115 for n in range( 5 ): # Retry in case election is still happening
2116 leaderList = []
2117 # Get all leaderboards
2118 for cli in nodes:
2119 leaderList.append( cli.specificLeaderCandidate( TOPIC ) )
2120 # Compare leaderboards
2121 result = all( i == leaderList[0] for i in leaderList ) and\
2122 leaderList is not None
2123 main.log.debug( leaderList )
2124 main.log.warn( result )
2125 if result:
2126 return ( result, leaderList )
2127 time.sleep(5) #TODO: paramerterize
2128 main.log.error( "Inconsistent leaderboards:" + str( leaderList ) )
2129 activeCLIs = [ main.CLIs[i] for i in main.activeNodes ]
2130 sameResult, oldLeaders = consistentLeaderboards( activeCLIs )
2131 if sameResult:
2132 oldLeader = oldLeaders[ 0 ][ 0 ]
2133 main.log.warn( oldLeader )
Jon Hall85794ff2015-07-08 14:12:30 -07002134 else:
Jon Halla440e872016-03-31 15:15:50 -07002135 oldLeader = None
acsmars71adceb2015-08-31 15:09:26 -07002136 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07002137 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07002138 actual=sameResult,
Jon Halla440e872016-03-31 15:15:50 -07002139 onpass="Leaderboards are consistent for the election topic",
acsmars71adceb2015-08-31 15:09:26 -07002140 onfail=failMessage )
2141
2142 main.step( "Find current leader and withdraw" )
2143 withdrawResult = main.TRUE
2144 # do some sanity checking on leader before using it
2145 if oldLeader is None:
2146 main.log.error( "Leadership isn't consistent." )
2147 withdrawResult = main.FALSE
2148 # Get the CLI of the oldLeader
Jon Halla440e872016-03-31 15:15:50 -07002149 for i in main.activeNodes:
acsmars71adceb2015-08-31 15:09:26 -07002150 if oldLeader == main.nodes[ i ].ip_address:
2151 oldLeaderCLI = main.CLIs[ i ]
2152 break
2153 else: # FOR/ELSE statement
2154 main.log.error( "Leader election, could not find current leader" )
Jon Hall85794ff2015-07-08 14:12:30 -07002155 if oldLeader:
acsmars71adceb2015-08-31 15:09:26 -07002156 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall85794ff2015-07-08 14:12:30 -07002157 utilities.assert_equals(
2158 expect=main.TRUE,
2159 actual=withdrawResult,
2160 onpass="Node was withdrawn from election",
2161 onfail="Node was not withdrawn from election" )
2162
acsmars71adceb2015-08-31 15:09:26 -07002163 main.step( "Check that a new node was elected leader" )
acsmars71adceb2015-08-31 15:09:26 -07002164 failMessage = "Nodes have different leaders"
acsmars71adceb2015-08-31 15:09:26 -07002165 # Get new leaders and candidates
Jon Halla440e872016-03-31 15:15:50 -07002166 newLeaderResult, newLeaders = consistentLeaderboards( activeCLIs )
2167 if newLeaders[ 0 ][ 0 ] == 'none':
2168 main.log.error( "No leader was elected on at least 1 node" )
2169 if not expectNoLeader:
2170 newLeaderResult = False
2171 if newLeaderResult:
2172 newLeader = newLeaders[ 0 ][ 0 ]
acsmars71adceb2015-08-31 15:09:26 -07002173 else:
Jon Halla440e872016-03-31 15:15:50 -07002174 newLeader = None
acsmars71adceb2015-08-31 15:09:26 -07002175
2176 # Check that the new leader is not the older leader, which was withdrawn
2177 if newLeader == oldLeader:
Jon Halla440e872016-03-31 15:15:50 -07002178 newLeaderResult = False
2179 main.log.error( "All nodes still see old leader: " + str( oldLeader ) +
acsmars71adceb2015-08-31 15:09:26 -07002180 " as the current leader" )
Jon Hall85794ff2015-07-08 14:12:30 -07002181 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07002182 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07002183 actual=newLeaderResult,
2184 onpass="Leadership election passed",
2185 onfail="Something went wrong with Leadership election" )
Jon Hall85794ff2015-07-08 14:12:30 -07002186
Jon Halla440e872016-03-31 15:15:50 -07002187 main.step( "Check that that new leader was the candidate of old leader" )
2188 # candidates[ 2 ] should become the top candidate after withdrawl
acsmars71adceb2015-08-31 15:09:26 -07002189 correctCandidateResult = main.TRUE
2190 if expectNoLeader:
2191 if newLeader == 'none':
2192 main.log.info( "No leader expected. None found. Pass" )
2193 correctCandidateResult = main.TRUE
2194 else:
2195 main.log.info( "Expected no leader, got: " + str( newLeader ) )
2196 correctCandidateResult = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002197 elif len( oldLeaders[0] ) >= 3:
2198 if newLeader == oldLeaders[ 0 ][ 2 ]:
2199 # correct leader was elected
2200 correctCandidateResult = main.TRUE
2201 else:
2202 correctCandidateResult = main.FALSE
2203 main.log.error( "Candidate {} was elected. {} should have had priority.".format(
2204 newLeader, oldLeaders[ 0 ][ 2 ] ) )
2205 else:
2206 main.log.warn( "Could not determine who should be the correct leader" )
2207 main.log.debug( oldLeaders[ 0 ] )
acsmars71adceb2015-08-31 15:09:26 -07002208 correctCandidateResult = main.FALSE
acsmars71adceb2015-08-31 15:09:26 -07002209 utilities.assert_equals(
2210 expect=main.TRUE,
2211 actual=correctCandidateResult,
2212 onpass="Correct Candidate Elected",
2213 onfail="Incorrect Candidate Elected" )
2214
Jon Hall85794ff2015-07-08 14:12:30 -07002215 main.step( "Run for election on old leader( just so everyone " +
2216 "is in the hat )" )
acsmars71adceb2015-08-31 15:09:26 -07002217 if oldLeaderCLI is not None:
2218 runResult = oldLeaderCLI.electionTestRun()
Jon Hall85794ff2015-07-08 14:12:30 -07002219 else:
acsmars71adceb2015-08-31 15:09:26 -07002220 main.log.error( "No old leader to re-elect" )
Jon Hall85794ff2015-07-08 14:12:30 -07002221 runResult = main.FALSE
2222 utilities.assert_equals(
2223 expect=main.TRUE,
2224 actual=runResult,
2225 onpass="App re-ran for election",
2226 onfail="App failed to run for election" )
Jon Halla440e872016-03-31 15:15:50 -07002227
acsmars71adceb2015-08-31 15:09:26 -07002228 main.step(
2229 "Check that oldLeader is a candidate, and leader if only 1 node" )
2230 # verify leader didn't just change
Jon Halla440e872016-03-31 15:15:50 -07002231 # Get new leaders and candidates
2232 reRunLeaders = []
2233 time.sleep( 5 ) # Paremterize
2234 positionResult, reRunLeaders = consistentLeaderboards( activeCLIs )
acsmars71adceb2015-08-31 15:09:26 -07002235
2236 # Check that the re-elected node is last on the candidate List
Jon Halla440e872016-03-31 15:15:50 -07002237 if oldLeader != reRunLeaders[ 0 ][ -1 ]:
2238 main.log.error( "Old Leader ({}) not in the proper position: {} ".format( str( oldLeader),
2239 str( reRunLeaders[ 0 ] ) ) )
acsmars71adceb2015-08-31 15:09:26 -07002240 positionResult = main.FALSE
Jon Hall85794ff2015-07-08 14:12:30 -07002241
2242 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07002243 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07002244 actual=positionResult,
Jon Hall85794ff2015-07-08 14:12:30 -07002245 onpass="Old leader successfully re-ran for election",
2246 onfail="Something went wrong with Leadership election after " +
2247 "the old leader re-ran for election" )
2248
2249 def CASE16( self, main ):
2250 """
2251 Install Distributed Primitives app
2252 """
Jon Halla440e872016-03-31 15:15:50 -07002253 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002254 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002255 assert main, "main not defined"
2256 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002257 assert main.CLIs, "main.CLIs not defined"
2258 assert main.nodes, "main.nodes not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002259
2260 # Variables for the distributed primitives tests
2261 global pCounterName
Jon Hall85794ff2015-07-08 14:12:30 -07002262 global pCounterValue
Jon Hall85794ff2015-07-08 14:12:30 -07002263 global onosSet
2264 global onosSetName
2265 pCounterName = "TestON-Partitions"
Jon Hall85794ff2015-07-08 14:12:30 -07002266 pCounterValue = 0
Jon Hall85794ff2015-07-08 14:12:30 -07002267 onosSet = set([])
2268 onosSetName = "TestON-set"
2269
2270 description = "Install Primitives app"
2271 main.case( description )
2272 main.step( "Install Primitives app" )
2273 appName = "org.onosproject.distributedprimitives"
Jon Halla440e872016-03-31 15:15:50 -07002274 node = main.activeNodes[0]
2275 appResults = main.CLIs[node].activateApp( appName )
Jon Hall85794ff2015-07-08 14:12:30 -07002276 utilities.assert_equals( expect=main.TRUE,
2277 actual=appResults,
2278 onpass="Primitives app activated",
2279 onfail="Primitives app not activated" )
Jon Halla440e872016-03-31 15:15:50 -07002280 time.sleep( 5 ) # To allow all nodes to activate
Jon Hall85794ff2015-07-08 14:12:30 -07002281
2282 def CASE17( self, main ):
2283 """
2284 Check for basic functionality with distributed primitives
2285 """
Jon Hall85794ff2015-07-08 14:12:30 -07002286 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07002287 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002288 assert main, "main not defined"
2289 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002290 assert main.CLIs, "main.CLIs not defined"
2291 assert main.nodes, "main.nodes not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002292 assert pCounterName, "pCounterName not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002293 assert onosSetName, "onosSetName not defined"
2294 # NOTE: assert fails if value is 0/None/Empty/False
2295 try:
2296 pCounterValue
2297 except NameError:
2298 main.log.error( "pCounterValue not defined, setting to 0" )
2299 pCounterValue = 0
2300 try:
Jon Hall85794ff2015-07-08 14:12:30 -07002301 onosSet
2302 except NameError:
2303 main.log.error( "onosSet not defined, setting to empty Set" )
2304 onosSet = set([])
2305 # Variables for the distributed primitives tests. These are local only
2306 addValue = "a"
2307 addAllValue = "a b c d e f"
2308 retainValue = "c d e f"
2309
2310 description = "Check for basic functionality with distributed " +\
2311 "primitives"
2312 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07002313 main.caseExplanation = "Test the methods of the distributed " +\
2314 "primitives (counters and sets) throught the cli"
Jon Hall85794ff2015-07-08 14:12:30 -07002315 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07002316 # Partitioned counters
2317 main.step( "Increment then get a default counter on each node" )
Jon Hall85794ff2015-07-08 14:12:30 -07002318 pCounters = []
2319 threads = []
2320 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07002321 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002322 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2323 name="counterAddAndGet-" + str( i ),
Jon Hall85794ff2015-07-08 14:12:30 -07002324 args=[ pCounterName ] )
2325 pCounterValue += 1
2326 addedPValues.append( pCounterValue )
2327 threads.append( t )
2328 t.start()
2329
2330 for t in threads:
2331 t.join()
2332 pCounters.append( t.result )
2333 # Check that counter incremented numController times
2334 pCounterResults = True
2335 for i in addedPValues:
2336 tmpResult = i in pCounters
2337 pCounterResults = pCounterResults and tmpResult
2338 if not tmpResult:
2339 main.log.error( str( i ) + " is not in partitioned "
2340 "counter incremented results" )
2341 utilities.assert_equals( expect=True,
2342 actual=pCounterResults,
2343 onpass="Default counter incremented",
2344 onfail="Error incrementing default" +
2345 " counter" )
2346
Jon Halle1a3b752015-07-22 13:02:46 -07002347 main.step( "Get then Increment a default counter on each node" )
2348 pCounters = []
2349 threads = []
2350 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07002351 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002352 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
2353 name="counterGetAndAdd-" + str( i ),
2354 args=[ pCounterName ] )
2355 addedPValues.append( pCounterValue )
2356 pCounterValue += 1
2357 threads.append( t )
2358 t.start()
2359
2360 for t in threads:
2361 t.join()
2362 pCounters.append( t.result )
2363 # Check that counter incremented numController times
2364 pCounterResults = True
2365 for i in addedPValues:
2366 tmpResult = i in pCounters
2367 pCounterResults = pCounterResults and tmpResult
2368 if not tmpResult:
2369 main.log.error( str( i ) + " is not in partitioned "
2370 "counter incremented results" )
2371 utilities.assert_equals( expect=True,
2372 actual=pCounterResults,
2373 onpass="Default counter incremented",
2374 onfail="Error incrementing default" +
2375 " counter" )
2376
2377 main.step( "Counters we added have the correct values" )
2378 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
2379 utilities.assert_equals( expect=main.TRUE,
2380 actual=incrementCheck,
2381 onpass="Added counters are correct",
2382 onfail="Added counters are incorrect" )
2383
2384 main.step( "Add -8 to then get a default counter on each node" )
2385 pCounters = []
2386 threads = []
2387 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07002388 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002389 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2390 name="counterIncrement-" + str( i ),
2391 args=[ pCounterName ],
2392 kwargs={ "delta": -8 } )
2393 pCounterValue += -8
2394 addedPValues.append( pCounterValue )
2395 threads.append( t )
2396 t.start()
2397
2398 for t in threads:
2399 t.join()
2400 pCounters.append( t.result )
2401 # Check that counter incremented numController times
2402 pCounterResults = True
2403 for i in addedPValues:
2404 tmpResult = i in pCounters
2405 pCounterResults = pCounterResults and tmpResult
2406 if not tmpResult:
2407 main.log.error( str( i ) + " is not in partitioned "
2408 "counter incremented results" )
2409 utilities.assert_equals( expect=True,
2410 actual=pCounterResults,
2411 onpass="Default counter incremented",
2412 onfail="Error incrementing default" +
2413 " counter" )
2414
2415 main.step( "Add 5 to then get a default counter on each node" )
2416 pCounters = []
2417 threads = []
2418 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07002419 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002420 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2421 name="counterIncrement-" + str( i ),
2422 args=[ pCounterName ],
2423 kwargs={ "delta": 5 } )
2424 pCounterValue += 5
2425 addedPValues.append( pCounterValue )
2426 threads.append( t )
2427 t.start()
2428
2429 for t in threads:
2430 t.join()
2431 pCounters.append( t.result )
2432 # Check that counter incremented numController times
2433 pCounterResults = True
2434 for i in addedPValues:
2435 tmpResult = i in pCounters
2436 pCounterResults = pCounterResults and tmpResult
2437 if not tmpResult:
2438 main.log.error( str( i ) + " is not in partitioned "
2439 "counter incremented results" )
2440 utilities.assert_equals( expect=True,
2441 actual=pCounterResults,
2442 onpass="Default counter incremented",
2443 onfail="Error incrementing default" +
2444 " counter" )
2445
2446 main.step( "Get then add 5 to a default counter on each node" )
2447 pCounters = []
2448 threads = []
2449 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07002450 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002451 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
2452 name="counterIncrement-" + str( i ),
2453 args=[ pCounterName ],
2454 kwargs={ "delta": 5 } )
2455 addedPValues.append( pCounterValue )
2456 pCounterValue += 5
2457 threads.append( t )
2458 t.start()
2459
2460 for t in threads:
2461 t.join()
2462 pCounters.append( t.result )
2463 # Check that counter incremented numController times
2464 pCounterResults = True
2465 for i in addedPValues:
2466 tmpResult = i in pCounters
2467 pCounterResults = pCounterResults and tmpResult
2468 if not tmpResult:
2469 main.log.error( str( i ) + " is not in partitioned "
2470 "counter incremented results" )
2471 utilities.assert_equals( expect=True,
2472 actual=pCounterResults,
2473 onpass="Default counter incremented",
2474 onfail="Error incrementing default" +
2475 " counter" )
2476
2477 main.step( "Counters we added have the correct values" )
2478 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
2479 utilities.assert_equals( expect=main.TRUE,
2480 actual=incrementCheck,
2481 onpass="Added counters are correct",
2482 onfail="Added counters are incorrect" )
2483
Jon Hall85794ff2015-07-08 14:12:30 -07002484 # DISTRIBUTED SETS
2485 main.step( "Distributed Set get" )
2486 size = len( onosSet )
2487 getResponses = []
2488 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002489 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002490 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002491 name="setTestGet-" + str( i ),
2492 args=[ onosSetName ] )
2493 threads.append( t )
2494 t.start()
2495 for t in threads:
2496 t.join()
2497 getResponses.append( t.result )
2498
2499 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002500 for i in range( len( main.activeNodes ) ):
2501 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002502 if isinstance( getResponses[ i ], list):
2503 current = set( getResponses[ i ] )
2504 if len( current ) == len( getResponses[ i ] ):
2505 # no repeats
2506 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07002507 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002508 " has incorrect view" +
2509 " of set " + onosSetName + ":\n" +
2510 str( getResponses[ i ] ) )
2511 main.log.debug( "Expected: " + str( onosSet ) )
2512 main.log.debug( "Actual: " + str( current ) )
2513 getResults = main.FALSE
2514 else:
2515 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07002516 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002517 " has repeat elements in" +
2518 " set " + onosSetName + ":\n" +
2519 str( getResponses[ i ] ) )
2520 getResults = main.FALSE
2521 elif getResponses[ i ] == main.ERROR:
2522 getResults = main.FALSE
2523 utilities.assert_equals( expect=main.TRUE,
2524 actual=getResults,
2525 onpass="Set elements are correct",
2526 onfail="Set elements are incorrect" )
2527
2528 main.step( "Distributed Set size" )
2529 sizeResponses = []
2530 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002531 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002532 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002533 name="setTestSize-" + str( i ),
2534 args=[ onosSetName ] )
2535 threads.append( t )
2536 t.start()
2537 for t in threads:
2538 t.join()
2539 sizeResponses.append( t.result )
2540
2541 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002542 for i in range( len( main.activeNodes ) ):
2543 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002544 if size != sizeResponses[ i ]:
2545 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002546 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002547 " expected a size of " + str( size ) +
2548 " for set " + onosSetName +
2549 " but got " + str( sizeResponses[ i ] ) )
2550 utilities.assert_equals( expect=main.TRUE,
2551 actual=sizeResults,
2552 onpass="Set sizes are correct",
2553 onfail="Set sizes are incorrect" )
2554
2555 main.step( "Distributed Set add()" )
2556 onosSet.add( addValue )
2557 addResponses = []
2558 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002559 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002560 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07002561 name="setTestAdd-" + str( i ),
2562 args=[ onosSetName, addValue ] )
2563 threads.append( t )
2564 t.start()
2565 for t in threads:
2566 t.join()
2567 addResponses.append( t.result )
2568
2569 # main.TRUE = successfully changed the set
2570 # main.FALSE = action resulted in no change in set
2571 # main.ERROR - Some error in executing the function
2572 addResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002573 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07002574 if addResponses[ i ] == main.TRUE:
2575 # All is well
2576 pass
2577 elif addResponses[ i ] == main.FALSE:
2578 # Already in set, probably fine
2579 pass
2580 elif addResponses[ i ] == main.ERROR:
2581 # Error in execution
2582 addResults = main.FALSE
2583 else:
2584 # unexpected result
2585 addResults = main.FALSE
2586 if addResults != main.TRUE:
2587 main.log.error( "Error executing set add" )
2588
2589 # Check if set is still correct
2590 size = len( onosSet )
2591 getResponses = []
2592 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002593 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002594 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002595 name="setTestGet-" + str( i ),
2596 args=[ onosSetName ] )
2597 threads.append( t )
2598 t.start()
2599 for t in threads:
2600 t.join()
2601 getResponses.append( t.result )
2602 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002603 for i in range( len( main.activeNodes ) ):
2604 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002605 if isinstance( getResponses[ i ], list):
2606 current = set( getResponses[ i ] )
2607 if len( current ) == len( getResponses[ i ] ):
2608 # no repeats
2609 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07002610 main.log.error( "ONOS" + node + " has incorrect view" +
Jon Hall85794ff2015-07-08 14:12:30 -07002611 " of set " + onosSetName + ":\n" +
2612 str( getResponses[ i ] ) )
2613 main.log.debug( "Expected: " + str( onosSet ) )
2614 main.log.debug( "Actual: " + str( current ) )
2615 getResults = main.FALSE
2616 else:
2617 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07002618 main.log.error( "ONOS" + node + " has repeat elements in" +
Jon Hall85794ff2015-07-08 14:12:30 -07002619 " set " + onosSetName + ":\n" +
2620 str( getResponses[ i ] ) )
2621 getResults = main.FALSE
2622 elif getResponses[ i ] == main.ERROR:
2623 getResults = main.FALSE
2624 sizeResponses = []
2625 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002626 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002627 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002628 name="setTestSize-" + str( i ),
2629 args=[ onosSetName ] )
2630 threads.append( t )
2631 t.start()
2632 for t in threads:
2633 t.join()
2634 sizeResponses.append( t.result )
2635 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002636 for i in range( len( main.activeNodes ) ):
2637 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002638 if size != sizeResponses[ i ]:
2639 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002640 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002641 " expected a size of " + str( size ) +
2642 " for set " + onosSetName +
2643 " but got " + str( sizeResponses[ i ] ) )
2644 addResults = addResults and getResults and sizeResults
2645 utilities.assert_equals( expect=main.TRUE,
2646 actual=addResults,
2647 onpass="Set add correct",
2648 onfail="Set add was incorrect" )
2649
2650 main.step( "Distributed Set addAll()" )
2651 onosSet.update( addAllValue.split() )
2652 addResponses = []
2653 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002654 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002655 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07002656 name="setTestAddAll-" + str( i ),
2657 args=[ onosSetName, addAllValue ] )
2658 threads.append( t )
2659 t.start()
2660 for t in threads:
2661 t.join()
2662 addResponses.append( t.result )
2663
2664 # main.TRUE = successfully changed the set
2665 # main.FALSE = action resulted in no change in set
2666 # main.ERROR - Some error in executing the function
2667 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002668 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07002669 if addResponses[ i ] == main.TRUE:
2670 # All is well
2671 pass
2672 elif addResponses[ i ] == main.FALSE:
2673 # Already in set, probably fine
2674 pass
2675 elif addResponses[ i ] == main.ERROR:
2676 # Error in execution
2677 addAllResults = main.FALSE
2678 else:
2679 # unexpected result
2680 addAllResults = main.FALSE
2681 if addAllResults != main.TRUE:
2682 main.log.error( "Error executing set addAll" )
2683
2684 # Check if set is still correct
2685 size = len( onosSet )
2686 getResponses = []
2687 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002688 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002689 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002690 name="setTestGet-" + str( i ),
2691 args=[ onosSetName ] )
2692 threads.append( t )
2693 t.start()
2694 for t in threads:
2695 t.join()
2696 getResponses.append( t.result )
2697 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002698 for i in range( len( main.activeNodes ) ):
2699 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002700 if isinstance( getResponses[ i ], list):
2701 current = set( getResponses[ i ] )
2702 if len( current ) == len( getResponses[ i ] ):
2703 # no repeats
2704 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07002705 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002706 " has incorrect view" +
2707 " of set " + onosSetName + ":\n" +
2708 str( getResponses[ i ] ) )
2709 main.log.debug( "Expected: " + str( onosSet ) )
2710 main.log.debug( "Actual: " + str( current ) )
2711 getResults = main.FALSE
2712 else:
2713 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07002714 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002715 " has repeat elements in" +
2716 " set " + onosSetName + ":\n" +
2717 str( getResponses[ i ] ) )
2718 getResults = main.FALSE
2719 elif getResponses[ i ] == main.ERROR:
2720 getResults = main.FALSE
2721 sizeResponses = []
2722 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002723 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002724 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002725 name="setTestSize-" + str( i ),
2726 args=[ onosSetName ] )
2727 threads.append( t )
2728 t.start()
2729 for t in threads:
2730 t.join()
2731 sizeResponses.append( t.result )
2732 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002733 for i in range( len( main.activeNodes ) ):
2734 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002735 if size != sizeResponses[ i ]:
2736 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002737 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002738 " expected a size of " + str( size ) +
2739 " for set " + onosSetName +
2740 " but got " + str( sizeResponses[ i ] ) )
2741 addAllResults = addAllResults and getResults and sizeResults
2742 utilities.assert_equals( expect=main.TRUE,
2743 actual=addAllResults,
2744 onpass="Set addAll correct",
2745 onfail="Set addAll was incorrect" )
2746
2747 main.step( "Distributed Set contains()" )
2748 containsResponses = []
2749 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002750 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002751 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002752 name="setContains-" + str( i ),
2753 args=[ onosSetName ],
2754 kwargs={ "values": addValue } )
2755 threads.append( t )
2756 t.start()
2757 for t in threads:
2758 t.join()
2759 # NOTE: This is the tuple
2760 containsResponses.append( t.result )
2761
2762 containsResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002763 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07002764 if containsResponses[ i ] == main.ERROR:
2765 containsResults = main.FALSE
2766 else:
2767 containsResults = containsResults and\
2768 containsResponses[ i ][ 1 ]
2769 utilities.assert_equals( expect=main.TRUE,
2770 actual=containsResults,
2771 onpass="Set contains is functional",
2772 onfail="Set contains failed" )
2773
2774 main.step( "Distributed Set containsAll()" )
2775 containsAllResponses = []
2776 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002777 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002778 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002779 name="setContainsAll-" + str( i ),
2780 args=[ onosSetName ],
2781 kwargs={ "values": addAllValue } )
2782 threads.append( t )
2783 t.start()
2784 for t in threads:
2785 t.join()
2786 # NOTE: This is the tuple
2787 containsAllResponses.append( t.result )
2788
2789 containsAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002790 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07002791 if containsResponses[ i ] == main.ERROR:
2792 containsResults = main.FALSE
2793 else:
2794 containsResults = containsResults and\
2795 containsResponses[ i ][ 1 ]
2796 utilities.assert_equals( expect=main.TRUE,
2797 actual=containsAllResults,
2798 onpass="Set containsAll is functional",
2799 onfail="Set containsAll failed" )
2800
2801 main.step( "Distributed Set remove()" )
2802 onosSet.remove( addValue )
2803 removeResponses = []
2804 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002805 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002806 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07002807 name="setTestRemove-" + str( i ),
2808 args=[ onosSetName, addValue ] )
2809 threads.append( t )
2810 t.start()
2811 for t in threads:
2812 t.join()
2813 removeResponses.append( t.result )
2814
2815 # main.TRUE = successfully changed the set
2816 # main.FALSE = action resulted in no change in set
2817 # main.ERROR - Some error in executing the function
2818 removeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002819 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07002820 if removeResponses[ i ] == main.TRUE:
2821 # All is well
2822 pass
2823 elif removeResponses[ i ] == main.FALSE:
2824 # not in set, probably fine
2825 pass
2826 elif removeResponses[ i ] == main.ERROR:
2827 # Error in execution
2828 removeResults = main.FALSE
2829 else:
2830 # unexpected result
2831 removeResults = main.FALSE
2832 if removeResults != main.TRUE:
2833 main.log.error( "Error executing set remove" )
2834
2835 # Check if set is still correct
2836 size = len( onosSet )
2837 getResponses = []
2838 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002839 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002840 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002841 name="setTestGet-" + str( i ),
2842 args=[ onosSetName ] )
2843 threads.append( t )
2844 t.start()
2845 for t in threads:
2846 t.join()
2847 getResponses.append( t.result )
2848 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002849 for i in range( len( main.activeNodes ) ):
2850 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002851 if isinstance( getResponses[ i ], list):
2852 current = set( getResponses[ i ] )
2853 if len( current ) == len( getResponses[ i ] ):
2854 # no repeats
2855 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07002856 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002857 " has incorrect view" +
2858 " of set " + onosSetName + ":\n" +
2859 str( getResponses[ i ] ) )
2860 main.log.debug( "Expected: " + str( onosSet ) )
2861 main.log.debug( "Actual: " + str( current ) )
2862 getResults = main.FALSE
2863 else:
2864 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07002865 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002866 " has repeat elements in" +
2867 " set " + onosSetName + ":\n" +
2868 str( getResponses[ i ] ) )
2869 getResults = main.FALSE
2870 elif getResponses[ i ] == main.ERROR:
2871 getResults = main.FALSE
2872 sizeResponses = []
2873 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002874 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002875 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002876 name="setTestSize-" + str( i ),
2877 args=[ onosSetName ] )
2878 threads.append( t )
2879 t.start()
2880 for t in threads:
2881 t.join()
2882 sizeResponses.append( t.result )
2883 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002884 for i in range( len( main.activeNodes ) ):
2885 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002886 if size != sizeResponses[ i ]:
2887 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002888 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002889 " expected a size of " + str( size ) +
2890 " for set " + onosSetName +
2891 " but got " + str( sizeResponses[ i ] ) )
2892 removeResults = removeResults and getResults and sizeResults
2893 utilities.assert_equals( expect=main.TRUE,
2894 actual=removeResults,
2895 onpass="Set remove correct",
2896 onfail="Set remove was incorrect" )
2897
2898 main.step( "Distributed Set removeAll()" )
2899 onosSet.difference_update( addAllValue.split() )
2900 removeAllResponses = []
2901 threads = []
2902 try:
Jon Halla440e872016-03-31 15:15:50 -07002903 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002904 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07002905 name="setTestRemoveAll-" + str( i ),
2906 args=[ onosSetName, addAllValue ] )
2907 threads.append( t )
2908 t.start()
2909 for t in threads:
2910 t.join()
2911 removeAllResponses.append( t.result )
2912 except Exception, e:
2913 main.log.exception(e)
2914
2915 # main.TRUE = successfully changed the set
2916 # main.FALSE = action resulted in no change in set
2917 # main.ERROR - Some error in executing the function
2918 removeAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002919 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07002920 if removeAllResponses[ i ] == main.TRUE:
2921 # All is well
2922 pass
2923 elif removeAllResponses[ i ] == main.FALSE:
2924 # not in set, probably fine
2925 pass
2926 elif removeAllResponses[ i ] == main.ERROR:
2927 # Error in execution
2928 removeAllResults = main.FALSE
2929 else:
2930 # unexpected result
2931 removeAllResults = main.FALSE
2932 if removeAllResults != main.TRUE:
2933 main.log.error( "Error executing set removeAll" )
2934
2935 # Check if set is still correct
2936 size = len( onosSet )
2937 getResponses = []
2938 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002939 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002940 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002941 name="setTestGet-" + str( i ),
2942 args=[ onosSetName ] )
2943 threads.append( t )
2944 t.start()
2945 for t in threads:
2946 t.join()
2947 getResponses.append( t.result )
2948 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002949 for i in range( len( main.activeNodes ) ):
2950 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002951 if isinstance( getResponses[ i ], list):
2952 current = set( getResponses[ i ] )
2953 if len( current ) == len( getResponses[ i ] ):
2954 # no repeats
2955 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07002956 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002957 " has incorrect view" +
2958 " of set " + onosSetName + ":\n" +
2959 str( getResponses[ i ] ) )
2960 main.log.debug( "Expected: " + str( onosSet ) )
2961 main.log.debug( "Actual: " + str( current ) )
2962 getResults = main.FALSE
2963 else:
2964 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07002965 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002966 " has repeat elements in" +
2967 " set " + onosSetName + ":\n" +
2968 str( getResponses[ i ] ) )
2969 getResults = main.FALSE
2970 elif getResponses[ i ] == main.ERROR:
2971 getResults = main.FALSE
2972 sizeResponses = []
2973 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002974 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002975 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002976 name="setTestSize-" + str( i ),
2977 args=[ onosSetName ] )
2978 threads.append( t )
2979 t.start()
2980 for t in threads:
2981 t.join()
2982 sizeResponses.append( t.result )
2983 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002984 for i in range( len( main.activeNodes ) ):
2985 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07002986 if size != sizeResponses[ i ]:
2987 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002988 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07002989 " expected a size of " + str( size ) +
2990 " for set " + onosSetName +
2991 " but got " + str( sizeResponses[ i ] ) )
2992 removeAllResults = removeAllResults and getResults and sizeResults
2993 utilities.assert_equals( expect=main.TRUE,
2994 actual=removeAllResults,
2995 onpass="Set removeAll correct",
2996 onfail="Set removeAll was incorrect" )
2997
2998 main.step( "Distributed Set addAll()" )
2999 onosSet.update( addAllValue.split() )
3000 addResponses = []
3001 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003002 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003003 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07003004 name="setTestAddAll-" + str( i ),
3005 args=[ onosSetName, addAllValue ] )
3006 threads.append( t )
3007 t.start()
3008 for t in threads:
3009 t.join()
3010 addResponses.append( t.result )
3011
3012 # main.TRUE = successfully changed the set
3013 # main.FALSE = action resulted in no change in set
3014 # main.ERROR - Some error in executing the function
3015 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003016 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07003017 if addResponses[ i ] == main.TRUE:
3018 # All is well
3019 pass
3020 elif addResponses[ i ] == main.FALSE:
3021 # Already in set, probably fine
3022 pass
3023 elif addResponses[ i ] == main.ERROR:
3024 # Error in execution
3025 addAllResults = main.FALSE
3026 else:
3027 # unexpected result
3028 addAllResults = main.FALSE
3029 if addAllResults != main.TRUE:
3030 main.log.error( "Error executing set addAll" )
3031
3032 # Check if set is still correct
3033 size = len( onosSet )
3034 getResponses = []
3035 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003036 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003037 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003038 name="setTestGet-" + str( i ),
3039 args=[ onosSetName ] )
3040 threads.append( t )
3041 t.start()
3042 for t in threads:
3043 t.join()
3044 getResponses.append( t.result )
3045 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003046 for i in range( len( main.activeNodes ) ):
3047 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003048 if isinstance( getResponses[ i ], list):
3049 current = set( getResponses[ i ] )
3050 if len( current ) == len( getResponses[ i ] ):
3051 # no repeats
3052 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07003053 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003054 " has incorrect view" +
3055 " of set " + onosSetName + ":\n" +
3056 str( getResponses[ i ] ) )
3057 main.log.debug( "Expected: " + str( onosSet ) )
3058 main.log.debug( "Actual: " + str( current ) )
3059 getResults = main.FALSE
3060 else:
3061 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003062 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003063 " has repeat elements in" +
3064 " set " + onosSetName + ":\n" +
3065 str( getResponses[ i ] ) )
3066 getResults = main.FALSE
3067 elif getResponses[ i ] == main.ERROR:
3068 getResults = main.FALSE
3069 sizeResponses = []
3070 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003071 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003072 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003073 name="setTestSize-" + str( i ),
3074 args=[ onosSetName ] )
3075 threads.append( t )
3076 t.start()
3077 for t in threads:
3078 t.join()
3079 sizeResponses.append( t.result )
3080 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003081 for i in range( len( main.activeNodes ) ):
3082 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003083 if size != sizeResponses[ i ]:
3084 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003085 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003086 " expected a size of " + str( size ) +
3087 " for set " + onosSetName +
3088 " but got " + str( sizeResponses[ i ] ) )
3089 addAllResults = addAllResults and getResults and sizeResults
3090 utilities.assert_equals( expect=main.TRUE,
3091 actual=addAllResults,
3092 onpass="Set addAll correct",
3093 onfail="Set addAll was incorrect" )
3094
3095 main.step( "Distributed Set clear()" )
3096 onosSet.clear()
3097 clearResponses = []
3098 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003099 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003100 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07003101 name="setTestClear-" + str( i ),
3102 args=[ onosSetName, " "], # Values doesn't matter
3103 kwargs={ "clear": True } )
3104 threads.append( t )
3105 t.start()
3106 for t in threads:
3107 t.join()
3108 clearResponses.append( t.result )
3109
3110 # main.TRUE = successfully changed the set
3111 # main.FALSE = action resulted in no change in set
3112 # main.ERROR - Some error in executing the function
3113 clearResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003114 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07003115 if clearResponses[ i ] == main.TRUE:
3116 # All is well
3117 pass
3118 elif clearResponses[ i ] == main.FALSE:
3119 # Nothing set, probably fine
3120 pass
3121 elif clearResponses[ i ] == main.ERROR:
3122 # Error in execution
3123 clearResults = main.FALSE
3124 else:
3125 # unexpected result
3126 clearResults = main.FALSE
3127 if clearResults != main.TRUE:
3128 main.log.error( "Error executing set clear" )
3129
3130 # Check if set is still correct
3131 size = len( onosSet )
3132 getResponses = []
3133 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003134 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003135 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003136 name="setTestGet-" + str( i ),
3137 args=[ onosSetName ] )
3138 threads.append( t )
3139 t.start()
3140 for t in threads:
3141 t.join()
3142 getResponses.append( t.result )
3143 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003144 for i in range( len( main.activeNodes ) ):
3145 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003146 if isinstance( getResponses[ i ], list):
3147 current = set( getResponses[ i ] )
3148 if len( current ) == len( getResponses[ i ] ):
3149 # no repeats
3150 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07003151 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003152 " has incorrect view" +
3153 " of set " + onosSetName + ":\n" +
3154 str( getResponses[ i ] ) )
3155 main.log.debug( "Expected: " + str( onosSet ) )
3156 main.log.debug( "Actual: " + str( current ) )
3157 getResults = main.FALSE
3158 else:
3159 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003160 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003161 " has repeat elements in" +
3162 " set " + onosSetName + ":\n" +
3163 str( getResponses[ i ] ) )
3164 getResults = main.FALSE
3165 elif getResponses[ i ] == main.ERROR:
3166 getResults = main.FALSE
3167 sizeResponses = []
3168 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003169 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003170 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003171 name="setTestSize-" + str( i ),
3172 args=[ onosSetName ] )
3173 threads.append( t )
3174 t.start()
3175 for t in threads:
3176 t.join()
3177 sizeResponses.append( t.result )
3178 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003179 for i in range( len( main.activeNodes ) ):
3180 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003181 if size != sizeResponses[ i ]:
3182 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003183 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003184 " expected a size of " + str( size ) +
3185 " for set " + onosSetName +
3186 " but got " + str( sizeResponses[ i ] ) )
3187 clearResults = clearResults and getResults and sizeResults
3188 utilities.assert_equals( expect=main.TRUE,
3189 actual=clearResults,
3190 onpass="Set clear correct",
3191 onfail="Set clear was incorrect" )
3192
3193 main.step( "Distributed Set addAll()" )
3194 onosSet.update( addAllValue.split() )
3195 addResponses = []
3196 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003197 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003198 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07003199 name="setTestAddAll-" + str( i ),
3200 args=[ onosSetName, addAllValue ] )
3201 threads.append( t )
3202 t.start()
3203 for t in threads:
3204 t.join()
3205 addResponses.append( t.result )
3206
3207 # main.TRUE = successfully changed the set
3208 # main.FALSE = action resulted in no change in set
3209 # main.ERROR - Some error in executing the function
3210 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003211 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07003212 if addResponses[ i ] == main.TRUE:
3213 # All is well
3214 pass
3215 elif addResponses[ i ] == main.FALSE:
3216 # Already in set, probably fine
3217 pass
3218 elif addResponses[ i ] == main.ERROR:
3219 # Error in execution
3220 addAllResults = main.FALSE
3221 else:
3222 # unexpected result
3223 addAllResults = main.FALSE
3224 if addAllResults != main.TRUE:
3225 main.log.error( "Error executing set addAll" )
3226
3227 # Check if set is still correct
3228 size = len( onosSet )
3229 getResponses = []
3230 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003231 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003232 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003233 name="setTestGet-" + str( i ),
3234 args=[ onosSetName ] )
3235 threads.append( t )
3236 t.start()
3237 for t in threads:
3238 t.join()
3239 getResponses.append( t.result )
3240 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003241 for i in range( len( main.activeNodes ) ):
3242 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003243 if isinstance( getResponses[ i ], list):
3244 current = set( getResponses[ i ] )
3245 if len( current ) == len( getResponses[ i ] ):
3246 # no repeats
3247 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07003248 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003249 " has incorrect view" +
3250 " of set " + onosSetName + ":\n" +
3251 str( getResponses[ i ] ) )
3252 main.log.debug( "Expected: " + str( onosSet ) )
3253 main.log.debug( "Actual: " + str( current ) )
3254 getResults = main.FALSE
3255 else:
3256 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003257 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003258 " has repeat elements in" +
3259 " set " + onosSetName + ":\n" +
3260 str( getResponses[ i ] ) )
3261 getResults = main.FALSE
3262 elif getResponses[ i ] == main.ERROR:
3263 getResults = main.FALSE
3264 sizeResponses = []
3265 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003266 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003267 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003268 name="setTestSize-" + str( i ),
3269 args=[ onosSetName ] )
3270 threads.append( t )
3271 t.start()
3272 for t in threads:
3273 t.join()
3274 sizeResponses.append( t.result )
3275 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003276 for i in range( len( main.activeNodes ) ):
3277 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003278 if size != sizeResponses[ i ]:
3279 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003280 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003281 " expected a size of " + str( size ) +
3282 " for set " + onosSetName +
3283 " but got " + str( sizeResponses[ i ] ) )
3284 addAllResults = addAllResults and getResults and sizeResults
3285 utilities.assert_equals( expect=main.TRUE,
3286 actual=addAllResults,
3287 onpass="Set addAll correct",
3288 onfail="Set addAll was incorrect" )
3289
3290 main.step( "Distributed Set retain()" )
3291 onosSet.intersection_update( retainValue.split() )
3292 retainResponses = []
3293 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003294 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003295 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07003296 name="setTestRetain-" + str( i ),
3297 args=[ onosSetName, retainValue ],
3298 kwargs={ "retain": True } )
3299 threads.append( t )
3300 t.start()
3301 for t in threads:
3302 t.join()
3303 retainResponses.append( t.result )
3304
3305 # main.TRUE = successfully changed the set
3306 # main.FALSE = action resulted in no change in set
3307 # main.ERROR - Some error in executing the function
3308 retainResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003309 for i in range( len( main.activeNodes ) ):
Jon Hall85794ff2015-07-08 14:12:30 -07003310 if retainResponses[ i ] == main.TRUE:
3311 # All is well
3312 pass
3313 elif retainResponses[ i ] == main.FALSE:
3314 # Already in set, probably fine
3315 pass
3316 elif retainResponses[ i ] == main.ERROR:
3317 # Error in execution
3318 retainResults = main.FALSE
3319 else:
3320 # unexpected result
3321 retainResults = main.FALSE
3322 if retainResults != main.TRUE:
3323 main.log.error( "Error executing set retain" )
3324
3325 # Check if set is still correct
3326 size = len( onosSet )
3327 getResponses = []
3328 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003329 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003330 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003331 name="setTestGet-" + str( i ),
3332 args=[ onosSetName ] )
3333 threads.append( t )
3334 t.start()
3335 for t in threads:
3336 t.join()
3337 getResponses.append( t.result )
3338 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003339 for i in range( len( main.activeNodes ) ):
3340 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003341 if isinstance( getResponses[ i ], list):
3342 current = set( getResponses[ i ] )
3343 if len( current ) == len( getResponses[ i ] ):
3344 # no repeats
3345 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07003346 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003347 " has incorrect view" +
3348 " of set " + onosSetName + ":\n" +
3349 str( getResponses[ i ] ) )
3350 main.log.debug( "Expected: " + str( onosSet ) )
3351 main.log.debug( "Actual: " + str( current ) )
3352 getResults = main.FALSE
3353 else:
3354 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003355 main.log.error( "ONOS" + node +
Jon Hall85794ff2015-07-08 14:12:30 -07003356 " has repeat elements in" +
3357 " set " + onosSetName + ":\n" +
3358 str( getResponses[ i ] ) )
3359 getResults = main.FALSE
3360 elif getResponses[ i ] == main.ERROR:
3361 getResults = main.FALSE
3362 sizeResponses = []
3363 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003364 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003365 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003366 name="setTestSize-" + str( i ),
3367 args=[ onosSetName ] )
3368 threads.append( t )
3369 t.start()
3370 for t in threads:
3371 t.join()
3372 sizeResponses.append( t.result )
3373 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003374 for i in range( len( main.activeNodes ) ):
3375 node = str( main.activeNodes[i] + 1 )
Jon Hall85794ff2015-07-08 14:12:30 -07003376 if size != sizeResponses[ i ]:
3377 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003378 main.log.error( "ONOS" + node + " expected a size of " +
Jon Hall85794ff2015-07-08 14:12:30 -07003379 str( size ) + " for set " + onosSetName +
3380 " but got " + str( sizeResponses[ i ] ) )
3381 retainResults = retainResults and getResults and sizeResults
3382 utilities.assert_equals( expect=main.TRUE,
3383 actual=retainResults,
3384 onpass="Set retain correct",
3385 onfail="Set retain was incorrect" )
3386
Jon Hall2a5002c2015-08-21 16:49:11 -07003387 # Transactional maps
3388 main.step( "Partitioned Transactional maps put" )
3389 tMapValue = "Testing"
3390 numKeys = 100
3391 putResult = True
Jon Halla440e872016-03-31 15:15:50 -07003392 node = main.activeNodes[0]
3393 putResponses = main.CLIs[node].transactionalMapPut( numKeys, tMapValue )
3394 if putResponses and len( putResponses ) == 100:
Jon Hall2a5002c2015-08-21 16:49:11 -07003395 for i in putResponses:
3396 if putResponses[ i ][ 'value' ] != tMapValue:
3397 putResult = False
3398 else:
3399 putResult = False
3400 if not putResult:
3401 main.log.debug( "Put response values: " + str( putResponses ) )
3402 utilities.assert_equals( expect=True,
3403 actual=putResult,
3404 onpass="Partitioned Transactional Map put successful",
3405 onfail="Partitioned Transactional Map put values are incorrect" )
3406
3407 main.step( "Partitioned Transactional maps get" )
3408 getCheck = True
3409 for n in range( 1, numKeys + 1 ):
3410 getResponses = []
3411 threads = []
3412 valueCheck = True
Jon Halla440e872016-03-31 15:15:50 -07003413 for i in main.activeNodes:
Jon Hall2a5002c2015-08-21 16:49:11 -07003414 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
3415 name="TMap-get-" + str( i ),
Jon Halla440e872016-03-31 15:15:50 -07003416 args=[ "Key" + str( n ) ] )
Jon Hall2a5002c2015-08-21 16:49:11 -07003417 threads.append( t )
3418 t.start()
3419 for t in threads:
3420 t.join()
3421 getResponses.append( t.result )
3422 for node in getResponses:
3423 if node != tMapValue:
3424 valueCheck = False
3425 if not valueCheck:
3426 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
3427 main.log.warn( getResponses )
3428 getCheck = getCheck and valueCheck
3429 utilities.assert_equals( expect=True,
3430 actual=getCheck,
3431 onpass="Partitioned Transactional Map get values were correct",
3432 onfail="Partitioned Transactional Map values incorrect" )