blob: 7b1acd47de5887a25055c8ace2cbbc0ae5c3835b [file] [log] [blame]
Jon Hall5cf14d52015-07-16 12:15:19 -07001"""
2Description: This test is to determine if ONOS can handle
3 all of it's nodes restarting
4
5List of test cases:
6CASE1: Compile ONOS and push it to the test machines
7CASE2: Assign devices to controllers
8CASE21: Assign mastership to controllers
9CASE3: Assign intents
10CASE4: Ping across added host intents
11CASE5: Reading state of ONOS
12CASE6: The Failure case.
13CASE7: Check state after control plane failure
14CASE8: Compare topo
15CASE9: Link s3-s28 down
16CASE10: Link s3-s28 up
17CASE11: Switch down
18CASE12: Switch up
19CASE13: Clean up
20CASE14: start election app on all onos nodes
21CASE15: Check that Leadership Election is still functional
22CASE16: Install Distributed Primitives app
23CASE17: Check for basic functionality with distributed primitives
24"""
25
26
27class HAclusterRestart:
28
29 def __init__( self ):
30 self.default = ''
31
32 def CASE1( self, main ):
33 """
34 CASE1 is to compile ONOS and push it to the test machines
35
36 Startup sequence:
37 cell <name>
38 onos-verify-cell
39 NOTE: temporary - onos-remove-raft-logs
40 onos-uninstall
41 start mininet
42 git pull
43 mvn clean install
44 onos-package
45 onos-install -f
46 onos-wait-for-start
47 start cli sessions
48 start tcpdump
49 """
Jon Halle1a3b752015-07-22 13:02:46 -070050 import imp
Jon Hallf3d16e72015-12-16 17:45:08 -080051 import time
Jon Halla440e872016-03-31 15:15:50 -070052 import json
Jon Hall5cf14d52015-07-16 12:15:19 -070053 main.log.info( "ONOS HA test: Restart all ONOS nodes - " +
54 "initialization" )
55 main.case( "Setting up test environment" )
Jon Hall783bbf92015-07-23 14:33:19 -070056 main.caseExplanation = "Setup the test environment including " +\
Jon Hall5cf14d52015-07-16 12:15:19 -070057 "installing ONOS, starting Mininet and ONOS" +\
58 "cli sessions."
Jon Hall5cf14d52015-07-16 12:15:19 -070059
60 # load some variables from the params file
61 PULLCODE = False
62 if main.params[ 'Git' ] == 'True':
63 PULLCODE = True
64 gitBranch = main.params[ 'branch' ]
65 cellName = main.params[ 'ENV' ][ 'cellName' ]
66
Jon Halle1a3b752015-07-22 13:02:46 -070067 main.numCtrls = int( main.params[ 'num_controllers' ] )
Jon Hall5cf14d52015-07-16 12:15:19 -070068 if main.ONOSbench.maxNodes:
Jon Halle1a3b752015-07-22 13:02:46 -070069 if main.ONOSbench.maxNodes < main.numCtrls:
70 main.numCtrls = int( main.ONOSbench.maxNodes )
71 # set global variables
Jon Hall5cf14d52015-07-16 12:15:19 -070072 global ONOS1Port
73 global ONOS2Port
74 global ONOS3Port
75 global ONOS4Port
76 global ONOS5Port
77 global ONOS6Port
78 global ONOS7Port
79 # These are for csv plotting in jenkins
80 global labels
81 global data
82 labels = []
83 data = []
84
85 # FIXME: just get controller port from params?
86 # TODO: do we really need all these?
87 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
88 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
89 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
90 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
91 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
92 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
93 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
94
Jon Halle1a3b752015-07-22 13:02:46 -070095 try:
Jon Halla440e872016-03-31 15:15:50 -070096 from tests.HAsanity.dependencies.Counters import Counters
97 main.Counters = Counters()
Jon Halle1a3b752015-07-22 13:02:46 -070098 except Exception as e:
99 main.log.exception( e )
100 main.cleanup()
101 main.exit()
102
103 main.CLIs = []
104 main.nodes = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700105 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700106 for i in range( 1, main.numCtrls + 1 ):
107 try:
108 main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
109 main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
110 ipList.append( main.nodes[ -1 ].ip_address )
111 except AttributeError:
112 break
Jon Hall5cf14d52015-07-16 12:15:19 -0700113
114 main.step( "Create cell file" )
115 cellAppString = main.params[ 'ENV' ][ 'appString' ]
116 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
117 main.Mininet1.ip_address,
118 cellAppString, ipList )
119 main.step( "Applying cell variable to environment" )
120 cellResult = main.ONOSbench.setCell( cellName )
121 verifyResult = main.ONOSbench.verifyCell()
122
123 # FIXME:this is short term fix
124 main.log.info( "Removing raft logs" )
125 main.ONOSbench.onosRemoveRaftLogs()
126
127 main.log.info( "Uninstalling ONOS" )
Jon Halle1a3b752015-07-22 13:02:46 -0700128 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700129 main.ONOSbench.onosUninstall( node.ip_address )
130
131 # Make sure ONOS is DEAD
132 main.log.info( "Killing any ONOS processes" )
133 killResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700134 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700135 killed = main.ONOSbench.onosKill( node.ip_address )
136 killResults = killResults and killed
137
138 cleanInstallResult = main.TRUE
139 gitPullResult = main.TRUE
140
141 main.step( "Starting Mininet" )
142 # scp topo file to mininet
143 # TODO: move to params?
144 topoName = "obelisk.py"
145 filePath = main.ONOSbench.home + "/tools/test/topos/"
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700146 main.ONOSbench.scp( main.Mininet1,
147 filePath + topoName,
148 main.Mininet1.home,
149 direction="to" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700150 mnResult = main.Mininet1.startNet( )
151 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
152 onpass="Mininet Started",
153 onfail="Error starting Mininet" )
154
155 main.step( "Git checkout and pull " + gitBranch )
156 if PULLCODE:
157 main.ONOSbench.gitCheckout( gitBranch )
158 gitPullResult = main.ONOSbench.gitPull()
159 # values of 1 or 3 are good
160 utilities.assert_lesser( expect=0, actual=gitPullResult,
161 onpass="Git pull successful",
162 onfail="Git pull failed" )
163 main.ONOSbench.getVersion( report=True )
164
165 main.step( "Using mvn clean install" )
166 cleanInstallResult = main.TRUE
167 if PULLCODE and gitPullResult == main.TRUE:
168 cleanInstallResult = main.ONOSbench.cleanInstall()
169 else:
170 main.log.warn( "Did not pull new code so skipping mvn " +
171 "clean install" )
172 utilities.assert_equals( expect=main.TRUE,
173 actual=cleanInstallResult,
174 onpass="MCI successful",
175 onfail="MCI failed" )
176 # GRAPHS
177 # NOTE: important params here:
178 # job = name of Jenkins job
179 # Plot Name = Plot-HA, only can be used if multiple plots
180 # index = The number of the graph under plot name
181 job = "HAclusterRestart"
182 plotName = "Plot-HA"
Jon Hall843f8bc2016-03-18 14:28:13 -0700183 index = "2"
Jon Hall5cf14d52015-07-16 12:15:19 -0700184 graphs = '<ac:structured-macro ac:name="html">\n'
185 graphs += '<ac:plain-text-body><![CDATA[\n'
186 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
Jon Halla9845df2016-01-15 14:55:58 -0800187 '/plot/' + plotName + '/getPlot?index=' + index +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700188 '&width=500&height=300"' +\
189 'noborder="0" width="500" height="300" scrolling="yes" ' +\
190 'seamless="seamless"></iframe>\n'
191 graphs += ']]></ac:plain-text-body>\n'
192 graphs += '</ac:structured-macro>\n'
193 main.log.wiki(graphs)
194
195 main.step( "Creating ONOS package" )
196 packageResult = main.ONOSbench.onosPackage()
197 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
198 onpass="ONOS package successful",
199 onfail="ONOS package failed" )
200
201 main.step( "Installing ONOS package" )
202 onosInstallResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700203 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700204 tmpResult = main.ONOSbench.onosInstall( options="-f",
205 node=node.ip_address )
206 onosInstallResult = onosInstallResult and tmpResult
207 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
208 onpass="ONOS install successful",
209 onfail="ONOS install failed" )
210
211 main.step( "Checking if ONOS is up yet" )
212 for i in range( 2 ):
213 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700214 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700215 started = main.ONOSbench.isup( node.ip_address )
216 if not started:
Jon Hallc6793552016-01-19 14:18:37 -0800217 main.log.error( node.name + " hasn't started" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700218 onosIsupResult = onosIsupResult and started
219 if onosIsupResult == main.TRUE:
220 break
221 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
222 onpass="ONOS startup successful",
223 onfail="ONOS startup failed" )
224
225 main.log.step( "Starting ONOS CLI sessions" )
226 cliResults = main.TRUE
227 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700228 for i in range( main.numCtrls ):
229 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -0700230 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -0700231 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -0700232 threads.append( t )
233 t.start()
234
235 for t in threads:
236 t.join()
237 cliResults = cliResults and t.result
238 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
239 onpass="ONOS cli startup successful",
240 onfail="ONOS cli startup failed" )
241
Jon Halla440e872016-03-31 15:15:50 -0700242 # Create a list of active nodes for use when some nodes are stopped
243 main.activeNodes = [ i for i in range( 0, len( main.CLIs ) ) ]
244
Jon Hall5cf14d52015-07-16 12:15:19 -0700245 if main.params[ 'tcpdump' ].lower() == "true":
246 main.step( "Start Packet Capture MN" )
247 main.Mininet2.startTcpdump(
248 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
249 + "-MN.pcap",
250 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
251 port=main.params[ 'MNtcpdump' ][ 'port' ] )
252
253 main.step( "App Ids check" )
254 appCheck = main.TRUE
255 threads = []
Jon Halla440e872016-03-31 15:15:50 -0700256 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -0700257 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700258 name="appToIDCheck-" + str( i ),
259 args=[] )
260 threads.append( t )
261 t.start()
262
263 for t in threads:
264 t.join()
265 appCheck = appCheck and t.result
266 if appCheck != main.TRUE:
Jon Halla440e872016-03-31 15:15:50 -0700267 node = main.activeNodes[0]
268 main.log.warn( main.CLIs[node].apps() )
269 main.log.warn( main.CLIs[node].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700270 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
271 onpass="App Ids seem to be correct",
272 onfail="Something is wrong with app Ids" )
273
Jon Halla440e872016-03-31 15:15:50 -0700274 main.step( "Checking ONOS nodes" )
275 nodesOutput = []
276 nodeResults = main.TRUE
277 threads = []
278 for i in main.activeNodes:
279 t = main.Thread( target=main.CLIs[i].nodes,
280 name="nodes-" + str( i ),
281 args=[ ] )
282 threads.append( t )
283 t.start()
284
285 for t in threads:
286 t.join()
287 nodesOutput.append( t.result )
288 ips = [ main.nodes[node].ip_address for node in main.activeNodes ]
289 ips.sort()
290 for i in nodesOutput:
291 try:
292 current = json.loads( i )
293 activeIps = []
294 currentResult = main.FALSE
295 for node in current:
296 if node['state'] == 'READY':
297 activeIps.append( node['ip'] )
298 activeIps.sort()
299 if ips == activeIps:
300 currentResult = main.TRUE
301 except ( ValueError, TypeError ):
302 main.log.error( "Error parsing nodes output" )
303 main.log.warn( repr( i ) )
304 currentResult = main.FALSE
305 nodeResults = nodeResults and currentResult
306 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
307 onpass="Nodes check successful",
308 onfail="Nodes check NOT successful" )
309
310 if not nodeResults:
311 for cli in main.CLIs:
312 main.log.debug( "{} components not ACTIVE: \n{}".format(
313 cli.name,
314 cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
315
Jon Hall5cf14d52015-07-16 12:15:19 -0700316 if cliResults == main.FALSE:
317 main.log.error( "Failed to start ONOS, stopping test" )
318 main.cleanup()
319 main.exit()
320
321 def CASE2( self, main ):
322 """
323 Assign devices to controllers
324 """
325 import re
Jon Halle1a3b752015-07-22 13:02:46 -0700326 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700327 assert main, "main not defined"
328 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700329 assert main.CLIs, "main.CLIs not defined"
330 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700331 assert ONOS1Port, "ONOS1Port not defined"
332 assert ONOS2Port, "ONOS2Port not defined"
333 assert ONOS3Port, "ONOS3Port not defined"
334 assert ONOS4Port, "ONOS4Port not defined"
335 assert ONOS5Port, "ONOS5Port not defined"
336 assert ONOS6Port, "ONOS6Port not defined"
337 assert ONOS7Port, "ONOS7Port not defined"
338
339 main.case( "Assigning devices to controllers" )
Jon Hall783bbf92015-07-23 14:33:19 -0700340 main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700341 "and check that an ONOS node becomes the " +\
342 "master of the device."
343 main.step( "Assign switches to controllers" )
344
345 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700346 for i in range( main.numCtrls ):
347 ipList.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -0700348 swList = []
349 for i in range( 1, 29 ):
350 swList.append( "s" + str( i ) )
351 main.Mininet1.assignSwController( sw=swList, ip=ipList )
352
353 mastershipCheck = main.TRUE
354 for i in range( 1, 29 ):
355 response = main.Mininet1.getSwController( "s" + str( i ) )
356 try:
357 main.log.info( str( response ) )
358 except Exception:
359 main.log.info( repr( response ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700360 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700361 if re.search( "tcp:" + node.ip_address, response ):
362 mastershipCheck = mastershipCheck and main.TRUE
363 else:
364 main.log.error( "Error, node " + node.ip_address + " is " +
365 "not in the list of controllers s" +
366 str( i ) + " is connecting to." )
367 mastershipCheck = main.FALSE
368 utilities.assert_equals(
369 expect=main.TRUE,
370 actual=mastershipCheck,
371 onpass="Switch mastership assigned correctly",
372 onfail="Switches not assigned correctly to controllers" )
373
374 def CASE21( self, main ):
375 """
376 Assign mastership to controllers
377 """
Jon Hall5cf14d52015-07-16 12:15:19 -0700378 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700379 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700380 assert main, "main not defined"
381 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700382 assert main.CLIs, "main.CLIs not defined"
383 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700384 assert ONOS1Port, "ONOS1Port not defined"
385 assert ONOS2Port, "ONOS2Port not defined"
386 assert ONOS3Port, "ONOS3Port not defined"
387 assert ONOS4Port, "ONOS4Port not defined"
388 assert ONOS5Port, "ONOS5Port not defined"
389 assert ONOS6Port, "ONOS6Port not defined"
390 assert ONOS7Port, "ONOS7Port not defined"
391
392 main.case( "Assigning Controller roles for switches" )
Jon Hall783bbf92015-07-23 14:33:19 -0700393 main.caseExplanation = "Check that ONOS is connected to each " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700394 "device. Then manually assign" +\
395 " mastership to specific ONOS nodes using" +\
396 " 'device-role'"
397 main.step( "Assign mastership of switches to specific controllers" )
398 # Manually assign mastership to the controller we want
399 roleCall = main.TRUE
400
401 ipList = [ ]
402 deviceList = []
Jon Halla440e872016-03-31 15:15:50 -0700403 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -0700404 try:
405 # Assign mastership to specific controllers. This assignment was
406 # determined for a 7 node cluser, but will work with any sized
407 # cluster
408 for i in range( 1, 29 ): # switches 1 through 28
409 # set up correct variables:
410 if i == 1:
411 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700412 ip = main.nodes[ c ].ip_address # ONOS1
Jon Halla440e872016-03-31 15:15:50 -0700413 deviceId = onosCli.getDevice( "1000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700414 elif i == 2:
Jon Halle1a3b752015-07-22 13:02:46 -0700415 c = 1 % main.numCtrls
416 ip = main.nodes[ c ].ip_address # ONOS2
Jon Halla440e872016-03-31 15:15:50 -0700417 deviceId = onosCli.getDevice( "2000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700418 elif i == 3:
Jon Halle1a3b752015-07-22 13:02:46 -0700419 c = 1 % main.numCtrls
420 ip = main.nodes[ c ].ip_address # ONOS2
Jon Halla440e872016-03-31 15:15:50 -0700421 deviceId = onosCli.getDevice( "3000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700422 elif i == 4:
Jon Halle1a3b752015-07-22 13:02:46 -0700423 c = 3 % main.numCtrls
424 ip = main.nodes[ c ].ip_address # ONOS4
Jon Halla440e872016-03-31 15:15:50 -0700425 deviceId = onosCli.getDevice( "3004" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700426 elif i == 5:
Jon Halle1a3b752015-07-22 13:02:46 -0700427 c = 2 % main.numCtrls
428 ip = main.nodes[ c ].ip_address # ONOS3
Jon Halla440e872016-03-31 15:15:50 -0700429 deviceId = onosCli.getDevice( "5000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700430 elif i == 6:
Jon Halle1a3b752015-07-22 13:02:46 -0700431 c = 2 % main.numCtrls
432 ip = main.nodes[ c ].ip_address # ONOS3
Jon Halla440e872016-03-31 15:15:50 -0700433 deviceId = onosCli.getDevice( "6000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700434 elif i == 7:
Jon Halle1a3b752015-07-22 13:02:46 -0700435 c = 5 % main.numCtrls
436 ip = main.nodes[ c ].ip_address # ONOS6
Jon Halla440e872016-03-31 15:15:50 -0700437 deviceId = onosCli.getDevice( "6007" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700438 elif i >= 8 and i <= 17:
Jon Halle1a3b752015-07-22 13:02:46 -0700439 c = 4 % main.numCtrls
440 ip = main.nodes[ c ].ip_address # ONOS5
Jon Hall5cf14d52015-07-16 12:15:19 -0700441 dpid = '3' + str( i ).zfill( 3 )
Jon Halla440e872016-03-31 15:15:50 -0700442 deviceId = onosCli.getDevice( dpid ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700443 elif i >= 18 and i <= 27:
Jon Halle1a3b752015-07-22 13:02:46 -0700444 c = 6 % main.numCtrls
445 ip = main.nodes[ c ].ip_address # ONOS7
Jon Hall5cf14d52015-07-16 12:15:19 -0700446 dpid = '6' + str( i ).zfill( 3 )
Jon Halla440e872016-03-31 15:15:50 -0700447 deviceId = onosCli.getDevice( dpid ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700448 elif i == 28:
449 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700450 ip = main.nodes[ c ].ip_address # ONOS1
Jon Halla440e872016-03-31 15:15:50 -0700451 deviceId = onosCli.getDevice( "2800" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700452 else:
453 main.log.error( "You didn't write an else statement for " +
454 "switch s" + str( i ) )
455 roleCall = main.FALSE
456 # Assign switch
457 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
458 # TODO: make this controller dynamic
Jon Halla440e872016-03-31 15:15:50 -0700459 roleCall = roleCall and onosCli.deviceRole( deviceId, ip )
Jon Hall5cf14d52015-07-16 12:15:19 -0700460 ipList.append( ip )
461 deviceList.append( deviceId )
462 except ( AttributeError, AssertionError ):
463 main.log.exception( "Something is wrong with ONOS device view" )
Jon Halla440e872016-03-31 15:15:50 -0700464 main.log.info( onosCli.devices() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700465 utilities.assert_equals(
466 expect=main.TRUE,
467 actual=roleCall,
468 onpass="Re-assigned switch mastership to designated controller",
469 onfail="Something wrong with deviceRole calls" )
470
471 main.step( "Check mastership was correctly assigned" )
472 roleCheck = main.TRUE
473 # NOTE: This is due to the fact that device mastership change is not
474 # atomic and is actually a multi step process
475 time.sleep( 5 )
476 for i in range( len( ipList ) ):
477 ip = ipList[i]
478 deviceId = deviceList[i]
479 # Check assignment
Jon Halla440e872016-03-31 15:15:50 -0700480 master = onosCli.getRole( deviceId ).get( 'master' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700481 if ip in master:
482 roleCheck = roleCheck and main.TRUE
483 else:
484 roleCheck = roleCheck and main.FALSE
485 main.log.error( "Error, controller " + ip + " is not" +
486 " master " + "of device " +
487 str( deviceId ) + ". Master is " +
488 repr( master ) + "." )
489 utilities.assert_equals(
490 expect=main.TRUE,
491 actual=roleCheck,
492 onpass="Switches were successfully reassigned to designated " +
493 "controller",
494 onfail="Switches were not successfully reassigned" )
495
496 def CASE3( self, main ):
497 """
498 Assign intents
499 """
500 import time
501 import json
Jon Halle1a3b752015-07-22 13:02:46 -0700502 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700503 assert main, "main not defined"
504 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700505 assert main.CLIs, "main.CLIs not defined"
506 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700507 try:
508 labels
509 except NameError:
510 main.log.error( "labels not defined, setting to []" )
511 labels = []
512 try:
513 data
514 except NameError:
515 main.log.error( "data not defined, setting to []" )
516 data = []
517 # NOTE: we must reinstall intents until we have a persistant intent
518 # datastore!
519 main.case( "Adding host Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700520 main.caseExplanation = "Discover hosts by using pingall then " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700521 "assign predetermined host-to-host intents." +\
522 " After installation, check that the intent" +\
523 " is distributed to all nodes and the state" +\
524 " is INSTALLED"
525
526 # install onos-app-fwd
527 main.step( "Install reactive forwarding app" )
Jon Halla440e872016-03-31 15:15:50 -0700528 onosCli = main.CLIs[ main.activeNodes[0] ]
529 installResults = onosCli.activateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700530 utilities.assert_equals( expect=main.TRUE, actual=installResults,
531 onpass="Install fwd successful",
532 onfail="Install fwd failed" )
533
534 main.step( "Check app ids" )
535 appCheck = main.TRUE
536 threads = []
Jon Halla440e872016-03-31 15:15:50 -0700537 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -0700538 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700539 name="appToIDCheck-" + str( i ),
540 args=[] )
541 threads.append( t )
542 t.start()
543
544 for t in threads:
545 t.join()
546 appCheck = appCheck and t.result
547 if appCheck != main.TRUE:
Jon Halla440e872016-03-31 15:15:50 -0700548 main.log.warn( onosCli.apps() )
549 main.log.warn( onosCli.appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700550 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
551 onpass="App Ids seem to be correct",
552 onfail="Something is wrong with app Ids" )
553
554 main.step( "Discovering Hosts( Via pingall for now )" )
555 # FIXME: Once we have a host discovery mechanism, use that instead
556 # REACTIVE FWD test
557 pingResult = main.FALSE
Jon Hall96091e62015-09-21 17:34:17 -0700558 passMsg = "Reactive Pingall test passed"
559 time1 = time.time()
560 pingResult = main.Mininet1.pingall()
561 time2 = time.time()
562 if not pingResult:
563 main.log.warn("First pingall failed. Trying again...")
Jon Hall5cf14d52015-07-16 12:15:19 -0700564 pingResult = main.Mininet1.pingall()
Jon Hall96091e62015-09-21 17:34:17 -0700565 passMsg += " on the second try"
566 utilities.assert_equals(
567 expect=main.TRUE,
568 actual=pingResult,
569 onpass= passMsg,
570 onfail="Reactive Pingall failed, " +
571 "one or more ping pairs failed" )
572 main.log.info( "Time for pingall: %2f seconds" %
573 ( time2 - time1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -0700574 # timeout for fwd flows
575 time.sleep( 11 )
576 # uninstall onos-app-fwd
577 main.step( "Uninstall reactive forwarding app" )
Jon Halla440e872016-03-31 15:15:50 -0700578 node = main.activeNodes[0]
579 uninstallResult = main.CLIs[node].deactivateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700580 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
581 onpass="Uninstall fwd successful",
582 onfail="Uninstall fwd failed" )
583
584 main.step( "Check app ids" )
585 threads = []
586 appCheck2 = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -0700587 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -0700588 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700589 name="appToIDCheck-" + str( i ),
590 args=[] )
591 threads.append( t )
592 t.start()
593
594 for t in threads:
595 t.join()
596 appCheck2 = appCheck2 and t.result
597 if appCheck2 != main.TRUE:
Jon Halla440e872016-03-31 15:15:50 -0700598 node = main.activeNodes[0]
599 main.log.warn( main.CLIs[node].apps() )
600 main.log.warn( main.CLIs[node].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700601 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
602 onpass="App Ids seem to be correct",
603 onfail="Something is wrong with app Ids" )
604
605 main.step( "Add host intents via cli" )
606 intentIds = []
Jon Hall6e709752016-02-01 13:38:46 -0800607 # TODO: move the host numbers to params
608 # Maybe look at all the paths we ping?
Jon Hall5cf14d52015-07-16 12:15:19 -0700609 intentAddResult = True
610 hostResult = main.TRUE
611 for i in range( 8, 18 ):
612 main.log.info( "Adding host intent between h" + str( i ) +
613 " and h" + str( i + 10 ) )
614 host1 = "00:00:00:00:00:" + \
615 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
616 host2 = "00:00:00:00:00:" + \
617 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
618 # NOTE: getHost can return None
Jon Halla440e872016-03-31 15:15:50 -0700619 host1Dict = onosCli.getHost( host1 )
620 host2Dict = onosCli.getHost( host2 )
Jon Hall5cf14d52015-07-16 12:15:19 -0700621 host1Id = None
622 host2Id = None
623 if host1Dict and host2Dict:
624 host1Id = host1Dict.get( 'id', None )
625 host2Id = host2Dict.get( 'id', None )
626 if host1Id and host2Id:
Jon Halla440e872016-03-31 15:15:50 -0700627 nodeNum = ( i % len( main.activeNodes ) )
628 node = main.activeNodes[nodeNum]
629 tmpId = main.CLIs[node].addHostIntent( host1Id, host2Id )
Jon Hall5cf14d52015-07-16 12:15:19 -0700630 if tmpId:
631 main.log.info( "Added intent with id: " + tmpId )
632 intentIds.append( tmpId )
633 else:
634 main.log.error( "addHostIntent returned: " +
635 repr( tmpId ) )
636 else:
637 main.log.error( "Error, getHost() failed for h" + str( i ) +
638 " and/or h" + str( i + 10 ) )
Jon Halla440e872016-03-31 15:15:50 -0700639 node = main.activeNodes[0]
640 hosts = main.CLIs[node].hosts()
Jon Hall5cf14d52015-07-16 12:15:19 -0700641 main.log.warn( "Hosts output: " )
642 try:
643 main.log.warn( json.dumps( json.loads( hosts ),
644 sort_keys=True,
645 indent=4,
646 separators=( ',', ': ' ) ) )
647 except ( ValueError, TypeError ):
648 main.log.warn( repr( hosts ) )
649 hostResult = main.FALSE
650 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
651 onpass="Found a host id for each host",
652 onfail="Error looking up host ids" )
653
654 intentStart = time.time()
Jon Halla440e872016-03-31 15:15:50 -0700655 onosIds = onosCli.getAllIntentsId()
Jon Hall5cf14d52015-07-16 12:15:19 -0700656 main.log.info( "Submitted intents: " + str( intentIds ) )
657 main.log.info( "Intents in ONOS: " + str( onosIds ) )
658 for intent in intentIds:
659 if intent in onosIds:
660 pass # intent submitted is in onos
661 else:
662 intentAddResult = False
663 if intentAddResult:
664 intentStop = time.time()
665 else:
666 intentStop = None
667 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -0700668 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700669 intentStates = []
670 installedCheck = True
671 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
672 count = 0
673 try:
674 for intent in json.loads( intents ):
675 state = intent.get( 'state', None )
676 if "INSTALLED" not in state:
677 installedCheck = False
678 intentId = intent.get( 'id', None )
679 intentStates.append( ( intentId, state ) )
680 except ( ValueError, TypeError ):
681 main.log.exception( "Error parsing intents" )
682 # add submitted intents not in the store
683 tmplist = [ i for i, s in intentStates ]
684 missingIntents = False
685 for i in intentIds:
686 if i not in tmplist:
687 intentStates.append( ( i, " - " ) )
688 missingIntents = True
689 intentStates.sort()
690 for i, s in intentStates:
691 count += 1
692 main.log.info( "%-6s%-15s%-15s" %
693 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -0700694 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -0700695 try:
696 missing = False
697 if leaders:
698 parsedLeaders = json.loads( leaders )
699 main.log.warn( json.dumps( parsedLeaders,
700 sort_keys=True,
701 indent=4,
702 separators=( ',', ': ' ) ) )
703 # check for all intent partitions
704 topics = []
705 for i in range( 14 ):
706 topics.append( "intent-partition-" + str( i ) )
707 main.log.debug( topics )
708 ONOStopics = [ j['topic'] for j in parsedLeaders ]
709 for topic in topics:
710 if topic not in ONOStopics:
711 main.log.error( "Error: " + topic +
712 " not in leaders" )
713 missing = True
714 else:
715 main.log.error( "leaders() returned None" )
716 except ( ValueError, TypeError ):
717 main.log.exception( "Error parsing leaders" )
718 main.log.error( repr( leaders ) )
719 # Check all nodes
720 if missing:
Jon Halla440e872016-03-31 15:15:50 -0700721 for i in main.activeNodes:
722 response = main.CLIs[i].leaders( jsonFormat=False)
723 main.log.warn( str( main.CLIs[i].name ) + " leaders output: \n" +
Jon Hall5cf14d52015-07-16 12:15:19 -0700724 str( response ) )
725
Jon Halla440e872016-03-31 15:15:50 -0700726 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -0700727 try:
728 if partitions :
729 parsedPartitions = json.loads( partitions )
730 main.log.warn( json.dumps( parsedPartitions,
731 sort_keys=True,
732 indent=4,
733 separators=( ',', ': ' ) ) )
734 # TODO check for a leader in all paritions
735 # TODO check for consistency among nodes
736 else:
737 main.log.error( "partitions() returned None" )
738 except ( ValueError, TypeError ):
739 main.log.exception( "Error parsing partitions" )
740 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -0700741 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -0700742 try:
743 if pendingMap :
744 parsedPending = json.loads( pendingMap )
745 main.log.warn( json.dumps( parsedPending,
746 sort_keys=True,
747 indent=4,
748 separators=( ',', ': ' ) ) )
749 # TODO check something here?
750 else:
751 main.log.error( "pendingMap() returned None" )
752 except ( ValueError, TypeError ):
753 main.log.exception( "Error parsing pending map" )
754 main.log.error( repr( pendingMap ) )
755
756 intentAddResult = bool( intentAddResult and not missingIntents and
757 installedCheck )
758 if not intentAddResult:
759 main.log.error( "Error in pushing host intents to ONOS" )
760
761 main.step( "Intent Anti-Entropy dispersion" )
Jon Halla440e872016-03-31 15:15:50 -0700762 for j in range(100):
Jon Hall5cf14d52015-07-16 12:15:19 -0700763 correct = True
764 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Halla440e872016-03-31 15:15:50 -0700765 for i in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700766 onosIds = []
Jon Halla440e872016-03-31 15:15:50 -0700767 ids = main.CLIs[i].getAllIntentsId()
Jon Hall5cf14d52015-07-16 12:15:19 -0700768 onosIds.append( ids )
Jon Halla440e872016-03-31 15:15:50 -0700769 main.log.debug( "Intents in " + main.CLIs[i].name + ": " +
Jon Hall5cf14d52015-07-16 12:15:19 -0700770 str( sorted( onosIds ) ) )
771 if sorted( ids ) != sorted( intentIds ):
772 main.log.warn( "Set of intent IDs doesn't match" )
773 correct = False
774 break
775 else:
Jon Halla440e872016-03-31 15:15:50 -0700776 intents = json.loads( main.CLIs[i].intents() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700777 for intent in intents:
778 if intent[ 'state' ] != "INSTALLED":
779 main.log.warn( "Intent " + intent[ 'id' ] +
780 " is " + intent[ 'state' ] )
781 correct = False
782 break
783 if correct:
784 break
785 else:
786 time.sleep(1)
787 if not intentStop:
788 intentStop = time.time()
789 global gossipTime
790 gossipTime = intentStop - intentStart
791 main.log.info( "It took about " + str( gossipTime ) +
792 " seconds for all intents to appear in each node" )
793 append = False
794 title = "Gossip Intents"
795 count = 1
796 while append is False:
797 curTitle = title + str( count )
798 if curTitle not in labels:
799 labels.append( curTitle )
800 data.append( str( gossipTime ) )
801 append = True
802 else:
803 count += 1
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700804 gossipPeriod = int( main.params['timers']['gossip'] )
Jon Halla440e872016-03-31 15:15:50 -0700805 maxGossipTime = gossipPeriod * len( main.activeNodes )
Jon Hall5cf14d52015-07-16 12:15:19 -0700806 utilities.assert_greater_equals(
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700807 expect=maxGossipTime, actual=gossipTime,
Jon Hall5cf14d52015-07-16 12:15:19 -0700808 onpass="ECM anti-entropy for intents worked within " +
809 "expected time",
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700810 onfail="Intent ECM anti-entropy took too long. " +
811 "Expected time:{}, Actual time:{}".format( maxGossipTime,
812 gossipTime ) )
813 if gossipTime <= maxGossipTime:
Jon Hall5cf14d52015-07-16 12:15:19 -0700814 intentAddResult = True
815
816 if not intentAddResult or "key" in pendingMap:
817 import time
818 installedCheck = True
819 main.log.info( "Sleeping 60 seconds to see if intents are found" )
820 time.sleep( 60 )
Jon Halla440e872016-03-31 15:15:50 -0700821 onosIds = onosCli.getAllIntentsId()
Jon Hall5cf14d52015-07-16 12:15:19 -0700822 main.log.info( "Submitted intents: " + str( intentIds ) )
823 main.log.info( "Intents in ONOS: " + str( onosIds ) )
824 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -0700825 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700826 intentStates = []
827 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
828 count = 0
829 try:
830 for intent in json.loads( intents ):
831 # Iter through intents of a node
832 state = intent.get( 'state', None )
833 if "INSTALLED" not in state:
834 installedCheck = False
835 intentId = intent.get( 'id', None )
836 intentStates.append( ( intentId, state ) )
837 except ( ValueError, TypeError ):
838 main.log.exception( "Error parsing intents" )
839 # add submitted intents not in the store
840 tmplist = [ i for i, s in intentStates ]
841 for i in intentIds:
842 if i not in tmplist:
843 intentStates.append( ( i, " - " ) )
844 intentStates.sort()
845 for i, s in intentStates:
846 count += 1
847 main.log.info( "%-6s%-15s%-15s" %
848 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -0700849 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -0700850 try:
851 missing = False
852 if leaders:
853 parsedLeaders = json.loads( leaders )
854 main.log.warn( json.dumps( parsedLeaders,
855 sort_keys=True,
856 indent=4,
857 separators=( ',', ': ' ) ) )
858 # check for all intent partitions
859 # check for election
860 topics = []
861 for i in range( 14 ):
862 topics.append( "intent-partition-" + str( i ) )
863 # FIXME: this should only be after we start the app
864 topics.append( "org.onosproject.election" )
865 main.log.debug( topics )
866 ONOStopics = [ j['topic'] for j in parsedLeaders ]
867 for topic in topics:
868 if topic not in ONOStopics:
869 main.log.error( "Error: " + topic +
870 " not in leaders" )
871 missing = True
872 else:
873 main.log.error( "leaders() returned None" )
874 except ( ValueError, TypeError ):
875 main.log.exception( "Error parsing leaders" )
876 main.log.error( repr( leaders ) )
877 # Check all nodes
878 if missing:
Jon Halla440e872016-03-31 15:15:50 -0700879 for i in main.activeNodes:
880 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -0700881 response = node.leaders( jsonFormat=False)
882 main.log.warn( str( node.name ) + " leaders output: \n" +
883 str( response ) )
884
Jon Halla440e872016-03-31 15:15:50 -0700885 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -0700886 try:
887 if partitions :
888 parsedPartitions = json.loads( partitions )
889 main.log.warn( json.dumps( parsedPartitions,
890 sort_keys=True,
891 indent=4,
892 separators=( ',', ': ' ) ) )
893 # TODO check for a leader in all paritions
894 # TODO check for consistency among nodes
895 else:
896 main.log.error( "partitions() returned None" )
897 except ( ValueError, TypeError ):
898 main.log.exception( "Error parsing partitions" )
899 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -0700900 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -0700901 try:
902 if pendingMap :
903 parsedPending = json.loads( pendingMap )
904 main.log.warn( json.dumps( parsedPending,
905 sort_keys=True,
906 indent=4,
907 separators=( ',', ': ' ) ) )
908 # TODO check something here?
909 else:
910 main.log.error( "pendingMap() returned None" )
911 except ( ValueError, TypeError ):
912 main.log.exception( "Error parsing pending map" )
913 main.log.error( repr( pendingMap ) )
914
915 def CASE4( self, main ):
916 """
917 Ping across added host intents
918 """
919 import json
920 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700921 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700922 assert main, "main not defined"
923 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700924 assert main.CLIs, "main.CLIs not defined"
925 assert main.nodes, "main.nodes not defined"
Jon Hall6e709752016-02-01 13:38:46 -0800926 main.case( "Verify connectivity by sending traffic across Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700927 main.caseExplanation = "Ping across added host intents to check " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700928 "functionality and check the state of " +\
929 "the intent"
930 main.step( "Ping across added host intents" )
Jon Halla440e872016-03-31 15:15:50 -0700931 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -0700932 PingResult = main.TRUE
933 for i in range( 8, 18 ):
934 ping = main.Mininet1.pingHost( src="h" + str( i ),
935 target="h" + str( i + 10 ) )
936 PingResult = PingResult and ping
937 if ping == main.FALSE:
938 main.log.warn( "Ping failed between h" + str( i ) +
939 " and h" + str( i + 10 ) )
940 elif ping == main.TRUE:
941 main.log.info( "Ping test passed!" )
942 # Don't set PingResult or you'd override failures
943 if PingResult == main.FALSE:
944 main.log.error(
945 "Intents have not been installed correctly, pings failed." )
946 # TODO: pretty print
947 main.log.warn( "ONOS1 intents: " )
948 try:
Jon Halla440e872016-03-31 15:15:50 -0700949 tmpIntents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700950 main.log.warn( json.dumps( json.loads( tmpIntents ),
951 sort_keys=True,
952 indent=4,
953 separators=( ',', ': ' ) ) )
954 except ( ValueError, TypeError ):
955 main.log.warn( repr( tmpIntents ) )
956 utilities.assert_equals(
957 expect=main.TRUE,
958 actual=PingResult,
959 onpass="Intents have been installed correctly and pings work",
960 onfail="Intents have not been installed correctly, pings failed." )
961
962 main.step( "Check Intent state" )
963 installedCheck = False
964 loopCount = 0
965 while not installedCheck and loopCount < 40:
966 installedCheck = True
967 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -0700968 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700969 intentStates = []
970 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700971 count = 0
Jon Hall5cf14d52015-07-16 12:15:19 -0700972 # Iter through intents of a node
973 try:
974 for intent in json.loads( intents ):
975 state = intent.get( 'state', None )
976 if "INSTALLED" not in state:
977 installedCheck = False
978 intentId = intent.get( 'id', None )
979 intentStates.append( ( intentId, state ) )
980 except ( ValueError, TypeError ):
981 main.log.exception( "Error parsing intents." )
982 # Print states
983 intentStates.sort()
984 for i, s in intentStates:
985 count += 1
986 main.log.info( "%-6s%-15s%-15s" %
987 ( str( count ), str( i ), str( s ) ) )
988 if not installedCheck:
989 time.sleep( 1 )
990 loopCount += 1
991 utilities.assert_equals( expect=True, actual=installedCheck,
992 onpass="Intents are all INSTALLED",
993 onfail="Intents are not all in " +
994 "INSTALLED state" )
995
996 main.step( "Check leadership of topics" )
Jon Halla440e872016-03-31 15:15:50 -0700997 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -0700998 topicCheck = main.TRUE
999 try:
1000 if leaders:
1001 parsedLeaders = json.loads( leaders )
1002 main.log.warn( json.dumps( parsedLeaders,
1003 sort_keys=True,
1004 indent=4,
1005 separators=( ',', ': ' ) ) )
1006 # check for all intent partitions
1007 # check for election
1008 # TODO: Look at Devices as topics now that it uses this system
1009 topics = []
1010 for i in range( 14 ):
1011 topics.append( "intent-partition-" + str( i ) )
1012 # FIXME: this should only be after we start the app
1013 # FIXME: topics.append( "org.onosproject.election" )
1014 # Print leaders output
1015 main.log.debug( topics )
1016 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1017 for topic in topics:
1018 if topic not in ONOStopics:
1019 main.log.error( "Error: " + topic +
1020 " not in leaders" )
1021 topicCheck = main.FALSE
1022 else:
1023 main.log.error( "leaders() returned None" )
1024 topicCheck = main.FALSE
1025 except ( ValueError, TypeError ):
1026 topicCheck = main.FALSE
1027 main.log.exception( "Error parsing leaders" )
1028 main.log.error( repr( leaders ) )
1029 # TODO: Check for a leader of these topics
1030 # Check all nodes
1031 if topicCheck:
Jon Halla440e872016-03-31 15:15:50 -07001032 for i in main.activeNodes:
1033 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07001034 response = node.leaders( jsonFormat=False)
1035 main.log.warn( str( node.name ) + " leaders output: \n" +
1036 str( response ) )
1037
1038 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
1039 onpass="intent Partitions is in leaders",
1040 onfail="Some topics were lost " )
1041 # Print partitions
Jon Halla440e872016-03-31 15:15:50 -07001042 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -07001043 try:
1044 if partitions :
1045 parsedPartitions = json.loads( partitions )
1046 main.log.warn( json.dumps( parsedPartitions,
1047 sort_keys=True,
1048 indent=4,
1049 separators=( ',', ': ' ) ) )
1050 # TODO check for a leader in all paritions
1051 # TODO check for consistency among nodes
1052 else:
1053 main.log.error( "partitions() returned None" )
1054 except ( ValueError, TypeError ):
1055 main.log.exception( "Error parsing partitions" )
1056 main.log.error( repr( partitions ) )
1057 # Print Pending Map
Jon Halla440e872016-03-31 15:15:50 -07001058 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -07001059 try:
1060 if pendingMap :
1061 parsedPending = json.loads( pendingMap )
1062 main.log.warn( json.dumps( parsedPending,
1063 sort_keys=True,
1064 indent=4,
1065 separators=( ',', ': ' ) ) )
1066 # TODO check something here?
1067 else:
1068 main.log.error( "pendingMap() returned None" )
1069 except ( ValueError, TypeError ):
1070 main.log.exception( "Error parsing pending map" )
1071 main.log.error( repr( pendingMap ) )
1072
1073 if not installedCheck:
1074 main.log.info( "Waiting 60 seconds to see if the state of " +
1075 "intents change" )
1076 time.sleep( 60 )
1077 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -07001078 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -07001079 intentStates = []
1080 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
1081 count = 0
1082 # Iter through intents of a node
1083 try:
1084 for intent in json.loads( intents ):
1085 state = intent.get( 'state', None )
1086 if "INSTALLED" not in state:
1087 installedCheck = False
1088 intentId = intent.get( 'id', None )
1089 intentStates.append( ( intentId, state ) )
1090 except ( ValueError, TypeError ):
1091 main.log.exception( "Error parsing intents." )
1092 intentStates.sort()
1093 for i, s in intentStates:
1094 count += 1
1095 main.log.info( "%-6s%-15s%-15s" %
1096 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -07001097 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -07001098 try:
1099 missing = False
1100 if leaders:
1101 parsedLeaders = json.loads( leaders )
1102 main.log.warn( json.dumps( parsedLeaders,
1103 sort_keys=True,
1104 indent=4,
1105 separators=( ',', ': ' ) ) )
1106 # check for all intent partitions
1107 # check for election
1108 topics = []
1109 for i in range( 14 ):
1110 topics.append( "intent-partition-" + str( i ) )
1111 # FIXME: this should only be after we start the app
1112 topics.append( "org.onosproject.election" )
1113 main.log.debug( topics )
1114 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1115 for topic in topics:
1116 if topic not in ONOStopics:
1117 main.log.error( "Error: " + topic +
1118 " not in leaders" )
1119 missing = True
1120 else:
1121 main.log.error( "leaders() returned None" )
1122 except ( ValueError, TypeError ):
1123 main.log.exception( "Error parsing leaders" )
1124 main.log.error( repr( leaders ) )
1125 if missing:
Jon Halla440e872016-03-31 15:15:50 -07001126 for i in main.activeNodes:
1127 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07001128 response = node.leaders( jsonFormat=False)
1129 main.log.warn( str( node.name ) + " leaders output: \n" +
1130 str( response ) )
1131
Jon Halla440e872016-03-31 15:15:50 -07001132 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -07001133 try:
1134 if partitions :
1135 parsedPartitions = json.loads( partitions )
1136 main.log.warn( json.dumps( parsedPartitions,
1137 sort_keys=True,
1138 indent=4,
1139 separators=( ',', ': ' ) ) )
1140 # TODO check for a leader in all paritions
1141 # TODO check for consistency among nodes
1142 else:
1143 main.log.error( "partitions() returned None" )
1144 except ( ValueError, TypeError ):
1145 main.log.exception( "Error parsing partitions" )
1146 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -07001147 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -07001148 try:
1149 if pendingMap :
1150 parsedPending = json.loads( pendingMap )
1151 main.log.warn( json.dumps( parsedPending,
1152 sort_keys=True,
1153 indent=4,
1154 separators=( ',', ': ' ) ) )
1155 # TODO check something here?
1156 else:
1157 main.log.error( "pendingMap() returned None" )
1158 except ( ValueError, TypeError ):
1159 main.log.exception( "Error parsing pending map" )
1160 main.log.error( repr( pendingMap ) )
1161 # Print flowrules
Jon Halla440e872016-03-31 15:15:50 -07001162 node = main.activeNodes[0]
1163 main.log.debug( main.CLIs[node].flows( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001164 main.step( "Wait a minute then ping again" )
1165 # the wait is above
1166 PingResult = main.TRUE
1167 for i in range( 8, 18 ):
1168 ping = main.Mininet1.pingHost( src="h" + str( i ),
1169 target="h" + str( i + 10 ) )
1170 PingResult = PingResult and ping
1171 if ping == main.FALSE:
1172 main.log.warn( "Ping failed between h" + str( i ) +
1173 " and h" + str( i + 10 ) )
1174 elif ping == main.TRUE:
1175 main.log.info( "Ping test passed!" )
1176 # Don't set PingResult or you'd override failures
1177 if PingResult == main.FALSE:
1178 main.log.error(
1179 "Intents have not been installed correctly, pings failed." )
1180 # TODO: pretty print
1181 main.log.warn( "ONOS1 intents: " )
1182 try:
Jon Halla440e872016-03-31 15:15:50 -07001183 tmpIntents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -07001184 main.log.warn( json.dumps( json.loads( tmpIntents ),
1185 sort_keys=True,
1186 indent=4,
1187 separators=( ',', ': ' ) ) )
1188 except ( ValueError, TypeError ):
1189 main.log.warn( repr( tmpIntents ) )
1190 utilities.assert_equals(
1191 expect=main.TRUE,
1192 actual=PingResult,
1193 onpass="Intents have been installed correctly and pings work",
1194 onfail="Intents have not been installed correctly, pings failed." )
1195
1196 def CASE5( self, main ):
1197 """
1198 Reading state of ONOS
1199 """
1200 import json
1201 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001202 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001203 assert main, "main not defined"
1204 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001205 assert main.CLIs, "main.CLIs not defined"
1206 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001207
1208 main.case( "Setting up and gathering data for current state" )
1209 # The general idea for this test case is to pull the state of
1210 # ( intents,flows, topology,... ) from each ONOS node
1211 # We can then compare them with each other and also with past states
1212
1213 main.step( "Check that each switch has a master" )
1214 global mastershipState
1215 mastershipState = '[]'
1216
1217 # Assert that each device has a master
1218 rolesNotNull = main.TRUE
1219 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001220 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001221 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001222 name="rolesNotNull-" + str( i ),
1223 args=[] )
1224 threads.append( t )
1225 t.start()
1226
1227 for t in threads:
1228 t.join()
1229 rolesNotNull = rolesNotNull and t.result
1230 utilities.assert_equals(
1231 expect=main.TRUE,
1232 actual=rolesNotNull,
1233 onpass="Each device has a master",
1234 onfail="Some devices don't have a master assigned" )
1235
1236 main.step( "Get the Mastership of each switch from each controller" )
1237 ONOSMastership = []
1238 mastershipCheck = main.FALSE
1239 consistentMastership = True
1240 rolesResults = True
1241 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001242 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001243 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001244 name="roles-" + str( i ),
1245 args=[] )
1246 threads.append( t )
1247 t.start()
1248
1249 for t in threads:
1250 t.join()
1251 ONOSMastership.append( t.result )
1252
Jon Halla440e872016-03-31 15:15:50 -07001253 for i in range( len( ONOSMastership ) ):
1254 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001255 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Halla440e872016-03-31 15:15:50 -07001256 main.log.error( "Error in getting ONOS" + node + " roles" )
1257 main.log.warn( "ONOS" + node + " mastership response: " +
1258 repr( ONOSMastership[i] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001259 rolesResults = False
1260 utilities.assert_equals(
1261 expect=True,
1262 actual=rolesResults,
1263 onpass="No error in reading roles output",
1264 onfail="Error in reading roles from ONOS" )
1265
1266 main.step( "Check for consistency in roles from each controller" )
1267 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1268 main.log.info(
1269 "Switch roles are consistent across all ONOS nodes" )
1270 else:
1271 consistentMastership = False
1272 utilities.assert_equals(
1273 expect=True,
1274 actual=consistentMastership,
1275 onpass="Switch roles are consistent across all ONOS nodes",
1276 onfail="ONOS nodes have different views of switch roles" )
1277
1278 if rolesResults and not consistentMastership:
Jon Halla440e872016-03-31 15:15:50 -07001279 for i in range( len( main.activeNodes ) ):
1280 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001281 try:
1282 main.log.warn(
Jon Halla440e872016-03-31 15:15:50 -07001283 "ONOS" + node + " roles: ",
Jon Hall5cf14d52015-07-16 12:15:19 -07001284 json.dumps(
1285 json.loads( ONOSMastership[ i ] ),
1286 sort_keys=True,
1287 indent=4,
1288 separators=( ',', ': ' ) ) )
1289 except ( ValueError, TypeError ):
1290 main.log.warn( repr( ONOSMastership[ i ] ) )
1291 elif rolesResults and consistentMastership:
1292 mastershipCheck = main.TRUE
1293 mastershipState = ONOSMastership[ 0 ]
1294
1295 main.step( "Get the intents from each controller" )
1296 global intentState
1297 intentState = []
1298 ONOSIntents = []
1299 intentCheck = main.FALSE
1300 consistentIntents = True
1301 intentsResults = True
1302 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001303 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001304 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001305 name="intents-" + str( i ),
1306 args=[],
1307 kwargs={ 'jsonFormat': True } )
1308 threads.append( t )
1309 t.start()
1310
1311 for t in threads:
1312 t.join()
1313 ONOSIntents.append( t.result )
1314
Jon Halla440e872016-03-31 15:15:50 -07001315 for i in range( len( ONOSIntents ) ):
1316 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001317 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall6e709752016-02-01 13:38:46 -08001318 main.log.error( "Error in getting ONOS" + node + " intents" )
1319 main.log.warn( "ONOS" + node + " intents response: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07001320 repr( ONOSIntents[ i ] ) )
1321 intentsResults = False
1322 utilities.assert_equals(
1323 expect=True,
1324 actual=intentsResults,
1325 onpass="No error in reading intents output",
1326 onfail="Error in reading intents from ONOS" )
1327
1328 main.step( "Check for consistency in Intents from each controller" )
1329 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1330 main.log.info( "Intents are consistent across all ONOS " +
1331 "nodes" )
1332 else:
1333 consistentIntents = False
1334 main.log.error( "Intents not consistent" )
1335 utilities.assert_equals(
1336 expect=True,
1337 actual=consistentIntents,
1338 onpass="Intents are consistent across all ONOS nodes",
1339 onfail="ONOS nodes have different views of intents" )
1340
1341 if intentsResults:
1342 # Try to make it easy to figure out what is happening
1343 #
1344 # Intent ONOS1 ONOS2 ...
1345 # 0x01 INSTALLED INSTALLING
1346 # ... ... ...
1347 # ... ... ...
1348 title = " Id"
Jon Halla440e872016-03-31 15:15:50 -07001349 for n in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001350 title += " " * 10 + "ONOS" + str( n + 1 )
1351 main.log.warn( title )
1352 # get all intent keys in the cluster
1353 keys = []
Jon Halla440e872016-03-31 15:15:50 -07001354 try:
1355 # Get the set of all intent keys
Jon Hall5cf14d52015-07-16 12:15:19 -07001356 for nodeStr in ONOSIntents:
1357 node = json.loads( nodeStr )
1358 for intent in node:
Jon Halla440e872016-03-31 15:15:50 -07001359 keys.append( intent.get( 'id' ) )
1360 keys = set( keys )
1361 # For each intent key, print the state on each node
1362 for key in keys:
1363 row = "%-13s" % key
1364 for nodeStr in ONOSIntents:
1365 node = json.loads( nodeStr )
1366 for intent in node:
1367 if intent.get( 'id', "Error" ) == key:
1368 row += "%-15s" % intent.get( 'state' )
1369 main.log.warn( row )
1370 # End of intent state table
1371 except ValueError as e:
1372 main.log.exception( e )
1373 main.log.debug( "nodeStr was: " + repr( nodeStr ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001374
1375 if intentsResults and not consistentIntents:
1376 # print the json objects
Jon Halla440e872016-03-31 15:15:50 -07001377 n = str( main.activeNodes[-1] + 1 )
1378 main.log.debug( "ONOS" + n + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07001379 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1380 sort_keys=True,
1381 indent=4,
1382 separators=( ',', ': ' ) ) )
Jon Halla440e872016-03-31 15:15:50 -07001383 for i in range( len( ONOSIntents ) ):
1384 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001385 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
Jon Halla440e872016-03-31 15:15:50 -07001386 main.log.debug( "ONOS" + node + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07001387 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1388 sort_keys=True,
1389 indent=4,
1390 separators=( ',', ': ' ) ) )
1391 else:
Jon Halla440e872016-03-31 15:15:50 -07001392 main.log.debug( "ONOS" + node + " intents match ONOS" +
1393 n + " intents" )
Jon Hall5cf14d52015-07-16 12:15:19 -07001394 elif intentsResults and consistentIntents:
1395 intentCheck = main.TRUE
1396 intentState = ONOSIntents[ 0 ]
1397
1398 main.step( "Get the flows from each controller" )
1399 global flowState
1400 flowState = []
1401 ONOSFlows = []
1402 ONOSFlowsJson = []
1403 flowCheck = main.FALSE
1404 consistentFlows = True
1405 flowsResults = True
1406 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001407 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001408 t = main.Thread( target=main.CLIs[i].flows,
Jon Hall5cf14d52015-07-16 12:15:19 -07001409 name="flows-" + str( i ),
1410 args=[],
1411 kwargs={ 'jsonFormat': True } )
1412 threads.append( t )
1413 t.start()
1414
1415 # NOTE: Flows command can take some time to run
1416 time.sleep(30)
1417 for t in threads:
1418 t.join()
1419 result = t.result
1420 ONOSFlows.append( result )
1421
Jon Halla440e872016-03-31 15:15:50 -07001422 for i in range( len( ONOSFlows ) ):
1423 num = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001424 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1425 main.log.error( "Error in getting ONOS" + num + " flows" )
1426 main.log.warn( "ONOS" + num + " flows response: " +
1427 repr( ONOSFlows[ i ] ) )
1428 flowsResults = False
1429 ONOSFlowsJson.append( None )
1430 else:
1431 try:
1432 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1433 except ( ValueError, TypeError ):
1434 # FIXME: change this to log.error?
1435 main.log.exception( "Error in parsing ONOS" + num +
1436 " response as json." )
1437 main.log.error( repr( ONOSFlows[ i ] ) )
1438 ONOSFlowsJson.append( None )
1439 flowsResults = False
1440 utilities.assert_equals(
1441 expect=True,
1442 actual=flowsResults,
1443 onpass="No error in reading flows output",
1444 onfail="Error in reading flows from ONOS" )
1445
1446 main.step( "Check for consistency in Flows from each controller" )
1447 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1448 if all( tmp ):
1449 main.log.info( "Flow count is consistent across all ONOS nodes" )
1450 else:
1451 consistentFlows = False
1452 utilities.assert_equals(
1453 expect=True,
1454 actual=consistentFlows,
1455 onpass="The flow count is consistent across all ONOS nodes",
1456 onfail="ONOS nodes have different flow counts" )
1457
1458 if flowsResults and not consistentFlows:
Jon Halla440e872016-03-31 15:15:50 -07001459 for i in range( len( ONOSFlows ) ):
1460 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001461 try:
1462 main.log.warn(
Jon Halla440e872016-03-31 15:15:50 -07001463 "ONOS" + node + " flows: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07001464 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1465 indent=4, separators=( ',', ': ' ) ) )
1466 except ( ValueError, TypeError ):
Jon Halla440e872016-03-31 15:15:50 -07001467 main.log.warn( "ONOS" + node + " flows: " +
1468 repr( ONOSFlows[ i ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001469 elif flowsResults and consistentFlows:
1470 flowCheck = main.TRUE
1471 flowState = ONOSFlows[ 0 ]
1472
1473 main.step( "Get the OF Table entries" )
1474 global flows
1475 flows = []
1476 for i in range( 1, 29 ):
Jon Halla440e872016-03-31 15:15:50 -07001477 flows.append( main.Mininet1.getFlowTable( "s" + str( i ), version="1.3", debug=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001478 if flowCheck == main.FALSE:
1479 for table in flows:
1480 main.log.warn( table )
1481 # TODO: Compare switch flow tables with ONOS flow tables
1482
1483 main.step( "Start continuous pings" )
1484 main.Mininet2.pingLong(
1485 src=main.params[ 'PING' ][ 'source1' ],
1486 target=main.params[ 'PING' ][ 'target1' ],
1487 pingTime=500 )
1488 main.Mininet2.pingLong(
1489 src=main.params[ 'PING' ][ 'source2' ],
1490 target=main.params[ 'PING' ][ 'target2' ],
1491 pingTime=500 )
1492 main.Mininet2.pingLong(
1493 src=main.params[ 'PING' ][ 'source3' ],
1494 target=main.params[ 'PING' ][ 'target3' ],
1495 pingTime=500 )
1496 main.Mininet2.pingLong(
1497 src=main.params[ 'PING' ][ 'source4' ],
1498 target=main.params[ 'PING' ][ 'target4' ],
1499 pingTime=500 )
1500 main.Mininet2.pingLong(
1501 src=main.params[ 'PING' ][ 'source5' ],
1502 target=main.params[ 'PING' ][ 'target5' ],
1503 pingTime=500 )
1504 main.Mininet2.pingLong(
1505 src=main.params[ 'PING' ][ 'source6' ],
1506 target=main.params[ 'PING' ][ 'target6' ],
1507 pingTime=500 )
1508 main.Mininet2.pingLong(
1509 src=main.params[ 'PING' ][ 'source7' ],
1510 target=main.params[ 'PING' ][ 'target7' ],
1511 pingTime=500 )
1512 main.Mininet2.pingLong(
1513 src=main.params[ 'PING' ][ 'source8' ],
1514 target=main.params[ 'PING' ][ 'target8' ],
1515 pingTime=500 )
1516 main.Mininet2.pingLong(
1517 src=main.params[ 'PING' ][ 'source9' ],
1518 target=main.params[ 'PING' ][ 'target9' ],
1519 pingTime=500 )
1520 main.Mininet2.pingLong(
1521 src=main.params[ 'PING' ][ 'source10' ],
1522 target=main.params[ 'PING' ][ 'target10' ],
1523 pingTime=500 )
1524
1525 main.step( "Collecting topology information from ONOS" )
1526 devices = []
1527 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001528 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001529 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07001530 name="devices-" + str( i ),
1531 args=[ ] )
1532 threads.append( t )
1533 t.start()
1534
1535 for t in threads:
1536 t.join()
1537 devices.append( t.result )
1538 hosts = []
1539 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001540 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001541 t = main.Thread( target=main.CLIs[i].hosts,
Jon Hall5cf14d52015-07-16 12:15:19 -07001542 name="hosts-" + str( i ),
1543 args=[ ] )
1544 threads.append( t )
1545 t.start()
1546
1547 for t in threads:
1548 t.join()
1549 try:
1550 hosts.append( json.loads( t.result ) )
1551 except ( ValueError, TypeError ):
1552 # FIXME: better handling of this, print which node
1553 # Maybe use thread name?
1554 main.log.exception( "Error parsing json output of hosts" )
Jon Hall3afe4c92015-12-14 19:30:38 -08001555 main.log.warn( repr( t.result ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001556 hosts.append( None )
1557
1558 ports = []
1559 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001560 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001561 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07001562 name="ports-" + str( i ),
1563 args=[ ] )
1564 threads.append( t )
1565 t.start()
1566
1567 for t in threads:
1568 t.join()
1569 ports.append( t.result )
1570 links = []
1571 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001572 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001573 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07001574 name="links-" + str( i ),
1575 args=[ ] )
1576 threads.append( t )
1577 t.start()
1578
1579 for t in threads:
1580 t.join()
1581 links.append( t.result )
1582 clusters = []
1583 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001584 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001585 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07001586 name="clusters-" + str( i ),
1587 args=[ ] )
1588 threads.append( t )
1589 t.start()
1590
1591 for t in threads:
1592 t.join()
1593 clusters.append( t.result )
1594 # Compare json objects for hosts and dataplane clusters
1595
1596 # hosts
1597 main.step( "Host view is consistent across ONOS nodes" )
1598 consistentHostsResult = main.TRUE
1599 for controller in range( len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07001600 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall3afe4c92015-12-14 19:30:38 -08001601 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001602 if hosts[ controller ] == hosts[ 0 ]:
1603 continue
1604 else: # hosts not consistent
1605 main.log.error( "hosts from ONOS" +
1606 controllerStr +
1607 " is inconsistent with ONOS1" )
1608 main.log.warn( repr( hosts[ controller ] ) )
1609 consistentHostsResult = main.FALSE
1610
1611 else:
1612 main.log.error( "Error in getting ONOS hosts from ONOS" +
1613 controllerStr )
1614 consistentHostsResult = main.FALSE
1615 main.log.warn( "ONOS" + controllerStr +
1616 " hosts response: " +
1617 repr( hosts[ controller ] ) )
1618 utilities.assert_equals(
1619 expect=main.TRUE,
1620 actual=consistentHostsResult,
1621 onpass="Hosts view is consistent across all ONOS nodes",
1622 onfail="ONOS nodes have different views of hosts" )
1623
1624 main.step( "Each host has an IP address" )
1625 ipResult = main.TRUE
1626 for controller in range( 0, len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07001627 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall3afe4c92015-12-14 19:30:38 -08001628 if hosts[ controller ]:
1629 for host in hosts[ controller ]:
1630 if not host.get( 'ipAddresses', [ ] ):
Jon Hallf3d16e72015-12-16 17:45:08 -08001631 main.log.error( "Error with host ips on controller" +
Jon Hall3afe4c92015-12-14 19:30:38 -08001632 controllerStr + ": " + str( host ) )
1633 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07001634 utilities.assert_equals(
1635 expect=main.TRUE,
1636 actual=ipResult,
1637 onpass="The ips of the hosts aren't empty",
1638 onfail="The ip of at least one host is missing" )
1639
1640 # Strongly connected clusters of devices
1641 main.step( "Cluster view is consistent across ONOS nodes" )
1642 consistentClustersResult = main.TRUE
1643 for controller in range( len( clusters ) ):
Jon Halla440e872016-03-31 15:15:50 -07001644 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001645 if "Error" not in clusters[ controller ]:
1646 if clusters[ controller ] == clusters[ 0 ]:
1647 continue
1648 else: # clusters not consistent
1649 main.log.error( "clusters from ONOS" + controllerStr +
1650 " is inconsistent with ONOS1" )
1651 consistentClustersResult = main.FALSE
1652
1653 else:
1654 main.log.error( "Error in getting dataplane clusters " +
1655 "from ONOS" + controllerStr )
1656 consistentClustersResult = main.FALSE
1657 main.log.warn( "ONOS" + controllerStr +
1658 " clusters response: " +
1659 repr( clusters[ controller ] ) )
1660 utilities.assert_equals(
1661 expect=main.TRUE,
1662 actual=consistentClustersResult,
1663 onpass="Clusters view is consistent across all ONOS nodes",
1664 onfail="ONOS nodes have different views of clusters" )
1665 # there should always only be one cluster
1666 main.step( "Cluster view correct across ONOS nodes" )
1667 try:
1668 numClusters = len( json.loads( clusters[ 0 ] ) )
1669 except ( ValueError, TypeError ):
1670 main.log.exception( "Error parsing clusters[0]: " +
1671 repr( clusters[ 0 ] ) )
Jon Hall6e709752016-02-01 13:38:46 -08001672 numClusters = "ERROR"
Jon Hall5cf14d52015-07-16 12:15:19 -07001673 clusterResults = main.FALSE
1674 if numClusters == 1:
1675 clusterResults = main.TRUE
1676 utilities.assert_equals(
1677 expect=1,
1678 actual=numClusters,
1679 onpass="ONOS shows 1 SCC",
1680 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1681
1682 main.step( "Comparing ONOS topology to MN" )
1683 devicesResults = main.TRUE
1684 linksResults = main.TRUE
1685 hostsResults = main.TRUE
1686 mnSwitches = main.Mininet1.getSwitches()
1687 mnLinks = main.Mininet1.getLinks()
1688 mnHosts = main.Mininet1.getHosts()
Jon Halla440e872016-03-31 15:15:50 -07001689 for controller in main.activeNodes:
1690 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001691 if devices[ controller ] and ports[ controller ] and\
1692 "Error" not in devices[ controller ] and\
1693 "Error" not in ports[ controller ]:
Jon Halle1a3b752015-07-22 13:02:46 -07001694 currentDevicesResult = main.Mininet1.compareSwitches(
1695 mnSwitches,
1696 json.loads( devices[ controller ] ),
1697 json.loads( ports[ controller ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001698 else:
1699 currentDevicesResult = main.FALSE
1700 utilities.assert_equals( expect=main.TRUE,
1701 actual=currentDevicesResult,
1702 onpass="ONOS" + controllerStr +
1703 " Switches view is correct",
1704 onfail="ONOS" + controllerStr +
1705 " Switches view is incorrect" )
1706 if links[ controller ] and "Error" not in links[ controller ]:
1707 currentLinksResult = main.Mininet1.compareLinks(
1708 mnSwitches, mnLinks,
1709 json.loads( links[ controller ] ) )
1710 else:
1711 currentLinksResult = main.FALSE
1712 utilities.assert_equals( expect=main.TRUE,
1713 actual=currentLinksResult,
1714 onpass="ONOS" + controllerStr +
1715 " links view is correct",
1716 onfail="ONOS" + controllerStr +
1717 " links view is incorrect" )
1718
Jon Hall657cdf62015-12-17 14:40:51 -08001719 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001720 currentHostsResult = main.Mininet1.compareHosts(
1721 mnHosts,
1722 hosts[ controller ] )
1723 else:
1724 currentHostsResult = main.FALSE
1725 utilities.assert_equals( expect=main.TRUE,
1726 actual=currentHostsResult,
1727 onpass="ONOS" + controllerStr +
1728 " hosts exist in Mininet",
1729 onfail="ONOS" + controllerStr +
1730 " hosts don't match Mininet" )
1731
1732 devicesResults = devicesResults and currentDevicesResult
1733 linksResults = linksResults and currentLinksResult
1734 hostsResults = hostsResults and currentHostsResult
1735
1736 main.step( "Device information is correct" )
1737 utilities.assert_equals(
1738 expect=main.TRUE,
1739 actual=devicesResults,
1740 onpass="Device information is correct",
1741 onfail="Device information is incorrect" )
1742
1743 main.step( "Links are correct" )
1744 utilities.assert_equals(
1745 expect=main.TRUE,
1746 actual=linksResults,
1747 onpass="Link are correct",
1748 onfail="Links are incorrect" )
1749
1750 main.step( "Hosts are correct" )
1751 utilities.assert_equals(
1752 expect=main.TRUE,
1753 actual=hostsResults,
1754 onpass="Hosts are correct",
1755 onfail="Hosts are incorrect" )
1756
1757 def CASE6( self, main ):
1758 """
1759 The Failure case.
1760 """
1761 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001762 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001763 assert main, "main not defined"
1764 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001765 assert main.CLIs, "main.CLIs not defined"
1766 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001767 try:
1768 labels
1769 except NameError:
1770 main.log.error( "labels not defined, setting to []" )
1771 global labels
1772 labels = []
1773 try:
1774 data
1775 except NameError:
1776 main.log.error( "data not defined, setting to []" )
1777 global data
1778 data = []
1779 # Reset non-persistent variables
1780 try:
1781 iCounterValue = 0
1782 except NameError:
1783 main.log.error( "iCounterValue not defined, setting to 0" )
1784 iCounterValue = 0
1785
1786 main.case( "Restart entire ONOS cluster" )
1787
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001788 main.step( "Checking ONOS Logs for errors" )
1789 for node in main.nodes:
1790 main.log.debug( "Checking logs for errors on " + node.name + ":" )
1791 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
1792
Jon Hall5cf14d52015-07-16 12:15:19 -07001793 main.step( "Killing ONOS nodes" )
1794 killResults = main.TRUE
1795 killTime = time.time()
Jon Halle1a3b752015-07-22 13:02:46 -07001796 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001797 killed = main.ONOSbench.onosKill( node.ip_address )
1798 killResults = killResults and killed
1799 utilities.assert_equals( expect=main.TRUE, actual=killResults,
1800 onpass="ONOS nodes killed",
1801 onfail="ONOS kill unsuccessful" )
1802
1803 main.step( "Checking if ONOS is up yet" )
1804 for i in range( 2 ):
1805 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001806 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001807 started = main.ONOSbench.isup( node.ip_address )
1808 if not started:
1809 main.log.error( node.name + " didn't start!" )
1810 onosIsupResult = onosIsupResult and started
1811 if onosIsupResult == main.TRUE:
1812 break
1813 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1814 onpass="ONOS restarted",
1815 onfail="ONOS restart NOT successful" )
1816
1817 main.log.step( "Starting ONOS CLI sessions" )
1818 cliResults = main.TRUE
1819 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001820 for i in range( main.numCtrls ):
1821 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -07001822 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -07001823 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -07001824 threads.append( t )
1825 t.start()
1826
1827 for t in threads:
1828 t.join()
1829 cliResults = cliResults and t.result
1830 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1831 onpass="ONOS cli started",
1832 onfail="ONOS clis did not restart" )
1833
Jon Hall6e709752016-02-01 13:38:46 -08001834 for i in range( 10 ):
1835 ready = True
1836 for cli in main.CLIs:
1837 output = cli.summary()
1838 if not output:
1839 ready = False
1840 time.sleep( 30 )
1841 utilities.assert_equals( expect=True, actual=ready,
1842 onpass="ONOS summary command succeded",
1843 onfail="ONOS summary command failed" )
1844 if not ready:
1845 main.cleanup()
1846 main.exit()
1847
Jon Hall5cf14d52015-07-16 12:15:19 -07001848 # Grab the time of restart so we chan check how long the gossip
1849 # protocol has had time to work
1850 main.restartTime = time.time() - killTime
1851 main.log.debug( "Restart time: " + str( main.restartTime ) )
1852 labels.append( "Restart" )
1853 data.append( str( main.restartTime ) )
1854
Jon Hall5cf14d52015-07-16 12:15:19 -07001855 # Rerun for election on restarted nodes
1856 runResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001857 for cli in main.CLIs:
Jon Halla440e872016-03-31 15:15:50 -07001858 run = cli.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07001859 if run != main.TRUE:
1860 main.log.error( "Error running for election on " + cli.name )
1861 runResults = runResults and run
1862 utilities.assert_equals( expect=main.TRUE, actual=runResults,
1863 onpass="Reran for election",
1864 onfail="Failed to rerun for election" )
1865
1866 # TODO: Make this configurable
1867 time.sleep( 60 )
Jon Halla440e872016-03-31 15:15:50 -07001868 node = main.activeNodes[0]
1869 main.log.debug( main.CLIs[node].nodes( jsonFormat=False ) )
1870 main.log.debug( main.CLIs[node].leaders( jsonFormat=False ) )
1871 main.log.debug( main.CLIs[node].partitions( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001872
1873 def CASE7( self, main ):
1874 """
1875 Check state after ONOS failure
1876 """
1877 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001878 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001879 assert main, "main not defined"
1880 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001881 assert main.CLIs, "main.CLIs not defined"
1882 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001883 main.case( "Running ONOS Constant State Tests" )
1884
1885 main.step( "Check that each switch has a master" )
1886 # Assert that each device has a master
1887 rolesNotNull = main.TRUE
1888 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001889 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001890 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001891 name="rolesNotNull-" + str( i ),
1892 args=[ ] )
1893 threads.append( t )
1894 t.start()
1895
1896 for t in threads:
1897 t.join()
1898 rolesNotNull = rolesNotNull and t.result
1899 utilities.assert_equals(
1900 expect=main.TRUE,
1901 actual=rolesNotNull,
1902 onpass="Each device has a master",
1903 onfail="Some devices don't have a master assigned" )
1904
1905 main.step( "Read device roles from ONOS" )
1906 ONOSMastership = []
1907 mastershipCheck = main.FALSE
1908 consistentMastership = True
1909 rolesResults = True
1910 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001911 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001912 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001913 name="roles-" + str( i ),
1914 args=[] )
1915 threads.append( t )
1916 t.start()
1917
1918 for t in threads:
1919 t.join()
1920 ONOSMastership.append( t.result )
1921
Jon Halla440e872016-03-31 15:15:50 -07001922 for i in range( len( ONOSMastership ) ):
1923 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001924 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Halla440e872016-03-31 15:15:50 -07001925 main.log.error( "Error in getting ONOS" + node + " roles" )
1926 main.log.warn( "ONOS" + node + " mastership response: " +
1927 repr( ONOSMastership[i] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001928 rolesResults = False
1929 utilities.assert_equals(
1930 expect=True,
1931 actual=rolesResults,
1932 onpass="No error in reading roles output",
1933 onfail="Error in reading roles from ONOS" )
1934
1935 main.step( "Check for consistency in roles from each controller" )
1936 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1937 main.log.info(
1938 "Switch roles are consistent across all ONOS nodes" )
1939 else:
1940 consistentMastership = False
1941 utilities.assert_equals(
1942 expect=True,
1943 actual=consistentMastership,
1944 onpass="Switch roles are consistent across all ONOS nodes",
1945 onfail="ONOS nodes have different views of switch roles" )
1946
1947 if rolesResults and not consistentMastership:
Jon Halla440e872016-03-31 15:15:50 -07001948 for i in range( len( ONOSMastership ) ):
1949 node = str( main.activeNodes[i] + 1 )
1950 main.log.warn( "ONOS" + node + " roles: ",
Jon Hall6e709752016-02-01 13:38:46 -08001951 json.dumps( json.loads( ONOSMastership[ i ] ),
1952 sort_keys=True,
1953 indent=4,
1954 separators=( ',', ': ' ) ) )
1955 elif rolesResults and consistentMastership:
Jon Hall5cf14d52015-07-16 12:15:19 -07001956 mastershipCheck = main.TRUE
1957
Jon Hall5cf14d52015-07-16 12:15:19 -07001958 # NOTE: we expect mastership to change on controller failure
1959
1960 main.step( "Get the intents and compare across all nodes" )
1961 ONOSIntents = []
1962 intentCheck = main.FALSE
1963 consistentIntents = True
1964 intentsResults = True
1965 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001966 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001967 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001968 name="intents-" + str( i ),
1969 args=[],
1970 kwargs={ 'jsonFormat': True } )
1971 threads.append( t )
1972 t.start()
1973
1974 for t in threads:
1975 t.join()
1976 ONOSIntents.append( t.result )
1977
Jon Halla440e872016-03-31 15:15:50 -07001978 for i in range( len( ONOSIntents) ):
1979 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001980 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Halla440e872016-03-31 15:15:50 -07001981 main.log.error( "Error in getting ONOS" + node + " intents" )
1982 main.log.warn( "ONOS" + node + " intents response: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07001983 repr( ONOSIntents[ i ] ) )
1984 intentsResults = False
1985 utilities.assert_equals(
1986 expect=True,
1987 actual=intentsResults,
1988 onpass="No error in reading intents output",
1989 onfail="Error in reading intents from ONOS" )
1990
1991 main.step( "Check for consistency in Intents from each controller" )
1992 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1993 main.log.info( "Intents are consistent across all ONOS " +
1994 "nodes" )
1995 else:
1996 consistentIntents = False
1997
1998 # Try to make it easy to figure out what is happening
1999 #
2000 # Intent ONOS1 ONOS2 ...
2001 # 0x01 INSTALLED INSTALLING
2002 # ... ... ...
2003 # ... ... ...
2004 title = " ID"
Jon Halla440e872016-03-31 15:15:50 -07002005 for n in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07002006 title += " " * 10 + "ONOS" + str( n + 1 )
2007 main.log.warn( title )
2008 # get all intent keys in the cluster
2009 keys = []
2010 for nodeStr in ONOSIntents:
2011 node = json.loads( nodeStr )
2012 for intent in node:
2013 keys.append( intent.get( 'id' ) )
2014 keys = set( keys )
2015 for key in keys:
2016 row = "%-13s" % key
2017 for nodeStr in ONOSIntents:
2018 node = json.loads( nodeStr )
2019 for intent in node:
2020 if intent.get( 'id' ) == key:
2021 row += "%-15s" % intent.get( 'state' )
2022 main.log.warn( row )
2023 # End table view
2024
2025 utilities.assert_equals(
2026 expect=True,
2027 actual=consistentIntents,
2028 onpass="Intents are consistent across all ONOS nodes",
2029 onfail="ONOS nodes have different views of intents" )
2030 intentStates = []
2031 for node in ONOSIntents: # Iter through ONOS nodes
2032 nodeStates = []
2033 # Iter through intents of a node
2034 try:
2035 for intent in json.loads( node ):
2036 nodeStates.append( intent[ 'state' ] )
2037 except ( ValueError, TypeError ):
2038 main.log.exception( "Error in parsing intents" )
2039 main.log.error( repr( node ) )
2040 intentStates.append( nodeStates )
2041 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
2042 main.log.info( dict( out ) )
2043
2044 if intentsResults and not consistentIntents:
Jon Halla440e872016-03-31 15:15:50 -07002045 for i in range( len( main.activeNodes ) ):
2046 node = str( main.activeNodes[i] + 1 )
2047 main.log.warn( "ONOS" + node + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07002048 main.log.warn( json.dumps(
2049 json.loads( ONOSIntents[ i ] ),
2050 sort_keys=True,
2051 indent=4,
2052 separators=( ',', ': ' ) ) )
2053 elif intentsResults and consistentIntents:
2054 intentCheck = main.TRUE
2055
2056 # NOTE: Store has no durability, so intents are lost across system
2057 # restarts
2058 """
2059 main.step( "Compare current intents with intents before the failure" )
2060 # NOTE: this requires case 5 to pass for intentState to be set.
2061 # maybe we should stop the test if that fails?
2062 sameIntents = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002063 try:
2064 intentState
2065 except NameError:
2066 main.log.warn( "No previous intent state was saved" )
2067 else:
2068 if intentState and intentState == ONOSIntents[ 0 ]:
2069 sameIntents = main.TRUE
2070 main.log.info( "Intents are consistent with before failure" )
2071 # TODO: possibly the states have changed? we may need to figure out
2072 # what the acceptable states are
2073 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
2074 sameIntents = main.TRUE
2075 try:
2076 before = json.loads( intentState )
2077 after = json.loads( ONOSIntents[ 0 ] )
2078 for intent in before:
2079 if intent not in after:
2080 sameIntents = main.FALSE
2081 main.log.debug( "Intent is not currently in ONOS " +
2082 "(at least in the same form):" )
2083 main.log.debug( json.dumps( intent ) )
2084 except ( ValueError, TypeError ):
2085 main.log.exception( "Exception printing intents" )
2086 main.log.debug( repr( ONOSIntents[0] ) )
2087 main.log.debug( repr( intentState ) )
2088 if sameIntents == main.FALSE:
2089 try:
2090 main.log.debug( "ONOS intents before: " )
2091 main.log.debug( json.dumps( json.loads( intentState ),
2092 sort_keys=True, indent=4,
2093 separators=( ',', ': ' ) ) )
2094 main.log.debug( "Current ONOS intents: " )
2095 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
2096 sort_keys=True, indent=4,
2097 separators=( ',', ': ' ) ) )
2098 except ( ValueError, TypeError ):
2099 main.log.exception( "Exception printing intents" )
2100 main.log.debug( repr( ONOSIntents[0] ) )
2101 main.log.debug( repr( intentState ) )
2102 utilities.assert_equals(
2103 expect=main.TRUE,
2104 actual=sameIntents,
2105 onpass="Intents are consistent with before failure",
2106 onfail="The Intents changed during failure" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002107 intentCheck = intentCheck and sameIntents
2108 """
2109 main.step( "Get the OF Table entries and compare to before " +
2110 "component failure" )
2111 FlowTables = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002112 for i in range( 28 ):
2113 main.log.info( "Checking flow table on s" + str( i + 1 ) )
GlennRC68467eb2015-11-16 18:01:01 -08002114 tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
2115 FlowTables = FlowTables and main.Mininet1.flowTableComp( flows[i], tmpFlows )
Jon Hall5cf14d52015-07-16 12:15:19 -07002116 if FlowTables == main.FALSE:
GlennRC68467eb2015-11-16 18:01:01 -08002117 main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002118 utilities.assert_equals(
2119 expect=main.TRUE,
2120 actual=FlowTables,
2121 onpass="No changes were found in the flow tables",
2122 onfail="Changes were found in the flow tables" )
2123
2124 main.Mininet2.pingLongKill()
2125 '''
2126 # main.step( "Check the continuous pings to ensure that no packets " +
2127 # "were dropped during component failure" )
2128 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
2129 main.params[ 'TESTONIP' ] )
2130 LossInPings = main.FALSE
2131 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
2132 for i in range( 8, 18 ):
2133 main.log.info(
2134 "Checking for a loss in pings along flow from s" +
2135 str( i ) )
2136 LossInPings = main.Mininet2.checkForLoss(
2137 "/tmp/ping.h" +
2138 str( i ) ) or LossInPings
2139 if LossInPings == main.TRUE:
2140 main.log.info( "Loss in ping detected" )
2141 elif LossInPings == main.ERROR:
2142 main.log.info( "There are multiple mininet process running" )
2143 elif LossInPings == main.FALSE:
2144 main.log.info( "No Loss in the pings" )
2145 main.log.info( "No loss of dataplane connectivity" )
2146 # utilities.assert_equals(
2147 # expect=main.FALSE,
2148 # actual=LossInPings,
2149 # onpass="No Loss of connectivity",
2150 # onfail="Loss of dataplane connectivity detected" )
2151
2152 # NOTE: Since intents are not persisted with IntnentStore,
2153 # we expect loss in dataplane connectivity
2154 LossInPings = main.FALSE
2155 '''
2156
2157 main.step( "Leadership Election is still functional" )
2158 # Test of LeadershipElection
2159 leaderList = []
2160 leaderResult = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002161
2162 for i in main.activeNodes:
2163 cli = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07002164 leaderN = cli.electionTestLeader()
2165 leaderList.append( leaderN )
2166 if leaderN == main.FALSE:
2167 # error in response
2168 main.log.error( "Something is wrong with " +
2169 "electionTestLeader function, check the" +
2170 " error logs" )
2171 leaderResult = main.FALSE
2172 elif leaderN is None:
2173 main.log.error( cli.name +
2174 " shows no leader for the election-app." )
2175 leaderResult = main.FALSE
2176 if len( set( leaderList ) ) != 1:
2177 leaderResult = main.FALSE
2178 main.log.error(
2179 "Inconsistent view of leader for the election test app" )
2180 # TODO: print the list
2181 utilities.assert_equals(
2182 expect=main.TRUE,
2183 actual=leaderResult,
2184 onpass="Leadership election passed",
2185 onfail="Something went wrong with Leadership election" )
2186
2187 def CASE8( self, main ):
2188 """
2189 Compare topo
2190 """
2191 import json
2192 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002193 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002194 assert main, "main not defined"
2195 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002196 assert main.CLIs, "main.CLIs not defined"
2197 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002198
2199 main.case( "Compare ONOS Topology view to Mininet topology" )
Jon Hall783bbf92015-07-23 14:33:19 -07002200 main.caseExplanation = "Compare topology objects between Mininet" +\
Jon Hall5cf14d52015-07-16 12:15:19 -07002201 " and ONOS"
Jon Hall5cf14d52015-07-16 12:15:19 -07002202 topoResult = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08002203 topoFailMsg = "ONOS topology don't match Mininet"
Jon Hall5cf14d52015-07-16 12:15:19 -07002204 elapsed = 0
2205 count = 0
Jon Halle9b1fa32015-12-08 15:32:21 -08002206 main.step( "Comparing ONOS topology to MN topology" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002207 startTime = time.time()
2208 # Give time for Gossip to work
Jon Halle9b1fa32015-12-08 15:32:21 -08002209 while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
Jon Hallba609822015-09-18 12:00:21 -07002210 devicesResults = main.TRUE
2211 linksResults = main.TRUE
2212 hostsResults = main.TRUE
2213 hostAttachmentResults = True
Jon Hall5cf14d52015-07-16 12:15:19 -07002214 count += 1
2215 cliStart = time.time()
2216 devices = []
2217 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002218 for i in main.activeNodes:
Jon Hall6e709752016-02-01 13:38:46 -08002219 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002220 name="devices-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08002221 args=[ main.CLIs[i].devices, [ None ] ],
2222 kwargs= { 'sleep': 5, 'attempts': 5,
2223 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002224 threads.append( t )
2225 t.start()
2226
2227 for t in threads:
2228 t.join()
2229 devices.append( t.result )
2230 hosts = []
2231 ipResult = main.TRUE
2232 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002233 for i in main.activeNodes:
Jon Halld8f6de82015-12-17 17:04:34 -08002234 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002235 name="hosts-" + str( i ),
Jon Halld8f6de82015-12-17 17:04:34 -08002236 args=[ main.CLIs[i].hosts, [ None ] ],
2237 kwargs= { 'sleep': 5, 'attempts': 5,
2238 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002239 threads.append( t )
2240 t.start()
2241
2242 for t in threads:
2243 t.join()
2244 try:
2245 hosts.append( json.loads( t.result ) )
2246 except ( ValueError, TypeError ):
2247 main.log.exception( "Error parsing hosts results" )
2248 main.log.error( repr( t.result ) )
Jon Hall3afe4c92015-12-14 19:30:38 -08002249 hosts.append( None )
Jon Hall5cf14d52015-07-16 12:15:19 -07002250 for controller in range( 0, len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07002251 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hallacd1b182015-12-17 11:43:20 -08002252 if hosts[ controller ]:
2253 for host in hosts[ controller ]:
2254 if host is None or host.get( 'ipAddresses', [] ) == []:
2255 main.log.error(
2256 "Error with host ipAddresses on controller" +
2257 controllerStr + ": " + str( host ) )
2258 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002259 ports = []
2260 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002261 for i in main.activeNodes:
Jon Hall6e709752016-02-01 13:38:46 -08002262 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002263 name="ports-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08002264 args=[ main.CLIs[i].ports, [ None ] ],
2265 kwargs= { 'sleep': 5, 'attempts': 5,
2266 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002267 threads.append( t )
2268 t.start()
2269
2270 for t in threads:
2271 t.join()
2272 ports.append( t.result )
2273 links = []
2274 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002275 for i in main.activeNodes:
Jon Hall6e709752016-02-01 13:38:46 -08002276 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002277 name="links-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08002278 args=[ main.CLIs[i].links, [ None ] ],
2279 kwargs= { 'sleep': 5, 'attempts': 5,
2280 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002281 threads.append( t )
2282 t.start()
2283
2284 for t in threads:
2285 t.join()
2286 links.append( t.result )
2287 clusters = []
2288 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002289 for i in main.activeNodes:
Jon Hall6e709752016-02-01 13:38:46 -08002290 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002291 name="clusters-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08002292 args=[ main.CLIs[i].clusters, [ None ] ],
2293 kwargs= { 'sleep': 5, 'attempts': 5,
2294 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002295 threads.append( t )
2296 t.start()
2297
2298 for t in threads:
2299 t.join()
2300 clusters.append( t.result )
2301
2302 elapsed = time.time() - startTime
2303 cliTime = time.time() - cliStart
2304 print "Elapsed time: " + str( elapsed )
2305 print "CLI time: " + str( cliTime )
2306
Jon Hall6e709752016-02-01 13:38:46 -08002307 if all( e is None for e in devices ) and\
2308 all( e is None for e in hosts ) and\
2309 all( e is None for e in ports ) and\
2310 all( e is None for e in links ) and\
2311 all( e is None for e in clusters ):
2312 topoFailMsg = "Could not get topology from ONOS"
2313 main.log.error( topoFailMsg )
2314 continue # Try again, No use trying to compare
2315
Jon Hall5cf14d52015-07-16 12:15:19 -07002316 mnSwitches = main.Mininet1.getSwitches()
2317 mnLinks = main.Mininet1.getLinks()
2318 mnHosts = main.Mininet1.getHosts()
Jon Halla440e872016-03-31 15:15:50 -07002319 for controller in range( len( main.activeNodes ) ):
2320 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002321 if devices[ controller ] and ports[ controller ] and\
2322 "Error" not in devices[ controller ] and\
2323 "Error" not in ports[ controller ]:
2324
Jon Hallc6793552016-01-19 14:18:37 -08002325 try:
2326 currentDevicesResult = main.Mininet1.compareSwitches(
2327 mnSwitches,
2328 json.loads( devices[ controller ] ),
2329 json.loads( ports[ controller ] ) )
2330 except ( TypeError, ValueError ) as e:
2331 main.log.exception( "Object not as expected; devices={!r}\nports={!r}".format(
2332 devices[ controller ], ports[ controller ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002333 else:
2334 currentDevicesResult = main.FALSE
2335 utilities.assert_equals( expect=main.TRUE,
2336 actual=currentDevicesResult,
2337 onpass="ONOS" + controllerStr +
2338 " Switches view is correct",
2339 onfail="ONOS" + controllerStr +
2340 " Switches view is incorrect" )
2341
2342 if links[ controller ] and "Error" not in links[ controller ]:
2343 currentLinksResult = main.Mininet1.compareLinks(
2344 mnSwitches, mnLinks,
2345 json.loads( links[ controller ] ) )
2346 else:
2347 currentLinksResult = main.FALSE
2348 utilities.assert_equals( expect=main.TRUE,
2349 actual=currentLinksResult,
2350 onpass="ONOS" + controllerStr +
2351 " links view is correct",
2352 onfail="ONOS" + controllerStr +
2353 " links view is incorrect" )
Jon Hall657cdf62015-12-17 14:40:51 -08002354 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002355 currentHostsResult = main.Mininet1.compareHosts(
2356 mnHosts,
2357 hosts[ controller ] )
Jon Hall13b446e2016-01-05 12:17:01 -08002358 elif hosts[ controller ] == []:
2359 currentHostsResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002360 else:
2361 currentHostsResult = main.FALSE
2362 utilities.assert_equals( expect=main.TRUE,
2363 actual=currentHostsResult,
2364 onpass="ONOS" + controllerStr +
2365 " hosts exist in Mininet",
2366 onfail="ONOS" + controllerStr +
2367 " hosts don't match Mininet" )
2368 # CHECKING HOST ATTACHMENT POINTS
2369 hostAttachment = True
Jon Halla440e872016-03-31 15:15:50 -07002370 zeroHosts = False
Jon Hall5cf14d52015-07-16 12:15:19 -07002371 # FIXME: topo-HA/obelisk specific mappings:
2372 # key is mac and value is dpid
2373 mappings = {}
2374 for i in range( 1, 29 ): # hosts 1 through 28
2375 # set up correct variables:
2376 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2377 if i == 1:
2378 deviceId = "1000".zfill(16)
2379 elif i == 2:
2380 deviceId = "2000".zfill(16)
2381 elif i == 3:
2382 deviceId = "3000".zfill(16)
2383 elif i == 4:
2384 deviceId = "3004".zfill(16)
2385 elif i == 5:
2386 deviceId = "5000".zfill(16)
2387 elif i == 6:
2388 deviceId = "6000".zfill(16)
2389 elif i == 7:
2390 deviceId = "6007".zfill(16)
2391 elif i >= 8 and i <= 17:
2392 dpid = '3' + str( i ).zfill( 3 )
2393 deviceId = dpid.zfill(16)
2394 elif i >= 18 and i <= 27:
2395 dpid = '6' + str( i ).zfill( 3 )
2396 deviceId = dpid.zfill(16)
2397 elif i == 28:
2398 deviceId = "2800".zfill(16)
2399 mappings[ macId ] = deviceId
Jon Halld8f6de82015-12-17 17:04:34 -08002400 if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002401 if hosts[ controller ] == []:
2402 main.log.warn( "There are no hosts discovered" )
Jon Halla440e872016-03-31 15:15:50 -07002403 zeroHosts = True
Jon Hall5cf14d52015-07-16 12:15:19 -07002404 else:
2405 for host in hosts[ controller ]:
2406 mac = None
2407 location = None
2408 device = None
2409 port = None
2410 try:
2411 mac = host.get( 'mac' )
2412 assert mac, "mac field could not be found for this host object"
2413
2414 location = host.get( 'location' )
2415 assert location, "location field could not be found for this host object"
2416
2417 # Trim the protocol identifier off deviceId
2418 device = str( location.get( 'elementId' ) ).split(':')[1]
2419 assert device, "elementId field could not be found for this host location object"
2420
2421 port = location.get( 'port' )
2422 assert port, "port field could not be found for this host location object"
2423
2424 # Now check if this matches where they should be
2425 if mac and device and port:
2426 if str( port ) != "1":
2427 main.log.error( "The attachment port is incorrect for " +
2428 "host " + str( mac ) +
2429 ". Expected: 1 Actual: " + str( port) )
2430 hostAttachment = False
2431 if device != mappings[ str( mac ) ]:
2432 main.log.error( "The attachment device is incorrect for " +
2433 "host " + str( mac ) +
2434 ". Expected: " + mappings[ str( mac ) ] +
2435 " Actual: " + device )
2436 hostAttachment = False
2437 else:
2438 hostAttachment = False
2439 except AssertionError:
2440 main.log.exception( "Json object not as expected" )
2441 main.log.error( repr( host ) )
2442 hostAttachment = False
2443 else:
2444 main.log.error( "No hosts json output or \"Error\"" +
2445 " in output. hosts = " +
2446 repr( hosts[ controller ] ) )
Jon Halla440e872016-03-31 15:15:50 -07002447 if zeroHosts is False:
Jon Hall5cf14d52015-07-16 12:15:19 -07002448 # TODO: Find a way to know if there should be hosts in a
2449 # given point of the test
2450 hostAttachment = True
2451
2452 # END CHECKING HOST ATTACHMENT POINTS
2453 devicesResults = devicesResults and currentDevicesResult
2454 linksResults = linksResults and currentLinksResult
2455 hostsResults = hostsResults and currentHostsResult
2456 hostAttachmentResults = hostAttachmentResults and\
2457 hostAttachment
2458 topoResult = ( devicesResults and linksResults
2459 and hostsResults and ipResult and
2460 hostAttachmentResults )
Jon Halle9b1fa32015-12-08 15:32:21 -08002461 utilities.assert_equals( expect=True,
2462 actual=topoResult,
2463 onpass="ONOS topology matches Mininet",
Jon Hall6e709752016-02-01 13:38:46 -08002464 onfail=topoFailMsg )
Jon Halle9b1fa32015-12-08 15:32:21 -08002465 # End of While loop to pull ONOS state
Jon Hall5cf14d52015-07-16 12:15:19 -07002466
2467 # Compare json objects for hosts and dataplane clusters
2468
2469 # hosts
2470 main.step( "Hosts view is consistent across all ONOS nodes" )
2471 consistentHostsResult = main.TRUE
2472 for controller in range( len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07002473 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall13b446e2016-01-05 12:17:01 -08002474 if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002475 if hosts[ controller ] == hosts[ 0 ]:
2476 continue
2477 else: # hosts not consistent
2478 main.log.error( "hosts from ONOS" + controllerStr +
2479 " is inconsistent with ONOS1" )
2480 main.log.warn( repr( hosts[ controller ] ) )
2481 consistentHostsResult = main.FALSE
2482
2483 else:
2484 main.log.error( "Error in getting ONOS hosts from ONOS" +
2485 controllerStr )
2486 consistentHostsResult = main.FALSE
2487 main.log.warn( "ONOS" + controllerStr +
2488 " hosts response: " +
2489 repr( hosts[ controller ] ) )
2490 utilities.assert_equals(
2491 expect=main.TRUE,
2492 actual=consistentHostsResult,
2493 onpass="Hosts view is consistent across all ONOS nodes",
2494 onfail="ONOS nodes have different views of hosts" )
2495
2496 main.step( "Hosts information is correct" )
2497 hostsResults = hostsResults and ipResult
2498 utilities.assert_equals(
2499 expect=main.TRUE,
2500 actual=hostsResults,
2501 onpass="Host information is correct",
2502 onfail="Host information is incorrect" )
2503
2504 main.step( "Host attachment points to the network" )
2505 utilities.assert_equals(
2506 expect=True,
2507 actual=hostAttachmentResults,
2508 onpass="Hosts are correctly attached to the network",
2509 onfail="ONOS did not correctly attach hosts to the network" )
2510
2511 # Strongly connected clusters of devices
2512 main.step( "Clusters view is consistent across all ONOS nodes" )
2513 consistentClustersResult = main.TRUE
2514 for controller in range( len( clusters ) ):
Jon Halla440e872016-03-31 15:15:50 -07002515 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002516 if "Error" not in clusters[ controller ]:
2517 if clusters[ controller ] == clusters[ 0 ]:
2518 continue
2519 else: # clusters not consistent
2520 main.log.error( "clusters from ONOS" +
2521 controllerStr +
2522 " is inconsistent with ONOS1" )
2523 consistentClustersResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002524 else:
2525 main.log.error( "Error in getting dataplane clusters " +
2526 "from ONOS" + controllerStr )
2527 consistentClustersResult = main.FALSE
2528 main.log.warn( "ONOS" + controllerStr +
2529 " clusters response: " +
2530 repr( clusters[ controller ] ) )
2531 utilities.assert_equals(
2532 expect=main.TRUE,
2533 actual=consistentClustersResult,
2534 onpass="Clusters view is consistent across all ONOS nodes",
2535 onfail="ONOS nodes have different views of clusters" )
2536
2537 main.step( "There is only one SCC" )
2538 # there should always only be one cluster
2539 try:
2540 numClusters = len( json.loads( clusters[ 0 ] ) )
2541 except ( ValueError, TypeError ):
2542 main.log.exception( "Error parsing clusters[0]: " +
2543 repr( clusters[0] ) )
Jon Halla440e872016-03-31 15:15:50 -07002544 numClusters = "ERROR"
Jon Hall5cf14d52015-07-16 12:15:19 -07002545 clusterResults = main.FALSE
2546 if numClusters == 1:
2547 clusterResults = main.TRUE
2548 utilities.assert_equals(
2549 expect=1,
2550 actual=numClusters,
2551 onpass="ONOS shows 1 SCC",
2552 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2553
2554 topoResult = ( devicesResults and linksResults
2555 and hostsResults and consistentHostsResult
2556 and consistentClustersResult and clusterResults
2557 and ipResult and hostAttachmentResults )
2558
2559 topoResult = topoResult and int( count <= 2 )
2560 note = "note it takes about " + str( int( cliTime ) ) + \
2561 " seconds for the test to make all the cli calls to fetch " +\
2562 "the topology from each ONOS instance"
2563 main.log.info(
2564 "Very crass estimate for topology discovery/convergence( " +
2565 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2566 str( count ) + " tries" )
2567
2568 main.step( "Device information is correct" )
2569 utilities.assert_equals(
2570 expect=main.TRUE,
2571 actual=devicesResults,
2572 onpass="Device information is correct",
2573 onfail="Device information is incorrect" )
2574
2575 main.step( "Links are correct" )
2576 utilities.assert_equals(
2577 expect=main.TRUE,
2578 actual=linksResults,
2579 onpass="Link are correct",
2580 onfail="Links are incorrect" )
2581
Jon Halla440e872016-03-31 15:15:50 -07002582 main.step( "Hosts are correct" )
2583 utilities.assert_equals(
2584 expect=main.TRUE,
2585 actual=hostsResults,
2586 onpass="Hosts are correct",
2587 onfail="Hosts are incorrect" )
2588
Jon Hall5cf14d52015-07-16 12:15:19 -07002589 # FIXME: move this to an ONOS state case
2590 main.step( "Checking ONOS nodes" )
2591 nodesOutput = []
2592 nodeResults = main.TRUE
2593 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002594 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002595 t = main.Thread( target=main.CLIs[i].nodes,
Jon Hall5cf14d52015-07-16 12:15:19 -07002596 name="nodes-" + str( i ),
2597 args=[ ] )
2598 threads.append( t )
2599 t.start()
2600
2601 for t in threads:
2602 t.join()
2603 nodesOutput.append( t.result )
Jon Halla440e872016-03-31 15:15:50 -07002604 ips = [ main.nodes[node].ip_address for node in main.activeNodes ]
Jon Halle9b1fa32015-12-08 15:32:21 -08002605 ips.sort()
Jon Hall5cf14d52015-07-16 12:15:19 -07002606 for i in nodesOutput:
2607 try:
2608 current = json.loads( i )
Jon Halle9b1fa32015-12-08 15:32:21 -08002609 activeIps = []
2610 currentResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002611 for node in current:
Jon Hallbd182782016-03-28 16:42:22 -07002612 if node['state'] == 'READY':
Jon Halle9b1fa32015-12-08 15:32:21 -08002613 activeIps.append( node['ip'] )
2614 activeIps.sort()
2615 if ips == activeIps:
2616 currentResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002617 except ( ValueError, TypeError ):
2618 main.log.error( "Error parsing nodes output" )
2619 main.log.warn( repr( i ) )
Jon Halle9b1fa32015-12-08 15:32:21 -08002620 currentResult = main.FALSE
2621 nodeResults = nodeResults and currentResult
Jon Hall5cf14d52015-07-16 12:15:19 -07002622 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2623 onpass="Nodes check successful",
2624 onfail="Nodes check NOT successful" )
Jon Halla440e872016-03-31 15:15:50 -07002625 if not nodeResults:
2626 for cli in main.CLIs:
2627 main.log.debug( "{} components not ACTIVE: \n{}".format(
2628 cli.name,
2629 cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002630
2631 def CASE9( self, main ):
2632 """
2633 Link s3-s28 down
2634 """
2635 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002636 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002637 assert main, "main not defined"
2638 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002639 assert main.CLIs, "main.CLIs not defined"
2640 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002641 # NOTE: You should probably run a topology check after this
2642
2643 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2644
2645 description = "Turn off a link to ensure that Link Discovery " +\
2646 "is working properly"
2647 main.case( description )
2648
2649 main.step( "Kill Link between s3 and s28" )
2650 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
2651 main.log.info( "Waiting " + str( linkSleep ) +
2652 " seconds for link down to be discovered" )
2653 time.sleep( linkSleep )
2654 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
2655 onpass="Link down successful",
2656 onfail="Failed to bring link down" )
2657 # TODO do some sort of check here
2658
2659 def CASE10( self, main ):
2660 """
2661 Link s3-s28 up
2662 """
2663 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002664 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002665 assert main, "main not defined"
2666 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002667 assert main.CLIs, "main.CLIs not defined"
2668 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002669 # NOTE: You should probably run a topology check after this
2670
2671 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2672
2673 description = "Restore a link to ensure that Link Discovery is " + \
2674 "working properly"
2675 main.case( description )
2676
2677 main.step( "Bring link between s3 and s28 back up" )
2678 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
2679 main.log.info( "Waiting " + str( linkSleep ) +
2680 " seconds for link up to be discovered" )
2681 time.sleep( linkSleep )
2682 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
2683 onpass="Link up successful",
2684 onfail="Failed to bring link up" )
2685 # TODO do some sort of check here
2686
2687 def CASE11( self, main ):
2688 """
2689 Switch Down
2690 """
2691 # NOTE: You should probably run a topology check after this
2692 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002693 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002694 assert main, "main not defined"
2695 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002696 assert main.CLIs, "main.CLIs not defined"
2697 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002698
2699 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2700
2701 description = "Killing a switch to ensure it is discovered correctly"
Jon Halla440e872016-03-31 15:15:50 -07002702 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002703 main.case( description )
2704 switch = main.params[ 'kill' ][ 'switch' ]
2705 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2706
2707 # TODO: Make this switch parameterizable
2708 main.step( "Kill " + switch )
2709 main.log.info( "Deleting " + switch )
2710 main.Mininet1.delSwitch( switch )
2711 main.log.info( "Waiting " + str( switchSleep ) +
2712 " seconds for switch down to be discovered" )
2713 time.sleep( switchSleep )
Jon Halla440e872016-03-31 15:15:50 -07002714 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall5cf14d52015-07-16 12:15:19 -07002715 # Peek at the deleted switch
2716 main.log.warn( str( device ) )
2717 result = main.FALSE
2718 if device and device[ 'available' ] is False:
2719 result = main.TRUE
2720 utilities.assert_equals( expect=main.TRUE, actual=result,
2721 onpass="Kill switch successful",
2722 onfail="Failed to kill switch?" )
2723
2724 def CASE12( self, main ):
2725 """
2726 Switch Up
2727 """
2728 # NOTE: You should probably run a topology check after this
2729 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002730 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002731 assert main, "main not defined"
2732 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002733 assert main.CLIs, "main.CLIs not defined"
2734 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002735 assert ONOS1Port, "ONOS1Port not defined"
2736 assert ONOS2Port, "ONOS2Port not defined"
2737 assert ONOS3Port, "ONOS3Port not defined"
2738 assert ONOS4Port, "ONOS4Port not defined"
2739 assert ONOS5Port, "ONOS5Port not defined"
2740 assert ONOS6Port, "ONOS6Port not defined"
2741 assert ONOS7Port, "ONOS7Port not defined"
2742
2743 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2744 switch = main.params[ 'kill' ][ 'switch' ]
2745 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2746 links = main.params[ 'kill' ][ 'links' ].split()
Jon Halla440e872016-03-31 15:15:50 -07002747 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002748 description = "Adding a switch to ensure it is discovered correctly"
2749 main.case( description )
2750
2751 main.step( "Add back " + switch )
2752 main.Mininet1.addSwitch( switch, dpid=switchDPID )
2753 for peer in links:
2754 main.Mininet1.addLink( switch, peer )
Jon Halla440e872016-03-31 15:15:50 -07002755 ipList = [ node.ip_address for node in main.nodes ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002756 main.Mininet1.assignSwController( sw=switch, ip=ipList )
2757 main.log.info( "Waiting " + str( switchSleep ) +
2758 " seconds for switch up to be discovered" )
2759 time.sleep( switchSleep )
Jon Halla440e872016-03-31 15:15:50 -07002760 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall5cf14d52015-07-16 12:15:19 -07002761 # Peek at the deleted switch
2762 main.log.warn( str( device ) )
2763 result = main.FALSE
2764 if device and device[ 'available' ]:
2765 result = main.TRUE
2766 utilities.assert_equals( expect=main.TRUE, actual=result,
2767 onpass="add switch successful",
2768 onfail="Failed to add switch?" )
2769
2770 def CASE13( self, main ):
2771 """
2772 Clean up
2773 """
2774 import os
2775 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002776 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002777 assert main, "main not defined"
2778 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002779 assert main.CLIs, "main.CLIs not defined"
2780 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002781
2782 # printing colors to terminal
2783 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2784 'blue': '\033[94m', 'green': '\033[92m',
2785 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
2786 main.case( "Test Cleanup" )
2787 main.step( "Killing tcpdumps" )
2788 main.Mininet2.stopTcpdump()
2789
2790 testname = main.TEST
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002791 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall5cf14d52015-07-16 12:15:19 -07002792 main.step( "Copying MN pcap and ONOS log files to test station" )
2793 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
2794 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
Jon Hall96091e62015-09-21 17:34:17 -07002795 # NOTE: MN Pcap file is being saved to logdir.
2796 # We scp this file as MN and TestON aren't necessarily the same vm
2797
2798 # FIXME: To be replaced with a Jenkin's post script
Jon Hall5cf14d52015-07-16 12:15:19 -07002799 # TODO: Load these from params
2800 # NOTE: must end in /
2801 logFolder = "/opt/onos/log/"
2802 logFiles = [ "karaf.log", "karaf.log.1" ]
2803 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002804 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002805 for node in main.nodes:
Jon Hall6e709752016-02-01 13:38:46 -08002806 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002807 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2808 logFolder + f, dstName )
Jon Hall5cf14d52015-07-16 12:15:19 -07002809 # std*.log's
2810 # NOTE: must end in /
2811 logFolder = "/opt/onos/var/"
2812 logFiles = [ "stderr.log", "stdout.log" ]
2813 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002814 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002815 for node in main.nodes:
Jon Hall6e709752016-02-01 13:38:46 -08002816 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002817 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2818 logFolder + f, dstName )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002819 else:
2820 main.log.debug( "skipping saving log files" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002821
2822 main.step( "Stopping Mininet" )
2823 mnResult = main.Mininet1.stopNet()
2824 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2825 onpass="Mininet stopped",
2826 onfail="MN cleanup NOT successful" )
2827
2828 main.step( "Checking ONOS Logs for errors" )
Jon Halle1a3b752015-07-22 13:02:46 -07002829 for node in main.nodes:
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002830 main.log.debug( "Checking logs for errors on " + node.name + ":" )
2831 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002832
2833 try:
2834 timerLog = open( main.logdir + "/Timers.csv", 'w')
2835 main.log.error( ", ".join( labels ) + "\n" + ", ".join( data ) )
2836 timerLog.write( ", ".join( labels ) + "\n" + ", ".join( data ) )
2837 timerLog.close()
2838 except NameError, e:
2839 main.log.exception(e)
2840
2841 def CASE14( self, main ):
2842 """
2843 start election app on all onos nodes
2844 """
Jon Halle1a3b752015-07-22 13:02:46 -07002845 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002846 assert main, "main not defined"
2847 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002848 assert main.CLIs, "main.CLIs not defined"
2849 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002850
2851 main.case("Start Leadership Election app")
2852 main.step( "Install leadership election app" )
Jon Halla440e872016-03-31 15:15:50 -07002853 onosCli = main.CLIs[ main.activeNodes[0] ]
2854 appResult = onosCli.activateApp( "org.onosproject.election" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002855 utilities.assert_equals(
2856 expect=main.TRUE,
2857 actual=appResult,
2858 onpass="Election app installed",
2859 onfail="Something went wrong with installing Leadership election" )
2860
2861 main.step( "Run for election on each node" )
2862 leaderResult = main.TRUE
2863 leaders = []
Jon Halla440e872016-03-31 15:15:50 -07002864 for i in main.activeNodes:
2865 main.CLIs[i].electionTestRun()
2866 for i in main.activeNodes:
2867 cli = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07002868 leader = cli.electionTestLeader()
2869 if leader is None or leader == main.FALSE:
2870 main.log.error( cli.name + ": Leader for the election app " +
2871 "should be an ONOS node, instead got '" +
2872 str( leader ) + "'" )
2873 leaderResult = main.FALSE
2874 leaders.append( leader )
2875 utilities.assert_equals(
2876 expect=main.TRUE,
2877 actual=leaderResult,
2878 onpass="Successfully ran for leadership",
2879 onfail="Failed to run for leadership" )
2880
2881 main.step( "Check that each node shows the same leader" )
2882 sameLeader = main.TRUE
2883 if len( set( leaders ) ) != 1:
2884 sameLeader = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08002885 main.log.error( "Results of electionTestLeader is order of main.CLIs:" +
Jon Hall5cf14d52015-07-16 12:15:19 -07002886 str( leaders ) )
2887 utilities.assert_equals(
2888 expect=main.TRUE,
2889 actual=sameLeader,
2890 onpass="Leadership is consistent for the election topic",
2891 onfail="Nodes have different leaders" )
2892
2893 def CASE15( self, main ):
2894 """
2895 Check that Leadership Election is still functional
acsmars9475b1c2015-08-28 18:02:08 -07002896 15.1 Run election on each node
2897 15.2 Check that each node has the same leaders and candidates
2898 15.3 Find current leader and withdraw
2899 15.4 Check that a new node was elected leader
2900 15.5 Check that that new leader was the candidate of old leader
2901 15.6 Run for election on old leader
2902 15.7 Check that oldLeader is a candidate, and leader if only 1 node
2903 15.8 Make sure that the old leader was added to the candidate list
2904
2905 old and new variable prefixes refer to data from before vs after
2906 withdrawl and later before withdrawl vs after re-election
Jon Hall5cf14d52015-07-16 12:15:19 -07002907 """
2908 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002909 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002910 assert main, "main not defined"
2911 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002912 assert main.CLIs, "main.CLIs not defined"
2913 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002914
Jon Hall5cf14d52015-07-16 12:15:19 -07002915 description = "Check that Leadership Election is still functional"
2916 main.case( description )
Jon Halla440e872016-03-31 15:15:50 -07002917 # NOTE: Need to re-run after restarts since being a canidate is not persistant
acsmars9475b1c2015-08-28 18:02:08 -07002918
Jon Halla440e872016-03-31 15:15:50 -07002919 oldLeaders = [] # list of lists of each nodes' candidates before
2920 newLeaders = [] # list of lists of each nodes' candidates after
acsmars9475b1c2015-08-28 18:02:08 -07002921 oldLeader = '' # the old leader from oldLeaders, None if not same
2922 newLeader = '' # the new leaders fron newLoeaders, None if not same
2923 oldLeaderCLI = None # the CLI of the old leader used for re-electing
acsmars71adceb2015-08-31 15:09:26 -07002924 expectNoLeader = False # True when there is only one leader
2925 if main.numCtrls == 1:
2926 expectNoLeader = True
acsmars9475b1c2015-08-28 18:02:08 -07002927
Jon Hall5cf14d52015-07-16 12:15:19 -07002928 main.step( "Run for election on each node" )
acsmars9475b1c2015-08-28 18:02:08 -07002929 electionResult = main.TRUE
2930
Jon Halla440e872016-03-31 15:15:50 -07002931 for i in main.activeNodes: # run test election on each node
2932 if main.CLIs[i].electionTestRun() == main.FALSE:
acsmars9475b1c2015-08-28 18:02:08 -07002933 electionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002934 utilities.assert_equals(
2935 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07002936 actual=electionResult,
2937 onpass="All nodes successfully ran for leadership",
2938 onfail="At least one node failed to run for leadership" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002939
acsmars3a72bde2015-09-02 14:16:22 -07002940 if electionResult == main.FALSE:
2941 main.log.error(
2942 "Skipping Test Case because Election Test App isn't loaded" )
2943 main.skipCase()
2944
acsmars9475b1c2015-08-28 18:02:08 -07002945 main.step( "Check that each node shows the same leader and candidates" )
Jon Halla440e872016-03-31 15:15:50 -07002946 failMessage = "Nodes have different leaderboards"
2947 def consistentLeaderboards( nodes ):
2948 TOPIC = 'org.onosproject.election'
2949 # FIXME: use threads
2950 #FIXME: should we retry outside the function?
2951 for n in range( 5 ): # Retry in case election is still happening
2952 leaderList = []
2953 # Get all leaderboards
2954 for cli in nodes:
2955 leaderList.append( cli.specificLeaderCandidate( TOPIC ) )
2956 # Compare leaderboards
2957 result = all( i == leaderList[0] for i in leaderList ) and\
2958 leaderList is not None
2959 main.log.debug( leaderList )
2960 main.log.warn( result )
2961 if result:
2962 return ( result, leaderList )
2963 time.sleep(5) #TODO: paramerterize
2964 main.log.error( "Inconsistent leaderboards:" + str( leaderList ) )
2965 activeCLIs = [ main.CLIs[i] for i in main.activeNodes ]
2966 sameResult, oldLeaders = consistentLeaderboards( activeCLIs )
2967 if sameResult:
2968 oldLeader = oldLeaders[ 0 ][ 0 ]
2969 main.log.warn( oldLeader )
acsmars9475b1c2015-08-28 18:02:08 -07002970 else:
Jon Halla440e872016-03-31 15:15:50 -07002971 oldLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07002972 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07002973 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07002974 actual=sameResult,
Jon Halla440e872016-03-31 15:15:50 -07002975 onpass="Leaderboards are consistent for the election topic",
acsmars9475b1c2015-08-28 18:02:08 -07002976 onfail=failMessage )
Jon Hall5cf14d52015-07-16 12:15:19 -07002977
2978 main.step( "Find current leader and withdraw" )
acsmars9475b1c2015-08-28 18:02:08 -07002979 withdrawResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002980 # do some sanity checking on leader before using it
acsmars9475b1c2015-08-28 18:02:08 -07002981 if oldLeader is None:
2982 main.log.error( "Leadership isn't consistent." )
2983 withdrawResult = main.FALSE
2984 # Get the CLI of the oldLeader
Jon Halla440e872016-03-31 15:15:50 -07002985 for i in main.activeNodes:
acsmars9475b1c2015-08-28 18:02:08 -07002986 if oldLeader == main.nodes[ i ].ip_address:
2987 oldLeaderCLI = main.CLIs[ i ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002988 break
2989 else: # FOR/ELSE statement
2990 main.log.error( "Leader election, could not find current leader" )
2991 if oldLeader:
acsmars9475b1c2015-08-28 18:02:08 -07002992 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall5cf14d52015-07-16 12:15:19 -07002993 utilities.assert_equals(
2994 expect=main.TRUE,
2995 actual=withdrawResult,
2996 onpass="Node was withdrawn from election",
2997 onfail="Node was not withdrawn from election" )
2998
acsmars9475b1c2015-08-28 18:02:08 -07002999 main.step( "Check that a new node was elected leader" )
acsmars9475b1c2015-08-28 18:02:08 -07003000 failMessage = "Nodes have different leaders"
acsmars9475b1c2015-08-28 18:02:08 -07003001 # Get new leaders and candidates
Jon Halla440e872016-03-31 15:15:50 -07003002 newLeaderResult, newLeaders = consistentLeaderboards( activeCLIs )
3003 if newLeaders[ 0 ][ 0 ] == 'none':
3004 main.log.error( "No leader was elected on at least 1 node" )
3005 if not expectNoLeader:
3006 newLeaderResult = False
3007 if newLeaderResult:
3008 newLeader = newLeaders[ 0 ][ 0 ]
Jon Hall5cf14d52015-07-16 12:15:19 -07003009 else:
Jon Halla440e872016-03-31 15:15:50 -07003010 newLeader = None
acsmars71adceb2015-08-31 15:09:26 -07003011
acsmars9475b1c2015-08-28 18:02:08 -07003012 # Check that the new leader is not the older leader, which was withdrawn
3013 if newLeader == oldLeader:
Jon Halla440e872016-03-31 15:15:50 -07003014 newLeaderResult = False
Jon Hall6e709752016-02-01 13:38:46 -08003015 main.log.error( "All nodes still see old leader: " + str( oldLeader ) +
acsmars9475b1c2015-08-28 18:02:08 -07003016 " as the current leader" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003017 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07003018 expect=True,
acsmars9475b1c2015-08-28 18:02:08 -07003019 actual=newLeaderResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07003020 onpass="Leadership election passed",
3021 onfail="Something went wrong with Leadership election" )
3022
Jon Halla440e872016-03-31 15:15:50 -07003023 main.step( "Check that that new leader was the candidate of old leader" )
Jon Hall6e709752016-02-01 13:38:46 -08003024 # candidates[ 2 ] should become the top candidate after withdrawl
acsmars9475b1c2015-08-28 18:02:08 -07003025 correctCandidateResult = main.TRUE
acsmars71adceb2015-08-31 15:09:26 -07003026 if expectNoLeader:
3027 if newLeader == 'none':
3028 main.log.info( "No leader expected. None found. Pass" )
3029 correctCandidateResult = main.TRUE
3030 else:
3031 main.log.info( "Expected no leader, got: " + str( newLeader ) )
3032 correctCandidateResult = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003033 elif len( oldLeaders[0] ) >= 3:
3034 if newLeader == oldLeaders[ 0 ][ 2 ]:
3035 # correct leader was elected
3036 correctCandidateResult = main.TRUE
3037 else:
3038 correctCandidateResult = main.FALSE
3039 main.log.error( "Candidate {} was elected. {} should have had priority.".format(
3040 newLeader, oldLeaders[ 0 ][ 2 ] ) )
Jon Hall6e709752016-02-01 13:38:46 -08003041 else:
3042 main.log.warn( "Could not determine who should be the correct leader" )
Jon Halla440e872016-03-31 15:15:50 -07003043 main.log.debug( oldLeaders[ 0 ] )
Jon Hall6e709752016-02-01 13:38:46 -08003044 correctCandidateResult = main.FALSE
acsmars9475b1c2015-08-28 18:02:08 -07003045 utilities.assert_equals(
3046 expect=main.TRUE,
3047 actual=correctCandidateResult,
3048 onpass="Correct Candidate Elected",
3049 onfail="Incorrect Candidate Elected" )
3050
Jon Hall5cf14d52015-07-16 12:15:19 -07003051 main.step( "Run for election on old leader( just so everyone " +
3052 "is in the hat )" )
acsmars9475b1c2015-08-28 18:02:08 -07003053 if oldLeaderCLI is not None:
3054 runResult = oldLeaderCLI.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07003055 else:
acsmars9475b1c2015-08-28 18:02:08 -07003056 main.log.error( "No old leader to re-elect" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003057 runResult = main.FALSE
3058 utilities.assert_equals(
3059 expect=main.TRUE,
3060 actual=runResult,
3061 onpass="App re-ran for election",
3062 onfail="App failed to run for election" )
Jon Halla440e872016-03-31 15:15:50 -07003063
acsmars9475b1c2015-08-28 18:02:08 -07003064 main.step(
3065 "Check that oldLeader is a candidate, and leader if only 1 node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003066 # verify leader didn't just change
Jon Halla440e872016-03-31 15:15:50 -07003067 # Get new leaders and candidates
3068 reRunLeaders = []
3069 time.sleep( 5 ) # Paremterize
3070 positionResult, reRunLeaders = consistentLeaderboards( activeCLIs )
acsmars71adceb2015-08-31 15:09:26 -07003071
acsmars9475b1c2015-08-28 18:02:08 -07003072 # Check that the re-elected node is last on the candidate List
Jon Halla440e872016-03-31 15:15:50 -07003073 if oldLeader != reRunLeaders[ 0 ][ -1 ]:
3074 main.log.error( "Old Leader ({}) not in the proper position: {} ".format( str( oldLeader),
3075 str( reRunLeaders[ 0 ] ) ) )
acsmars9475b1c2015-08-28 18:02:08 -07003076 positionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07003077
3078 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07003079 expect=True,
acsmars9475b1c2015-08-28 18:02:08 -07003080 actual=positionResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07003081 onpass="Old leader successfully re-ran for election",
3082 onfail="Something went wrong with Leadership election after " +
3083 "the old leader re-ran for election" )
3084
3085 def CASE16( self, main ):
3086 """
3087 Install Distributed Primitives app
3088 """
3089 import time
Jon Halle1a3b752015-07-22 13:02:46 -07003090 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003091 assert main, "main not defined"
3092 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003093 assert main.CLIs, "main.CLIs not defined"
3094 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003095
3096 # Variables for the distributed primitives tests
3097 global pCounterName
Jon Hall5cf14d52015-07-16 12:15:19 -07003098 global pCounterValue
Jon Hall5cf14d52015-07-16 12:15:19 -07003099 global onosSet
3100 global onosSetName
3101 pCounterName = "TestON-Partitions"
Jon Hall5cf14d52015-07-16 12:15:19 -07003102 pCounterValue = 0
Jon Hall5cf14d52015-07-16 12:15:19 -07003103 onosSet = set([])
3104 onosSetName = "TestON-set"
3105
3106 description = "Install Primitives app"
3107 main.case( description )
3108 main.step( "Install Primitives app" )
3109 appName = "org.onosproject.distributedprimitives"
Jon Halla440e872016-03-31 15:15:50 -07003110 node = main.activeNodes[0]
3111 appResults = main.CLIs[node].activateApp( appName )
Jon Hall5cf14d52015-07-16 12:15:19 -07003112 utilities.assert_equals( expect=main.TRUE,
3113 actual=appResults,
3114 onpass="Primitives app activated",
3115 onfail="Primitives app not activated" )
3116 time.sleep( 5 ) # To allow all nodes to activate
3117
3118 def CASE17( self, main ):
3119 """
3120 Check for basic functionality with distributed primitives
3121 """
Jon Hall5cf14d52015-07-16 12:15:19 -07003122 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07003123 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003124 assert main, "main not defined"
3125 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003126 assert main.CLIs, "main.CLIs not defined"
3127 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003128 assert pCounterName, "pCounterName not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003129 assert onosSetName, "onosSetName not defined"
3130 # NOTE: assert fails if value is 0/None/Empty/False
3131 try:
3132 pCounterValue
3133 except NameError:
3134 main.log.error( "pCounterValue not defined, setting to 0" )
3135 pCounterValue = 0
3136 try:
Jon Hall5cf14d52015-07-16 12:15:19 -07003137 onosSet
3138 except NameError:
3139 main.log.error( "onosSet not defined, setting to empty Set" )
3140 onosSet = set([])
3141 # Variables for the distributed primitives tests. These are local only
3142 addValue = "a"
3143 addAllValue = "a b c d e f"
3144 retainValue = "c d e f"
3145
3146 description = "Check for basic functionality with distributed " +\
3147 "primitives"
3148 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07003149 main.caseExplanation = "Test the methods of the distributed " +\
3150 "primitives (counters and sets) throught the cli"
Jon Hall5cf14d52015-07-16 12:15:19 -07003151 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07003152 # Partitioned counters
3153 main.step( "Increment then get a default counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003154 pCounters = []
3155 threads = []
3156 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003157 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003158 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3159 name="counterAddAndGet-" + str( i ),
Jon Hall5cf14d52015-07-16 12:15:19 -07003160 args=[ pCounterName ] )
3161 pCounterValue += 1
3162 addedPValues.append( pCounterValue )
3163 threads.append( t )
3164 t.start()
3165
3166 for t in threads:
3167 t.join()
3168 pCounters.append( t.result )
3169 # Check that counter incremented numController times
3170 pCounterResults = True
3171 for i in addedPValues:
3172 tmpResult = i in pCounters
3173 pCounterResults = pCounterResults and tmpResult
3174 if not tmpResult:
3175 main.log.error( str( i ) + " is not in partitioned "
3176 "counter incremented results" )
3177 utilities.assert_equals( expect=True,
3178 actual=pCounterResults,
3179 onpass="Default counter incremented",
3180 onfail="Error incrementing default" +
3181 " counter" )
3182
Jon Halle1a3b752015-07-22 13:02:46 -07003183 main.step( "Get then Increment a default counter on each node" )
3184 pCounters = []
3185 threads = []
3186 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003187 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003188 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3189 name="counterGetAndAdd-" + str( i ),
3190 args=[ pCounterName ] )
3191 addedPValues.append( pCounterValue )
3192 pCounterValue += 1
3193 threads.append( t )
3194 t.start()
3195
3196 for t in threads:
3197 t.join()
3198 pCounters.append( t.result )
3199 # Check that counter incremented numController times
3200 pCounterResults = True
3201 for i in addedPValues:
3202 tmpResult = i in pCounters
3203 pCounterResults = pCounterResults and tmpResult
3204 if not tmpResult:
3205 main.log.error( str( i ) + " is not in partitioned "
3206 "counter incremented results" )
3207 utilities.assert_equals( expect=True,
3208 actual=pCounterResults,
3209 onpass="Default counter incremented",
3210 onfail="Error incrementing default" +
3211 " counter" )
3212
3213 main.step( "Counters we added have the correct values" )
3214 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3215 utilities.assert_equals( expect=main.TRUE,
3216 actual=incrementCheck,
3217 onpass="Added counters are correct",
3218 onfail="Added counters are incorrect" )
3219
3220 main.step( "Add -8 to then get a default counter on each node" )
3221 pCounters = []
3222 threads = []
3223 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003224 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003225 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3226 name="counterIncrement-" + str( i ),
3227 args=[ pCounterName ],
3228 kwargs={ "delta": -8 } )
3229 pCounterValue += -8
3230 addedPValues.append( pCounterValue )
3231 threads.append( t )
3232 t.start()
3233
3234 for t in threads:
3235 t.join()
3236 pCounters.append( t.result )
3237 # Check that counter incremented numController times
3238 pCounterResults = True
3239 for i in addedPValues:
3240 tmpResult = i in pCounters
3241 pCounterResults = pCounterResults and tmpResult
3242 if not tmpResult:
3243 main.log.error( str( i ) + " is not in partitioned "
3244 "counter incremented results" )
3245 utilities.assert_equals( expect=True,
3246 actual=pCounterResults,
3247 onpass="Default counter incremented",
3248 onfail="Error incrementing default" +
3249 " counter" )
3250
3251 main.step( "Add 5 to then get a default counter on each node" )
3252 pCounters = []
3253 threads = []
3254 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003255 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003256 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3257 name="counterIncrement-" + str( i ),
3258 args=[ pCounterName ],
3259 kwargs={ "delta": 5 } )
3260 pCounterValue += 5
3261 addedPValues.append( pCounterValue )
3262 threads.append( t )
3263 t.start()
3264
3265 for t in threads:
3266 t.join()
3267 pCounters.append( t.result )
3268 # Check that counter incremented numController times
3269 pCounterResults = True
3270 for i in addedPValues:
3271 tmpResult = i in pCounters
3272 pCounterResults = pCounterResults and tmpResult
3273 if not tmpResult:
3274 main.log.error( str( i ) + " is not in partitioned "
3275 "counter incremented results" )
3276 utilities.assert_equals( expect=True,
3277 actual=pCounterResults,
3278 onpass="Default counter incremented",
3279 onfail="Error incrementing default" +
3280 " counter" )
3281
3282 main.step( "Get then add 5 to a default counter on each node" )
3283 pCounters = []
3284 threads = []
3285 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003286 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003287 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3288 name="counterIncrement-" + str( i ),
3289 args=[ pCounterName ],
3290 kwargs={ "delta": 5 } )
3291 addedPValues.append( pCounterValue )
3292 pCounterValue += 5
3293 threads.append( t )
3294 t.start()
3295
3296 for t in threads:
3297 t.join()
3298 pCounters.append( t.result )
3299 # Check that counter incremented numController times
3300 pCounterResults = True
3301 for i in addedPValues:
3302 tmpResult = i in pCounters
3303 pCounterResults = pCounterResults and tmpResult
3304 if not tmpResult:
3305 main.log.error( str( i ) + " is not in partitioned "
3306 "counter incremented results" )
3307 utilities.assert_equals( expect=True,
3308 actual=pCounterResults,
3309 onpass="Default counter incremented",
3310 onfail="Error incrementing default" +
3311 " counter" )
3312
3313 main.step( "Counters we added have the correct values" )
3314 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3315 utilities.assert_equals( expect=main.TRUE,
3316 actual=incrementCheck,
3317 onpass="Added counters are correct",
3318 onfail="Added counters are incorrect" )
3319
Jon Hall5cf14d52015-07-16 12:15:19 -07003320 # DISTRIBUTED SETS
3321 main.step( "Distributed Set get" )
3322 size = len( onosSet )
3323 getResponses = []
3324 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003325 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003326 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003327 name="setTestGet-" + str( i ),
3328 args=[ onosSetName ] )
3329 threads.append( t )
3330 t.start()
3331 for t in threads:
3332 t.join()
3333 getResponses.append( t.result )
3334
3335 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003336 for i in range( len( main.activeNodes ) ):
3337 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003338 if isinstance( getResponses[ i ], list):
3339 current = set( getResponses[ i ] )
3340 if len( current ) == len( getResponses[ i ] ):
3341 # no repeats
3342 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003343 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003344 " has incorrect view" +
3345 " of set " + onosSetName + ":\n" +
3346 str( getResponses[ i ] ) )
3347 main.log.debug( "Expected: " + str( onosSet ) )
3348 main.log.debug( "Actual: " + str( current ) )
3349 getResults = main.FALSE
3350 else:
3351 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003352 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003353 " has repeat elements in" +
3354 " set " + onosSetName + ":\n" +
3355 str( getResponses[ i ] ) )
3356 getResults = main.FALSE
3357 elif getResponses[ i ] == main.ERROR:
3358 getResults = main.FALSE
3359 utilities.assert_equals( expect=main.TRUE,
3360 actual=getResults,
3361 onpass="Set elements are correct",
3362 onfail="Set elements are incorrect" )
3363
3364 main.step( "Distributed Set size" )
3365 sizeResponses = []
3366 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003367 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003368 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003369 name="setTestSize-" + str( i ),
3370 args=[ onosSetName ] )
3371 threads.append( t )
3372 t.start()
3373 for t in threads:
3374 t.join()
3375 sizeResponses.append( t.result )
3376
3377 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003378 for i in range( len( main.activeNodes ) ):
3379 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003380 if size != sizeResponses[ i ]:
3381 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003382 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003383 " expected a size of " + str( size ) +
3384 " for set " + onosSetName +
3385 " but got " + str( sizeResponses[ i ] ) )
3386 utilities.assert_equals( expect=main.TRUE,
3387 actual=sizeResults,
3388 onpass="Set sizes are correct",
3389 onfail="Set sizes are incorrect" )
3390
3391 main.step( "Distributed Set add()" )
3392 onosSet.add( addValue )
3393 addResponses = []
3394 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003395 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003396 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003397 name="setTestAdd-" + str( i ),
3398 args=[ onosSetName, addValue ] )
3399 threads.append( t )
3400 t.start()
3401 for t in threads:
3402 t.join()
3403 addResponses.append( t.result )
3404
3405 # main.TRUE = successfully changed the set
3406 # main.FALSE = action resulted in no change in set
3407 # main.ERROR - Some error in executing the function
3408 addResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003409 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003410 if addResponses[ i ] == main.TRUE:
3411 # All is well
3412 pass
3413 elif addResponses[ i ] == main.FALSE:
3414 # Already in set, probably fine
3415 pass
3416 elif addResponses[ i ] == main.ERROR:
3417 # Error in execution
3418 addResults = main.FALSE
3419 else:
3420 # unexpected result
3421 addResults = main.FALSE
3422 if addResults != main.TRUE:
3423 main.log.error( "Error executing set add" )
3424
3425 # Check if set is still correct
3426 size = len( onosSet )
3427 getResponses = []
3428 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003429 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003430 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003431 name="setTestGet-" + str( i ),
3432 args=[ onosSetName ] )
3433 threads.append( t )
3434 t.start()
3435 for t in threads:
3436 t.join()
3437 getResponses.append( t.result )
3438 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003439 for i in range( len( main.activeNodes ) ):
3440 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003441 if isinstance( getResponses[ i ], list):
3442 current = set( getResponses[ i ] )
3443 if len( current ) == len( getResponses[ i ] ):
3444 # no repeats
3445 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003446 main.log.error( "ONOS" + node + " has incorrect view" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003447 " of set " + onosSetName + ":\n" +
3448 str( getResponses[ i ] ) )
3449 main.log.debug( "Expected: " + str( onosSet ) )
3450 main.log.debug( "Actual: " + str( current ) )
3451 getResults = main.FALSE
3452 else:
3453 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003454 main.log.error( "ONOS" + node + " has repeat elements in" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003455 " set " + onosSetName + ":\n" +
3456 str( getResponses[ i ] ) )
3457 getResults = main.FALSE
3458 elif getResponses[ i ] == main.ERROR:
3459 getResults = main.FALSE
3460 sizeResponses = []
3461 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003462 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003463 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003464 name="setTestSize-" + str( i ),
3465 args=[ onosSetName ] )
3466 threads.append( t )
3467 t.start()
3468 for t in threads:
3469 t.join()
3470 sizeResponses.append( t.result )
3471 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003472 for i in range( len( main.activeNodes ) ):
3473 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003474 if size != sizeResponses[ i ]:
3475 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003476 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003477 " expected a size of " + str( size ) +
3478 " for set " + onosSetName +
3479 " but got " + str( sizeResponses[ i ] ) )
3480 addResults = addResults and getResults and sizeResults
3481 utilities.assert_equals( expect=main.TRUE,
3482 actual=addResults,
3483 onpass="Set add correct",
3484 onfail="Set add was incorrect" )
3485
3486 main.step( "Distributed Set addAll()" )
3487 onosSet.update( addAllValue.split() )
3488 addResponses = []
3489 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003490 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003491 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003492 name="setTestAddAll-" + str( i ),
3493 args=[ onosSetName, addAllValue ] )
3494 threads.append( t )
3495 t.start()
3496 for t in threads:
3497 t.join()
3498 addResponses.append( t.result )
3499
3500 # main.TRUE = successfully changed the set
3501 # main.FALSE = action resulted in no change in set
3502 # main.ERROR - Some error in executing the function
3503 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003504 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003505 if addResponses[ i ] == main.TRUE:
3506 # All is well
3507 pass
3508 elif addResponses[ i ] == main.FALSE:
3509 # Already in set, probably fine
3510 pass
3511 elif addResponses[ i ] == main.ERROR:
3512 # Error in execution
3513 addAllResults = main.FALSE
3514 else:
3515 # unexpected result
3516 addAllResults = main.FALSE
3517 if addAllResults != main.TRUE:
3518 main.log.error( "Error executing set addAll" )
3519
3520 # Check if set is still correct
3521 size = len( onosSet )
3522 getResponses = []
3523 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003524 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003525 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003526 name="setTestGet-" + str( i ),
3527 args=[ onosSetName ] )
3528 threads.append( t )
3529 t.start()
3530 for t in threads:
3531 t.join()
3532 getResponses.append( t.result )
3533 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003534 for i in range( len( main.activeNodes ) ):
3535 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003536 if isinstance( getResponses[ i ], list):
3537 current = set( getResponses[ i ] )
3538 if len( current ) == len( getResponses[ i ] ):
3539 # no repeats
3540 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003541 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003542 " has incorrect view" +
3543 " of set " + onosSetName + ":\n" +
3544 str( getResponses[ i ] ) )
3545 main.log.debug( "Expected: " + str( onosSet ) )
3546 main.log.debug( "Actual: " + str( current ) )
3547 getResults = main.FALSE
3548 else:
3549 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003550 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003551 " has repeat elements in" +
3552 " set " + onosSetName + ":\n" +
3553 str( getResponses[ i ] ) )
3554 getResults = main.FALSE
3555 elif getResponses[ i ] == main.ERROR:
3556 getResults = main.FALSE
3557 sizeResponses = []
3558 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003559 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003560 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003561 name="setTestSize-" + str( i ),
3562 args=[ onosSetName ] )
3563 threads.append( t )
3564 t.start()
3565 for t in threads:
3566 t.join()
3567 sizeResponses.append( t.result )
3568 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003569 for i in range( len( main.activeNodes ) ):
3570 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003571 if size != sizeResponses[ i ]:
3572 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003573 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003574 " expected a size of " + str( size ) +
3575 " for set " + onosSetName +
3576 " but got " + str( sizeResponses[ i ] ) )
3577 addAllResults = addAllResults and getResults and sizeResults
3578 utilities.assert_equals( expect=main.TRUE,
3579 actual=addAllResults,
3580 onpass="Set addAll correct",
3581 onfail="Set addAll was incorrect" )
3582
3583 main.step( "Distributed Set contains()" )
3584 containsResponses = []
3585 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003586 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003587 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003588 name="setContains-" + str( i ),
3589 args=[ onosSetName ],
3590 kwargs={ "values": addValue } )
3591 threads.append( t )
3592 t.start()
3593 for t in threads:
3594 t.join()
3595 # NOTE: This is the tuple
3596 containsResponses.append( t.result )
3597
3598 containsResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003599 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003600 if containsResponses[ i ] == main.ERROR:
3601 containsResults = main.FALSE
3602 else:
3603 containsResults = containsResults and\
3604 containsResponses[ i ][ 1 ]
3605 utilities.assert_equals( expect=main.TRUE,
3606 actual=containsResults,
3607 onpass="Set contains is functional",
3608 onfail="Set contains failed" )
3609
3610 main.step( "Distributed Set containsAll()" )
3611 containsAllResponses = []
3612 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003613 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003614 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003615 name="setContainsAll-" + str( i ),
3616 args=[ onosSetName ],
3617 kwargs={ "values": addAllValue } )
3618 threads.append( t )
3619 t.start()
3620 for t in threads:
3621 t.join()
3622 # NOTE: This is the tuple
3623 containsAllResponses.append( t.result )
3624
3625 containsAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003626 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003627 if containsResponses[ i ] == main.ERROR:
3628 containsResults = main.FALSE
3629 else:
3630 containsResults = containsResults and\
3631 containsResponses[ i ][ 1 ]
3632 utilities.assert_equals( expect=main.TRUE,
3633 actual=containsAllResults,
3634 onpass="Set containsAll is functional",
3635 onfail="Set containsAll failed" )
3636
3637 main.step( "Distributed Set remove()" )
3638 onosSet.remove( addValue )
3639 removeResponses = []
3640 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003641 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003642 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003643 name="setTestRemove-" + str( i ),
3644 args=[ onosSetName, addValue ] )
3645 threads.append( t )
3646 t.start()
3647 for t in threads:
3648 t.join()
3649 removeResponses.append( t.result )
3650
3651 # main.TRUE = successfully changed the set
3652 # main.FALSE = action resulted in no change in set
3653 # main.ERROR - Some error in executing the function
3654 removeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003655 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003656 if removeResponses[ i ] == main.TRUE:
3657 # All is well
3658 pass
3659 elif removeResponses[ i ] == main.FALSE:
3660 # not in set, probably fine
3661 pass
3662 elif removeResponses[ i ] == main.ERROR:
3663 # Error in execution
3664 removeResults = main.FALSE
3665 else:
3666 # unexpected result
3667 removeResults = main.FALSE
3668 if removeResults != main.TRUE:
3669 main.log.error( "Error executing set remove" )
3670
3671 # Check if set is still correct
3672 size = len( onosSet )
3673 getResponses = []
3674 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003675 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003676 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003677 name="setTestGet-" + str( i ),
3678 args=[ onosSetName ] )
3679 threads.append( t )
3680 t.start()
3681 for t in threads:
3682 t.join()
3683 getResponses.append( t.result )
3684 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003685 for i in range( len( main.activeNodes ) ):
3686 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003687 if isinstance( getResponses[ i ], list):
3688 current = set( getResponses[ i ] )
3689 if len( current ) == len( getResponses[ i ] ):
3690 # no repeats
3691 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003692 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003693 " has incorrect view" +
3694 " of set " + onosSetName + ":\n" +
3695 str( getResponses[ i ] ) )
3696 main.log.debug( "Expected: " + str( onosSet ) )
3697 main.log.debug( "Actual: " + str( current ) )
3698 getResults = main.FALSE
3699 else:
3700 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003701 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003702 " has repeat elements in" +
3703 " set " + onosSetName + ":\n" +
3704 str( getResponses[ i ] ) )
3705 getResults = main.FALSE
3706 elif getResponses[ i ] == main.ERROR:
3707 getResults = main.FALSE
3708 sizeResponses = []
3709 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003710 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003711 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003712 name="setTestSize-" + str( i ),
3713 args=[ onosSetName ] )
3714 threads.append( t )
3715 t.start()
3716 for t in threads:
3717 t.join()
3718 sizeResponses.append( t.result )
3719 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003720 for i in range( len( main.activeNodes ) ):
3721 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003722 if size != sizeResponses[ i ]:
3723 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003724 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003725 " expected a size of " + str( size ) +
3726 " for set " + onosSetName +
3727 " but got " + str( sizeResponses[ i ] ) )
3728 removeResults = removeResults and getResults and sizeResults
3729 utilities.assert_equals( expect=main.TRUE,
3730 actual=removeResults,
3731 onpass="Set remove correct",
3732 onfail="Set remove was incorrect" )
3733
3734 main.step( "Distributed Set removeAll()" )
3735 onosSet.difference_update( addAllValue.split() )
3736 removeAllResponses = []
3737 threads = []
3738 try:
Jon Halla440e872016-03-31 15:15:50 -07003739 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003740 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003741 name="setTestRemoveAll-" + str( i ),
3742 args=[ onosSetName, addAllValue ] )
3743 threads.append( t )
3744 t.start()
3745 for t in threads:
3746 t.join()
3747 removeAllResponses.append( t.result )
3748 except Exception, e:
3749 main.log.exception(e)
3750
3751 # main.TRUE = successfully changed the set
3752 # main.FALSE = action resulted in no change in set
3753 # main.ERROR - Some error in executing the function
3754 removeAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003755 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003756 if removeAllResponses[ i ] == main.TRUE:
3757 # All is well
3758 pass
3759 elif removeAllResponses[ i ] == main.FALSE:
3760 # not in set, probably fine
3761 pass
3762 elif removeAllResponses[ i ] == main.ERROR:
3763 # Error in execution
3764 removeAllResults = main.FALSE
3765 else:
3766 # unexpected result
3767 removeAllResults = main.FALSE
3768 if removeAllResults != main.TRUE:
3769 main.log.error( "Error executing set removeAll" )
3770
3771 # Check if set is still correct
3772 size = len( onosSet )
3773 getResponses = []
3774 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003775 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003776 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003777 name="setTestGet-" + str( i ),
3778 args=[ onosSetName ] )
3779 threads.append( t )
3780 t.start()
3781 for t in threads:
3782 t.join()
3783 getResponses.append( t.result )
3784 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003785 for i in range( len( main.activeNodes ) ):
3786 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003787 if isinstance( getResponses[ i ], list):
3788 current = set( getResponses[ i ] )
3789 if len( current ) == len( getResponses[ i ] ):
3790 # no repeats
3791 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003792 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003793 " has incorrect view" +
3794 " of set " + onosSetName + ":\n" +
3795 str( getResponses[ i ] ) )
3796 main.log.debug( "Expected: " + str( onosSet ) )
3797 main.log.debug( "Actual: " + str( current ) )
3798 getResults = main.FALSE
3799 else:
3800 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003801 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003802 " has repeat elements in" +
3803 " set " + onosSetName + ":\n" +
3804 str( getResponses[ i ] ) )
3805 getResults = main.FALSE
3806 elif getResponses[ i ] == main.ERROR:
3807 getResults = main.FALSE
3808 sizeResponses = []
3809 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003810 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003811 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003812 name="setTestSize-" + str( i ),
3813 args=[ onosSetName ] )
3814 threads.append( t )
3815 t.start()
3816 for t in threads:
3817 t.join()
3818 sizeResponses.append( t.result )
3819 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003820 for i in range( len( main.activeNodes ) ):
3821 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003822 if size != sizeResponses[ i ]:
3823 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003824 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003825 " expected a size of " + str( size ) +
3826 " for set " + onosSetName +
3827 " but got " + str( sizeResponses[ i ] ) )
3828 removeAllResults = removeAllResults and getResults and sizeResults
3829 utilities.assert_equals( expect=main.TRUE,
3830 actual=removeAllResults,
3831 onpass="Set removeAll correct",
3832 onfail="Set removeAll was incorrect" )
3833
3834 main.step( "Distributed Set addAll()" )
3835 onosSet.update( addAllValue.split() )
3836 addResponses = []
3837 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003838 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003839 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003840 name="setTestAddAll-" + str( i ),
3841 args=[ onosSetName, addAllValue ] )
3842 threads.append( t )
3843 t.start()
3844 for t in threads:
3845 t.join()
3846 addResponses.append( t.result )
3847
3848 # main.TRUE = successfully changed the set
3849 # main.FALSE = action resulted in no change in set
3850 # main.ERROR - Some error in executing the function
3851 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003852 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003853 if addResponses[ i ] == main.TRUE:
3854 # All is well
3855 pass
3856 elif addResponses[ i ] == main.FALSE:
3857 # Already in set, probably fine
3858 pass
3859 elif addResponses[ i ] == main.ERROR:
3860 # Error in execution
3861 addAllResults = main.FALSE
3862 else:
3863 # unexpected result
3864 addAllResults = main.FALSE
3865 if addAllResults != main.TRUE:
3866 main.log.error( "Error executing set addAll" )
3867
3868 # Check if set is still correct
3869 size = len( onosSet )
3870 getResponses = []
3871 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003872 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003873 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003874 name="setTestGet-" + str( i ),
3875 args=[ onosSetName ] )
3876 threads.append( t )
3877 t.start()
3878 for t in threads:
3879 t.join()
3880 getResponses.append( t.result )
3881 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003882 for i in range( len( main.activeNodes ) ):
3883 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003884 if isinstance( getResponses[ i ], list):
3885 current = set( getResponses[ i ] )
3886 if len( current ) == len( getResponses[ i ] ):
3887 # no repeats
3888 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003889 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003890 " has incorrect view" +
3891 " of set " + onosSetName + ":\n" +
3892 str( getResponses[ i ] ) )
3893 main.log.debug( "Expected: " + str( onosSet ) )
3894 main.log.debug( "Actual: " + str( current ) )
3895 getResults = main.FALSE
3896 else:
3897 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003898 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003899 " has repeat elements in" +
3900 " set " + onosSetName + ":\n" +
3901 str( getResponses[ i ] ) )
3902 getResults = main.FALSE
3903 elif getResponses[ i ] == main.ERROR:
3904 getResults = main.FALSE
3905 sizeResponses = []
3906 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003907 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003908 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003909 name="setTestSize-" + str( i ),
3910 args=[ onosSetName ] )
3911 threads.append( t )
3912 t.start()
3913 for t in threads:
3914 t.join()
3915 sizeResponses.append( t.result )
3916 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003917 for i in range( len( main.activeNodes ) ):
3918 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003919 if size != sizeResponses[ i ]:
3920 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08003921 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003922 " expected a size of " + str( size ) +
3923 " for set " + onosSetName +
3924 " but got " + str( sizeResponses[ i ] ) )
3925 addAllResults = addAllResults and getResults and sizeResults
3926 utilities.assert_equals( expect=main.TRUE,
3927 actual=addAllResults,
3928 onpass="Set addAll correct",
3929 onfail="Set addAll was incorrect" )
3930
3931 main.step( "Distributed Set clear()" )
3932 onosSet.clear()
3933 clearResponses = []
3934 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003935 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003936 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003937 name="setTestClear-" + str( i ),
3938 args=[ onosSetName, " "], # Values doesn't matter
3939 kwargs={ "clear": True } )
3940 threads.append( t )
3941 t.start()
3942 for t in threads:
3943 t.join()
3944 clearResponses.append( t.result )
3945
3946 # main.TRUE = successfully changed the set
3947 # main.FALSE = action resulted in no change in set
3948 # main.ERROR - Some error in executing the function
3949 clearResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003950 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003951 if clearResponses[ i ] == main.TRUE:
3952 # All is well
3953 pass
3954 elif clearResponses[ i ] == main.FALSE:
3955 # Nothing set, probably fine
3956 pass
3957 elif clearResponses[ i ] == main.ERROR:
3958 # Error in execution
3959 clearResults = main.FALSE
3960 else:
3961 # unexpected result
3962 clearResults = main.FALSE
3963 if clearResults != main.TRUE:
3964 main.log.error( "Error executing set clear" )
3965
3966 # Check if set is still correct
3967 size = len( onosSet )
3968 getResponses = []
3969 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003970 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003971 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003972 name="setTestGet-" + str( i ),
3973 args=[ onosSetName ] )
3974 threads.append( t )
3975 t.start()
3976 for t in threads:
3977 t.join()
3978 getResponses.append( t.result )
3979 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003980 for i in range( len( main.activeNodes ) ):
3981 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003982 if isinstance( getResponses[ i ], list):
3983 current = set( getResponses[ i ] )
3984 if len( current ) == len( getResponses[ i ] ):
3985 # no repeats
3986 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08003987 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003988 " has incorrect view" +
3989 " of set " + onosSetName + ":\n" +
3990 str( getResponses[ i ] ) )
3991 main.log.debug( "Expected: " + str( onosSet ) )
3992 main.log.debug( "Actual: " + str( current ) )
3993 getResults = main.FALSE
3994 else:
3995 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08003996 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003997 " has repeat elements in" +
3998 " set " + onosSetName + ":\n" +
3999 str( getResponses[ i ] ) )
4000 getResults = main.FALSE
4001 elif getResponses[ i ] == main.ERROR:
4002 getResults = main.FALSE
4003 sizeResponses = []
4004 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004005 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004006 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004007 name="setTestSize-" + str( i ),
4008 args=[ onosSetName ] )
4009 threads.append( t )
4010 t.start()
4011 for t in threads:
4012 t.join()
4013 sizeResponses.append( t.result )
4014 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004015 for i in range( len( main.activeNodes ) ):
4016 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004017 if size != sizeResponses[ i ]:
4018 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08004019 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004020 " expected a size of " + str( size ) +
4021 " for set " + onosSetName +
4022 " but got " + str( sizeResponses[ i ] ) )
4023 clearResults = clearResults and getResults and sizeResults
4024 utilities.assert_equals( expect=main.TRUE,
4025 actual=clearResults,
4026 onpass="Set clear correct",
4027 onfail="Set clear was incorrect" )
4028
4029 main.step( "Distributed Set addAll()" )
4030 onosSet.update( addAllValue.split() )
4031 addResponses = []
4032 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004033 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004034 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004035 name="setTestAddAll-" + str( i ),
4036 args=[ onosSetName, addAllValue ] )
4037 threads.append( t )
4038 t.start()
4039 for t in threads:
4040 t.join()
4041 addResponses.append( t.result )
4042
4043 # main.TRUE = successfully changed the set
4044 # main.FALSE = action resulted in no change in set
4045 # main.ERROR - Some error in executing the function
4046 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004047 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004048 if addResponses[ i ] == main.TRUE:
4049 # All is well
4050 pass
4051 elif addResponses[ i ] == main.FALSE:
4052 # Already in set, probably fine
4053 pass
4054 elif addResponses[ i ] == main.ERROR:
4055 # Error in execution
4056 addAllResults = main.FALSE
4057 else:
4058 # unexpected result
4059 addAllResults = main.FALSE
4060 if addAllResults != main.TRUE:
4061 main.log.error( "Error executing set addAll" )
4062
4063 # Check if set is still correct
4064 size = len( onosSet )
4065 getResponses = []
4066 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004067 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004068 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004069 name="setTestGet-" + str( i ),
4070 args=[ onosSetName ] )
4071 threads.append( t )
4072 t.start()
4073 for t in threads:
4074 t.join()
4075 getResponses.append( t.result )
4076 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004077 for i in range( len( main.activeNodes ) ):
4078 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004079 if isinstance( getResponses[ i ], list):
4080 current = set( getResponses[ i ] )
4081 if len( current ) == len( getResponses[ i ] ):
4082 # no repeats
4083 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08004084 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004085 " has incorrect view" +
4086 " of set " + onosSetName + ":\n" +
4087 str( getResponses[ i ] ) )
4088 main.log.debug( "Expected: " + str( onosSet ) )
4089 main.log.debug( "Actual: " + str( current ) )
4090 getResults = main.FALSE
4091 else:
4092 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08004093 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004094 " has repeat elements in" +
4095 " set " + onosSetName + ":\n" +
4096 str( getResponses[ i ] ) )
4097 getResults = main.FALSE
4098 elif getResponses[ i ] == main.ERROR:
4099 getResults = main.FALSE
4100 sizeResponses = []
4101 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004102 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004103 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004104 name="setTestSize-" + str( i ),
4105 args=[ onosSetName ] )
4106 threads.append( t )
4107 t.start()
4108 for t in threads:
4109 t.join()
4110 sizeResponses.append( t.result )
4111 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004112 for i in range( len( main.activeNodes ) ):
4113 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004114 if size != sizeResponses[ i ]:
4115 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08004116 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004117 " expected a size of " + str( size ) +
4118 " for set " + onosSetName +
4119 " but got " + str( sizeResponses[ i ] ) )
4120 addAllResults = addAllResults and getResults and sizeResults
4121 utilities.assert_equals( expect=main.TRUE,
4122 actual=addAllResults,
4123 onpass="Set addAll correct",
4124 onfail="Set addAll was incorrect" )
4125
4126 main.step( "Distributed Set retain()" )
4127 onosSet.intersection_update( retainValue.split() )
4128 retainResponses = []
4129 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004130 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004131 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004132 name="setTestRetain-" + str( i ),
4133 args=[ onosSetName, retainValue ],
4134 kwargs={ "retain": True } )
4135 threads.append( t )
4136 t.start()
4137 for t in threads:
4138 t.join()
4139 retainResponses.append( t.result )
4140
4141 # main.TRUE = successfully changed the set
4142 # main.FALSE = action resulted in no change in set
4143 # main.ERROR - Some error in executing the function
4144 retainResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004145 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004146 if retainResponses[ i ] == main.TRUE:
4147 # All is well
4148 pass
4149 elif retainResponses[ i ] == main.FALSE:
4150 # Already in set, probably fine
4151 pass
4152 elif retainResponses[ i ] == main.ERROR:
4153 # Error in execution
4154 retainResults = main.FALSE
4155 else:
4156 # unexpected result
4157 retainResults = main.FALSE
4158 if retainResults != main.TRUE:
4159 main.log.error( "Error executing set retain" )
4160
4161 # Check if set is still correct
4162 size = len( onosSet )
4163 getResponses = []
4164 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004165 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004166 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004167 name="setTestGet-" + str( i ),
4168 args=[ onosSetName ] )
4169 threads.append( t )
4170 t.start()
4171 for t in threads:
4172 t.join()
4173 getResponses.append( t.result )
4174 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004175 for i in range( len( main.activeNodes ) ):
4176 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004177 if isinstance( getResponses[ i ], list):
4178 current = set( getResponses[ i ] )
4179 if len( current ) == len( getResponses[ i ] ):
4180 # no repeats
4181 if onosSet != current:
Jon Hall6e709752016-02-01 13:38:46 -08004182 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004183 " has incorrect view" +
4184 " of set " + onosSetName + ":\n" +
4185 str( getResponses[ i ] ) )
4186 main.log.debug( "Expected: " + str( onosSet ) )
4187 main.log.debug( "Actual: " + str( current ) )
4188 getResults = main.FALSE
4189 else:
4190 # error, set is not a set
Jon Hall6e709752016-02-01 13:38:46 -08004191 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004192 " has repeat elements in" +
4193 " set " + onosSetName + ":\n" +
4194 str( getResponses[ i ] ) )
4195 getResults = main.FALSE
4196 elif getResponses[ i ] == main.ERROR:
4197 getResults = main.FALSE
4198 sizeResponses = []
4199 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004200 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004201 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004202 name="setTestSize-" + str( i ),
4203 args=[ onosSetName ] )
4204 threads.append( t )
4205 t.start()
4206 for t in threads:
4207 t.join()
4208 sizeResponses.append( t.result )
4209 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004210 for i in range( len( main.activeNodes ) ):
4211 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004212 if size != sizeResponses[ i ]:
4213 sizeResults = main.FALSE
Jon Hall6e709752016-02-01 13:38:46 -08004214 main.log.error( "ONOS" + node + " expected a size of " +
Jon Hall5cf14d52015-07-16 12:15:19 -07004215 str( size ) + " for set " + onosSetName +
4216 " but got " + str( sizeResponses[ i ] ) )
4217 retainResults = retainResults and getResults and sizeResults
4218 utilities.assert_equals( expect=main.TRUE,
4219 actual=retainResults,
4220 onpass="Set retain correct",
4221 onfail="Set retain was incorrect" )
4222
Jon Hall2a5002c2015-08-21 16:49:11 -07004223 # Transactional maps
4224 main.step( "Partitioned Transactional maps put" )
4225 tMapValue = "Testing"
4226 numKeys = 100
4227 putResult = True
Jon Halla440e872016-03-31 15:15:50 -07004228 node = main.activeNodes[0]
4229 putResponses = main.CLIs[node].transactionalMapPut( numKeys, tMapValue )
Jon Hall6e709752016-02-01 13:38:46 -08004230 if putResponses and len( putResponses ) == 100:
Jon Hall2a5002c2015-08-21 16:49:11 -07004231 for i in putResponses:
4232 if putResponses[ i ][ 'value' ] != tMapValue:
4233 putResult = False
4234 else:
4235 putResult = False
4236 if not putResult:
4237 main.log.debug( "Put response values: " + str( putResponses ) )
4238 utilities.assert_equals( expect=True,
4239 actual=putResult,
4240 onpass="Partitioned Transactional Map put successful",
4241 onfail="Partitioned Transactional Map put values are incorrect" )
4242
4243 main.step( "Partitioned Transactional maps get" )
4244 getCheck = True
4245 for n in range( 1, numKeys + 1 ):
4246 getResponses = []
4247 threads = []
4248 valueCheck = True
Jon Halla440e872016-03-31 15:15:50 -07004249 for i in main.activeNodes:
Jon Hall2a5002c2015-08-21 16:49:11 -07004250 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4251 name="TMap-get-" + str( i ),
Jon Hall6e709752016-02-01 13:38:46 -08004252 args=[ "Key" + str( n ) ] )
Jon Hall2a5002c2015-08-21 16:49:11 -07004253 threads.append( t )
4254 t.start()
4255 for t in threads:
4256 t.join()
4257 getResponses.append( t.result )
4258 for node in getResponses:
4259 if node != tMapValue:
4260 valueCheck = False
4261 if not valueCheck:
4262 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4263 main.log.warn( getResponses )
4264 getCheck = getCheck and valueCheck
4265 utilities.assert_equals( expect=True,
4266 actual=getCheck,
4267 onpass="Partitioned Transactional Map get values were correct",
4268 onfail="Partitioned Transactional Map values incorrect" )