blob: 312da649969caa90bdb8c61c6188b5432a9f907e [file] [log] [blame]
Jon Hall5cf14d52015-07-16 12:15:19 -07001"""
2Description: This test is to determine if the HA test setup is
3 working correctly. There are no failures so this test should
4 have a 100% pass rate
5
6List of test cases:
7CASE1: Compile ONOS and push it to the test machines
8CASE2: Assign devices to controllers
9CASE21: Assign mastership to controllers
10CASE3: Assign intents
11CASE4: Ping across added host intents
12CASE5: Reading state of ONOS
13CASE6: The Failure case. Since this is the Sanity test, we do nothing.
14CASE7: Check state after control plane failure
15CASE8: Compare topo
16CASE9: Link s3-s28 down
17CASE10: Link s3-s28 up
18CASE11: Switch down
19CASE12: Switch up
20CASE13: Clean up
21CASE14: start election app on all onos nodes
22CASE15: Check that Leadership Election is still functional
23CASE16: Install Distributed Primitives app
24CASE17: Check for basic functionality with distributed primitives
25"""
26
27
28class HAsanity:
29
30 def __init__( self ):
31 self.default = ''
32
33 def CASE1( self, main ):
34 """
35 CASE1 is to compile ONOS and push it to the test machines
36
37 Startup sequence:
38 cell <name>
39 onos-verify-cell
40 NOTE: temporary - onos-remove-raft-logs
41 onos-uninstall
42 start mininet
43 git pull
44 mvn clean install
45 onos-package
46 onos-install -f
47 onos-wait-for-start
48 start cli sessions
49 start tcpdump
50 """
Jon Halle1a3b752015-07-22 13:02:46 -070051 import imp
Jon Hallf3d16e72015-12-16 17:45:08 -080052 import time
Jon Halla440e872016-03-31 15:15:50 -070053 import json
Jon Hall5cf14d52015-07-16 12:15:19 -070054 main.log.info( "ONOS HA Sanity test - initialization" )
55 main.case( "Setting up test environment" )
Jon Hall783bbf92015-07-23 14:33:19 -070056 main.caseExplanation = "Setup the test environment including " +\
Jon 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 )
Jon Hall5cf14d52015-07-16 12:15:19 -070071 # TODO: refactor how to get onos port, maybe put into component tag?
Jon Halle1a3b752015-07-22 13:02:46 -070072 # set global variables
Jon Hall5cf14d52015-07-16 12:15:19 -070073 global ONOS1Port
74 global ONOS2Port
75 global ONOS3Port
76 global ONOS4Port
77 global ONOS5Port
78 global ONOS6Port
79 global ONOS7Port
Jon Halla440e872016-03-31 15:15:50 -070080 # These are for csv plotting in jenkins
81 global labels
82 global data
83 labels = []
84 data = []
Jon Hall5cf14d52015-07-16 12:15:19 -070085
86 # FIXME: just get controller port from params?
87 # TODO: do we really need all these?
88 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
89 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
90 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
91 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
92 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
93 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
94 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
95
Jon Halle1a3b752015-07-22 13:02:46 -070096 try:
Jon Halla440e872016-03-31 15:15:50 -070097 from tests.HAsanity.dependencies.Counters import Counters
98 main.Counters = Counters()
Jon Halle1a3b752015-07-22 13:02:46 -070099 except Exception as e:
100 main.log.exception( e )
101 main.cleanup()
102 main.exit()
103
104 main.CLIs = []
105 main.nodes = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700106 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700107 for i in range( 1, main.numCtrls + 1 ):
108 try:
109 main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
110 main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
111 ipList.append( main.nodes[ -1 ].ip_address )
112 except AttributeError:
113 break
Jon Hall5cf14d52015-07-16 12:15:19 -0700114
115 main.step( "Create cell file" )
116 cellAppString = main.params[ 'ENV' ][ 'appString' ]
117 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
118 main.Mininet1.ip_address,
119 cellAppString, ipList )
120 main.step( "Applying cell variable to environment" )
121 cellResult = main.ONOSbench.setCell( cellName )
122 verifyResult = main.ONOSbench.verifyCell()
123
124 # FIXME:this is short term fix
125 main.log.info( "Removing raft logs" )
126 main.ONOSbench.onosRemoveRaftLogs()
127
128 main.log.info( "Uninstalling ONOS" )
Jon Halle1a3b752015-07-22 13:02:46 -0700129 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700130 main.ONOSbench.onosUninstall( node.ip_address )
131
132 # Make sure ONOS is DEAD
133 main.log.info( "Killing any ONOS processes" )
134 killResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700135 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700136 killed = main.ONOSbench.onosKill( node.ip_address )
137 killResults = killResults and killed
138
139 cleanInstallResult = main.TRUE
140 gitPullResult = main.TRUE
141
142 main.step( "Starting Mininet" )
143 # scp topo file to mininet
144 # TODO: move to params?
145 topoName = "obelisk.py"
146 filePath = main.ONOSbench.home + "/tools/test/topos/"
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700147 main.ONOSbench.scp( main.Mininet1,
148 filePath + topoName,
149 main.Mininet1.home,
150 direction="to" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700151 mnResult = main.Mininet1.startNet( )
152 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
153 onpass="Mininet Started",
154 onfail="Error starting Mininet" )
155
156 main.step( "Git checkout and pull " + gitBranch )
157 if PULLCODE:
158 main.ONOSbench.gitCheckout( gitBranch )
159 gitPullResult = main.ONOSbench.gitPull()
160 # values of 1 or 3 are good
161 utilities.assert_lesser( expect=0, actual=gitPullResult,
162 onpass="Git pull successful",
163 onfail="Git pull failed" )
164 main.ONOSbench.getVersion( report=True )
165
166 main.step( "Using mvn clean install" )
167 cleanInstallResult = main.TRUE
168 if PULLCODE and gitPullResult == main.TRUE:
169 cleanInstallResult = main.ONOSbench.cleanInstall()
170 else:
171 main.log.warn( "Did not pull new code so skipping mvn " +
172 "clean install" )
173 utilities.assert_equals( expect=main.TRUE,
174 actual=cleanInstallResult,
175 onpass="MCI successful",
176 onfail="MCI failed" )
177 # GRAPHS
178 # NOTE: important params here:
179 # job = name of Jenkins job
180 # Plot Name = Plot-HA, only can be used if multiple plots
181 # index = The number of the graph under plot name
182 job = "HAsanity"
183 plotName = "Plot-HA"
Jon Hall843f8bc2016-03-18 14:28:13 -0700184 index = "2"
Jon Hall5cf14d52015-07-16 12:15:19 -0700185 graphs = '<ac:structured-macro ac:name="html">\n'
186 graphs += '<ac:plain-text-body><![CDATA[\n'
187 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
Jon Halla9845df2016-01-15 14:55:58 -0800188 '/plot/' + plotName + '/getPlot?index=' + index +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700189 '&width=500&height=300"' +\
190 'noborder="0" width="500" height="300" scrolling="yes" ' +\
191 'seamless="seamless"></iframe>\n'
192 graphs += ']]></ac:plain-text-body>\n'
193 graphs += '</ac:structured-macro>\n'
194 main.log.wiki(graphs)
195
196 main.step( "Creating ONOS package" )
197 packageResult = main.ONOSbench.onosPackage()
198 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
199 onpass="ONOS package successful",
200 onfail="ONOS package failed" )
201
202 main.step( "Installing ONOS package" )
203 onosInstallResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700204 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700205 tmpResult = main.ONOSbench.onosInstall( options="-f",
206 node=node.ip_address )
207 onosInstallResult = onosInstallResult and tmpResult
208 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
209 onpass="ONOS install successful",
210 onfail="ONOS install failed" )
211
212 main.step( "Checking if ONOS is up yet" )
213 for i in range( 2 ):
214 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700215 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700216 started = main.ONOSbench.isup( node.ip_address )
217 if not started:
Jon Hallc6793552016-01-19 14:18:37 -0800218 main.log.error( node.name + " hasn't started" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700219 onosIsupResult = onosIsupResult and started
220 if onosIsupResult == main.TRUE:
221 break
222 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
223 onpass="ONOS startup successful",
224 onfail="ONOS startup failed" )
225
226 main.log.step( "Starting ONOS CLI sessions" )
227 cliResults = main.TRUE
228 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700229 for i in range( main.numCtrls ):
230 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -0700231 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -0700232 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -0700233 threads.append( t )
234 t.start()
235
236 for t in threads:
237 t.join()
238 cliResults = cliResults and t.result
239 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
240 onpass="ONOS cli startup successful",
241 onfail="ONOS cli startup failed" )
242
Jon Halla440e872016-03-31 15:15:50 -0700243 # Create a list of active nodes for use when some nodes are stopped
244 main.activeNodes = [ i for i in range( 0, len( main.CLIs ) ) ]
245
Jon Hall5cf14d52015-07-16 12:15:19 -0700246 if main.params[ 'tcpdump' ].lower() == "true":
247 main.step( "Start Packet Capture MN" )
248 main.Mininet2.startTcpdump(
249 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
250 + "-MN.pcap",
251 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
252 port=main.params[ 'MNtcpdump' ][ 'port' ] )
253
254 main.step( "App Ids check" )
255 appCheck = main.TRUE
256 threads = []
Jon Halla440e872016-03-31 15:15:50 -0700257 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -0700258 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700259 name="appToIDCheck-" + str( i ),
260 args=[] )
261 threads.append( t )
262 t.start()
263
264 for t in threads:
265 t.join()
266 appCheck = appCheck and t.result
267 if appCheck != main.TRUE:
Jon Halla440e872016-03-31 15:15:50 -0700268 node = main.activeNodes[0]
269 main.log.warn( main.CLIs[node].apps() )
270 main.log.warn( main.CLIs[node].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700271 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
272 onpass="App Ids seem to be correct",
273 onfail="Something is wrong with app Ids" )
274
Jon Halla440e872016-03-31 15:15:50 -0700275 main.step( "Checking ONOS nodes" )
276 nodesOutput = []
277 nodeResults = main.TRUE
278 threads = []
279 for i in main.activeNodes:
280 t = main.Thread( target=main.CLIs[i].nodes,
281 name="nodes-" + str( i ),
282 args=[ ] )
283 threads.append( t )
284 t.start()
285
286 for t in threads:
287 t.join()
288 nodesOutput.append( t.result )
289 ips = [ main.nodes[node].ip_address for node in main.activeNodes ]
290 ips.sort()
291 for i in nodesOutput:
292 try:
293 current = json.loads( i )
294 activeIps = []
295 currentResult = main.FALSE
296 for node in current:
297 if node['state'] == 'READY':
298 activeIps.append( node['ip'] )
299 activeIps.sort()
300 if ips == activeIps:
301 currentResult = main.TRUE
302 except ( ValueError, TypeError ):
303 main.log.error( "Error parsing nodes output" )
304 main.log.warn( repr( i ) )
305 currentResult = main.FALSE
306 nodeResults = nodeResults and currentResult
307 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
308 onpass="Nodes check successful",
309 onfail="Nodes check NOT successful" )
310
311 if not nodeResults:
312 for cli in main.CLIs:
313 main.log.debug( "{} components not ACTIVE: \n{}".format(
314 cli.name,
315 cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
316
Jon Hall5cf14d52015-07-16 12:15:19 -0700317 if cliResults == main.FALSE:
318 main.log.error( "Failed to start ONOS, stopping test" )
319 main.cleanup()
320 main.exit()
321
322 def CASE2( self, main ):
323 """
324 Assign devices to controllers
325 """
326 import re
Jon Halle1a3b752015-07-22 13:02:46 -0700327 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700328 assert main, "main not defined"
329 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700330 assert main.CLIs, "main.CLIs not defined"
331 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700332 assert ONOS1Port, "ONOS1Port not defined"
333 assert ONOS2Port, "ONOS2Port not defined"
334 assert ONOS3Port, "ONOS3Port not defined"
335 assert ONOS4Port, "ONOS4Port not defined"
336 assert ONOS5Port, "ONOS5Port not defined"
337 assert ONOS6Port, "ONOS6Port not defined"
338 assert ONOS7Port, "ONOS7Port not defined"
339
340 main.case( "Assigning devices to controllers" )
Jon Hall783bbf92015-07-23 14:33:19 -0700341 main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700342 "and check that an ONOS node becomes the " +\
343 "master of the device."
344 main.step( "Assign switches to controllers" )
345
346 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700347 for i in range( main.numCtrls ):
348 ipList.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -0700349 swList = []
350 for i in range( 1, 29 ):
351 swList.append( "s" + str( i ) )
352 main.Mininet1.assignSwController( sw=swList, ip=ipList )
353
354 mastershipCheck = main.TRUE
355 for i in range( 1, 29 ):
356 response = main.Mininet1.getSwController( "s" + str( i ) )
357 try:
358 main.log.info( str( response ) )
359 except Exception:
360 main.log.info( repr( response ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700361 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700362 if re.search( "tcp:" + node.ip_address, response ):
363 mastershipCheck = mastershipCheck and main.TRUE
364 else:
365 main.log.error( "Error, node " + node.ip_address + " is " +
366 "not in the list of controllers s" +
367 str( i ) + " is connecting to." )
368 mastershipCheck = main.FALSE
369 utilities.assert_equals(
370 expect=main.TRUE,
371 actual=mastershipCheck,
372 onpass="Switch mastership assigned correctly",
373 onfail="Switches not assigned correctly to controllers" )
374
375 def CASE21( self, main ):
376 """
377 Assign mastership to controllers
378 """
Jon Hall5cf14d52015-07-16 12:15:19 -0700379 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700380 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700381 assert main, "main not defined"
382 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700383 assert main.CLIs, "main.CLIs not defined"
384 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700385 assert ONOS1Port, "ONOS1Port not defined"
386 assert ONOS2Port, "ONOS2Port not defined"
387 assert ONOS3Port, "ONOS3Port not defined"
388 assert ONOS4Port, "ONOS4Port not defined"
389 assert ONOS5Port, "ONOS5Port not defined"
390 assert ONOS6Port, "ONOS6Port not defined"
391 assert ONOS7Port, "ONOS7Port not defined"
392
393 main.case( "Assigning Controller roles for switches" )
Jon Hall783bbf92015-07-23 14:33:19 -0700394 main.caseExplanation = "Check that ONOS is connected to each " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700395 "device. Then manually assign" +\
396 " mastership to specific ONOS nodes using" +\
397 " 'device-role'"
398 main.step( "Assign mastership of switches to specific controllers" )
399 # Manually assign mastership to the controller we want
400 roleCall = main.TRUE
401
402 ipList = [ ]
403 deviceList = []
Jon Halla440e872016-03-31 15:15:50 -0700404 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -0700405 try:
406 # Assign mastership to specific controllers. This assignment was
407 # determined for a 7 node cluser, but will work with any sized
408 # cluster
409 for i in range( 1, 29 ): # switches 1 through 28
410 # set up correct variables:
411 if i == 1:
412 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700413 ip = main.nodes[ c ].ip_address # ONOS1
Jon Halla440e872016-03-31 15:15:50 -0700414 deviceId = onosCli.getDevice( "1000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700415 elif i == 2:
Jon Halle1a3b752015-07-22 13:02:46 -0700416 c = 1 % main.numCtrls
417 ip = main.nodes[ c ].ip_address # ONOS2
Jon Halla440e872016-03-31 15:15:50 -0700418 deviceId = onosCli.getDevice( "2000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700419 elif i == 3:
Jon Halle1a3b752015-07-22 13:02:46 -0700420 c = 1 % main.numCtrls
421 ip = main.nodes[ c ].ip_address # ONOS2
Jon Halla440e872016-03-31 15:15:50 -0700422 deviceId = onosCli.getDevice( "3000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700423 elif i == 4:
Jon Halle1a3b752015-07-22 13:02:46 -0700424 c = 3 % main.numCtrls
425 ip = main.nodes[ c ].ip_address # ONOS4
Jon Halla440e872016-03-31 15:15:50 -0700426 deviceId = onosCli.getDevice( "3004" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700427 elif i == 5:
Jon Halle1a3b752015-07-22 13:02:46 -0700428 c = 2 % main.numCtrls
429 ip = main.nodes[ c ].ip_address # ONOS3
Jon Halla440e872016-03-31 15:15:50 -0700430 deviceId = onosCli.getDevice( "5000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700431 elif i == 6:
Jon Halle1a3b752015-07-22 13:02:46 -0700432 c = 2 % main.numCtrls
433 ip = main.nodes[ c ].ip_address # ONOS3
Jon Halla440e872016-03-31 15:15:50 -0700434 deviceId = onosCli.getDevice( "6000" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700435 elif i == 7:
Jon Halle1a3b752015-07-22 13:02:46 -0700436 c = 5 % main.numCtrls
437 ip = main.nodes[ c ].ip_address # ONOS6
Jon Halla440e872016-03-31 15:15:50 -0700438 deviceId = onosCli.getDevice( "6007" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700439 elif i >= 8 and i <= 17:
Jon Halle1a3b752015-07-22 13:02:46 -0700440 c = 4 % main.numCtrls
441 ip = main.nodes[ c ].ip_address # ONOS5
Jon Hall5cf14d52015-07-16 12:15:19 -0700442 dpid = '3' + str( i ).zfill( 3 )
Jon Halla440e872016-03-31 15:15:50 -0700443 deviceId = onosCli.getDevice( dpid ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700444 elif i >= 18 and i <= 27:
Jon Halle1a3b752015-07-22 13:02:46 -0700445 c = 6 % main.numCtrls
446 ip = main.nodes[ c ].ip_address # ONOS7
Jon Hall5cf14d52015-07-16 12:15:19 -0700447 dpid = '6' + str( i ).zfill( 3 )
Jon Halla440e872016-03-31 15:15:50 -0700448 deviceId = onosCli.getDevice( dpid ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700449 elif i == 28:
450 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700451 ip = main.nodes[ c ].ip_address # ONOS1
Jon Halla440e872016-03-31 15:15:50 -0700452 deviceId = onosCli.getDevice( "2800" ).get( 'id' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700453 else:
454 main.log.error( "You didn't write an else statement for " +
455 "switch s" + str( i ) )
456 roleCall = main.FALSE
457 # Assign switch
458 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
459 # TODO: make this controller dynamic
Jon Halla440e872016-03-31 15:15:50 -0700460 roleCall = roleCall and onosCli.deviceRole( deviceId, ip )
Jon Hall5cf14d52015-07-16 12:15:19 -0700461 ipList.append( ip )
462 deviceList.append( deviceId )
463 except ( AttributeError, AssertionError ):
464 main.log.exception( "Something is wrong with ONOS device view" )
Jon Halla440e872016-03-31 15:15:50 -0700465 main.log.info( onosCli.devices() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700466 utilities.assert_equals(
467 expect=main.TRUE,
468 actual=roleCall,
469 onpass="Re-assigned switch mastership to designated controller",
470 onfail="Something wrong with deviceRole calls" )
471
472 main.step( "Check mastership was correctly assigned" )
473 roleCheck = main.TRUE
474 # NOTE: This is due to the fact that device mastership change is not
475 # atomic and is actually a multi step process
476 time.sleep( 5 )
477 for i in range( len( ipList ) ):
478 ip = ipList[i]
479 deviceId = deviceList[i]
480 # Check assignment
Jon Halla440e872016-03-31 15:15:50 -0700481 master = onosCli.getRole( deviceId ).get( 'master' )
Jon Hall5cf14d52015-07-16 12:15:19 -0700482 if ip in master:
483 roleCheck = roleCheck and main.TRUE
484 else:
485 roleCheck = roleCheck and main.FALSE
486 main.log.error( "Error, controller " + ip + " is not" +
487 " master " + "of device " +
488 str( deviceId ) + ". Master is " +
489 repr( master ) + "." )
490 utilities.assert_equals(
491 expect=main.TRUE,
492 actual=roleCheck,
493 onpass="Switches were successfully reassigned to designated " +
494 "controller",
495 onfail="Switches were not successfully reassigned" )
496
497 def CASE3( self, main ):
498 """
499 Assign intents
500 """
501 import time
502 import json
Jon Halle1a3b752015-07-22 13:02:46 -0700503 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700504 assert main, "main not defined"
505 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700506 assert main.CLIs, "main.CLIs not defined"
507 assert main.nodes, "main.nodes not defined"
Jon Halla440e872016-03-31 15:15:50 -0700508 try:
509 labels
510 except NameError:
511 main.log.error( "labels not defined, setting to []" )
512 labels = []
513 try:
514 data
515 except NameError:
516 main.log.error( "data not defined, setting to []" )
517 data = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700518 main.case( "Adding host Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700519 main.caseExplanation = "Discover hosts by using pingall then " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700520 "assign predetermined host-to-host intents." +\
521 " After installation, check that the intent" +\
522 " is distributed to all nodes and the state" +\
523 " is INSTALLED"
524
525 # install onos-app-fwd
526 main.step( "Install reactive forwarding app" )
Jon Halla440e872016-03-31 15:15:50 -0700527 onosCli = main.CLIs[ main.activeNodes[0] ]
528 installResults = onosCli.activateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700529 utilities.assert_equals( expect=main.TRUE, actual=installResults,
530 onpass="Install fwd successful",
531 onfail="Install fwd failed" )
532
533 main.step( "Check app ids" )
534 appCheck = main.TRUE
535 threads = []
Jon Halla440e872016-03-31 15:15:50 -0700536 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -0700537 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700538 name="appToIDCheck-" + str( i ),
539 args=[] )
540 threads.append( t )
541 t.start()
542
543 for t in threads:
544 t.join()
545 appCheck = appCheck and t.result
546 if appCheck != main.TRUE:
Jon Halla440e872016-03-31 15:15:50 -0700547 main.log.warn( onosCli.apps() )
548 main.log.warn( onosCli.appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700549 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
550 onpass="App Ids seem to be correct",
551 onfail="Something is wrong with app Ids" )
552
553 main.step( "Discovering Hosts( Via pingall for now )" )
554 # FIXME: Once we have a host discovery mechanism, use that instead
555 # REACTIVE FWD test
556 pingResult = main.FALSE
Jon Hall96091e62015-09-21 17:34:17 -0700557 passMsg = "Reactive Pingall test passed"
558 time1 = time.time()
559 pingResult = main.Mininet1.pingall()
560 time2 = time.time()
561 if not pingResult:
562 main.log.warn("First pingall failed. Trying again...")
Jon Hall5cf14d52015-07-16 12:15:19 -0700563 pingResult = main.Mininet1.pingall()
Jon Hall96091e62015-09-21 17:34:17 -0700564 passMsg += " on the second try"
565 utilities.assert_equals(
566 expect=main.TRUE,
567 actual=pingResult,
568 onpass= passMsg,
569 onfail="Reactive Pingall failed, " +
570 "one or more ping pairs failed" )
571 main.log.info( "Time for pingall: %2f seconds" %
572 ( time2 - time1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -0700573 # timeout for fwd flows
574 time.sleep( 11 )
575 # uninstall onos-app-fwd
576 main.step( "Uninstall reactive forwarding app" )
Jon Halla440e872016-03-31 15:15:50 -0700577 node = main.activeNodes[0]
578 uninstallResult = main.CLIs[node].deactivateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700579 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
580 onpass="Uninstall fwd successful",
581 onfail="Uninstall fwd failed" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700582
583 main.step( "Check app ids" )
584 threads = []
585 appCheck2 = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -0700586 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -0700587 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700588 name="appToIDCheck-" + str( i ),
589 args=[] )
590 threads.append( t )
591 t.start()
592
593 for t in threads:
594 t.join()
595 appCheck2 = appCheck2 and t.result
596 if appCheck2 != main.TRUE:
Jon Halla440e872016-03-31 15:15:50 -0700597 node = main.activeNodes[0]
598 main.log.warn( main.CLIs[node].apps() )
599 main.log.warn( main.CLIs[node].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700600 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
601 onpass="App Ids seem to be correct",
602 onfail="Something is wrong with app Ids" )
603
604 main.step( "Add host intents via cli" )
605 intentIds = []
Jon Hall6e709752016-02-01 13:38:46 -0800606 # TODO: move the host numbers to params
607 # Maybe look at all the paths we ping?
Jon Hall5cf14d52015-07-16 12:15:19 -0700608 intentAddResult = True
609 hostResult = main.TRUE
610 for i in range( 8, 18 ):
611 main.log.info( "Adding host intent between h" + str( i ) +
612 " and h" + str( i + 10 ) )
613 host1 = "00:00:00:00:00:" + \
614 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
615 host2 = "00:00:00:00:00:" + \
616 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
617 # NOTE: getHost can return None
Jon Halla440e872016-03-31 15:15:50 -0700618 host1Dict = onosCli.getHost( host1 )
619 host2Dict = onosCli.getHost( host2 )
Jon Hall5cf14d52015-07-16 12:15:19 -0700620 host1Id = None
621 host2Id = None
622 if host1Dict and host2Dict:
623 host1Id = host1Dict.get( 'id', None )
624 host2Id = host2Dict.get( 'id', None )
625 if host1Id and host2Id:
Jon Halla440e872016-03-31 15:15:50 -0700626 nodeNum = ( i % len( main.activeNodes ) )
627 node = main.activeNodes[nodeNum]
628 tmpId = main.CLIs[node].addHostIntent( host1Id, host2Id )
Jon Hall5cf14d52015-07-16 12:15:19 -0700629 if tmpId:
630 main.log.info( "Added intent with id: " + tmpId )
631 intentIds.append( tmpId )
632 else:
633 main.log.error( "addHostIntent returned: " +
634 repr( tmpId ) )
635 else:
636 main.log.error( "Error, getHost() failed for h" + str( i ) +
637 " and/or h" + str( i + 10 ) )
Jon Halla440e872016-03-31 15:15:50 -0700638 node = main.activeNodes[0]
639 hosts = main.CLIs[node].hosts()
Jon Hall5cf14d52015-07-16 12:15:19 -0700640 main.log.warn( "Hosts output: " )
641 try:
642 main.log.warn( json.dumps( json.loads( hosts ),
643 sort_keys=True,
644 indent=4,
645 separators=( ',', ': ' ) ) )
646 except ( ValueError, TypeError ):
647 main.log.warn( repr( hosts ) )
648 hostResult = main.FALSE
649 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
650 onpass="Found a host id for each host",
651 onfail="Error looking up host ids" )
652
653 intentStart = time.time()
Jon Halla440e872016-03-31 15:15:50 -0700654 onosIds = onosCli.getAllIntentsId()
Jon Hall5cf14d52015-07-16 12:15:19 -0700655 main.log.info( "Submitted intents: " + str( intentIds ) )
656 main.log.info( "Intents in ONOS: " + str( onosIds ) )
657 for intent in intentIds:
658 if intent in onosIds:
659 pass # intent submitted is in onos
660 else:
661 intentAddResult = False
662 if intentAddResult:
663 intentStop = time.time()
664 else:
665 intentStop = None
666 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -0700667 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700668 intentStates = []
669 installedCheck = True
670 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
671 count = 0
672 try:
673 for intent in json.loads( intents ):
674 state = intent.get( 'state', None )
675 if "INSTALLED" not in state:
676 installedCheck = False
677 intentId = intent.get( 'id', None )
678 intentStates.append( ( intentId, state ) )
679 except ( ValueError, TypeError ):
680 main.log.exception( "Error parsing intents" )
681 # add submitted intents not in the store
682 tmplist = [ i for i, s in intentStates ]
683 missingIntents = False
684 for i in intentIds:
685 if i not in tmplist:
686 intentStates.append( ( i, " - " ) )
687 missingIntents = True
688 intentStates.sort()
689 for i, s in intentStates:
690 count += 1
691 main.log.info( "%-6s%-15s%-15s" %
692 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -0700693 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -0700694 try:
695 missing = False
696 if leaders:
697 parsedLeaders = json.loads( leaders )
698 main.log.warn( json.dumps( parsedLeaders,
699 sort_keys=True,
700 indent=4,
701 separators=( ',', ': ' ) ) )
702 # check for all intent partitions
703 topics = []
704 for i in range( 14 ):
705 topics.append( "intent-partition-" + str( i ) )
706 main.log.debug( topics )
707 ONOStopics = [ j['topic'] for j in parsedLeaders ]
708 for topic in topics:
709 if topic not in ONOStopics:
710 main.log.error( "Error: " + topic +
711 " not in leaders" )
712 missing = True
713 else:
714 main.log.error( "leaders() returned None" )
715 except ( ValueError, TypeError ):
716 main.log.exception( "Error parsing leaders" )
717 main.log.error( repr( leaders ) )
718 # Check all nodes
719 if missing:
Jon Halla440e872016-03-31 15:15:50 -0700720 for i in main.activeNodes:
721 response = main.CLIs[i].leaders( jsonFormat=False)
722 main.log.warn( str( main.CLIs[i].name ) + " leaders output: \n" +
Jon Hall5cf14d52015-07-16 12:15:19 -0700723 str( response ) )
724
Jon Halla440e872016-03-31 15:15:50 -0700725 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -0700726 try:
727 if partitions :
728 parsedPartitions = json.loads( partitions )
729 main.log.warn( json.dumps( parsedPartitions,
730 sort_keys=True,
731 indent=4,
732 separators=( ',', ': ' ) ) )
733 # TODO check for a leader in all paritions
734 # TODO check for consistency among nodes
735 else:
736 main.log.error( "partitions() returned None" )
737 except ( ValueError, TypeError ):
738 main.log.exception( "Error parsing partitions" )
739 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -0700740 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -0700741 try:
742 if pendingMap :
743 parsedPending = json.loads( pendingMap )
744 main.log.warn( json.dumps( parsedPending,
745 sort_keys=True,
746 indent=4,
747 separators=( ',', ': ' ) ) )
748 # TODO check something here?
749 else:
750 main.log.error( "pendingMap() returned None" )
751 except ( ValueError, TypeError ):
752 main.log.exception( "Error parsing pending map" )
753 main.log.error( repr( pendingMap ) )
754
755 intentAddResult = bool( intentAddResult and not missingIntents and
756 installedCheck )
757 if not intentAddResult:
758 main.log.error( "Error in pushing host intents to ONOS" )
759
760 main.step( "Intent Anti-Entropy dispersion" )
Jon Halla440e872016-03-31 15:15:50 -0700761 for j in range(100):
Jon Hall5cf14d52015-07-16 12:15:19 -0700762 correct = True
763 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Halla440e872016-03-31 15:15:50 -0700764 for i in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700765 onosIds = []
Jon Halla440e872016-03-31 15:15:50 -0700766 ids = main.CLIs[i].getAllIntentsId()
Jon Hall5cf14d52015-07-16 12:15:19 -0700767 onosIds.append( ids )
Jon Halla440e872016-03-31 15:15:50 -0700768 main.log.debug( "Intents in " + main.CLIs[i].name + ": " +
Jon Hall5cf14d52015-07-16 12:15:19 -0700769 str( sorted( onosIds ) ) )
770 if sorted( ids ) != sorted( intentIds ):
771 main.log.warn( "Set of intent IDs doesn't match" )
772 correct = False
773 break
774 else:
Jon Halla440e872016-03-31 15:15:50 -0700775 intents = json.loads( main.CLIs[i].intents() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700776 for intent in intents:
777 if intent[ 'state' ] != "INSTALLED":
778 main.log.warn( "Intent " + intent[ 'id' ] +
779 " is " + intent[ 'state' ] )
780 correct = False
781 break
782 if correct:
783 break
784 else:
785 time.sleep(1)
786 if not intentStop:
787 intentStop = time.time()
788 global gossipTime
789 gossipTime = intentStop - intentStart
790 main.log.info( "It took about " + str( gossipTime ) +
791 " seconds for all intents to appear in each node" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700792 gossipPeriod = int( main.params['timers']['gossip'] )
Jon Halla440e872016-03-31 15:15:50 -0700793 maxGossipTime = gossipPeriod * len( main.activeNodes )
Jon Hall5cf14d52015-07-16 12:15:19 -0700794 utilities.assert_greater_equals(
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700795 expect=maxGossipTime, actual=gossipTime,
Jon Hall5cf14d52015-07-16 12:15:19 -0700796 onpass="ECM anti-entropy for intents worked within " +
797 "expected time",
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700798 onfail="Intent ECM anti-entropy took too long. " +
799 "Expected time:{}, Actual time:{}".format( maxGossipTime,
800 gossipTime ) )
801 if gossipTime <= maxGossipTime:
Jon Hall5cf14d52015-07-16 12:15:19 -0700802 intentAddResult = True
803
804 if not intentAddResult or "key" in pendingMap:
805 import time
806 installedCheck = True
807 main.log.info( "Sleeping 60 seconds to see if intents are found" )
808 time.sleep( 60 )
Jon Halla440e872016-03-31 15:15:50 -0700809 onosIds = onosCli.getAllIntentsId()
Jon Hall5cf14d52015-07-16 12:15:19 -0700810 main.log.info( "Submitted intents: " + str( intentIds ) )
811 main.log.info( "Intents in ONOS: " + str( onosIds ) )
812 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -0700813 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700814 intentStates = []
815 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
816 count = 0
817 try:
818 for intent in json.loads( intents ):
819 # Iter through intents of a node
820 state = intent.get( 'state', None )
821 if "INSTALLED" not in state:
822 installedCheck = False
823 intentId = intent.get( 'id', None )
824 intentStates.append( ( intentId, state ) )
825 except ( ValueError, TypeError ):
826 main.log.exception( "Error parsing intents" )
827 # add submitted intents not in the store
828 tmplist = [ i for i, s in intentStates ]
829 for i in intentIds:
830 if i not in tmplist:
831 intentStates.append( ( i, " - " ) )
832 intentStates.sort()
833 for i, s in intentStates:
834 count += 1
835 main.log.info( "%-6s%-15s%-15s" %
836 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -0700837 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -0700838 try:
839 missing = False
840 if leaders:
841 parsedLeaders = json.loads( leaders )
842 main.log.warn( json.dumps( parsedLeaders,
843 sort_keys=True,
844 indent=4,
845 separators=( ',', ': ' ) ) )
846 # check for all intent partitions
847 # check for election
848 topics = []
849 for i in range( 14 ):
850 topics.append( "intent-partition-" + str( i ) )
851 # FIXME: this should only be after we start the app
852 topics.append( "org.onosproject.election" )
853 main.log.debug( topics )
854 ONOStopics = [ j['topic'] for j in parsedLeaders ]
855 for topic in topics:
856 if topic not in ONOStopics:
857 main.log.error( "Error: " + topic +
858 " not in leaders" )
859 missing = True
860 else:
861 main.log.error( "leaders() returned None" )
862 except ( ValueError, TypeError ):
863 main.log.exception( "Error parsing leaders" )
864 main.log.error( repr( leaders ) )
865 # Check all nodes
866 if missing:
Jon Halla440e872016-03-31 15:15:50 -0700867 for i in main.activeNodes:
868 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -0700869 response = node.leaders( jsonFormat=False)
870 main.log.warn( str( node.name ) + " leaders output: \n" +
871 str( response ) )
872
Jon Halla440e872016-03-31 15:15:50 -0700873 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -0700874 try:
875 if partitions :
876 parsedPartitions = json.loads( partitions )
877 main.log.warn( json.dumps( parsedPartitions,
878 sort_keys=True,
879 indent=4,
880 separators=( ',', ': ' ) ) )
881 # TODO check for a leader in all paritions
882 # TODO check for consistency among nodes
883 else:
884 main.log.error( "partitions() returned None" )
885 except ( ValueError, TypeError ):
886 main.log.exception( "Error parsing partitions" )
887 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -0700888 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -0700889 try:
890 if pendingMap :
891 parsedPending = json.loads( pendingMap )
892 main.log.warn( json.dumps( parsedPending,
893 sort_keys=True,
894 indent=4,
895 separators=( ',', ': ' ) ) )
896 # TODO check something here?
897 else:
898 main.log.error( "pendingMap() returned None" )
899 except ( ValueError, TypeError ):
900 main.log.exception( "Error parsing pending map" )
901 main.log.error( repr( pendingMap ) )
902
903 def CASE4( self, main ):
904 """
905 Ping across added host intents
906 """
907 import json
908 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700909 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700910 assert main, "main not defined"
911 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700912 assert main.CLIs, "main.CLIs not defined"
913 assert main.nodes, "main.nodes not defined"
Jon Halla440e872016-03-31 15:15:50 -0700914 main.case( "Verify connectivity by sending traffic across Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700915 main.caseExplanation = "Ping across added host intents to check " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700916 "functionality and check the state of " +\
917 "the intent"
918 main.step( "Ping across added host intents" )
Jon Halla440e872016-03-31 15:15:50 -0700919 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -0700920 PingResult = main.TRUE
921 for i in range( 8, 18 ):
922 ping = main.Mininet1.pingHost( src="h" + str( i ),
923 target="h" + str( i + 10 ) )
924 PingResult = PingResult and ping
925 if ping == main.FALSE:
926 main.log.warn( "Ping failed between h" + str( i ) +
927 " and h" + str( i + 10 ) )
928 elif ping == main.TRUE:
929 main.log.info( "Ping test passed!" )
930 # Don't set PingResult or you'd override failures
931 if PingResult == main.FALSE:
932 main.log.error(
933 "Intents have not been installed correctly, pings failed." )
934 # TODO: pretty print
935 main.log.warn( "ONOS1 intents: " )
936 try:
Jon Halla440e872016-03-31 15:15:50 -0700937 tmpIntents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700938 main.log.warn( json.dumps( json.loads( tmpIntents ),
939 sort_keys=True,
940 indent=4,
941 separators=( ',', ': ' ) ) )
942 except ( ValueError, TypeError ):
943 main.log.warn( repr( tmpIntents ) )
944 utilities.assert_equals(
945 expect=main.TRUE,
946 actual=PingResult,
947 onpass="Intents have been installed correctly and pings work",
948 onfail="Intents have not been installed correctly, pings failed." )
949
950 main.step( "Check Intent state" )
951 installedCheck = False
952 loopCount = 0
953 while not installedCheck and loopCount < 40:
954 installedCheck = True
955 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -0700956 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -0700957 intentStates = []
958 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
959 count = 0
960 # Iter through intents of a node
961 try:
962 for intent in json.loads( intents ):
963 state = intent.get( 'state', None )
964 if "INSTALLED" not in state:
965 installedCheck = False
966 intentId = intent.get( 'id', None )
967 intentStates.append( ( intentId, state ) )
968 except ( ValueError, TypeError ):
969 main.log.exception( "Error parsing intents." )
970 # Print states
971 intentStates.sort()
972 for i, s in intentStates:
973 count += 1
974 main.log.info( "%-6s%-15s%-15s" %
975 ( str( count ), str( i ), str( s ) ) )
976 if not installedCheck:
977 time.sleep( 1 )
978 loopCount += 1
979 utilities.assert_equals( expect=True, actual=installedCheck,
980 onpass="Intents are all INSTALLED",
981 onfail="Intents are not all in " +
982 "INSTALLED state" )
983
984 main.step( "Check leadership of topics" )
Jon Halla440e872016-03-31 15:15:50 -0700985 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -0700986 topicCheck = main.TRUE
987 try:
988 if leaders:
989 parsedLeaders = json.loads( leaders )
990 main.log.warn( json.dumps( parsedLeaders,
991 sort_keys=True,
992 indent=4,
993 separators=( ',', ': ' ) ) )
994 # check for all intent partitions
995 # check for election
996 # TODO: Look at Devices as topics now that it uses this system
997 topics = []
998 for i in range( 14 ):
999 topics.append( "intent-partition-" + str( i ) )
1000 # FIXME: this should only be after we start the app
1001 # FIXME: topics.append( "org.onosproject.election" )
1002 # Print leaders output
1003 main.log.debug( topics )
1004 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1005 for topic in topics:
1006 if topic not in ONOStopics:
1007 main.log.error( "Error: " + topic +
1008 " not in leaders" )
1009 topicCheck = main.FALSE
1010 else:
1011 main.log.error( "leaders() returned None" )
1012 topicCheck = main.FALSE
1013 except ( ValueError, TypeError ):
1014 topicCheck = main.FALSE
1015 main.log.exception( "Error parsing leaders" )
1016 main.log.error( repr( leaders ) )
1017 # TODO: Check for a leader of these topics
1018 # Check all nodes
1019 if topicCheck:
Jon Halla440e872016-03-31 15:15:50 -07001020 for i in main.activeNodes:
1021 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07001022 response = node.leaders( jsonFormat=False)
1023 main.log.warn( str( node.name ) + " leaders output: \n" +
1024 str( response ) )
1025
1026 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
1027 onpass="intent Partitions is in leaders",
1028 onfail="Some topics were lost " )
1029 # Print partitions
Jon Halla440e872016-03-31 15:15:50 -07001030 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -07001031 try:
1032 if partitions :
1033 parsedPartitions = json.loads( partitions )
1034 main.log.warn( json.dumps( parsedPartitions,
1035 sort_keys=True,
1036 indent=4,
1037 separators=( ',', ': ' ) ) )
1038 # TODO check for a leader in all paritions
1039 # TODO check for consistency among nodes
1040 else:
1041 main.log.error( "partitions() returned None" )
1042 except ( ValueError, TypeError ):
1043 main.log.exception( "Error parsing partitions" )
1044 main.log.error( repr( partitions ) )
1045 # Print Pending Map
Jon Halla440e872016-03-31 15:15:50 -07001046 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -07001047 try:
1048 if pendingMap :
1049 parsedPending = json.loads( pendingMap )
1050 main.log.warn( json.dumps( parsedPending,
1051 sort_keys=True,
1052 indent=4,
1053 separators=( ',', ': ' ) ) )
1054 # TODO check something here?
1055 else:
1056 main.log.error( "pendingMap() returned None" )
1057 except ( ValueError, TypeError ):
1058 main.log.exception( "Error parsing pending map" )
1059 main.log.error( repr( pendingMap ) )
1060
1061 if not installedCheck:
1062 main.log.info( "Waiting 60 seconds to see if the state of " +
1063 "intents change" )
1064 time.sleep( 60 )
1065 # Print the intent states
Jon Halla440e872016-03-31 15:15:50 -07001066 intents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -07001067 intentStates = []
1068 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
1069 count = 0
1070 # Iter through intents of a node
1071 try:
1072 for intent in json.loads( intents ):
1073 state = intent.get( 'state', None )
1074 if "INSTALLED" not in state:
1075 installedCheck = False
1076 intentId = intent.get( 'id', None )
1077 intentStates.append( ( intentId, state ) )
1078 except ( ValueError, TypeError ):
1079 main.log.exception( "Error parsing intents." )
1080 intentStates.sort()
1081 for i, s in intentStates:
1082 count += 1
1083 main.log.info( "%-6s%-15s%-15s" %
1084 ( str( count ), str( i ), str( s ) ) )
Jon Halla440e872016-03-31 15:15:50 -07001085 leaders = onosCli.leaders()
Jon Hall5cf14d52015-07-16 12:15:19 -07001086 try:
1087 missing = False
1088 if leaders:
1089 parsedLeaders = json.loads( leaders )
1090 main.log.warn( json.dumps( parsedLeaders,
1091 sort_keys=True,
1092 indent=4,
1093 separators=( ',', ': ' ) ) )
1094 # check for all intent partitions
1095 # check for election
1096 topics = []
1097 for i in range( 14 ):
1098 topics.append( "intent-partition-" + str( i ) )
1099 # FIXME: this should only be after we start the app
1100 topics.append( "org.onosproject.election" )
1101 main.log.debug( topics )
1102 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1103 for topic in topics:
1104 if topic not in ONOStopics:
1105 main.log.error( "Error: " + topic +
1106 " not in leaders" )
1107 missing = True
1108 else:
1109 main.log.error( "leaders() returned None" )
1110 except ( ValueError, TypeError ):
1111 main.log.exception( "Error parsing leaders" )
1112 main.log.error( repr( leaders ) )
1113 if missing:
Jon Halla440e872016-03-31 15:15:50 -07001114 for i in main.activeNodes:
1115 node = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07001116 response = node.leaders( jsonFormat=False)
1117 main.log.warn( str( node.name ) + " leaders output: \n" +
1118 str( response ) )
1119
Jon Halla440e872016-03-31 15:15:50 -07001120 partitions = onosCli.partitions()
Jon Hall5cf14d52015-07-16 12:15:19 -07001121 try:
1122 if partitions :
1123 parsedPartitions = json.loads( partitions )
1124 main.log.warn( json.dumps( parsedPartitions,
1125 sort_keys=True,
1126 indent=4,
1127 separators=( ',', ': ' ) ) )
1128 # TODO check for a leader in all paritions
1129 # TODO check for consistency among nodes
1130 else:
1131 main.log.error( "partitions() returned None" )
1132 except ( ValueError, TypeError ):
1133 main.log.exception( "Error parsing partitions" )
1134 main.log.error( repr( partitions ) )
Jon Halla440e872016-03-31 15:15:50 -07001135 pendingMap = onosCli.pendingMap()
Jon Hall5cf14d52015-07-16 12:15:19 -07001136 try:
1137 if pendingMap :
1138 parsedPending = json.loads( pendingMap )
1139 main.log.warn( json.dumps( parsedPending,
1140 sort_keys=True,
1141 indent=4,
1142 separators=( ',', ': ' ) ) )
1143 # TODO check something here?
1144 else:
1145 main.log.error( "pendingMap() returned None" )
1146 except ( ValueError, TypeError ):
1147 main.log.exception( "Error parsing pending map" )
1148 main.log.error( repr( pendingMap ) )
1149 # Print flowrules
Jon Halla440e872016-03-31 15:15:50 -07001150 node = main.activeNodes[0]
1151 main.log.debug( main.CLIs[node].flows( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001152 main.step( "Wait a minute then ping again" )
1153 # the wait is above
1154 PingResult = main.TRUE
1155 for i in range( 8, 18 ):
1156 ping = main.Mininet1.pingHost( src="h" + str( i ),
1157 target="h" + str( i + 10 ) )
1158 PingResult = PingResult and ping
1159 if ping == main.FALSE:
1160 main.log.warn( "Ping failed between h" + str( i ) +
1161 " and h" + str( i + 10 ) )
1162 elif ping == main.TRUE:
1163 main.log.info( "Ping test passed!" )
1164 # Don't set PingResult or you'd override failures
1165 if PingResult == main.FALSE:
1166 main.log.error(
1167 "Intents have not been installed correctly, pings failed." )
1168 # TODO: pretty print
1169 main.log.warn( "ONOS1 intents: " )
1170 try:
Jon Halla440e872016-03-31 15:15:50 -07001171 tmpIntents = onosCli.intents()
Jon Hall5cf14d52015-07-16 12:15:19 -07001172 main.log.warn( json.dumps( json.loads( tmpIntents ),
1173 sort_keys=True,
1174 indent=4,
1175 separators=( ',', ': ' ) ) )
1176 except ( ValueError, TypeError ):
1177 main.log.warn( repr( tmpIntents ) )
1178 utilities.assert_equals(
1179 expect=main.TRUE,
1180 actual=PingResult,
1181 onpass="Intents have been installed correctly and pings work",
1182 onfail="Intents have not been installed correctly, pings failed." )
1183
1184 def CASE5( self, main ):
1185 """
1186 Reading state of ONOS
1187 """
1188 import json
1189 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001190 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001191 assert main, "main not defined"
1192 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001193 assert main.CLIs, "main.CLIs not defined"
1194 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001195
1196 main.case( "Setting up and gathering data for current state" )
1197 # The general idea for this test case is to pull the state of
1198 # ( intents,flows, topology,... ) from each ONOS node
1199 # We can then compare them with each other and also with past states
1200
1201 main.step( "Check that each switch has a master" )
1202 global mastershipState
1203 mastershipState = '[]'
1204
1205 # Assert that each device has a master
1206 rolesNotNull = main.TRUE
1207 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001208 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001209 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001210 name="rolesNotNull-" + str( i ),
1211 args=[] )
1212 threads.append( t )
1213 t.start()
1214
1215 for t in threads:
1216 t.join()
1217 rolesNotNull = rolesNotNull and t.result
1218 utilities.assert_equals(
1219 expect=main.TRUE,
1220 actual=rolesNotNull,
1221 onpass="Each device has a master",
1222 onfail="Some devices don't have a master assigned" )
1223
1224 main.step( "Get the Mastership of each switch from each controller" )
1225 ONOSMastership = []
1226 mastershipCheck = main.FALSE
1227 consistentMastership = True
1228 rolesResults = True
1229 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001230 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001231 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001232 name="roles-" + str( i ),
1233 args=[] )
1234 threads.append( t )
1235 t.start()
1236
1237 for t in threads:
1238 t.join()
1239 ONOSMastership.append( t.result )
1240
Jon Halla440e872016-03-31 15:15:50 -07001241 for i in range( len( ONOSMastership ) ):
1242 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001243 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Halla440e872016-03-31 15:15:50 -07001244 main.log.error( "Error in getting ONOS" + node + " roles" )
1245 main.log.warn( "ONOS" + node + " mastership response: " +
1246 repr( ONOSMastership[i] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001247 rolesResults = False
1248 utilities.assert_equals(
1249 expect=True,
1250 actual=rolesResults,
1251 onpass="No error in reading roles output",
1252 onfail="Error in reading roles from ONOS" )
1253
1254 main.step( "Check for consistency in roles from each controller" )
1255 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1256 main.log.info(
1257 "Switch roles are consistent across all ONOS nodes" )
1258 else:
1259 consistentMastership = False
1260 utilities.assert_equals(
1261 expect=True,
1262 actual=consistentMastership,
1263 onpass="Switch roles are consistent across all ONOS nodes",
1264 onfail="ONOS nodes have different views of switch roles" )
1265
1266 if rolesResults and not consistentMastership:
Jon Halla440e872016-03-31 15:15:50 -07001267 for i in range( len( main.activeNodes ) ):
1268 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001269 try:
1270 main.log.warn(
Jon Halla440e872016-03-31 15:15:50 -07001271 "ONOS" + node + " roles: ",
Jon Hall5cf14d52015-07-16 12:15:19 -07001272 json.dumps(
1273 json.loads( ONOSMastership[ i ] ),
1274 sort_keys=True,
1275 indent=4,
1276 separators=( ',', ': ' ) ) )
1277 except ( ValueError, TypeError ):
1278 main.log.warn( repr( ONOSMastership[ i ] ) )
1279 elif rolesResults and consistentMastership:
1280 mastershipCheck = main.TRUE
1281 mastershipState = ONOSMastership[ 0 ]
1282
1283 main.step( "Get the intents from each controller" )
1284 global intentState
1285 intentState = []
1286 ONOSIntents = []
1287 intentCheck = main.FALSE
1288 consistentIntents = True
1289 intentsResults = True
1290 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001291 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001292 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001293 name="intents-" + str( i ),
1294 args=[],
1295 kwargs={ 'jsonFormat': True } )
1296 threads.append( t )
1297 t.start()
1298
1299 for t in threads:
1300 t.join()
1301 ONOSIntents.append( t.result )
1302
Jon Halla440e872016-03-31 15:15:50 -07001303 for i in range( len( ONOSIntents ) ):
1304 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001305 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Halla440e872016-03-31 15:15:50 -07001306 main.log.error( "Error in getting ONOS" + node + " intents" )
1307 main.log.warn( "ONOS" + node + " intents response: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07001308 repr( ONOSIntents[ i ] ) )
1309 intentsResults = False
1310 utilities.assert_equals(
1311 expect=True,
1312 actual=intentsResults,
1313 onpass="No error in reading intents output",
1314 onfail="Error in reading intents from ONOS" )
1315
1316 main.step( "Check for consistency in Intents from each controller" )
1317 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1318 main.log.info( "Intents are consistent across all ONOS " +
1319 "nodes" )
1320 else:
1321 consistentIntents = False
1322 main.log.error( "Intents not consistent" )
1323 utilities.assert_equals(
1324 expect=True,
1325 actual=consistentIntents,
1326 onpass="Intents are consistent across all ONOS nodes",
1327 onfail="ONOS nodes have different views of intents" )
1328
1329 if intentsResults:
1330 # Try to make it easy to figure out what is happening
1331 #
1332 # Intent ONOS1 ONOS2 ...
1333 # 0x01 INSTALLED INSTALLING
1334 # ... ... ...
1335 # ... ... ...
1336 title = " Id"
Jon Halla440e872016-03-31 15:15:50 -07001337 for n in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001338 title += " " * 10 + "ONOS" + str( n + 1 )
1339 main.log.warn( title )
Jon Halle1a3b752015-07-22 13:02:46 -07001340 # get all intent keys in the cluster
Jon Hall5cf14d52015-07-16 12:15:19 -07001341 keys = []
1342 try:
1343 # Get the set of all intent keys
1344 for nodeStr in ONOSIntents:
1345 node = json.loads( nodeStr )
1346 for intent in node:
1347 keys.append( intent.get( 'id' ) )
1348 keys = set( keys )
1349 # For each intent key, print the state on each node
1350 for key in keys:
1351 row = "%-13s" % key
1352 for nodeStr in ONOSIntents:
1353 node = json.loads( nodeStr )
1354 for intent in node:
1355 if intent.get( 'id', "Error" ) == key:
1356 row += "%-15s" % intent.get( 'state' )
1357 main.log.warn( row )
1358 # End of intent state table
1359 except ValueError as e:
1360 main.log.exception( e )
1361 main.log.debug( "nodeStr was: " + repr( nodeStr ) )
1362
1363 if intentsResults and not consistentIntents:
1364 # print the json objects
Jon Halla440e872016-03-31 15:15:50 -07001365 n = str( main.activeNodes[-1] + 1 )
1366 main.log.debug( "ONOS" + n + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07001367 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1368 sort_keys=True,
1369 indent=4,
1370 separators=( ',', ': ' ) ) )
Jon Halla440e872016-03-31 15:15:50 -07001371 for i in range( len( ONOSIntents ) ):
1372 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001373 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
Jon Halla440e872016-03-31 15:15:50 -07001374 main.log.debug( "ONOS" + node + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07001375 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1376 sort_keys=True,
1377 indent=4,
1378 separators=( ',', ': ' ) ) )
1379 else:
Jon Halla440e872016-03-31 15:15:50 -07001380 main.log.debug( "ONOS" + node + " intents match ONOS" +
1381 n + " intents" )
Jon Hall5cf14d52015-07-16 12:15:19 -07001382 elif intentsResults and consistentIntents:
1383 intentCheck = main.TRUE
1384 intentState = ONOSIntents[ 0 ]
1385
1386 main.step( "Get the flows from each controller" )
1387 global flowState
1388 flowState = []
1389 ONOSFlows = []
1390 ONOSFlowsJson = []
1391 flowCheck = main.FALSE
1392 consistentFlows = True
1393 flowsResults = True
1394 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001395 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001396 t = main.Thread( target=main.CLIs[i].flows,
Jon Hall5cf14d52015-07-16 12:15:19 -07001397 name="flows-" + str( i ),
1398 args=[],
1399 kwargs={ 'jsonFormat': True } )
1400 threads.append( t )
1401 t.start()
1402
1403 # NOTE: Flows command can take some time to run
1404 time.sleep(30)
1405 for t in threads:
1406 t.join()
1407 result = t.result
1408 ONOSFlows.append( result )
1409
Jon Halla440e872016-03-31 15:15:50 -07001410 for i in range( len( ONOSFlows ) ):
1411 num = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001412 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1413 main.log.error( "Error in getting ONOS" + num + " flows" )
1414 main.log.warn( "ONOS" + num + " flows response: " +
1415 repr( ONOSFlows[ i ] ) )
1416 flowsResults = False
1417 ONOSFlowsJson.append( None )
1418 else:
1419 try:
1420 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1421 except ( ValueError, TypeError ):
1422 # FIXME: change this to log.error?
1423 main.log.exception( "Error in parsing ONOS" + num +
1424 " response as json." )
1425 main.log.error( repr( ONOSFlows[ i ] ) )
1426 ONOSFlowsJson.append( None )
1427 flowsResults = False
1428 utilities.assert_equals(
1429 expect=True,
1430 actual=flowsResults,
1431 onpass="No error in reading flows output",
1432 onfail="Error in reading flows from ONOS" )
1433
1434 main.step( "Check for consistency in Flows from each controller" )
1435 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1436 if all( tmp ):
1437 main.log.info( "Flow count is consistent across all ONOS nodes" )
1438 else:
1439 consistentFlows = False
1440 utilities.assert_equals(
1441 expect=True,
1442 actual=consistentFlows,
1443 onpass="The flow count is consistent across all ONOS nodes",
1444 onfail="ONOS nodes have different flow counts" )
1445
1446 if flowsResults and not consistentFlows:
Jon Halla440e872016-03-31 15:15:50 -07001447 for i in range( len( ONOSFlows ) ):
1448 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001449 try:
1450 main.log.warn(
Jon Halla440e872016-03-31 15:15:50 -07001451 "ONOS" + node + " flows: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07001452 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1453 indent=4, separators=( ',', ': ' ) ) )
1454 except ( ValueError, TypeError ):
Jon Halla440e872016-03-31 15:15:50 -07001455 main.log.warn( "ONOS" + node + " flows: " +
1456 repr( ONOSFlows[ i ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001457 elif flowsResults and consistentFlows:
1458 flowCheck = main.TRUE
1459 flowState = ONOSFlows[ 0 ]
1460
1461 main.step( "Get the OF Table entries" )
1462 global flows
1463 flows = []
1464 for i in range( 1, 29 ):
GlennRC68467eb2015-11-16 18:01:01 -08001465 flows.append( main.Mininet1.getFlowTable( "s" + str( i ), version="1.3", debug=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001466 if flowCheck == main.FALSE:
1467 for table in flows:
1468 main.log.warn( table )
1469 # TODO: Compare switch flow tables with ONOS flow tables
1470
1471 main.step( "Start continuous pings" )
1472 main.Mininet2.pingLong(
1473 src=main.params[ 'PING' ][ 'source1' ],
1474 target=main.params[ 'PING' ][ 'target1' ],
1475 pingTime=500 )
1476 main.Mininet2.pingLong(
1477 src=main.params[ 'PING' ][ 'source2' ],
1478 target=main.params[ 'PING' ][ 'target2' ],
1479 pingTime=500 )
1480 main.Mininet2.pingLong(
1481 src=main.params[ 'PING' ][ 'source3' ],
1482 target=main.params[ 'PING' ][ 'target3' ],
1483 pingTime=500 )
1484 main.Mininet2.pingLong(
1485 src=main.params[ 'PING' ][ 'source4' ],
1486 target=main.params[ 'PING' ][ 'target4' ],
1487 pingTime=500 )
1488 main.Mininet2.pingLong(
1489 src=main.params[ 'PING' ][ 'source5' ],
1490 target=main.params[ 'PING' ][ 'target5' ],
1491 pingTime=500 )
1492 main.Mininet2.pingLong(
1493 src=main.params[ 'PING' ][ 'source6' ],
1494 target=main.params[ 'PING' ][ 'target6' ],
1495 pingTime=500 )
1496 main.Mininet2.pingLong(
1497 src=main.params[ 'PING' ][ 'source7' ],
1498 target=main.params[ 'PING' ][ 'target7' ],
1499 pingTime=500 )
1500 main.Mininet2.pingLong(
1501 src=main.params[ 'PING' ][ 'source8' ],
1502 target=main.params[ 'PING' ][ 'target8' ],
1503 pingTime=500 )
1504 main.Mininet2.pingLong(
1505 src=main.params[ 'PING' ][ 'source9' ],
1506 target=main.params[ 'PING' ][ 'target9' ],
1507 pingTime=500 )
1508 main.Mininet2.pingLong(
1509 src=main.params[ 'PING' ][ 'source10' ],
1510 target=main.params[ 'PING' ][ 'target10' ],
1511 pingTime=500 )
1512
1513 main.step( "Collecting topology information from ONOS" )
1514 devices = []
1515 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001516 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001517 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07001518 name="devices-" + str( i ),
1519 args=[ ] )
1520 threads.append( t )
1521 t.start()
1522
1523 for t in threads:
1524 t.join()
1525 devices.append( t.result )
1526 hosts = []
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].hosts,
Jon Hall5cf14d52015-07-16 12:15:19 -07001530 name="hosts-" + str( i ),
1531 args=[ ] )
1532 threads.append( t )
1533 t.start()
1534
1535 for t in threads:
1536 t.join()
1537 try:
1538 hosts.append( json.loads( t.result ) )
1539 except ( ValueError, TypeError ):
1540 # FIXME: better handling of this, print which node
1541 # Maybe use thread name?
1542 main.log.exception( "Error parsing json output of hosts" )
Jon Hallf3d16e72015-12-16 17:45:08 -08001543 main.log.warn( repr( t.result ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001544 hosts.append( None )
1545
1546 ports = []
1547 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001548 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001549 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07001550 name="ports-" + str( i ),
1551 args=[ ] )
1552 threads.append( t )
1553 t.start()
1554
1555 for t in threads:
1556 t.join()
1557 ports.append( t.result )
1558 links = []
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].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07001562 name="links-" + str( i ),
1563 args=[ ] )
1564 threads.append( t )
1565 t.start()
1566
1567 for t in threads:
1568 t.join()
1569 links.append( t.result )
1570 clusters = []
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].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07001574 name="clusters-" + str( i ),
1575 args=[ ] )
1576 threads.append( t )
1577 t.start()
1578
1579 for t in threads:
1580 t.join()
1581 clusters.append( t.result )
1582 # Compare json objects for hosts and dataplane clusters
1583
1584 # hosts
1585 main.step( "Host view is consistent across ONOS nodes" )
1586 consistentHostsResult = main.TRUE
1587 for controller in range( len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07001588 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hallf3d16e72015-12-16 17:45:08 -08001589 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001590 if hosts[ controller ] == hosts[ 0 ]:
1591 continue
1592 else: # hosts not consistent
1593 main.log.error( "hosts from ONOS" +
1594 controllerStr +
1595 " is inconsistent with ONOS1" )
1596 main.log.warn( repr( hosts[ controller ] ) )
1597 consistentHostsResult = main.FALSE
1598
1599 else:
1600 main.log.error( "Error in getting ONOS hosts from ONOS" +
1601 controllerStr )
1602 consistentHostsResult = main.FALSE
1603 main.log.warn( "ONOS" + controllerStr +
1604 " hosts response: " +
1605 repr( hosts[ controller ] ) )
1606 utilities.assert_equals(
1607 expect=main.TRUE,
1608 actual=consistentHostsResult,
1609 onpass="Hosts view is consistent across all ONOS nodes",
1610 onfail="ONOS nodes have different views of hosts" )
1611
1612 main.step( "Each host has an IP address" )
1613 ipResult = main.TRUE
1614 for controller in range( 0, len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07001615 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hallf3d16e72015-12-16 17:45:08 -08001616 if hosts[ controller ]:
1617 for host in hosts[ controller ]:
1618 if not host.get( 'ipAddresses', [ ] ):
1619 main.log.error( "Error with host ips on controller" +
1620 controllerStr + ": " + str( host ) )
1621 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07001622 utilities.assert_equals(
1623 expect=main.TRUE,
1624 actual=ipResult,
1625 onpass="The ips of the hosts aren't empty",
1626 onfail="The ip of at least one host is missing" )
1627
1628 # Strongly connected clusters of devices
1629 main.step( "Cluster view is consistent across ONOS nodes" )
1630 consistentClustersResult = main.TRUE
1631 for controller in range( len( clusters ) ):
Jon Halla440e872016-03-31 15:15:50 -07001632 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001633 if "Error" not in clusters[ controller ]:
1634 if clusters[ controller ] == clusters[ 0 ]:
1635 continue
1636 else: # clusters not consistent
1637 main.log.error( "clusters from ONOS" + controllerStr +
1638 " is inconsistent with ONOS1" )
1639 consistentClustersResult = main.FALSE
1640
1641 else:
1642 main.log.error( "Error in getting dataplane clusters " +
1643 "from ONOS" + controllerStr )
1644 consistentClustersResult = main.FALSE
1645 main.log.warn( "ONOS" + controllerStr +
1646 " clusters response: " +
1647 repr( clusters[ controller ] ) )
1648 utilities.assert_equals(
1649 expect=main.TRUE,
1650 actual=consistentClustersResult,
1651 onpass="Clusters view is consistent across all ONOS nodes",
1652 onfail="ONOS nodes have different views of clusters" )
1653 # there should always only be one cluster
1654 main.step( "Cluster view correct across ONOS nodes" )
1655 try:
1656 numClusters = len( json.loads( clusters[ 0 ] ) )
1657 except ( ValueError, TypeError ):
1658 main.log.exception( "Error parsing clusters[0]: " +
1659 repr( clusters[ 0 ] ) )
Jon Hall6e709752016-02-01 13:38:46 -08001660 numClusters = "ERROR"
Jon Hall5cf14d52015-07-16 12:15:19 -07001661 clusterResults = main.FALSE
1662 if numClusters == 1:
1663 clusterResults = main.TRUE
1664 utilities.assert_equals(
1665 expect=1,
1666 actual=numClusters,
1667 onpass="ONOS shows 1 SCC",
1668 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1669
1670 main.step( "Comparing ONOS topology to MN" )
1671 devicesResults = main.TRUE
1672 linksResults = main.TRUE
1673 hostsResults = main.TRUE
1674 mnSwitches = main.Mininet1.getSwitches()
1675 mnLinks = main.Mininet1.getLinks()
1676 mnHosts = main.Mininet1.getHosts()
Jon Halla440e872016-03-31 15:15:50 -07001677 for controller in main.activeNodes:
1678 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001679 if devices[ controller ] and ports[ controller ] and\
1680 "Error" not in devices[ controller ] and\
1681 "Error" not in ports[ controller ]:
Jon Halla440e872016-03-31 15:15:50 -07001682 currentDevicesResult = main.Mininet1.compareSwitches(
1683 mnSwitches,
1684 json.loads( devices[ controller ] ),
1685 json.loads( ports[ controller ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001686 else:
1687 currentDevicesResult = main.FALSE
1688 utilities.assert_equals( expect=main.TRUE,
1689 actual=currentDevicesResult,
1690 onpass="ONOS" + controllerStr +
1691 " Switches view is correct",
1692 onfail="ONOS" + controllerStr +
1693 " Switches view is incorrect" )
1694 if links[ controller ] and "Error" not in links[ controller ]:
1695 currentLinksResult = main.Mininet1.compareLinks(
1696 mnSwitches, mnLinks,
1697 json.loads( links[ controller ] ) )
1698 else:
1699 currentLinksResult = main.FALSE
1700 utilities.assert_equals( expect=main.TRUE,
1701 actual=currentLinksResult,
1702 onpass="ONOS" + controllerStr +
1703 " links view is correct",
1704 onfail="ONOS" + controllerStr +
1705 " links view is incorrect" )
1706
Jon Hall657cdf62015-12-17 14:40:51 -08001707 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001708 currentHostsResult = main.Mininet1.compareHosts(
1709 mnHosts,
1710 hosts[ controller ] )
1711 else:
1712 currentHostsResult = main.FALSE
1713 utilities.assert_equals( expect=main.TRUE,
1714 actual=currentHostsResult,
1715 onpass="ONOS" + controllerStr +
1716 " hosts exist in Mininet",
1717 onfail="ONOS" + controllerStr +
1718 " hosts don't match Mininet" )
1719
1720 devicesResults = devicesResults and currentDevicesResult
1721 linksResults = linksResults and currentLinksResult
1722 hostsResults = hostsResults and currentHostsResult
1723
1724 main.step( "Device information is correct" )
1725 utilities.assert_equals(
1726 expect=main.TRUE,
1727 actual=devicesResults,
1728 onpass="Device information is correct",
1729 onfail="Device information is incorrect" )
1730
1731 main.step( "Links are correct" )
1732 utilities.assert_equals(
1733 expect=main.TRUE,
1734 actual=linksResults,
1735 onpass="Link are correct",
1736 onfail="Links are incorrect" )
1737
1738 main.step( "Hosts are correct" )
1739 utilities.assert_equals(
1740 expect=main.TRUE,
1741 actual=hostsResults,
1742 onpass="Hosts are correct",
1743 onfail="Hosts are incorrect" )
1744
1745 def CASE6( self, main ):
1746 """
1747 The Failure case. Since this is the Sanity test, we do nothing.
1748 """
1749 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001750 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001751 assert main, "main not defined"
1752 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001753 assert main.CLIs, "main.CLIs not defined"
1754 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001755 main.case( "Wait 60 seconds instead of inducing a failure" )
1756 time.sleep( 60 )
1757 utilities.assert_equals(
1758 expect=main.TRUE,
1759 actual=main.TRUE,
1760 onpass="Sleeping 60 seconds",
1761 onfail="Something is terribly wrong with my math" )
1762
1763 def CASE7( self, main ):
1764 """
1765 Check state after ONOS failure
1766 """
1767 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001768 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001769 assert main, "main not defined"
1770 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001771 assert main.CLIs, "main.CLIs not defined"
1772 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001773 main.case( "Running ONOS Constant State Tests" )
1774
1775 main.step( "Check that each switch has a master" )
1776 # Assert that each device has a master
1777 rolesNotNull = main.TRUE
1778 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001779 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001780 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001781 name="rolesNotNull-" + str( i ),
1782 args=[ ] )
1783 threads.append( t )
1784 t.start()
1785
1786 for t in threads:
1787 t.join()
1788 rolesNotNull = rolesNotNull and t.result
1789 utilities.assert_equals(
1790 expect=main.TRUE,
1791 actual=rolesNotNull,
1792 onpass="Each device has a master",
1793 onfail="Some devices don't have a master assigned" )
1794
1795 main.step( "Read device roles from ONOS" )
1796 ONOSMastership = []
1797 mastershipCheck = main.FALSE
1798 consistentMastership = True
1799 rolesResults = True
1800 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001801 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001802 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001803 name="roles-" + str( i ),
1804 args=[] )
1805 threads.append( t )
1806 t.start()
1807
1808 for t in threads:
1809 t.join()
1810 ONOSMastership.append( t.result )
1811
Jon Halla440e872016-03-31 15:15:50 -07001812 for i in range( len( ONOSMastership ) ):
1813 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001814 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Halla440e872016-03-31 15:15:50 -07001815 main.log.error( "Error in getting ONOS" + node + " roles" )
1816 main.log.warn( "ONOS" + node + " mastership response: " +
1817 repr( ONOSMastership[i] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001818 rolesResults = False
1819 utilities.assert_equals(
1820 expect=True,
1821 actual=rolesResults,
1822 onpass="No error in reading roles output",
1823 onfail="Error in reading roles from ONOS" )
1824
1825 main.step( "Check for consistency in roles from each controller" )
1826 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1827 main.log.info(
1828 "Switch roles are consistent across all ONOS nodes" )
1829 else:
1830 consistentMastership = False
1831 utilities.assert_equals(
1832 expect=True,
1833 actual=consistentMastership,
1834 onpass="Switch roles are consistent across all ONOS nodes",
1835 onfail="ONOS nodes have different views of switch roles" )
1836
1837 if rolesResults and not consistentMastership:
Jon Halla440e872016-03-31 15:15:50 -07001838 for i in range( len( ONOSMastership ) ):
1839 node = str( main.activeNodes[i] + 1 )
1840 main.log.warn( "ONOS" + node + " roles: ",
1841 json.dumps( json.loads( ONOSMastership[ i ] ),
1842 sort_keys=True,
1843 indent=4,
1844 separators=( ',', ': ' ) ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001845
1846 description2 = "Compare switch roles from before failure"
1847 main.step( description2 )
1848 try:
1849 currentJson = json.loads( ONOSMastership[0] )
1850 oldJson = json.loads( mastershipState )
1851 except ( ValueError, TypeError ):
1852 main.log.exception( "Something is wrong with parsing " +
1853 "ONOSMastership[0] or mastershipState" )
1854 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1855 main.log.error( "mastershipState" + repr( mastershipState ) )
1856 main.cleanup()
1857 main.exit()
1858 mastershipCheck = main.TRUE
1859 for i in range( 1, 29 ):
1860 switchDPID = str(
1861 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
1862 current = [ switch[ 'master' ] for switch in currentJson
1863 if switchDPID in switch[ 'id' ] ]
1864 old = [ switch[ 'master' ] for switch in oldJson
1865 if switchDPID in switch[ 'id' ] ]
1866 if current == old:
1867 mastershipCheck = mastershipCheck and main.TRUE
1868 else:
1869 main.log.warn( "Mastership of switch %s changed" % switchDPID )
1870 mastershipCheck = main.FALSE
1871 utilities.assert_equals(
1872 expect=main.TRUE,
1873 actual=mastershipCheck,
1874 onpass="Mastership of Switches was not changed",
1875 onfail="Mastership of some switches changed" )
1876 mastershipCheck = mastershipCheck and consistentMastership
1877
1878 main.step( "Get the intents and compare across all nodes" )
1879 ONOSIntents = []
1880 intentCheck = main.FALSE
1881 consistentIntents = True
1882 intentsResults = True
1883 threads = []
Jon Halla440e872016-03-31 15:15:50 -07001884 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07001885 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001886 name="intents-" + str( i ),
1887 args=[],
1888 kwargs={ 'jsonFormat': True } )
1889 threads.append( t )
1890 t.start()
1891
1892 for t in threads:
1893 t.join()
1894 ONOSIntents.append( t.result )
1895
Jon Halla440e872016-03-31 15:15:50 -07001896 for i in range( len( ONOSIntents) ):
1897 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07001898 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Halla440e872016-03-31 15:15:50 -07001899 main.log.error( "Error in getting ONOS" + node + " intents" )
1900 main.log.warn( "ONOS" + node + " intents response: " +
Jon Hall5cf14d52015-07-16 12:15:19 -07001901 repr( ONOSIntents[ i ] ) )
1902 intentsResults = False
1903 utilities.assert_equals(
1904 expect=True,
1905 actual=intentsResults,
1906 onpass="No error in reading intents output",
1907 onfail="Error in reading intents from ONOS" )
1908
1909 main.step( "Check for consistency in Intents from each controller" )
1910 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1911 main.log.info( "Intents are consistent across all ONOS " +
1912 "nodes" )
1913 else:
1914 consistentIntents = False
1915
1916 # Try to make it easy to figure out what is happening
1917 #
1918 # Intent ONOS1 ONOS2 ...
1919 # 0x01 INSTALLED INSTALLING
1920 # ... ... ...
1921 # ... ... ...
1922 title = " ID"
Jon Halla440e872016-03-31 15:15:50 -07001923 for n in main.activeNodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001924 title += " " * 10 + "ONOS" + str( n + 1 )
1925 main.log.warn( title )
1926 # get all intent keys in the cluster
1927 keys = []
1928 for nodeStr in ONOSIntents:
1929 node = json.loads( nodeStr )
1930 for intent in node:
1931 keys.append( intent.get( 'id' ) )
1932 keys = set( keys )
1933 for key in keys:
1934 row = "%-13s" % key
1935 for nodeStr in ONOSIntents:
1936 node = json.loads( nodeStr )
1937 for intent in node:
1938 if intent.get( 'id' ) == key:
1939 row += "%-15s" % intent.get( 'state' )
1940 main.log.warn( row )
1941 # End table view
1942
1943 utilities.assert_equals(
1944 expect=True,
1945 actual=consistentIntents,
1946 onpass="Intents are consistent across all ONOS nodes",
1947 onfail="ONOS nodes have different views of intents" )
1948 intentStates = []
1949 for node in ONOSIntents: # Iter through ONOS nodes
1950 nodeStates = []
1951 # Iter through intents of a node
1952 try:
1953 for intent in json.loads( node ):
1954 nodeStates.append( intent[ 'state' ] )
1955 except ( ValueError, TypeError ):
1956 main.log.exception( "Error in parsing intents" )
1957 main.log.error( repr( node ) )
1958 intentStates.append( nodeStates )
1959 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1960 main.log.info( dict( out ) )
1961
1962 if intentsResults and not consistentIntents:
Jon Halla440e872016-03-31 15:15:50 -07001963 for i in range( len( main.activeNodes ) ):
1964 node = str( main.activeNodes[i] + 1 )
1965 main.log.warn( "ONOS" + node + " intents: " )
Jon Hall5cf14d52015-07-16 12:15:19 -07001966 main.log.warn( json.dumps(
1967 json.loads( ONOSIntents[ i ] ),
1968 sort_keys=True,
1969 indent=4,
1970 separators=( ',', ': ' ) ) )
1971 elif intentsResults and consistentIntents:
1972 intentCheck = main.TRUE
1973
1974 # NOTE: Store has no durability, so intents are lost across system
1975 # restarts
1976 main.step( "Compare current intents with intents before the failure" )
1977 # NOTE: this requires case 5 to pass for intentState to be set.
1978 # maybe we should stop the test if that fails?
1979 sameIntents = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07001980 try:
1981 intentState
1982 except NameError:
1983 main.log.warn( "No previous intent state was saved" )
1984 else:
1985 if intentState and intentState == ONOSIntents[ 0 ]:
1986 sameIntents = main.TRUE
1987 main.log.info( "Intents are consistent with before failure" )
1988 # TODO: possibly the states have changed? we may need to figure out
1989 # what the acceptable states are
1990 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
1991 sameIntents = main.TRUE
1992 try:
1993 before = json.loads( intentState )
1994 after = json.loads( ONOSIntents[ 0 ] )
1995 for intent in before:
1996 if intent not in after:
1997 sameIntents = main.FALSE
1998 main.log.debug( "Intent is not currently in ONOS " +
1999 "(at least in the same form):" )
2000 main.log.debug( json.dumps( intent ) )
2001 except ( ValueError, TypeError ):
2002 main.log.exception( "Exception printing intents" )
2003 main.log.debug( repr( ONOSIntents[0] ) )
2004 main.log.debug( repr( intentState ) )
2005 if sameIntents == main.FALSE:
2006 try:
2007 main.log.debug( "ONOS intents before: " )
2008 main.log.debug( json.dumps( json.loads( intentState ),
2009 sort_keys=True, indent=4,
2010 separators=( ',', ': ' ) ) )
2011 main.log.debug( "Current ONOS intents: " )
2012 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
2013 sort_keys=True, indent=4,
2014 separators=( ',', ': ' ) ) )
2015 except ( ValueError, TypeError ):
2016 main.log.exception( "Exception printing intents" )
2017 main.log.debug( repr( ONOSIntents[0] ) )
2018 main.log.debug( repr( intentState ) )
2019 utilities.assert_equals(
2020 expect=main.TRUE,
2021 actual=sameIntents,
2022 onpass="Intents are consistent with before failure",
2023 onfail="The Intents changed during failure" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002024 intentCheck = intentCheck and sameIntents
2025
2026 main.step( "Get the OF Table entries and compare to before " +
2027 "component failure" )
2028 FlowTables = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002029 for i in range( 28 ):
2030 main.log.info( "Checking flow table on s" + str( i + 1 ) )
GlennRC68467eb2015-11-16 18:01:01 -08002031 tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
2032 FlowTables = FlowTables and main.Mininet1.flowTableComp( flows[i], tmpFlows )
Jon Hall5cf14d52015-07-16 12:15:19 -07002033 if FlowTables == main.FALSE:
GlennRC68467eb2015-11-16 18:01:01 -08002034 main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002035 utilities.assert_equals(
2036 expect=main.TRUE,
2037 actual=FlowTables,
2038 onpass="No changes were found in the flow tables",
2039 onfail="Changes were found in the flow tables" )
2040
2041 main.Mininet2.pingLongKill()
2042 '''
2043 main.step( "Check the continuous pings to ensure that no packets " +
2044 "were dropped during component failure" )
2045 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
2046 main.params[ 'TESTONIP' ] )
2047 LossInPings = main.FALSE
2048 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
2049 for i in range( 8, 18 ):
2050 main.log.info(
2051 "Checking for a loss in pings along flow from s" +
2052 str( i ) )
2053 LossInPings = main.Mininet2.checkForLoss(
2054 "/tmp/ping.h" +
2055 str( i ) ) or LossInPings
2056 if LossInPings == main.TRUE:
2057 main.log.info( "Loss in ping detected" )
2058 elif LossInPings == main.ERROR:
2059 main.log.info( "There are multiple mininet process running" )
2060 elif LossInPings == main.FALSE:
2061 main.log.info( "No Loss in the pings" )
2062 main.log.info( "No loss of dataplane connectivity" )
2063 utilities.assert_equals(
2064 expect=main.FALSE,
2065 actual=LossInPings,
2066 onpass="No Loss of connectivity",
2067 onfail="Loss of dataplane connectivity detected" )
2068 '''
2069
2070 main.step( "Leadership Election is still functional" )
2071 # Test of LeadershipElection
Jon Halla440e872016-03-31 15:15:50 -07002072 leaderList = []
2073
Jon Hall5cf14d52015-07-16 12:15:19 -07002074 # NOTE: this only works for the sanity test. In case of failures,
2075 # leader will likely change
Jon Halla440e872016-03-31 15:15:50 -07002076 leader = main.nodes[ main.activeNodes[ 0 ] ].ip_address
Jon Hall5cf14d52015-07-16 12:15:19 -07002077 leaderResult = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07002078
2079 for i in main.activeNodes:
2080 cli = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07002081 leaderN = cli.electionTestLeader()
Jon Halla440e872016-03-31 15:15:50 -07002082 leaderList.append( leaderN )
Jon Hall5cf14d52015-07-16 12:15:19 -07002083 # verify leader is ONOS1
2084 if leaderN == leader:
2085 # all is well
2086 # NOTE: In failure scenario, this could be a new node, maybe
2087 # check != ONOS1
2088 pass
2089 elif leaderN == main.FALSE:
2090 # error in response
2091 main.log.error( "Something is wrong with " +
2092 "electionTestLeader function, check the" +
2093 " error logs" )
2094 leaderResult = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002095 elif leaderN is None:
2096 main.log.error( cli.name +
2097 " shows no leader for the election-app was" +
2098 " elected after the old one died" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002099 leaderResult = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002100 if len( set( leaderList ) ) != 1:
2101 leaderResult = main.FALSE
2102 main.log.error(
2103 "Inconsistent view of leader for the election test app" )
2104 # TODO: print the list
Jon Hall5cf14d52015-07-16 12:15:19 -07002105 utilities.assert_equals(
2106 expect=main.TRUE,
2107 actual=leaderResult,
2108 onpass="Leadership election passed",
2109 onfail="Something went wrong with Leadership election" )
2110
2111 def CASE8( self, main ):
2112 """
2113 Compare topo
2114 """
2115 import json
2116 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002117 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002118 assert main, "main not defined"
2119 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002120 assert main.CLIs, "main.CLIs not defined"
2121 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002122
2123 main.case( "Compare ONOS Topology view to Mininet topology" )
Jon Hall783bbf92015-07-23 14:33:19 -07002124 main.caseExplanation = "Compare topology objects between Mininet" +\
Jon Hall5cf14d52015-07-16 12:15:19 -07002125 " and ONOS"
Jon Hall5cf14d52015-07-16 12:15:19 -07002126 topoResult = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002127 topoFailMsg = "ONOS topology don't match Mininet"
Jon Hall5cf14d52015-07-16 12:15:19 -07002128 elapsed = 0
2129 count = 0
Jon Halle9b1fa32015-12-08 15:32:21 -08002130 main.step( "Comparing ONOS topology to MN topology" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002131 startTime = time.time()
2132 # Give time for Gossip to work
Jon Halle9b1fa32015-12-08 15:32:21 -08002133 while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
Jon Hall96091e62015-09-21 17:34:17 -07002134 devicesResults = main.TRUE
2135 linksResults = main.TRUE
2136 hostsResults = main.TRUE
2137 hostAttachmentResults = True
Jon Hall5cf14d52015-07-16 12:15:19 -07002138 count += 1
2139 cliStart = time.time()
2140 devices = []
2141 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002142 for i in main.activeNodes:
2143 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002144 name="devices-" + str( i ),
Jon Halla440e872016-03-31 15:15:50 -07002145 args=[ main.CLIs[i].devices, [ None ] ],
2146 kwargs= { 'sleep': 5, 'attempts': 5,
2147 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002148 threads.append( t )
2149 t.start()
2150
2151 for t in threads:
2152 t.join()
2153 devices.append( t.result )
2154 hosts = []
2155 ipResult = main.TRUE
2156 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002157 for i in main.activeNodes:
Jon Halld8f6de82015-12-17 17:04:34 -08002158 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002159 name="hosts-" + str( i ),
Jon Halld8f6de82015-12-17 17:04:34 -08002160 args=[ main.CLIs[i].hosts, [ None ] ],
2161 kwargs= { 'sleep': 5, 'attempts': 5,
2162 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002163 threads.append( t )
2164 t.start()
2165
2166 for t in threads:
2167 t.join()
2168 try:
2169 hosts.append( json.loads( t.result ) )
2170 except ( ValueError, TypeError ):
2171 main.log.exception( "Error parsing hosts results" )
2172 main.log.error( repr( t.result ) )
Jon Hallf3d16e72015-12-16 17:45:08 -08002173 hosts.append( None )
Jon Hall5cf14d52015-07-16 12:15:19 -07002174 for controller in range( 0, len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07002175 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hallacd1b182015-12-17 11:43:20 -08002176 if hosts[ controller ]:
2177 for host in hosts[ controller ]:
2178 if host is None or host.get( 'ipAddresses', [] ) == []:
2179 main.log.error(
2180 "Error with host ipAddresses on controller" +
2181 controllerStr + ": " + str( host ) )
2182 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002183 ports = []
2184 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002185 for i in main.activeNodes:
2186 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002187 name="ports-" + str( i ),
Jon Halla440e872016-03-31 15:15:50 -07002188 args=[ main.CLIs[i].ports, [ None ] ],
2189 kwargs= { 'sleep': 5, 'attempts': 5,
2190 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002191 threads.append( t )
2192 t.start()
2193
2194 for t in threads:
2195 t.join()
2196 ports.append( t.result )
2197 links = []
2198 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002199 for i in main.activeNodes:
2200 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002201 name="links-" + str( i ),
Jon Halla440e872016-03-31 15:15:50 -07002202 args=[ main.CLIs[i].links, [ None ] ],
2203 kwargs= { 'sleep': 5, 'attempts': 5,
2204 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002205 threads.append( t )
2206 t.start()
2207
2208 for t in threads:
2209 t.join()
2210 links.append( t.result )
2211 clusters = []
2212 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002213 for i in main.activeNodes:
2214 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002215 name="clusters-" + str( i ),
Jon Halla440e872016-03-31 15:15:50 -07002216 args=[ main.CLIs[i].clusters, [ None ] ],
2217 kwargs= { 'sleep': 5, 'attempts': 5,
2218 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002219 threads.append( t )
2220 t.start()
2221
2222 for t in threads:
2223 t.join()
2224 clusters.append( t.result )
2225
2226 elapsed = time.time() - startTime
2227 cliTime = time.time() - cliStart
2228 print "Elapsed time: " + str( elapsed )
2229 print "CLI time: " + str( cliTime )
2230
Jon Halla440e872016-03-31 15:15:50 -07002231 if all( e is None for e in devices ) and\
2232 all( e is None for e in hosts ) and\
2233 all( e is None for e in ports ) and\
2234 all( e is None for e in links ) and\
2235 all( e is None for e in clusters ):
2236 topoFailMsg = "Could not get topology from ONOS"
2237 main.log.error( topoFailMsg )
2238 continue # Try again, No use trying to compare
2239
Jon Hall5cf14d52015-07-16 12:15:19 -07002240 mnSwitches = main.Mininet1.getSwitches()
2241 mnLinks = main.Mininet1.getLinks()
2242 mnHosts = main.Mininet1.getHosts()
Jon Halla440e872016-03-31 15:15:50 -07002243 for controller in range( len( main.activeNodes ) ):
2244 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002245 if devices[ controller ] and ports[ controller ] and\
2246 "Error" not in devices[ controller ] and\
2247 "Error" not in ports[ controller ]:
2248
Jon Hallc6793552016-01-19 14:18:37 -08002249 try:
2250 currentDevicesResult = main.Mininet1.compareSwitches(
2251 mnSwitches,
2252 json.loads( devices[ controller ] ),
2253 json.loads( ports[ controller ] ) )
2254 except ( TypeError, ValueError ) as e:
2255 main.log.exception( "Object not as expected; devices={!r}\nports={!r}".format(
2256 devices[ controller ], ports[ controller ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002257 else:
2258 currentDevicesResult = main.FALSE
2259 utilities.assert_equals( expect=main.TRUE,
2260 actual=currentDevicesResult,
2261 onpass="ONOS" + controllerStr +
2262 " Switches view is correct",
2263 onfail="ONOS" + controllerStr +
2264 " Switches view is incorrect" )
2265
2266 if links[ controller ] and "Error" not in links[ controller ]:
2267 currentLinksResult = main.Mininet1.compareLinks(
2268 mnSwitches, mnLinks,
2269 json.loads( links[ controller ] ) )
2270 else:
2271 currentLinksResult = main.FALSE
2272 utilities.assert_equals( expect=main.TRUE,
2273 actual=currentLinksResult,
2274 onpass="ONOS" + controllerStr +
2275 " links view is correct",
2276 onfail="ONOS" + controllerStr +
2277 " links view is incorrect" )
Jon Hall657cdf62015-12-17 14:40:51 -08002278 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002279 currentHostsResult = main.Mininet1.compareHosts(
2280 mnHosts,
2281 hosts[ controller ] )
Jon Hall13b446e2016-01-05 12:17:01 -08002282 elif hosts[ controller ] == []:
2283 currentHostsResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002284 else:
2285 currentHostsResult = main.FALSE
2286 utilities.assert_equals( expect=main.TRUE,
2287 actual=currentHostsResult,
2288 onpass="ONOS" + controllerStr +
2289 " hosts exist in Mininet",
2290 onfail="ONOS" + controllerStr +
2291 " hosts don't match Mininet" )
2292 # CHECKING HOST ATTACHMENT POINTS
2293 hostAttachment = True
2294 zeroHosts = False
2295 # FIXME: topo-HA/obelisk specific mappings:
2296 # key is mac and value is dpid
2297 mappings = {}
2298 for i in range( 1, 29 ): # hosts 1 through 28
2299 # set up correct variables:
2300 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2301 if i == 1:
2302 deviceId = "1000".zfill(16)
2303 elif i == 2:
2304 deviceId = "2000".zfill(16)
2305 elif i == 3:
2306 deviceId = "3000".zfill(16)
2307 elif i == 4:
2308 deviceId = "3004".zfill(16)
2309 elif i == 5:
2310 deviceId = "5000".zfill(16)
2311 elif i == 6:
2312 deviceId = "6000".zfill(16)
2313 elif i == 7:
2314 deviceId = "6007".zfill(16)
2315 elif i >= 8 and i <= 17:
2316 dpid = '3' + str( i ).zfill( 3 )
2317 deviceId = dpid.zfill(16)
2318 elif i >= 18 and i <= 27:
2319 dpid = '6' + str( i ).zfill( 3 )
2320 deviceId = dpid.zfill(16)
2321 elif i == 28:
2322 deviceId = "2800".zfill(16)
2323 mappings[ macId ] = deviceId
Jon Halld8f6de82015-12-17 17:04:34 -08002324 if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002325 if hosts[ controller ] == []:
2326 main.log.warn( "There are no hosts discovered" )
2327 zeroHosts = True
2328 else:
2329 for host in hosts[ controller ]:
2330 mac = None
2331 location = None
2332 device = None
2333 port = None
2334 try:
2335 mac = host.get( 'mac' )
2336 assert mac, "mac field could not be found for this host object"
2337
2338 location = host.get( 'location' )
2339 assert location, "location field could not be found for this host object"
2340
2341 # Trim the protocol identifier off deviceId
2342 device = str( location.get( 'elementId' ) ).split(':')[1]
2343 assert device, "elementId field could not be found for this host location object"
2344
2345 port = location.get( 'port' )
2346 assert port, "port field could not be found for this host location object"
2347
2348 # Now check if this matches where they should be
2349 if mac and device and port:
2350 if str( port ) != "1":
2351 main.log.error( "The attachment port is incorrect for " +
2352 "host " + str( mac ) +
2353 ". Expected: 1 Actual: " + str( port) )
2354 hostAttachment = False
2355 if device != mappings[ str( mac ) ]:
2356 main.log.error( "The attachment device is incorrect for " +
2357 "host " + str( mac ) +
2358 ". Expected: " + mappings[ str( mac ) ] +
2359 " Actual: " + device )
2360 hostAttachment = False
2361 else:
2362 hostAttachment = False
2363 except AssertionError:
2364 main.log.exception( "Json object not as expected" )
2365 main.log.error( repr( host ) )
2366 hostAttachment = False
2367 else:
2368 main.log.error( "No hosts json output or \"Error\"" +
2369 " in output. hosts = " +
2370 repr( hosts[ controller ] ) )
2371 if zeroHosts is False:
2372 hostAttachment = True
2373
2374 # END CHECKING HOST ATTACHMENT POINTS
2375 devicesResults = devicesResults and currentDevicesResult
2376 linksResults = linksResults and currentLinksResult
2377 hostsResults = hostsResults and currentHostsResult
2378 hostAttachmentResults = hostAttachmentResults and\
2379 hostAttachment
2380 topoResult = ( devicesResults and linksResults
2381 and hostsResults and ipResult and
2382 hostAttachmentResults )
Jon Halle9b1fa32015-12-08 15:32:21 -08002383 utilities.assert_equals( expect=True,
2384 actual=topoResult,
2385 onpass="ONOS topology matches Mininet",
Jon Halla440e872016-03-31 15:15:50 -07002386 onfail=topoFailMsg )
Jon Halle9b1fa32015-12-08 15:32:21 -08002387 # End of While loop to pull ONOS state
Jon Hall5cf14d52015-07-16 12:15:19 -07002388
2389 # Compare json objects for hosts and dataplane clusters
2390
2391 # hosts
2392 main.step( "Hosts view is consistent across all ONOS nodes" )
2393 consistentHostsResult = main.TRUE
2394 for controller in range( len( hosts ) ):
Jon Halla440e872016-03-31 15:15:50 -07002395 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall13b446e2016-01-05 12:17:01 -08002396 if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002397 if hosts[ controller ] == hosts[ 0 ]:
2398 continue
2399 else: # hosts not consistent
2400 main.log.error( "hosts from ONOS" + controllerStr +
2401 " is inconsistent with ONOS1" )
2402 main.log.warn( repr( hosts[ controller ] ) )
2403 consistentHostsResult = main.FALSE
2404
2405 else:
2406 main.log.error( "Error in getting ONOS hosts from ONOS" +
2407 controllerStr )
2408 consistentHostsResult = main.FALSE
2409 main.log.warn( "ONOS" + controllerStr +
2410 " hosts response: " +
2411 repr( hosts[ controller ] ) )
2412 utilities.assert_equals(
2413 expect=main.TRUE,
2414 actual=consistentHostsResult,
2415 onpass="Hosts view is consistent across all ONOS nodes",
2416 onfail="ONOS nodes have different views of hosts" )
2417
2418 main.step( "Hosts information is correct" )
2419 hostsResults = hostsResults and ipResult
2420 utilities.assert_equals(
2421 expect=main.TRUE,
2422 actual=hostsResults,
2423 onpass="Host information is correct",
2424 onfail="Host information is incorrect" )
2425
2426 main.step( "Host attachment points to the network" )
2427 utilities.assert_equals(
2428 expect=True,
2429 actual=hostAttachmentResults,
2430 onpass="Hosts are correctly attached to the network",
2431 onfail="ONOS did not correctly attach hosts to the network" )
2432
2433 # Strongly connected clusters of devices
2434 main.step( "Clusters view is consistent across all ONOS nodes" )
2435 consistentClustersResult = main.TRUE
2436 for controller in range( len( clusters ) ):
Jon Halla440e872016-03-31 15:15:50 -07002437 controllerStr = str( main.activeNodes[controller] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07002438 if "Error" not in clusters[ controller ]:
2439 if clusters[ controller ] == clusters[ 0 ]:
2440 continue
2441 else: # clusters not consistent
2442 main.log.error( "clusters from ONOS" +
2443 controllerStr +
2444 " is inconsistent with ONOS1" )
2445 consistentClustersResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002446 else:
2447 main.log.error( "Error in getting dataplane clusters " +
2448 "from ONOS" + controllerStr )
2449 consistentClustersResult = main.FALSE
2450 main.log.warn( "ONOS" + controllerStr +
2451 " clusters response: " +
2452 repr( clusters[ controller ] ) )
2453 utilities.assert_equals(
2454 expect=main.TRUE,
2455 actual=consistentClustersResult,
2456 onpass="Clusters view is consistent across all ONOS nodes",
2457 onfail="ONOS nodes have different views of clusters" )
2458
2459 main.step( "There is only one SCC" )
2460 # there should always only be one cluster
2461 try:
2462 numClusters = len( json.loads( clusters[ 0 ] ) )
2463 except ( ValueError, TypeError ):
2464 main.log.exception( "Error parsing clusters[0]: " +
2465 repr( clusters[0] ) )
Jon Halla440e872016-03-31 15:15:50 -07002466 numClusters = "ERROR"
Jon Hall5cf14d52015-07-16 12:15:19 -07002467 clusterResults = main.FALSE
2468 if numClusters == 1:
2469 clusterResults = main.TRUE
2470 utilities.assert_equals(
2471 expect=1,
2472 actual=numClusters,
2473 onpass="ONOS shows 1 SCC",
2474 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2475
2476 topoResult = ( devicesResults and linksResults
2477 and hostsResults and consistentHostsResult
2478 and consistentClustersResult and clusterResults
2479 and ipResult and hostAttachmentResults )
2480
2481 topoResult = topoResult and int( count <= 2 )
2482 note = "note it takes about " + str( int( cliTime ) ) + \
2483 " seconds for the test to make all the cli calls to fetch " +\
2484 "the topology from each ONOS instance"
2485 main.log.info(
2486 "Very crass estimate for topology discovery/convergence( " +
2487 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2488 str( count ) + " tries" )
2489
2490 main.step( "Device information is correct" )
2491 utilities.assert_equals(
2492 expect=main.TRUE,
2493 actual=devicesResults,
2494 onpass="Device information is correct",
2495 onfail="Device information is incorrect" )
2496
2497 main.step( "Links are correct" )
2498 utilities.assert_equals(
2499 expect=main.TRUE,
2500 actual=linksResults,
2501 onpass="Link are correct",
2502 onfail="Links are incorrect" )
2503
2504 main.step( "Hosts are correct" )
2505 utilities.assert_equals(
2506 expect=main.TRUE,
2507 actual=hostsResults,
2508 onpass="Hosts are correct",
2509 onfail="Hosts are incorrect" )
2510
2511 # FIXME: move this to an ONOS state case
2512 main.step( "Checking ONOS nodes" )
2513 nodesOutput = []
2514 nodeResults = main.TRUE
2515 threads = []
Jon Halla440e872016-03-31 15:15:50 -07002516 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07002517 t = main.Thread( target=main.CLIs[i].nodes,
Jon Hall5cf14d52015-07-16 12:15:19 -07002518 name="nodes-" + str( i ),
2519 args=[ ] )
2520 threads.append( t )
2521 t.start()
2522
2523 for t in threads:
2524 t.join()
2525 nodesOutput.append( t.result )
Jon Halla440e872016-03-31 15:15:50 -07002526 ips = [ main.nodes[node].ip_address for node in main.activeNodes ]
Jon Halle9b1fa32015-12-08 15:32:21 -08002527 ips.sort()
Jon Hall5cf14d52015-07-16 12:15:19 -07002528 for i in nodesOutput:
2529 try:
2530 current = json.loads( i )
Jon Halle9b1fa32015-12-08 15:32:21 -08002531 activeIps = []
2532 currentResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002533 for node in current:
Jon Hallbd182782016-03-28 16:42:22 -07002534 if node['state'] == 'READY':
Jon Halle9b1fa32015-12-08 15:32:21 -08002535 activeIps.append( node['ip'] )
2536 activeIps.sort()
2537 if ips == activeIps:
2538 currentResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002539 except ( ValueError, TypeError ):
2540 main.log.error( "Error parsing nodes output" )
2541 main.log.warn( repr( i ) )
Jon Halle9b1fa32015-12-08 15:32:21 -08002542 currentResult = main.FALSE
2543 nodeResults = nodeResults and currentResult
Jon Hall5cf14d52015-07-16 12:15:19 -07002544 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2545 onpass="Nodes check successful",
2546 onfail="Nodes check NOT successful" )
Jon Halla440e872016-03-31 15:15:50 -07002547 if not nodeResults:
2548 for cli in main.CLIs:
2549 main.log.debug( "{} components not ACTIVE: \n{}".format(
2550 cli.name,
2551 cli.sendline( "scr:list | grep -v ACTIVE" ) ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002552
2553 def CASE9( self, main ):
2554 """
2555 Link s3-s28 down
2556 """
2557 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002558 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002559 assert main, "main not defined"
2560 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002561 assert main.CLIs, "main.CLIs not defined"
2562 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002563 # NOTE: You should probably run a topology check after this
2564
2565 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2566
2567 description = "Turn off a link to ensure that Link Discovery " +\
2568 "is working properly"
2569 main.case( description )
2570
2571 main.step( "Kill Link between s3 and s28" )
2572 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
2573 main.log.info( "Waiting " + str( linkSleep ) +
2574 " seconds for link down to be discovered" )
2575 time.sleep( linkSleep )
2576 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
2577 onpass="Link down successful",
2578 onfail="Failed to bring link down" )
2579 # TODO do some sort of check here
2580
2581 def CASE10( self, main ):
2582 """
2583 Link s3-s28 up
2584 """
2585 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002586 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002587 assert main, "main not defined"
2588 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002589 assert main.CLIs, "main.CLIs not defined"
2590 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002591 # NOTE: You should probably run a topology check after this
2592
2593 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2594
2595 description = "Restore a link to ensure that Link Discovery is " + \
2596 "working properly"
2597 main.case( description )
2598
2599 main.step( "Bring link between s3 and s28 back up" )
2600 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
2601 main.log.info( "Waiting " + str( linkSleep ) +
2602 " seconds for link up to be discovered" )
2603 time.sleep( linkSleep )
2604 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
2605 onpass="Link up successful",
2606 onfail="Failed to bring link up" )
2607 # TODO do some sort of check here
2608
2609 def CASE11( self, main ):
2610 """
2611 Switch Down
2612 """
2613 # NOTE: You should probably run a topology check after this
2614 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002615 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002616 assert main, "main not defined"
2617 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002618 assert main.CLIs, "main.CLIs not defined"
2619 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002620
2621 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2622
2623 description = "Killing a switch to ensure it is discovered correctly"
Jon Halla440e872016-03-31 15:15:50 -07002624 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002625 main.case( description )
2626 switch = main.params[ 'kill' ][ 'switch' ]
2627 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2628
2629 # TODO: Make this switch parameterizable
2630 main.step( "Kill " + switch )
2631 main.log.info( "Deleting " + switch )
2632 main.Mininet1.delSwitch( switch )
2633 main.log.info( "Waiting " + str( switchSleep ) +
2634 " seconds for switch down to be discovered" )
2635 time.sleep( switchSleep )
Jon Halla440e872016-03-31 15:15:50 -07002636 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall5cf14d52015-07-16 12:15:19 -07002637 # Peek at the deleted switch
2638 main.log.warn( str( device ) )
2639 result = main.FALSE
2640 if device and device[ 'available' ] is False:
2641 result = main.TRUE
2642 utilities.assert_equals( expect=main.TRUE, actual=result,
2643 onpass="Kill switch successful",
2644 onfail="Failed to kill switch?" )
2645
2646 def CASE12( self, main ):
2647 """
2648 Switch Up
2649 """
2650 # NOTE: You should probably run a topology check after this
2651 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002652 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002653 assert main, "main not defined"
2654 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002655 assert main.CLIs, "main.CLIs not defined"
2656 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002657 assert ONOS1Port, "ONOS1Port not defined"
2658 assert ONOS2Port, "ONOS2Port not defined"
2659 assert ONOS3Port, "ONOS3Port not defined"
2660 assert ONOS4Port, "ONOS4Port not defined"
2661 assert ONOS5Port, "ONOS5Port not defined"
2662 assert ONOS6Port, "ONOS6Port not defined"
2663 assert ONOS7Port, "ONOS7Port not defined"
2664
2665 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2666 switch = main.params[ 'kill' ][ 'switch' ]
2667 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2668 links = main.params[ 'kill' ][ 'links' ].split()
Jon Halla440e872016-03-31 15:15:50 -07002669 onosCli = main.CLIs[ main.activeNodes[0] ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002670 description = "Adding a switch to ensure it is discovered correctly"
2671 main.case( description )
2672
2673 main.step( "Add back " + switch )
2674 main.Mininet1.addSwitch( switch, dpid=switchDPID )
2675 for peer in links:
2676 main.Mininet1.addLink( switch, peer )
Jon Halla440e872016-03-31 15:15:50 -07002677 ipList = [ node.ip_address for node in main.nodes ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002678 main.Mininet1.assignSwController( sw=switch, ip=ipList )
2679 main.log.info( "Waiting " + str( switchSleep ) +
2680 " seconds for switch up to be discovered" )
2681 time.sleep( switchSleep )
Jon Halla440e872016-03-31 15:15:50 -07002682 device = onosCli.getDevice( dpid=switchDPID )
Jon Hall5cf14d52015-07-16 12:15:19 -07002683 # Peek at the deleted switch
2684 main.log.warn( str( device ) )
2685 result = main.FALSE
2686 if device and device[ 'available' ]:
2687 result = main.TRUE
2688 utilities.assert_equals( expect=main.TRUE, actual=result,
2689 onpass="add switch successful",
2690 onfail="Failed to add switch?" )
2691
2692 def CASE13( self, main ):
2693 """
2694 Clean up
2695 """
2696 import os
2697 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002698 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002699 assert main, "main not defined"
2700 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002701 assert main.CLIs, "main.CLIs not defined"
2702 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002703
2704 # printing colors to terminal
2705 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2706 'blue': '\033[94m', 'green': '\033[92m',
2707 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
2708 main.case( "Test Cleanup" )
2709 main.step( "Killing tcpdumps" )
2710 main.Mininet2.stopTcpdump()
2711
2712 testname = main.TEST
Jon Hall96091e62015-09-21 17:34:17 -07002713 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall5cf14d52015-07-16 12:15:19 -07002714 main.step( "Copying MN pcap and ONOS log files to test station" )
2715 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
2716 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
Jon Hall96091e62015-09-21 17:34:17 -07002717 # NOTE: MN Pcap file is being saved to logdir.
2718 # We scp this file as MN and TestON aren't necessarily the same vm
2719
2720 # FIXME: To be replaced with a Jenkin's post script
Jon Hall5cf14d52015-07-16 12:15:19 -07002721 # TODO: Load these from params
2722 # NOTE: must end in /
2723 logFolder = "/opt/onos/log/"
2724 logFiles = [ "karaf.log", "karaf.log.1" ]
2725 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002726 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002727 for node in main.nodes:
Jon Halla440e872016-03-31 15:15:50 -07002728 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002729 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2730 logFolder + f, dstName )
Jon Hall5cf14d52015-07-16 12:15:19 -07002731 # std*.log's
2732 # NOTE: must end in /
2733 logFolder = "/opt/onos/var/"
2734 logFiles = [ "stderr.log", "stdout.log" ]
2735 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002736 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002737 for node in main.nodes:
Jon Halla440e872016-03-31 15:15:50 -07002738 dstName = main.logdir + "/" + node.name + "-" + f
Jon Hall96091e62015-09-21 17:34:17 -07002739 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2740 logFolder + f, dstName )
2741 else:
2742 main.log.debug( "skipping saving log files" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002743
2744 main.step( "Stopping Mininet" )
2745 mnResult = main.Mininet1.stopNet()
2746 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2747 onpass="Mininet stopped",
2748 onfail="MN cleanup NOT successful" )
2749
2750 main.step( "Checking ONOS Logs for errors" )
Jon Halle1a3b752015-07-22 13:02:46 -07002751 for node in main.nodes:
Jon Hall96091e62015-09-21 17:34:17 -07002752 main.log.debug( "Checking logs for errors on " + node.name + ":" )
2753 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002754
2755 try:
2756 timerLog = open( main.logdir + "/Timers.csv", 'w')
2757 # Overwrite with empty line and close
2758 labels = "Gossip Intents"
2759 data = str( gossipTime )
2760 timerLog.write( labels + "\n" + data )
2761 timerLog.close()
2762 except NameError, e:
2763 main.log.exception(e)
2764
2765 def CASE14( self, main ):
2766 """
2767 start election app on all onos nodes
2768 """
Jon Halle1a3b752015-07-22 13:02:46 -07002769 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002770 assert main, "main not defined"
2771 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002772 assert main.CLIs, "main.CLIs not defined"
2773 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002774
2775 main.case("Start Leadership Election app")
2776 main.step( "Install leadership election app" )
Jon Halla440e872016-03-31 15:15:50 -07002777 onosCli = main.CLIs[ main.activeNodes[0] ]
2778 appResult = onosCli.activateApp( "org.onosproject.election" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002779 utilities.assert_equals(
2780 expect=main.TRUE,
2781 actual=appResult,
2782 onpass="Election app installed",
2783 onfail="Something went wrong with installing Leadership election" )
2784
2785 main.step( "Run for election on each node" )
2786 leaderResult = main.TRUE
2787 leaders = []
Jon Halla440e872016-03-31 15:15:50 -07002788 for i in main.activeNodes:
2789 main.CLIs[i].electionTestRun()
2790 for i in main.activeNodes:
2791 cli = main.CLIs[i]
Jon Hall5cf14d52015-07-16 12:15:19 -07002792 leader = cli.electionTestLeader()
2793 if leader is None or leader == main.FALSE:
2794 main.log.error( cli.name + ": Leader for the election app " +
2795 "should be an ONOS node, instead got '" +
2796 str( leader ) + "'" )
2797 leaderResult = main.FALSE
2798 leaders.append( leader )
2799 utilities.assert_equals(
2800 expect=main.TRUE,
2801 actual=leaderResult,
2802 onpass="Successfully ran for leadership",
2803 onfail="Failed to run for leadership" )
2804
2805 main.step( "Check that each node shows the same leader" )
2806 sameLeader = main.TRUE
2807 if len( set( leaders ) ) != 1:
2808 sameLeader = main.FALSE
Jon Halle1a3b752015-07-22 13:02:46 -07002809 main.log.error( "Results of electionTestLeader is order of main.CLIs:" +
Jon Hall5cf14d52015-07-16 12:15:19 -07002810 str( leaders ) )
2811 utilities.assert_equals(
2812 expect=main.TRUE,
2813 actual=sameLeader,
2814 onpass="Leadership is consistent for the election topic",
2815 onfail="Nodes have different leaders" )
2816
2817 def CASE15( self, main ):
2818 """
2819 Check that Leadership Election is still functional
acsmars71adceb2015-08-31 15:09:26 -07002820 15.1 Run election on each node
2821 15.2 Check that each node has the same leaders and candidates
2822 15.3 Find current leader and withdraw
2823 15.4 Check that a new node was elected leader
2824 15.5 Check that that new leader was the candidate of old leader
2825 15.6 Run for election on old leader
2826 15.7 Check that oldLeader is a candidate, and leader if only 1 node
2827 15.8 Make sure that the old leader was added to the candidate list
2828
2829 old and new variable prefixes refer to data from before vs after
2830 withdrawl and later before withdrawl vs after re-election
Jon Hall5cf14d52015-07-16 12:15:19 -07002831 """
2832 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002833 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002834 assert main, "main not defined"
2835 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002836 assert main.CLIs, "main.CLIs not defined"
2837 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002838
Jon Halla440e872016-03-31 15:15:50 -07002839 description = "Check that Leadership Election is still functional"
Jon Hall5cf14d52015-07-16 12:15:19 -07002840 main.case( description )
Jon Halla440e872016-03-31 15:15:50 -07002841 # NOTE: Need to re-run after restarts since being a canidate is not persistant
Jon Hall5cf14d52015-07-16 12:15:19 -07002842
Jon Halla440e872016-03-31 15:15:50 -07002843 oldLeaders = [] # list of lists of each nodes' candidates before
2844 newLeaders = [] # list of lists of each nodes' candidates after
acsmars71adceb2015-08-31 15:09:26 -07002845 oldLeader = '' # the old leader from oldLeaders, None if not same
2846 newLeader = '' # the new leaders fron newLoeaders, None if not same
2847 oldLeaderCLI = None # the CLI of the old leader used for re-electing
2848 expectNoLeader = False # True when there is only one leader
2849 if main.numCtrls == 1:
2850 expectNoLeader = True
2851
2852 main.step( "Run for election on each node" )
2853 electionResult = main.TRUE
2854
Jon Halla440e872016-03-31 15:15:50 -07002855 for i in main.activeNodes: # run test election on each node
2856 if main.CLIs[i].electionTestRun() == main.FALSE:
acsmars71adceb2015-08-31 15:09:26 -07002857 electionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002858 utilities.assert_equals(
2859 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002860 actual=electionResult,
2861 onpass="All nodes successfully ran for leadership",
2862 onfail="At least one node failed to run for leadership" )
2863
acsmars3a72bde2015-09-02 14:16:22 -07002864 if electionResult == main.FALSE:
2865 main.log.error(
Jon Halla440e872016-03-31 15:15:50 -07002866 "Skipping Test Case because Election Test App isn't loaded" )
acsmars3a72bde2015-09-02 14:16:22 -07002867 main.skipCase()
2868
acsmars71adceb2015-08-31 15:09:26 -07002869 main.step( "Check that each node shows the same leader and candidates" )
Jon Halla440e872016-03-31 15:15:50 -07002870 failMessage = "Nodes have different leaderboards"
2871 def consistentLeaderboards( nodes ):
2872 TOPIC = 'org.onosproject.election'
2873 # FIXME: use threads
2874 #FIXME: should we retry outside the function?
2875 for n in range( 5 ): # Retry in case election is still happening
2876 leaderList = []
2877 # Get all leaderboards
2878 for cli in nodes:
2879 leaderList.append( cli.specificLeaderCandidate( TOPIC ) )
2880 # Compare leaderboards
2881 result = all( i == leaderList[0] for i in leaderList ) and\
2882 leaderList is not None
2883 main.log.debug( leaderList )
2884 main.log.warn( result )
2885 if result:
2886 return ( result, leaderList )
2887 time.sleep(5) #TODO: paramerterize
2888 main.log.error( "Inconsistent leaderboards:" + str( leaderList ) )
2889 activeCLIs = [ main.CLIs[i] for i in main.activeNodes ]
2890 sameResult, oldLeaders = consistentLeaderboards( activeCLIs )
2891 if sameResult:
2892 oldLeader = oldLeaders[ 0 ][ 0 ]
2893 main.log.warn( oldLeader )
acsmars71adceb2015-08-31 15:09:26 -07002894 else:
Jon Halla440e872016-03-31 15:15:50 -07002895 oldLeader = None
acsmars71adceb2015-08-31 15:09:26 -07002896 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07002897 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07002898 actual=sameResult,
Jon Halla440e872016-03-31 15:15:50 -07002899 onpass="Leaderboards are consistent for the election topic",
acsmars71adceb2015-08-31 15:09:26 -07002900 onfail=failMessage )
Jon Hall5cf14d52015-07-16 12:15:19 -07002901
2902 main.step( "Find current leader and withdraw" )
acsmars71adceb2015-08-31 15:09:26 -07002903 withdrawResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002904 # do some sanity checking on leader before using it
acsmars71adceb2015-08-31 15:09:26 -07002905 if oldLeader is None:
2906 main.log.error( "Leadership isn't consistent." )
2907 withdrawResult = main.FALSE
2908 # Get the CLI of the oldLeader
Jon Halla440e872016-03-31 15:15:50 -07002909 for i in main.activeNodes:
acsmars71adceb2015-08-31 15:09:26 -07002910 if oldLeader == main.nodes[ i ].ip_address:
2911 oldLeaderCLI = main.CLIs[ i ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002912 break
2913 else: # FOR/ELSE statement
2914 main.log.error( "Leader election, could not find current leader" )
2915 if oldLeader:
acsmars71adceb2015-08-31 15:09:26 -07002916 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall5cf14d52015-07-16 12:15:19 -07002917 utilities.assert_equals(
2918 expect=main.TRUE,
2919 actual=withdrawResult,
2920 onpass="Node was withdrawn from election",
2921 onfail="Node was not withdrawn from election" )
2922
acsmars71adceb2015-08-31 15:09:26 -07002923 main.step( "Check that a new node was elected leader" )
acsmars71adceb2015-08-31 15:09:26 -07002924 failMessage = "Nodes have different leaders"
acsmars71adceb2015-08-31 15:09:26 -07002925 # Get new leaders and candidates
Jon Halla440e872016-03-31 15:15:50 -07002926 newLeaderResult, newLeaders = consistentLeaderboards( activeCLIs )
2927 if newLeaders[ 0 ][ 0 ] == 'none':
2928 main.log.error( "No leader was elected on at least 1 node" )
2929 if not expectNoLeader:
2930 newLeaderResult = False
2931 if newLeaderResult:
2932 newLeader = newLeaders[ 0 ][ 0 ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002933 else:
Jon Halla440e872016-03-31 15:15:50 -07002934 newLeader = None
acsmars71adceb2015-08-31 15:09:26 -07002935
2936 # Check that the new leader is not the older leader, which was withdrawn
2937 if newLeader == oldLeader:
Jon Halla440e872016-03-31 15:15:50 -07002938 newLeaderResult = False
Jon Hall6e709752016-02-01 13:38:46 -08002939 main.log.error( "All nodes still see old leader: " + str( oldLeader ) +
acsmars71adceb2015-08-31 15:09:26 -07002940 " as the current leader" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002941 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07002942 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07002943 actual=newLeaderResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002944 onpass="Leadership election passed",
2945 onfail="Something went wrong with Leadership election" )
2946
Jon Halla440e872016-03-31 15:15:50 -07002947 main.step( "Check that that new leader was the candidate of old leader" )
2948 # candidates[ 2 ] should become the top candidate after withdrawl
acsmars71adceb2015-08-31 15:09:26 -07002949 correctCandidateResult = main.TRUE
2950 if expectNoLeader:
2951 if newLeader == 'none':
2952 main.log.info( "No leader expected. None found. Pass" )
2953 correctCandidateResult = main.TRUE
2954 else:
2955 main.log.info( "Expected no leader, got: " + str( newLeader ) )
2956 correctCandidateResult = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07002957 elif len( oldLeaders[0] ) >= 3:
2958 if newLeader == oldLeaders[ 0 ][ 2 ]:
2959 # correct leader was elected
2960 correctCandidateResult = main.TRUE
2961 else:
2962 correctCandidateResult = main.FALSE
2963 main.log.error( "Candidate {} was elected. {} should have had priority.".format(
2964 newLeader, oldLeaders[ 0 ][ 2 ] ) )
2965 else:
2966 main.log.warn( "Could not determine who should be the correct leader" )
2967 main.log.debug( oldLeaders[ 0 ] )
acsmars71adceb2015-08-31 15:09:26 -07002968 correctCandidateResult = main.FALSE
acsmars71adceb2015-08-31 15:09:26 -07002969 utilities.assert_equals(
2970 expect=main.TRUE,
2971 actual=correctCandidateResult,
2972 onpass="Correct Candidate Elected",
2973 onfail="Incorrect Candidate Elected" )
2974
Jon Hall5cf14d52015-07-16 12:15:19 -07002975 main.step( "Run for election on old leader( just so everyone " +
2976 "is in the hat )" )
acsmars71adceb2015-08-31 15:09:26 -07002977 if oldLeaderCLI is not None:
2978 runResult = oldLeaderCLI.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07002979 else:
acsmars71adceb2015-08-31 15:09:26 -07002980 main.log.error( "No old leader to re-elect" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002981 runResult = main.FALSE
2982 utilities.assert_equals(
2983 expect=main.TRUE,
2984 actual=runResult,
2985 onpass="App re-ran for election",
2986 onfail="App failed to run for election" )
Jon Halla440e872016-03-31 15:15:50 -07002987
acsmars71adceb2015-08-31 15:09:26 -07002988 main.step(
2989 "Check that oldLeader is a candidate, and leader if only 1 node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002990 # verify leader didn't just change
Jon Halla440e872016-03-31 15:15:50 -07002991 # Get new leaders and candidates
2992 reRunLeaders = []
2993 time.sleep( 5 ) # Paremterize
2994 positionResult, reRunLeaders = consistentLeaderboards( activeCLIs )
acsmars71adceb2015-08-31 15:09:26 -07002995
2996 # Check that the re-elected node is last on the candidate List
Jon Halla440e872016-03-31 15:15:50 -07002997 if oldLeader != reRunLeaders[ 0 ][ -1 ]:
2998 main.log.error( "Old Leader ({}) not in the proper position: {} ".format( str( oldLeader),
2999 str( reRunLeaders[ 0 ] ) ) )
acsmars71adceb2015-08-31 15:09:26 -07003000 positionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07003001
3002 utilities.assert_equals(
Jon Halla440e872016-03-31 15:15:50 -07003003 expect=True,
acsmars71adceb2015-08-31 15:09:26 -07003004 actual=positionResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07003005 onpass="Old leader successfully re-ran for election",
3006 onfail="Something went wrong with Leadership election after " +
3007 "the old leader re-ran for election" )
3008
3009 def CASE16( self, main ):
3010 """
3011 Install Distributed Primitives app
3012 """
3013 import time
Jon Halle1a3b752015-07-22 13:02:46 -07003014 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003015 assert main, "main not defined"
3016 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003017 assert main.CLIs, "main.CLIs not defined"
3018 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003019
3020 # Variables for the distributed primitives tests
3021 global pCounterName
Jon Hall5cf14d52015-07-16 12:15:19 -07003022 global pCounterValue
Jon Hall5cf14d52015-07-16 12:15:19 -07003023 global onosSet
3024 global onosSetName
3025 pCounterName = "TestON-Partitions"
Jon Hall5cf14d52015-07-16 12:15:19 -07003026 pCounterValue = 0
Jon Hall5cf14d52015-07-16 12:15:19 -07003027 onosSet = set([])
3028 onosSetName = "TestON-set"
3029
3030 description = "Install Primitives app"
3031 main.case( description )
3032 main.step( "Install Primitives app" )
3033 appName = "org.onosproject.distributedprimitives"
Jon Halla440e872016-03-31 15:15:50 -07003034 node = main.activeNodes[0]
3035 appResults = main.CLIs[node].activateApp( appName )
Jon Hall5cf14d52015-07-16 12:15:19 -07003036 utilities.assert_equals( expect=main.TRUE,
3037 actual=appResults,
3038 onpass="Primitives app activated",
3039 onfail="Primitives app not activated" )
3040 time.sleep( 5 ) # To allow all nodes to activate
3041
3042 def CASE17( self, main ):
3043 """
3044 Check for basic functionality with distributed primitives
3045 """
Jon Hall5cf14d52015-07-16 12:15:19 -07003046 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07003047 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003048 assert main, "main not defined"
3049 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003050 assert main.CLIs, "main.CLIs not defined"
3051 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003052 assert pCounterName, "pCounterName not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003053 assert onosSetName, "onosSetName not defined"
3054 # NOTE: assert fails if value is 0/None/Empty/False
3055 try:
3056 pCounterValue
3057 except NameError:
3058 main.log.error( "pCounterValue not defined, setting to 0" )
3059 pCounterValue = 0
3060 try:
Jon Hall5cf14d52015-07-16 12:15:19 -07003061 onosSet
3062 except NameError:
3063 main.log.error( "onosSet not defined, setting to empty Set" )
3064 onosSet = set([])
3065 # Variables for the distributed primitives tests. These are local only
3066 addValue = "a"
3067 addAllValue = "a b c d e f"
3068 retainValue = "c d e f"
3069
3070 description = "Check for basic functionality with distributed " +\
3071 "primitives"
3072 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07003073 main.caseExplanation = "Test the methods of the distributed " +\
3074 "primitives (counters and sets) throught the cli"
Jon Hall5cf14d52015-07-16 12:15:19 -07003075 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07003076 # Partitioned counters
3077 main.step( "Increment then get a default counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003078 pCounters = []
3079 threads = []
3080 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003081 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003082 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3083 name="counterAddAndGet-" + str( i ),
Jon Hall5cf14d52015-07-16 12:15:19 -07003084 args=[ pCounterName ] )
3085 pCounterValue += 1
3086 addedPValues.append( pCounterValue )
3087 threads.append( t )
3088 t.start()
3089
3090 for t in threads:
3091 t.join()
3092 pCounters.append( t.result )
3093 # Check that counter incremented numController times
3094 pCounterResults = True
3095 for i in addedPValues:
3096 tmpResult = i in pCounters
3097 pCounterResults = pCounterResults and tmpResult
3098 if not tmpResult:
3099 main.log.error( str( i ) + " is not in partitioned "
3100 "counter incremented results" )
3101 utilities.assert_equals( expect=True,
3102 actual=pCounterResults,
3103 onpass="Default counter incremented",
3104 onfail="Error incrementing default" +
3105 " counter" )
3106
Jon Halle1a3b752015-07-22 13:02:46 -07003107 main.step( "Get then Increment a default counter on each node" )
3108 pCounters = []
3109 threads = []
3110 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003111 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003112 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3113 name="counterGetAndAdd-" + str( i ),
3114 args=[ pCounterName ] )
3115 addedPValues.append( pCounterValue )
3116 pCounterValue += 1
3117 threads.append( t )
3118 t.start()
3119
3120 for t in threads:
3121 t.join()
3122 pCounters.append( t.result )
3123 # Check that counter incremented numController times
3124 pCounterResults = True
3125 for i in addedPValues:
3126 tmpResult = i in pCounters
3127 pCounterResults = pCounterResults and tmpResult
3128 if not tmpResult:
3129 main.log.error( str( i ) + " is not in partitioned "
3130 "counter incremented results" )
3131 utilities.assert_equals( expect=True,
3132 actual=pCounterResults,
3133 onpass="Default counter incremented",
3134 onfail="Error incrementing default" +
3135 " counter" )
3136
3137 main.step( "Counters we added have the correct values" )
3138 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3139 utilities.assert_equals( expect=main.TRUE,
3140 actual=incrementCheck,
3141 onpass="Added counters are correct",
3142 onfail="Added counters are incorrect" )
3143
3144 main.step( "Add -8 to then get a default counter on each node" )
3145 pCounters = []
3146 threads = []
3147 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003148 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003149 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3150 name="counterIncrement-" + str( i ),
3151 args=[ pCounterName ],
3152 kwargs={ "delta": -8 } )
3153 pCounterValue += -8
3154 addedPValues.append( pCounterValue )
3155 threads.append( t )
3156 t.start()
3157
3158 for t in threads:
3159 t.join()
3160 pCounters.append( t.result )
3161 # Check that counter incremented numController times
3162 pCounterResults = True
3163 for i in addedPValues:
3164 tmpResult = i in pCounters
3165 pCounterResults = pCounterResults and tmpResult
3166 if not tmpResult:
3167 main.log.error( str( i ) + " is not in partitioned "
3168 "counter incremented results" )
3169 utilities.assert_equals( expect=True,
3170 actual=pCounterResults,
3171 onpass="Default counter incremented",
3172 onfail="Error incrementing default" +
3173 " counter" )
3174
3175 main.step( "Add 5 to then get a default counter on each node" )
3176 pCounters = []
3177 threads = []
3178 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003179 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003180 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3181 name="counterIncrement-" + str( i ),
3182 args=[ pCounterName ],
3183 kwargs={ "delta": 5 } )
3184 pCounterValue += 5
3185 addedPValues.append( pCounterValue )
3186 threads.append( t )
3187 t.start()
3188
3189 for t in threads:
3190 t.join()
3191 pCounters.append( t.result )
3192 # Check that counter incremented numController times
3193 pCounterResults = True
3194 for i in addedPValues:
3195 tmpResult = i in pCounters
3196 pCounterResults = pCounterResults and tmpResult
3197 if not tmpResult:
3198 main.log.error( str( i ) + " is not in partitioned "
3199 "counter incremented results" )
3200 utilities.assert_equals( expect=True,
3201 actual=pCounterResults,
3202 onpass="Default counter incremented",
3203 onfail="Error incrementing default" +
3204 " counter" )
3205
3206 main.step( "Get then add 5 to a default counter on each node" )
3207 pCounters = []
3208 threads = []
3209 addedPValues = []
Jon Halla440e872016-03-31 15:15:50 -07003210 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003211 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3212 name="counterIncrement-" + str( i ),
3213 args=[ pCounterName ],
3214 kwargs={ "delta": 5 } )
3215 addedPValues.append( pCounterValue )
3216 pCounterValue += 5
3217 threads.append( t )
3218 t.start()
3219
3220 for t in threads:
3221 t.join()
3222 pCounters.append( t.result )
3223 # Check that counter incremented numController times
3224 pCounterResults = True
3225 for i in addedPValues:
3226 tmpResult = i in pCounters
3227 pCounterResults = pCounterResults and tmpResult
3228 if not tmpResult:
3229 main.log.error( str( i ) + " is not in partitioned "
3230 "counter incremented results" )
3231 utilities.assert_equals( expect=True,
3232 actual=pCounterResults,
3233 onpass="Default counter incremented",
3234 onfail="Error incrementing default" +
3235 " counter" )
3236
3237 main.step( "Counters we added have the correct values" )
3238 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3239 utilities.assert_equals( expect=main.TRUE,
3240 actual=incrementCheck,
3241 onpass="Added counters are correct",
3242 onfail="Added counters are incorrect" )
3243
Jon Hall5cf14d52015-07-16 12:15:19 -07003244 # DISTRIBUTED SETS
3245 main.step( "Distributed Set get" )
3246 size = len( onosSet )
3247 getResponses = []
3248 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003249 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003250 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003251 name="setTestGet-" + str( i ),
3252 args=[ onosSetName ] )
3253 threads.append( t )
3254 t.start()
3255 for t in threads:
3256 t.join()
3257 getResponses.append( t.result )
3258
3259 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003260 for i in range( len( main.activeNodes ) ):
3261 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003262 if isinstance( getResponses[ i ], list):
3263 current = set( getResponses[ i ] )
3264 if len( current ) == len( getResponses[ i ] ):
3265 # no repeats
3266 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07003267 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003268 " has incorrect view" +
3269 " of set " + onosSetName + ":\n" +
3270 str( getResponses[ i ] ) )
3271 main.log.debug( "Expected: " + str( onosSet ) )
3272 main.log.debug( "Actual: " + str( current ) )
3273 getResults = main.FALSE
3274 else:
3275 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003276 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003277 " has repeat elements in" +
3278 " set " + onosSetName + ":\n" +
3279 str( getResponses[ i ] ) )
3280 getResults = main.FALSE
3281 elif getResponses[ i ] == main.ERROR:
3282 getResults = main.FALSE
3283 utilities.assert_equals( expect=main.TRUE,
3284 actual=getResults,
3285 onpass="Set elements are correct",
3286 onfail="Set elements are incorrect" )
3287
3288 main.step( "Distributed Set size" )
3289 sizeResponses = []
3290 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003291 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003292 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003293 name="setTestSize-" + str( i ),
3294 args=[ onosSetName ] )
3295 threads.append( t )
3296 t.start()
3297 for t in threads:
3298 t.join()
3299 sizeResponses.append( t.result )
3300
3301 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003302 for i in range( len( main.activeNodes ) ):
3303 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003304 if size != sizeResponses[ i ]:
3305 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003306 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003307 " expected a size of " + str( size ) +
3308 " for set " + onosSetName +
3309 " but got " + str( sizeResponses[ i ] ) )
3310 utilities.assert_equals( expect=main.TRUE,
3311 actual=sizeResults,
3312 onpass="Set sizes are correct",
3313 onfail="Set sizes are incorrect" )
3314
3315 main.step( "Distributed Set add()" )
3316 onosSet.add( addValue )
3317 addResponses = []
3318 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003319 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003320 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003321 name="setTestAdd-" + str( i ),
3322 args=[ onosSetName, addValue ] )
3323 threads.append( t )
3324 t.start()
3325 for t in threads:
3326 t.join()
3327 addResponses.append( t.result )
3328
3329 # main.TRUE = successfully changed the set
3330 # main.FALSE = action resulted in no change in set
3331 # main.ERROR - Some error in executing the function
3332 addResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003333 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003334 if addResponses[ i ] == main.TRUE:
3335 # All is well
3336 pass
3337 elif addResponses[ i ] == main.FALSE:
3338 # Already in set, probably fine
3339 pass
3340 elif addResponses[ i ] == main.ERROR:
3341 # Error in execution
3342 addResults = main.FALSE
3343 else:
3344 # unexpected result
3345 addResults = main.FALSE
3346 if addResults != main.TRUE:
3347 main.log.error( "Error executing set add" )
3348
3349 # Check if set is still correct
3350 size = len( onosSet )
3351 getResponses = []
3352 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003353 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003354 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003355 name="setTestGet-" + str( i ),
3356 args=[ onosSetName ] )
3357 threads.append( t )
3358 t.start()
3359 for t in threads:
3360 t.join()
3361 getResponses.append( t.result )
3362 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003363 for i in range( len( main.activeNodes ) ):
3364 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003365 if isinstance( getResponses[ i ], list):
3366 current = set( getResponses[ i ] )
3367 if len( current ) == len( getResponses[ i ] ):
3368 # no repeats
3369 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07003370 main.log.error( "ONOS" + node + " has incorrect view" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003371 " of set " + onosSetName + ":\n" +
3372 str( getResponses[ i ] ) )
3373 main.log.debug( "Expected: " + str( onosSet ) )
3374 main.log.debug( "Actual: " + str( current ) )
3375 getResults = main.FALSE
3376 else:
3377 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003378 main.log.error( "ONOS" + node + " has repeat elements in" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003379 " set " + onosSetName + ":\n" +
3380 str( getResponses[ i ] ) )
3381 getResults = main.FALSE
3382 elif getResponses[ i ] == main.ERROR:
3383 getResults = main.FALSE
3384 sizeResponses = []
3385 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003386 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003387 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003388 name="setTestSize-" + str( i ),
3389 args=[ onosSetName ] )
3390 threads.append( t )
3391 t.start()
3392 for t in threads:
3393 t.join()
3394 sizeResponses.append( t.result )
3395 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003396 for i in range( len( main.activeNodes ) ):
3397 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003398 if size != sizeResponses[ i ]:
3399 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003400 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003401 " expected a size of " + str( size ) +
3402 " for set " + onosSetName +
3403 " but got " + str( sizeResponses[ i ] ) )
3404 addResults = addResults and getResults and sizeResults
3405 utilities.assert_equals( expect=main.TRUE,
3406 actual=addResults,
3407 onpass="Set add correct",
3408 onfail="Set add was incorrect" )
3409
3410 main.step( "Distributed Set addAll()" )
3411 onosSet.update( addAllValue.split() )
3412 addResponses = []
3413 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003414 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003415 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003416 name="setTestAddAll-" + str( i ),
3417 args=[ onosSetName, addAllValue ] )
3418 threads.append( t )
3419 t.start()
3420 for t in threads:
3421 t.join()
3422 addResponses.append( t.result )
3423
3424 # main.TRUE = successfully changed the set
3425 # main.FALSE = action resulted in no change in set
3426 # main.ERROR - Some error in executing the function
3427 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003428 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003429 if addResponses[ i ] == main.TRUE:
3430 # All is well
3431 pass
3432 elif addResponses[ i ] == main.FALSE:
3433 # Already in set, probably fine
3434 pass
3435 elif addResponses[ i ] == main.ERROR:
3436 # Error in execution
3437 addAllResults = main.FALSE
3438 else:
3439 # unexpected result
3440 addAllResults = main.FALSE
3441 if addAllResults != main.TRUE:
3442 main.log.error( "Error executing set addAll" )
3443
3444 # Check if set is still correct
3445 size = len( onosSet )
3446 getResponses = []
3447 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003448 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003449 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003450 name="setTestGet-" + str( i ),
3451 args=[ onosSetName ] )
3452 threads.append( t )
3453 t.start()
3454 for t in threads:
3455 t.join()
3456 getResponses.append( t.result )
3457 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003458 for i in range( len( main.activeNodes ) ):
3459 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003460 if isinstance( getResponses[ i ], list):
3461 current = set( getResponses[ i ] )
3462 if len( current ) == len( getResponses[ i ] ):
3463 # no repeats
3464 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07003465 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003466 " has incorrect view" +
3467 " of set " + onosSetName + ":\n" +
3468 str( getResponses[ i ] ) )
3469 main.log.debug( "Expected: " + str( onosSet ) )
3470 main.log.debug( "Actual: " + str( current ) )
3471 getResults = main.FALSE
3472 else:
3473 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003474 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003475 " has repeat elements in" +
3476 " set " + onosSetName + ":\n" +
3477 str( getResponses[ i ] ) )
3478 getResults = main.FALSE
3479 elif getResponses[ i ] == main.ERROR:
3480 getResults = main.FALSE
3481 sizeResponses = []
3482 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003483 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003484 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003485 name="setTestSize-" + str( i ),
3486 args=[ onosSetName ] )
3487 threads.append( t )
3488 t.start()
3489 for t in threads:
3490 t.join()
3491 sizeResponses.append( t.result )
3492 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003493 for i in range( len( main.activeNodes ) ):
3494 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003495 if size != sizeResponses[ i ]:
3496 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003497 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003498 " expected a size of " + str( size ) +
3499 " for set " + onosSetName +
3500 " but got " + str( sizeResponses[ i ] ) )
3501 addAllResults = addAllResults and getResults and sizeResults
3502 utilities.assert_equals( expect=main.TRUE,
3503 actual=addAllResults,
3504 onpass="Set addAll correct",
3505 onfail="Set addAll was incorrect" )
3506
3507 main.step( "Distributed Set contains()" )
3508 containsResponses = []
3509 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003510 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003511 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003512 name="setContains-" + str( i ),
3513 args=[ onosSetName ],
3514 kwargs={ "values": addValue } )
3515 threads.append( t )
3516 t.start()
3517 for t in threads:
3518 t.join()
3519 # NOTE: This is the tuple
3520 containsResponses.append( t.result )
3521
3522 containsResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003523 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003524 if containsResponses[ i ] == main.ERROR:
3525 containsResults = main.FALSE
3526 else:
3527 containsResults = containsResults and\
3528 containsResponses[ i ][ 1 ]
3529 utilities.assert_equals( expect=main.TRUE,
3530 actual=containsResults,
3531 onpass="Set contains is functional",
3532 onfail="Set contains failed" )
3533
3534 main.step( "Distributed Set containsAll()" )
3535 containsAllResponses = []
3536 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003537 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003538 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003539 name="setContainsAll-" + str( i ),
3540 args=[ onosSetName ],
3541 kwargs={ "values": addAllValue } )
3542 threads.append( t )
3543 t.start()
3544 for t in threads:
3545 t.join()
3546 # NOTE: This is the tuple
3547 containsAllResponses.append( t.result )
3548
3549 containsAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003550 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003551 if containsResponses[ i ] == main.ERROR:
3552 containsResults = main.FALSE
3553 else:
3554 containsResults = containsResults and\
3555 containsResponses[ i ][ 1 ]
3556 utilities.assert_equals( expect=main.TRUE,
3557 actual=containsAllResults,
3558 onpass="Set containsAll is functional",
3559 onfail="Set containsAll failed" )
3560
3561 main.step( "Distributed Set remove()" )
3562 onosSet.remove( addValue )
3563 removeResponses = []
3564 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003565 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003566 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003567 name="setTestRemove-" + str( i ),
3568 args=[ onosSetName, addValue ] )
3569 threads.append( t )
3570 t.start()
3571 for t in threads:
3572 t.join()
3573 removeResponses.append( t.result )
3574
3575 # main.TRUE = successfully changed the set
3576 # main.FALSE = action resulted in no change in set
3577 # main.ERROR - Some error in executing the function
3578 removeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003579 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003580 if removeResponses[ i ] == main.TRUE:
3581 # All is well
3582 pass
3583 elif removeResponses[ i ] == main.FALSE:
3584 # not in set, probably fine
3585 pass
3586 elif removeResponses[ i ] == main.ERROR:
3587 # Error in execution
3588 removeResults = main.FALSE
3589 else:
3590 # unexpected result
3591 removeResults = main.FALSE
3592 if removeResults != main.TRUE:
3593 main.log.error( "Error executing set remove" )
3594
3595 # Check if set is still correct
3596 size = len( onosSet )
3597 getResponses = []
3598 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003599 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003600 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003601 name="setTestGet-" + str( i ),
3602 args=[ onosSetName ] )
3603 threads.append( t )
3604 t.start()
3605 for t in threads:
3606 t.join()
3607 getResponses.append( t.result )
3608 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003609 for i in range( len( main.activeNodes ) ):
3610 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003611 if isinstance( getResponses[ i ], list):
3612 current = set( getResponses[ i ] )
3613 if len( current ) == len( getResponses[ i ] ):
3614 # no repeats
3615 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07003616 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003617 " has incorrect view" +
3618 " of set " + onosSetName + ":\n" +
3619 str( getResponses[ i ] ) )
3620 main.log.debug( "Expected: " + str( onosSet ) )
3621 main.log.debug( "Actual: " + str( current ) )
3622 getResults = main.FALSE
3623 else:
3624 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003625 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003626 " has repeat elements in" +
3627 " set " + onosSetName + ":\n" +
3628 str( getResponses[ i ] ) )
3629 getResults = main.FALSE
3630 elif getResponses[ i ] == main.ERROR:
3631 getResults = main.FALSE
3632 sizeResponses = []
3633 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003634 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003635 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003636 name="setTestSize-" + str( i ),
3637 args=[ onosSetName ] )
3638 threads.append( t )
3639 t.start()
3640 for t in threads:
3641 t.join()
3642 sizeResponses.append( t.result )
3643 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003644 for i in range( len( main.activeNodes ) ):
3645 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003646 if size != sizeResponses[ i ]:
3647 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003648 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003649 " expected a size of " + str( size ) +
3650 " for set " + onosSetName +
3651 " but got " + str( sizeResponses[ i ] ) )
3652 removeResults = removeResults and getResults and sizeResults
3653 utilities.assert_equals( expect=main.TRUE,
3654 actual=removeResults,
3655 onpass="Set remove correct",
3656 onfail="Set remove was incorrect" )
3657
3658 main.step( "Distributed Set removeAll()" )
3659 onosSet.difference_update( addAllValue.split() )
3660 removeAllResponses = []
3661 threads = []
3662 try:
Jon Halla440e872016-03-31 15:15:50 -07003663 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003664 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003665 name="setTestRemoveAll-" + str( i ),
3666 args=[ onosSetName, addAllValue ] )
3667 threads.append( t )
3668 t.start()
3669 for t in threads:
3670 t.join()
3671 removeAllResponses.append( t.result )
3672 except Exception, e:
3673 main.log.exception(e)
3674
3675 # main.TRUE = successfully changed the set
3676 # main.FALSE = action resulted in no change in set
3677 # main.ERROR - Some error in executing the function
3678 removeAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003679 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003680 if removeAllResponses[ i ] == main.TRUE:
3681 # All is well
3682 pass
3683 elif removeAllResponses[ i ] == main.FALSE:
3684 # not in set, probably fine
3685 pass
3686 elif removeAllResponses[ i ] == main.ERROR:
3687 # Error in execution
3688 removeAllResults = main.FALSE
3689 else:
3690 # unexpected result
3691 removeAllResults = main.FALSE
3692 if removeAllResults != main.TRUE:
3693 main.log.error( "Error executing set removeAll" )
3694
3695 # Check if set is still correct
3696 size = len( onosSet )
3697 getResponses = []
3698 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003699 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003700 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003701 name="setTestGet-" + str( i ),
3702 args=[ onosSetName ] )
3703 threads.append( t )
3704 t.start()
3705 for t in threads:
3706 t.join()
3707 getResponses.append( t.result )
3708 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003709 for i in range( len( main.activeNodes ) ):
3710 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003711 if isinstance( getResponses[ i ], list):
3712 current = set( getResponses[ i ] )
3713 if len( current ) == len( getResponses[ i ] ):
3714 # no repeats
3715 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07003716 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003717 " has incorrect view" +
3718 " of set " + onosSetName + ":\n" +
3719 str( getResponses[ i ] ) )
3720 main.log.debug( "Expected: " + str( onosSet ) )
3721 main.log.debug( "Actual: " + str( current ) )
3722 getResults = main.FALSE
3723 else:
3724 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003725 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003726 " has repeat elements in" +
3727 " set " + onosSetName + ":\n" +
3728 str( getResponses[ i ] ) )
3729 getResults = main.FALSE
3730 elif getResponses[ i ] == main.ERROR:
3731 getResults = main.FALSE
3732 sizeResponses = []
3733 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003734 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003735 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003736 name="setTestSize-" + str( i ),
3737 args=[ onosSetName ] )
3738 threads.append( t )
3739 t.start()
3740 for t in threads:
3741 t.join()
3742 sizeResponses.append( t.result )
3743 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003744 for i in range( len( main.activeNodes ) ):
3745 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003746 if size != sizeResponses[ i ]:
3747 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003748 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003749 " expected a size of " + str( size ) +
3750 " for set " + onosSetName +
3751 " but got " + str( sizeResponses[ i ] ) )
3752 removeAllResults = removeAllResults and getResults and sizeResults
3753 utilities.assert_equals( expect=main.TRUE,
3754 actual=removeAllResults,
3755 onpass="Set removeAll correct",
3756 onfail="Set removeAll was incorrect" )
3757
3758 main.step( "Distributed Set addAll()" )
3759 onosSet.update( addAllValue.split() )
3760 addResponses = []
3761 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003762 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003763 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003764 name="setTestAddAll-" + str( i ),
3765 args=[ onosSetName, addAllValue ] )
3766 threads.append( t )
3767 t.start()
3768 for t in threads:
3769 t.join()
3770 addResponses.append( t.result )
3771
3772 # main.TRUE = successfully changed the set
3773 # main.FALSE = action resulted in no change in set
3774 # main.ERROR - Some error in executing the function
3775 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003776 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003777 if addResponses[ i ] == main.TRUE:
3778 # All is well
3779 pass
3780 elif addResponses[ i ] == main.FALSE:
3781 # Already in set, probably fine
3782 pass
3783 elif addResponses[ i ] == main.ERROR:
3784 # Error in execution
3785 addAllResults = main.FALSE
3786 else:
3787 # unexpected result
3788 addAllResults = main.FALSE
3789 if addAllResults != main.TRUE:
3790 main.log.error( "Error executing set addAll" )
3791
3792 # Check if set is still correct
3793 size = len( onosSet )
3794 getResponses = []
3795 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003796 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003797 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003798 name="setTestGet-" + str( i ),
3799 args=[ onosSetName ] )
3800 threads.append( t )
3801 t.start()
3802 for t in threads:
3803 t.join()
3804 getResponses.append( t.result )
3805 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003806 for i in range( len( main.activeNodes ) ):
3807 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003808 if isinstance( getResponses[ i ], list):
3809 current = set( getResponses[ i ] )
3810 if len( current ) == len( getResponses[ i ] ):
3811 # no repeats
3812 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07003813 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003814 " has incorrect view" +
3815 " of set " + onosSetName + ":\n" +
3816 str( getResponses[ i ] ) )
3817 main.log.debug( "Expected: " + str( onosSet ) )
3818 main.log.debug( "Actual: " + str( current ) )
3819 getResults = main.FALSE
3820 else:
3821 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003822 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003823 " has repeat elements in" +
3824 " set " + onosSetName + ":\n" +
3825 str( getResponses[ i ] ) )
3826 getResults = main.FALSE
3827 elif getResponses[ i ] == main.ERROR:
3828 getResults = main.FALSE
3829 sizeResponses = []
3830 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003831 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003832 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003833 name="setTestSize-" + str( i ),
3834 args=[ onosSetName ] )
3835 threads.append( t )
3836 t.start()
3837 for t in threads:
3838 t.join()
3839 sizeResponses.append( t.result )
3840 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003841 for i in range( len( main.activeNodes ) ):
3842 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003843 if size != sizeResponses[ i ]:
3844 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003845 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003846 " expected a size of " + str( size ) +
3847 " for set " + onosSetName +
3848 " but got " + str( sizeResponses[ i ] ) )
3849 addAllResults = addAllResults and getResults and sizeResults
3850 utilities.assert_equals( expect=main.TRUE,
3851 actual=addAllResults,
3852 onpass="Set addAll correct",
3853 onfail="Set addAll was incorrect" )
3854
3855 main.step( "Distributed Set clear()" )
3856 onosSet.clear()
3857 clearResponses = []
3858 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003859 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003860 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003861 name="setTestClear-" + str( i ),
3862 args=[ onosSetName, " "], # Values doesn't matter
3863 kwargs={ "clear": True } )
3864 threads.append( t )
3865 t.start()
3866 for t in threads:
3867 t.join()
3868 clearResponses.append( t.result )
3869
3870 # main.TRUE = successfully changed the set
3871 # main.FALSE = action resulted in no change in set
3872 # main.ERROR - Some error in executing the function
3873 clearResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003874 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003875 if clearResponses[ i ] == main.TRUE:
3876 # All is well
3877 pass
3878 elif clearResponses[ i ] == main.FALSE:
3879 # Nothing set, probably fine
3880 pass
3881 elif clearResponses[ i ] == main.ERROR:
3882 # Error in execution
3883 clearResults = main.FALSE
3884 else:
3885 # unexpected result
3886 clearResults = main.FALSE
3887 if clearResults != main.TRUE:
3888 main.log.error( "Error executing set clear" )
3889
3890 # Check if set is still correct
3891 size = len( onosSet )
3892 getResponses = []
3893 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003894 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003895 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003896 name="setTestGet-" + str( i ),
3897 args=[ onosSetName ] )
3898 threads.append( t )
3899 t.start()
3900 for t in threads:
3901 t.join()
3902 getResponses.append( t.result )
3903 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003904 for i in range( len( main.activeNodes ) ):
3905 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003906 if isinstance( getResponses[ i ], list):
3907 current = set( getResponses[ i ] )
3908 if len( current ) == len( getResponses[ i ] ):
3909 # no repeats
3910 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07003911 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003912 " has incorrect view" +
3913 " of set " + onosSetName + ":\n" +
3914 str( getResponses[ i ] ) )
3915 main.log.debug( "Expected: " + str( onosSet ) )
3916 main.log.debug( "Actual: " + str( current ) )
3917 getResults = main.FALSE
3918 else:
3919 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07003920 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003921 " has repeat elements in" +
3922 " set " + onosSetName + ":\n" +
3923 str( getResponses[ i ] ) )
3924 getResults = main.FALSE
3925 elif getResponses[ i ] == main.ERROR:
3926 getResults = main.FALSE
3927 sizeResponses = []
3928 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003929 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003930 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003931 name="setTestSize-" + str( i ),
3932 args=[ onosSetName ] )
3933 threads.append( t )
3934 t.start()
3935 for t in threads:
3936 t.join()
3937 sizeResponses.append( t.result )
3938 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003939 for i in range( len( main.activeNodes ) ):
3940 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07003941 if size != sizeResponses[ i ]:
3942 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07003943 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07003944 " expected a size of " + str( size ) +
3945 " for set " + onosSetName +
3946 " but got " + str( sizeResponses[ i ] ) )
3947 clearResults = clearResults and getResults and sizeResults
3948 utilities.assert_equals( expect=main.TRUE,
3949 actual=clearResults,
3950 onpass="Set clear correct",
3951 onfail="Set clear was incorrect" )
3952
3953 main.step( "Distributed Set addAll()" )
3954 onosSet.update( addAllValue.split() )
3955 addResponses = []
3956 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003957 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003958 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003959 name="setTestAddAll-" + str( i ),
3960 args=[ onosSetName, addAllValue ] )
3961 threads.append( t )
3962 t.start()
3963 for t in threads:
3964 t.join()
3965 addResponses.append( t.result )
3966
3967 # main.TRUE = successfully changed the set
3968 # main.FALSE = action resulted in no change in set
3969 # main.ERROR - Some error in executing the function
3970 addAllResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07003971 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003972 if addResponses[ i ] == main.TRUE:
3973 # All is well
3974 pass
3975 elif addResponses[ i ] == main.FALSE:
3976 # Already in set, probably fine
3977 pass
3978 elif addResponses[ i ] == main.ERROR:
3979 # Error in execution
3980 addAllResults = main.FALSE
3981 else:
3982 # unexpected result
3983 addAllResults = main.FALSE
3984 if addAllResults != main.TRUE:
3985 main.log.error( "Error executing set addAll" )
3986
3987 # Check if set is still correct
3988 size = len( onosSet )
3989 getResponses = []
3990 threads = []
Jon Halla440e872016-03-31 15:15:50 -07003991 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07003992 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003993 name="setTestGet-" + str( i ),
3994 args=[ onosSetName ] )
3995 threads.append( t )
3996 t.start()
3997 for t in threads:
3998 t.join()
3999 getResponses.append( t.result )
4000 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004001 for i in range( len( main.activeNodes ) ):
4002 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004003 if isinstance( getResponses[ i ], list):
4004 current = set( getResponses[ i ] )
4005 if len( current ) == len( getResponses[ i ] ):
4006 # no repeats
4007 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07004008 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004009 " has incorrect view" +
4010 " of set " + onosSetName + ":\n" +
4011 str( getResponses[ i ] ) )
4012 main.log.debug( "Expected: " + str( onosSet ) )
4013 main.log.debug( "Actual: " + str( current ) )
4014 getResults = main.FALSE
4015 else:
4016 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07004017 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004018 " has repeat elements in" +
4019 " set " + onosSetName + ":\n" +
4020 str( getResponses[ i ] ) )
4021 getResults = main.FALSE
4022 elif getResponses[ i ] == main.ERROR:
4023 getResults = main.FALSE
4024 sizeResponses = []
4025 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004026 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004027 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004028 name="setTestSize-" + str( i ),
4029 args=[ onosSetName ] )
4030 threads.append( t )
4031 t.start()
4032 for t in threads:
4033 t.join()
4034 sizeResponses.append( t.result )
4035 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004036 for i in range( len( main.activeNodes ) ):
4037 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004038 if size != sizeResponses[ i ]:
4039 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07004040 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004041 " expected a size of " + str( size ) +
4042 " for set " + onosSetName +
4043 " but got " + str( sizeResponses[ i ] ) )
4044 addAllResults = addAllResults and getResults and sizeResults
4045 utilities.assert_equals( expect=main.TRUE,
4046 actual=addAllResults,
4047 onpass="Set addAll correct",
4048 onfail="Set addAll was incorrect" )
4049
4050 main.step( "Distributed Set retain()" )
4051 onosSet.intersection_update( retainValue.split() )
4052 retainResponses = []
4053 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004054 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004055 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004056 name="setTestRetain-" + str( i ),
4057 args=[ onosSetName, retainValue ],
4058 kwargs={ "retain": True } )
4059 threads.append( t )
4060 t.start()
4061 for t in threads:
4062 t.join()
4063 retainResponses.append( t.result )
4064
4065 # main.TRUE = successfully changed the set
4066 # main.FALSE = action resulted in no change in set
4067 # main.ERROR - Some error in executing the function
4068 retainResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004069 for i in range( len( main.activeNodes ) ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004070 if retainResponses[ i ] == main.TRUE:
4071 # All is well
4072 pass
4073 elif retainResponses[ i ] == main.FALSE:
4074 # Already in set, probably fine
4075 pass
4076 elif retainResponses[ i ] == main.ERROR:
4077 # Error in execution
4078 retainResults = main.FALSE
4079 else:
4080 # unexpected result
4081 retainResults = main.FALSE
4082 if retainResults != main.TRUE:
4083 main.log.error( "Error executing set retain" )
4084
4085 # Check if set is still correct
4086 size = len( onosSet )
4087 getResponses = []
4088 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004089 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004090 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004091 name="setTestGet-" + str( i ),
4092 args=[ onosSetName ] )
4093 threads.append( t )
4094 t.start()
4095 for t in threads:
4096 t.join()
4097 getResponses.append( t.result )
4098 getResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004099 for i in range( len( main.activeNodes ) ):
4100 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004101 if isinstance( getResponses[ i ], list):
4102 current = set( getResponses[ i ] )
4103 if len( current ) == len( getResponses[ i ] ):
4104 # no repeats
4105 if onosSet != current:
Jon Halla440e872016-03-31 15:15:50 -07004106 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004107 " has incorrect view" +
4108 " of set " + onosSetName + ":\n" +
4109 str( getResponses[ i ] ) )
4110 main.log.debug( "Expected: " + str( onosSet ) )
4111 main.log.debug( "Actual: " + str( current ) )
4112 getResults = main.FALSE
4113 else:
4114 # error, set is not a set
Jon Halla440e872016-03-31 15:15:50 -07004115 main.log.error( "ONOS" + node +
Jon Hall5cf14d52015-07-16 12:15:19 -07004116 " has repeat elements in" +
4117 " set " + onosSetName + ":\n" +
4118 str( getResponses[ i ] ) )
4119 getResults = main.FALSE
4120 elif getResponses[ i ] == main.ERROR:
4121 getResults = main.FALSE
4122 sizeResponses = []
4123 threads = []
Jon Halla440e872016-03-31 15:15:50 -07004124 for i in main.activeNodes:
Jon Halle1a3b752015-07-22 13:02:46 -07004125 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004126 name="setTestSize-" + str( i ),
4127 args=[ onosSetName ] )
4128 threads.append( t )
4129 t.start()
4130 for t in threads:
4131 t.join()
4132 sizeResponses.append( t.result )
4133 sizeResults = main.TRUE
Jon Halla440e872016-03-31 15:15:50 -07004134 for i in range( len( main.activeNodes ) ):
4135 node = str( main.activeNodes[i] + 1 )
Jon Hall5cf14d52015-07-16 12:15:19 -07004136 if size != sizeResponses[ i ]:
4137 sizeResults = main.FALSE
Jon Halla440e872016-03-31 15:15:50 -07004138 main.log.error( "ONOS" + node + " expected a size of " +
Jon Hall5cf14d52015-07-16 12:15:19 -07004139 str( size ) + " for set " + onosSetName +
4140 " but got " + str( sizeResponses[ i ] ) )
4141 retainResults = retainResults and getResults and sizeResults
4142 utilities.assert_equals( expect=main.TRUE,
4143 actual=retainResults,
4144 onpass="Set retain correct",
4145 onfail="Set retain was incorrect" )
4146
Jon Hall2a5002c2015-08-21 16:49:11 -07004147 # Transactional maps
4148 main.step( "Partitioned Transactional maps put" )
4149 tMapValue = "Testing"
4150 numKeys = 100
4151 putResult = True
Jon Halla440e872016-03-31 15:15:50 -07004152 node = main.activeNodes[0]
4153 putResponses = main.CLIs[node].transactionalMapPut( numKeys, tMapValue )
4154 if putResponses and len( putResponses ) == 100:
Jon Hall2a5002c2015-08-21 16:49:11 -07004155 for i in putResponses:
4156 if putResponses[ i ][ 'value' ] != tMapValue:
4157 putResult = False
4158 else:
4159 putResult = False
4160 if not putResult:
4161 main.log.debug( "Put response values: " + str( putResponses ) )
4162 utilities.assert_equals( expect=True,
4163 actual=putResult,
4164 onpass="Partitioned Transactional Map put successful",
4165 onfail="Partitioned Transactional Map put values are incorrect" )
4166
4167 main.step( "Partitioned Transactional maps get" )
4168 getCheck = True
4169 for n in range( 1, numKeys + 1 ):
4170 getResponses = []
4171 threads = []
4172 valueCheck = True
Jon Halla440e872016-03-31 15:15:50 -07004173 for i in main.activeNodes:
Jon Hall2a5002c2015-08-21 16:49:11 -07004174 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4175 name="TMap-get-" + str( i ),
Jon Halla440e872016-03-31 15:15:50 -07004176 args=[ "Key" + str( n ) ] )
Jon Hall2a5002c2015-08-21 16:49:11 -07004177 threads.append( t )
4178 t.start()
4179 for t in threads:
4180 t.join()
4181 getResponses.append( t.result )
4182 for node in getResponses:
4183 if node != tMapValue:
4184 valueCheck = False
4185 if not valueCheck:
4186 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4187 main.log.warn( getResponses )
4188 getCheck = getCheck and valueCheck
4189 utilities.assert_equals( expect=True,
4190 actual=getCheck,
4191 onpass="Partitioned Transactional Map get values were correct",
4192 onfail="Partitioned Transactional Map values incorrect" )