blob: 7b19efc553703d3af06bb8704d8ae2dcdb482c6a [file] [log] [blame]
Jon Hall5cf14d52015-07-16 12:15:19 -07001"""
2Description: This test is to determine if ONOS can handle
3 all of it's nodes restarting
4
5List of test cases:
6CASE1: Compile ONOS and push it to the test machines
7CASE2: Assign devices to controllers
8CASE21: Assign mastership to controllers
9CASE3: Assign intents
10CASE4: Ping across added host intents
11CASE5: Reading state of ONOS
12CASE6: The Failure case.
13CASE7: Check state after control plane failure
14CASE8: Compare topo
15CASE9: Link s3-s28 down
16CASE10: Link s3-s28 up
17CASE11: Switch down
18CASE12: Switch up
19CASE13: Clean up
20CASE14: start election app on all onos nodes
21CASE15: Check that Leadership Election is still functional
22CASE16: Install Distributed Primitives app
23CASE17: Check for basic functionality with distributed primitives
24"""
25
26
27class HAclusterRestart:
28
29 def __init__( self ):
30 self.default = ''
31
32 def CASE1( self, main ):
33 """
34 CASE1 is to compile ONOS and push it to the test machines
35
36 Startup sequence:
37 cell <name>
38 onos-verify-cell
39 NOTE: temporary - onos-remove-raft-logs
40 onos-uninstall
41 start mininet
42 git pull
43 mvn clean install
44 onos-package
45 onos-install -f
46 onos-wait-for-start
47 start cli sessions
48 start tcpdump
49 """
Jon Halle1a3b752015-07-22 13:02:46 -070050 import imp
Jon Hallf3d16e72015-12-16 17:45:08 -080051 import time
Jon Hall5cf14d52015-07-16 12:15:19 -070052 main.log.info( "ONOS HA test: Restart all ONOS nodes - " +
53 "initialization" )
54 main.case( "Setting up test environment" )
Jon Hall783bbf92015-07-23 14:33:19 -070055 main.caseExplanation = "Setup the test environment including " +\
Jon Hall5cf14d52015-07-16 12:15:19 -070056 "installing ONOS, starting Mininet and ONOS" +\
57 "cli sessions."
58 # TODO: save all the timers and output them for plotting
59
60 # load some variables from the params file
61 PULLCODE = False
62 if main.params[ 'Git' ] == 'True':
63 PULLCODE = True
64 gitBranch = main.params[ 'branch' ]
65 cellName = main.params[ 'ENV' ][ 'cellName' ]
66
Jon Halle1a3b752015-07-22 13:02:46 -070067 main.numCtrls = int( main.params[ 'num_controllers' ] )
Jon Hall5cf14d52015-07-16 12:15:19 -070068 if main.ONOSbench.maxNodes:
Jon Halle1a3b752015-07-22 13:02:46 -070069 if main.ONOSbench.maxNodes < main.numCtrls:
70 main.numCtrls = int( main.ONOSbench.maxNodes )
71 # set global variables
Jon Hall5cf14d52015-07-16 12:15:19 -070072 global ONOS1Port
73 global ONOS2Port
74 global ONOS3Port
75 global ONOS4Port
76 global ONOS5Port
77 global ONOS6Port
78 global ONOS7Port
79 # These are for csv plotting in jenkins
80 global labels
81 global data
82 labels = []
83 data = []
84
85 # FIXME: just get controller port from params?
86 # TODO: do we really need all these?
87 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
88 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
89 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
90 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
91 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
92 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
93 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
94
Jon Halle1a3b752015-07-22 13:02:46 -070095 try:
96 fileName = "Counters"
97 path = main.params[ 'imports' ][ 'path' ]
98 main.Counters = imp.load_source( fileName,
99 path + fileName + ".py" )
100 except Exception as e:
101 main.log.exception( e )
102 main.cleanup()
103 main.exit()
104
105 main.CLIs = []
106 main.nodes = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700107 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700108 for i in range( 1, main.numCtrls + 1 ):
109 try:
110 main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
111 main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
112 ipList.append( main.nodes[ -1 ].ip_address )
113 except AttributeError:
114 break
Jon Hall5cf14d52015-07-16 12:15:19 -0700115
116 main.step( "Create cell file" )
117 cellAppString = main.params[ 'ENV' ][ 'appString' ]
118 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
119 main.Mininet1.ip_address,
120 cellAppString, ipList )
121 main.step( "Applying cell variable to environment" )
122 cellResult = main.ONOSbench.setCell( cellName )
123 verifyResult = main.ONOSbench.verifyCell()
124
125 # FIXME:this is short term fix
126 main.log.info( "Removing raft logs" )
127 main.ONOSbench.onosRemoveRaftLogs()
128
129 main.log.info( "Uninstalling ONOS" )
Jon Halle1a3b752015-07-22 13:02:46 -0700130 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700131 main.ONOSbench.onosUninstall( node.ip_address )
132
133 # Make sure ONOS is DEAD
134 main.log.info( "Killing any ONOS processes" )
135 killResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700136 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700137 killed = main.ONOSbench.onosKill( node.ip_address )
138 killResults = killResults and killed
139
140 cleanInstallResult = main.TRUE
141 gitPullResult = main.TRUE
142
143 main.step( "Starting Mininet" )
144 # scp topo file to mininet
145 # TODO: move to params?
146 topoName = "obelisk.py"
147 filePath = main.ONOSbench.home + "/tools/test/topos/"
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700148 main.ONOSbench.scp( main.Mininet1,
149 filePath + topoName,
150 main.Mininet1.home,
151 direction="to" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700152 mnResult = main.Mininet1.startNet( )
153 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
154 onpass="Mininet Started",
155 onfail="Error starting Mininet" )
156
157 main.step( "Git checkout and pull " + gitBranch )
158 if PULLCODE:
159 main.ONOSbench.gitCheckout( gitBranch )
160 gitPullResult = main.ONOSbench.gitPull()
161 # values of 1 or 3 are good
162 utilities.assert_lesser( expect=0, actual=gitPullResult,
163 onpass="Git pull successful",
164 onfail="Git pull failed" )
165 main.ONOSbench.getVersion( report=True )
166
167 main.step( "Using mvn clean install" )
168 cleanInstallResult = main.TRUE
169 if PULLCODE and gitPullResult == main.TRUE:
170 cleanInstallResult = main.ONOSbench.cleanInstall()
171 else:
172 main.log.warn( "Did not pull new code so skipping mvn " +
173 "clean install" )
174 utilities.assert_equals( expect=main.TRUE,
175 actual=cleanInstallResult,
176 onpass="MCI successful",
177 onfail="MCI failed" )
178 # GRAPHS
179 # NOTE: important params here:
180 # job = name of Jenkins job
181 # Plot Name = Plot-HA, only can be used if multiple plots
182 # index = The number of the graph under plot name
183 job = "HAclusterRestart"
184 plotName = "Plot-HA"
Jon Hallff566d52016-01-15 14:45:36 -0800185 index = "1"
Jon Hall5cf14d52015-07-16 12:15:19 -0700186 graphs = '<ac:structured-macro ac:name="html">\n'
187 graphs += '<ac:plain-text-body><![CDATA[\n'
188 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
Jon Halla9845df2016-01-15 14:55:58 -0800189 '/plot/' + plotName + '/getPlot?index=' + index +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700190 '&width=500&height=300"' +\
191 'noborder="0" width="500" height="300" scrolling="yes" ' +\
192 'seamless="seamless"></iframe>\n'
193 graphs += ']]></ac:plain-text-body>\n'
194 graphs += '</ac:structured-macro>\n'
195 main.log.wiki(graphs)
196
197 main.step( "Creating ONOS package" )
198 packageResult = main.ONOSbench.onosPackage()
199 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
200 onpass="ONOS package successful",
201 onfail="ONOS package failed" )
202
203 main.step( "Installing ONOS package" )
204 onosInstallResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700205 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700206 tmpResult = main.ONOSbench.onosInstall( options="-f",
207 node=node.ip_address )
208 onosInstallResult = onosInstallResult and tmpResult
209 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
210 onpass="ONOS install successful",
211 onfail="ONOS install failed" )
212
213 main.step( "Checking if ONOS is up yet" )
214 for i in range( 2 ):
215 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700216 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700217 started = main.ONOSbench.isup( node.ip_address )
218 if not started:
Jon Hallc6793552016-01-19 14:18:37 -0800219 main.log.error( node.name + " hasn't started" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700220 onosIsupResult = onosIsupResult and started
221 if onosIsupResult == main.TRUE:
222 break
223 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
224 onpass="ONOS startup successful",
225 onfail="ONOS startup failed" )
226
227 main.log.step( "Starting ONOS CLI sessions" )
228 cliResults = main.TRUE
229 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700230 for i in range( main.numCtrls ):
231 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -0700232 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -0700233 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -0700234 threads.append( t )
235 t.start()
236
237 for t in threads:
238 t.join()
239 cliResults = cliResults and t.result
240 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
241 onpass="ONOS cli startup successful",
242 onfail="ONOS cli startup failed" )
243
244 if main.params[ 'tcpdump' ].lower() == "true":
245 main.step( "Start Packet Capture MN" )
246 main.Mininet2.startTcpdump(
247 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
248 + "-MN.pcap",
249 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
250 port=main.params[ 'MNtcpdump' ][ 'port' ] )
251
252 main.step( "App Ids check" )
Jon Hallf3d16e72015-12-16 17:45:08 -0800253 time.sleep(60)
Jon Hall5cf14d52015-07-16 12:15:19 -0700254 appCheck = main.TRUE
255 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700256 for i in range( main.numCtrls ):
257 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700258 name="appToIDCheck-" + str( i ),
259 args=[] )
260 threads.append( t )
261 t.start()
262
263 for t in threads:
264 t.join()
265 appCheck = appCheck and t.result
266 if appCheck != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700267 main.log.warn( main.CLIs[0].apps() )
268 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700269 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
270 onpass="App Ids seem to be correct",
271 onfail="Something is wrong with app Ids" )
272
273 if cliResults == main.FALSE:
274 main.log.error( "Failed to start ONOS, stopping test" )
275 main.cleanup()
276 main.exit()
277
278 def CASE2( self, main ):
279 """
280 Assign devices to controllers
281 """
282 import re
Jon Halle1a3b752015-07-22 13:02:46 -0700283 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700284 assert main, "main not defined"
285 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700286 assert main.CLIs, "main.CLIs not defined"
287 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700288 assert ONOS1Port, "ONOS1Port not defined"
289 assert ONOS2Port, "ONOS2Port not defined"
290 assert ONOS3Port, "ONOS3Port not defined"
291 assert ONOS4Port, "ONOS4Port not defined"
292 assert ONOS5Port, "ONOS5Port not defined"
293 assert ONOS6Port, "ONOS6Port not defined"
294 assert ONOS7Port, "ONOS7Port not defined"
295
296 main.case( "Assigning devices to controllers" )
Jon Hall783bbf92015-07-23 14:33:19 -0700297 main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700298 "and check that an ONOS node becomes the " +\
299 "master of the device."
300 main.step( "Assign switches to controllers" )
301
302 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700303 for i in range( main.numCtrls ):
304 ipList.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -0700305 swList = []
306 for i in range( 1, 29 ):
307 swList.append( "s" + str( i ) )
308 main.Mininet1.assignSwController( sw=swList, ip=ipList )
309
310 mastershipCheck = main.TRUE
311 for i in range( 1, 29 ):
312 response = main.Mininet1.getSwController( "s" + str( i ) )
313 try:
314 main.log.info( str( response ) )
315 except Exception:
316 main.log.info( repr( response ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700317 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700318 if re.search( "tcp:" + node.ip_address, response ):
319 mastershipCheck = mastershipCheck and main.TRUE
320 else:
321 main.log.error( "Error, node " + node.ip_address + " is " +
322 "not in the list of controllers s" +
323 str( i ) + " is connecting to." )
324 mastershipCheck = main.FALSE
325 utilities.assert_equals(
326 expect=main.TRUE,
327 actual=mastershipCheck,
328 onpass="Switch mastership assigned correctly",
329 onfail="Switches not assigned correctly to controllers" )
330
331 def CASE21( self, main ):
332 """
333 Assign mastership to controllers
334 """
Jon Hall5cf14d52015-07-16 12:15:19 -0700335 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700336 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700337 assert main, "main not defined"
338 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700339 assert main.CLIs, "main.CLIs not defined"
340 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700341 assert ONOS1Port, "ONOS1Port not defined"
342 assert ONOS2Port, "ONOS2Port not defined"
343 assert ONOS3Port, "ONOS3Port not defined"
344 assert ONOS4Port, "ONOS4Port not defined"
345 assert ONOS5Port, "ONOS5Port not defined"
346 assert ONOS6Port, "ONOS6Port not defined"
347 assert ONOS7Port, "ONOS7Port not defined"
348
349 main.case( "Assigning Controller roles for switches" )
Jon Hall783bbf92015-07-23 14:33:19 -0700350 main.caseExplanation = "Check that ONOS is connected to each " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700351 "device. Then manually assign" +\
352 " mastership to specific ONOS nodes using" +\
353 " 'device-role'"
354 main.step( "Assign mastership of switches to specific controllers" )
355 # Manually assign mastership to the controller we want
356 roleCall = main.TRUE
357
358 ipList = [ ]
359 deviceList = []
360 try:
361 # Assign mastership to specific controllers. This assignment was
362 # determined for a 7 node cluser, but will work with any sized
363 # cluster
364 for i in range( 1, 29 ): # switches 1 through 28
365 # set up correct variables:
366 if i == 1:
367 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700368 ip = main.nodes[ c ].ip_address # ONOS1
Jon Hall5cf14d52015-07-16 12:15:19 -0700369 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
370 elif i == 2:
Jon Halle1a3b752015-07-22 13:02:46 -0700371 c = 1 % main.numCtrls
372 ip = main.nodes[ c ].ip_address # ONOS2
Jon Hall5cf14d52015-07-16 12:15:19 -0700373 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
374 elif i == 3:
Jon Halle1a3b752015-07-22 13:02:46 -0700375 c = 1 % main.numCtrls
376 ip = main.nodes[ c ].ip_address # ONOS2
Jon Hall5cf14d52015-07-16 12:15:19 -0700377 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
378 elif i == 4:
Jon Halle1a3b752015-07-22 13:02:46 -0700379 c = 3 % main.numCtrls
380 ip = main.nodes[ c ].ip_address # ONOS4
Jon Hall5cf14d52015-07-16 12:15:19 -0700381 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
382 elif i == 5:
Jon Halle1a3b752015-07-22 13:02:46 -0700383 c = 2 % main.numCtrls
384 ip = main.nodes[ c ].ip_address # ONOS3
Jon Hall5cf14d52015-07-16 12:15:19 -0700385 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
386 elif i == 6:
Jon Halle1a3b752015-07-22 13:02:46 -0700387 c = 2 % main.numCtrls
388 ip = main.nodes[ c ].ip_address # ONOS3
Jon Hall5cf14d52015-07-16 12:15:19 -0700389 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
390 elif i == 7:
Jon Halle1a3b752015-07-22 13:02:46 -0700391 c = 5 % main.numCtrls
392 ip = main.nodes[ c ].ip_address # ONOS6
Jon Hall5cf14d52015-07-16 12:15:19 -0700393 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
394 elif i >= 8 and i <= 17:
Jon Halle1a3b752015-07-22 13:02:46 -0700395 c = 4 % main.numCtrls
396 ip = main.nodes[ c ].ip_address # ONOS5
Jon Hall5cf14d52015-07-16 12:15:19 -0700397 dpid = '3' + str( i ).zfill( 3 )
398 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
399 elif i >= 18 and i <= 27:
Jon Halle1a3b752015-07-22 13:02:46 -0700400 c = 6 % main.numCtrls
401 ip = main.nodes[ c ].ip_address # ONOS7
Jon Hall5cf14d52015-07-16 12:15:19 -0700402 dpid = '6' + str( i ).zfill( 3 )
403 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
404 elif i == 28:
405 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700406 ip = main.nodes[ c ].ip_address # ONOS1
Jon Hall5cf14d52015-07-16 12:15:19 -0700407 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
408 else:
409 main.log.error( "You didn't write an else statement for " +
410 "switch s" + str( i ) )
411 roleCall = main.FALSE
412 # Assign switch
413 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
414 # TODO: make this controller dynamic
415 roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
416 ip )
417 ipList.append( ip )
418 deviceList.append( deviceId )
419 except ( AttributeError, AssertionError ):
420 main.log.exception( "Something is wrong with ONOS device view" )
421 main.log.info( main.ONOScli1.devices() )
422 utilities.assert_equals(
423 expect=main.TRUE,
424 actual=roleCall,
425 onpass="Re-assigned switch mastership to designated controller",
426 onfail="Something wrong with deviceRole calls" )
427
428 main.step( "Check mastership was correctly assigned" )
429 roleCheck = main.TRUE
430 # NOTE: This is due to the fact that device mastership change is not
431 # atomic and is actually a multi step process
432 time.sleep( 5 )
433 for i in range( len( ipList ) ):
434 ip = ipList[i]
435 deviceId = deviceList[i]
436 # Check assignment
437 master = main.ONOScli1.getRole( deviceId ).get( 'master' )
438 if ip in master:
439 roleCheck = roleCheck and main.TRUE
440 else:
441 roleCheck = roleCheck and main.FALSE
442 main.log.error( "Error, controller " + ip + " is not" +
443 " master " + "of device " +
444 str( deviceId ) + ". Master is " +
445 repr( master ) + "." )
446 utilities.assert_equals(
447 expect=main.TRUE,
448 actual=roleCheck,
449 onpass="Switches were successfully reassigned to designated " +
450 "controller",
451 onfail="Switches were not successfully reassigned" )
452
453 def CASE3( self, main ):
454 """
455 Assign intents
456 """
457 import time
458 import json
Jon Halle1a3b752015-07-22 13:02:46 -0700459 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700460 assert main, "main not defined"
461 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700462 assert main.CLIs, "main.CLIs not defined"
463 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700464 try:
465 labels
466 except NameError:
467 main.log.error( "labels not defined, setting to []" )
468 labels = []
469 try:
470 data
471 except NameError:
472 main.log.error( "data not defined, setting to []" )
473 data = []
474 # NOTE: we must reinstall intents until we have a persistant intent
475 # datastore!
476 main.case( "Adding host Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700477 main.caseExplanation = "Discover hosts by using pingall then " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700478 "assign predetermined host-to-host intents." +\
479 " After installation, check that the intent" +\
480 " is distributed to all nodes and the state" +\
481 " is INSTALLED"
482
483 # install onos-app-fwd
484 main.step( "Install reactive forwarding app" )
Jon Halle1a3b752015-07-22 13:02:46 -0700485 installResults = main.CLIs[0].activateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700486 utilities.assert_equals( expect=main.TRUE, actual=installResults,
487 onpass="Install fwd successful",
488 onfail="Install fwd failed" )
489
490 main.step( "Check app ids" )
491 appCheck = main.TRUE
492 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700493 for i in range( main.numCtrls ):
494 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700495 name="appToIDCheck-" + str( i ),
496 args=[] )
497 threads.append( t )
498 t.start()
499
500 for t in threads:
501 t.join()
502 appCheck = appCheck and t.result
503 if appCheck != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700504 main.log.warn( main.CLIs[0].apps() )
505 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700506 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
507 onpass="App Ids seem to be correct",
508 onfail="Something is wrong with app Ids" )
509
510 main.step( "Discovering Hosts( Via pingall for now )" )
511 # FIXME: Once we have a host discovery mechanism, use that instead
512 # REACTIVE FWD test
513 pingResult = main.FALSE
Jon Hall96091e62015-09-21 17:34:17 -0700514 passMsg = "Reactive Pingall test passed"
515 time1 = time.time()
516 pingResult = main.Mininet1.pingall()
517 time2 = time.time()
518 if not pingResult:
519 main.log.warn("First pingall failed. Trying again...")
Jon Hall5cf14d52015-07-16 12:15:19 -0700520 pingResult = main.Mininet1.pingall()
Jon Hall96091e62015-09-21 17:34:17 -0700521 passMsg += " on the second try"
522 utilities.assert_equals(
523 expect=main.TRUE,
524 actual=pingResult,
525 onpass= passMsg,
526 onfail="Reactive Pingall failed, " +
527 "one or more ping pairs failed" )
528 main.log.info( "Time for pingall: %2f seconds" %
529 ( time2 - time1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -0700530 # timeout for fwd flows
531 time.sleep( 11 )
532 # uninstall onos-app-fwd
533 main.step( "Uninstall reactive forwarding app" )
Jon Halle1a3b752015-07-22 13:02:46 -0700534 uninstallResult = main.CLIs[0].deactivateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700535 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
536 onpass="Uninstall fwd successful",
537 onfail="Uninstall fwd failed" )
538
539 main.step( "Check app ids" )
540 threads = []
541 appCheck2 = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700542 for i in range( main.numCtrls ):
543 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700544 name="appToIDCheck-" + str( i ),
545 args=[] )
546 threads.append( t )
547 t.start()
548
549 for t in threads:
550 t.join()
551 appCheck2 = appCheck2 and t.result
552 if appCheck2 != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700553 main.log.warn( main.CLIs[0].apps() )
554 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700555 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
556 onpass="App Ids seem to be correct",
557 onfail="Something is wrong with app Ids" )
558
559 main.step( "Add host intents via cli" )
560 intentIds = []
561 # TODO: move the host numbers to params
562 # Maybe look at all the paths we ping?
563 intentAddResult = True
564 hostResult = main.TRUE
565 for i in range( 8, 18 ):
566 main.log.info( "Adding host intent between h" + str( i ) +
567 " and h" + str( i + 10 ) )
568 host1 = "00:00:00:00:00:" + \
569 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
570 host2 = "00:00:00:00:00:" + \
571 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
572 # NOTE: getHost can return None
573 host1Dict = main.ONOScli1.getHost( host1 )
574 host2Dict = main.ONOScli1.getHost( host2 )
575 host1Id = None
576 host2Id = None
577 if host1Dict and host2Dict:
578 host1Id = host1Dict.get( 'id', None )
579 host2Id = host2Dict.get( 'id', None )
580 if host1Id and host2Id:
Jon Halle1a3b752015-07-22 13:02:46 -0700581 nodeNum = ( i % main.numCtrls )
582 tmpId = main.CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
Jon Hall5cf14d52015-07-16 12:15:19 -0700583 if tmpId:
584 main.log.info( "Added intent with id: " + tmpId )
585 intentIds.append( tmpId )
586 else:
587 main.log.error( "addHostIntent returned: " +
588 repr( tmpId ) )
589 else:
590 main.log.error( "Error, getHost() failed for h" + str( i ) +
591 " and/or h" + str( i + 10 ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700592 hosts = main.CLIs[ 0 ].hosts()
Jon Hall5cf14d52015-07-16 12:15:19 -0700593 main.log.warn( "Hosts output: " )
594 try:
595 main.log.warn( json.dumps( json.loads( hosts ),
596 sort_keys=True,
597 indent=4,
598 separators=( ',', ': ' ) ) )
599 except ( ValueError, TypeError ):
600 main.log.warn( repr( hosts ) )
601 hostResult = main.FALSE
602 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
603 onpass="Found a host id for each host",
604 onfail="Error looking up host ids" )
605
606 intentStart = time.time()
607 onosIds = main.ONOScli1.getAllIntentsId()
608 main.log.info( "Submitted intents: " + str( intentIds ) )
609 main.log.info( "Intents in ONOS: " + str( onosIds ) )
610 for intent in intentIds:
611 if intent in onosIds:
612 pass # intent submitted is in onos
613 else:
614 intentAddResult = False
615 if intentAddResult:
616 intentStop = time.time()
617 else:
618 intentStop = None
619 # Print the intent states
620 intents = main.ONOScli1.intents()
621 intentStates = []
622 installedCheck = True
623 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
624 count = 0
625 try:
626 for intent in json.loads( intents ):
627 state = intent.get( 'state', None )
628 if "INSTALLED" not in state:
629 installedCheck = False
630 intentId = intent.get( 'id', None )
631 intentStates.append( ( intentId, state ) )
632 except ( ValueError, TypeError ):
633 main.log.exception( "Error parsing intents" )
634 # add submitted intents not in the store
635 tmplist = [ i for i, s in intentStates ]
636 missingIntents = False
637 for i in intentIds:
638 if i not in tmplist:
639 intentStates.append( ( i, " - " ) )
640 missingIntents = True
641 intentStates.sort()
642 for i, s in intentStates:
643 count += 1
644 main.log.info( "%-6s%-15s%-15s" %
645 ( str( count ), str( i ), str( s ) ) )
646 leaders = main.ONOScli1.leaders()
647 try:
648 missing = False
649 if leaders:
650 parsedLeaders = json.loads( leaders )
651 main.log.warn( json.dumps( parsedLeaders,
652 sort_keys=True,
653 indent=4,
654 separators=( ',', ': ' ) ) )
655 # check for all intent partitions
656 topics = []
657 for i in range( 14 ):
658 topics.append( "intent-partition-" + str( i ) )
659 main.log.debug( topics )
660 ONOStopics = [ j['topic'] for j in parsedLeaders ]
661 for topic in topics:
662 if topic not in ONOStopics:
663 main.log.error( "Error: " + topic +
664 " not in leaders" )
665 missing = True
666 else:
667 main.log.error( "leaders() returned None" )
668 except ( ValueError, TypeError ):
669 main.log.exception( "Error parsing leaders" )
670 main.log.error( repr( leaders ) )
671 # Check all nodes
672 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -0700673 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700674 response = node.leaders( jsonFormat=False)
675 main.log.warn( str( node.name ) + " leaders output: \n" +
676 str( response ) )
677
678 partitions = main.ONOScli1.partitions()
679 try:
680 if partitions :
681 parsedPartitions = json.loads( partitions )
682 main.log.warn( json.dumps( parsedPartitions,
683 sort_keys=True,
684 indent=4,
685 separators=( ',', ': ' ) ) )
686 # TODO check for a leader in all paritions
687 # TODO check for consistency among nodes
688 else:
689 main.log.error( "partitions() returned None" )
690 except ( ValueError, TypeError ):
691 main.log.exception( "Error parsing partitions" )
692 main.log.error( repr( partitions ) )
693 pendingMap = main.ONOScli1.pendingMap()
694 try:
695 if pendingMap :
696 parsedPending = json.loads( pendingMap )
697 main.log.warn( json.dumps( parsedPending,
698 sort_keys=True,
699 indent=4,
700 separators=( ',', ': ' ) ) )
701 # TODO check something here?
702 else:
703 main.log.error( "pendingMap() returned None" )
704 except ( ValueError, TypeError ):
705 main.log.exception( "Error parsing pending map" )
706 main.log.error( repr( pendingMap ) )
707
708 intentAddResult = bool( intentAddResult and not missingIntents and
709 installedCheck )
710 if not intentAddResult:
711 main.log.error( "Error in pushing host intents to ONOS" )
712
713 main.step( "Intent Anti-Entropy dispersion" )
714 for i in range(100):
715 correct = True
716 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700717 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700718 onosIds = []
719 ids = cli.getAllIntentsId()
720 onosIds.append( ids )
721 main.log.debug( "Intents in " + cli.name + ": " +
722 str( sorted( onosIds ) ) )
723 if sorted( ids ) != sorted( intentIds ):
724 main.log.warn( "Set of intent IDs doesn't match" )
725 correct = False
726 break
727 else:
728 intents = json.loads( cli.intents() )
729 for intent in intents:
730 if intent[ 'state' ] != "INSTALLED":
731 main.log.warn( "Intent " + intent[ 'id' ] +
732 " is " + intent[ 'state' ] )
733 correct = False
734 break
735 if correct:
736 break
737 else:
738 time.sleep(1)
739 if not intentStop:
740 intentStop = time.time()
741 global gossipTime
742 gossipTime = intentStop - intentStart
743 main.log.info( "It took about " + str( gossipTime ) +
744 " seconds for all intents to appear in each node" )
745 append = False
746 title = "Gossip Intents"
747 count = 1
748 while append is False:
749 curTitle = title + str( count )
750 if curTitle not in labels:
751 labels.append( curTitle )
752 data.append( str( gossipTime ) )
753 append = True
754 else:
755 count += 1
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700756 gossipPeriod = int( main.params['timers']['gossip'] )
757 maxGossipTime = gossipPeriod * len( main.nodes )
Jon Hall5cf14d52015-07-16 12:15:19 -0700758 utilities.assert_greater_equals(
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700759 expect=maxGossipTime, actual=gossipTime,
Jon Hall5cf14d52015-07-16 12:15:19 -0700760 onpass="ECM anti-entropy for intents worked within " +
761 "expected time",
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700762 onfail="Intent ECM anti-entropy took too long. " +
763 "Expected time:{}, Actual time:{}".format( maxGossipTime,
764 gossipTime ) )
765 if gossipTime <= maxGossipTime:
Jon Hall5cf14d52015-07-16 12:15:19 -0700766 intentAddResult = True
767
768 if not intentAddResult or "key" in pendingMap:
769 import time
770 installedCheck = True
771 main.log.info( "Sleeping 60 seconds to see if intents are found" )
772 time.sleep( 60 )
773 onosIds = main.ONOScli1.getAllIntentsId()
774 main.log.info( "Submitted intents: " + str( intentIds ) )
775 main.log.info( "Intents in ONOS: " + str( onosIds ) )
776 # Print the intent states
777 intents = main.ONOScli1.intents()
778 intentStates = []
779 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
780 count = 0
781 try:
782 for intent in json.loads( intents ):
783 # Iter through intents of a node
784 state = intent.get( 'state', None )
785 if "INSTALLED" not in state:
786 installedCheck = False
787 intentId = intent.get( 'id', None )
788 intentStates.append( ( intentId, state ) )
789 except ( ValueError, TypeError ):
790 main.log.exception( "Error parsing intents" )
791 # add submitted intents not in the store
792 tmplist = [ i for i, s in intentStates ]
793 for i in intentIds:
794 if i not in tmplist:
795 intentStates.append( ( i, " - " ) )
796 intentStates.sort()
797 for i, s in intentStates:
798 count += 1
799 main.log.info( "%-6s%-15s%-15s" %
800 ( str( count ), str( i ), str( s ) ) )
801 leaders = main.ONOScli1.leaders()
802 try:
803 missing = False
804 if leaders:
805 parsedLeaders = json.loads( leaders )
806 main.log.warn( json.dumps( parsedLeaders,
807 sort_keys=True,
808 indent=4,
809 separators=( ',', ': ' ) ) )
810 # check for all intent partitions
811 # check for election
812 topics = []
813 for i in range( 14 ):
814 topics.append( "intent-partition-" + str( i ) )
815 # FIXME: this should only be after we start the app
816 topics.append( "org.onosproject.election" )
817 main.log.debug( topics )
818 ONOStopics = [ j['topic'] for j in parsedLeaders ]
819 for topic in topics:
820 if topic not in ONOStopics:
821 main.log.error( "Error: " + topic +
822 " not in leaders" )
823 missing = True
824 else:
825 main.log.error( "leaders() returned None" )
826 except ( ValueError, TypeError ):
827 main.log.exception( "Error parsing leaders" )
828 main.log.error( repr( leaders ) )
829 # Check all nodes
830 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -0700831 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700832 response = node.leaders( jsonFormat=False)
833 main.log.warn( str( node.name ) + " leaders output: \n" +
834 str( response ) )
835
836 partitions = main.ONOScli1.partitions()
837 try:
838 if partitions :
839 parsedPartitions = json.loads( partitions )
840 main.log.warn( json.dumps( parsedPartitions,
841 sort_keys=True,
842 indent=4,
843 separators=( ',', ': ' ) ) )
844 # TODO check for a leader in all paritions
845 # TODO check for consistency among nodes
846 else:
847 main.log.error( "partitions() returned None" )
848 except ( ValueError, TypeError ):
849 main.log.exception( "Error parsing partitions" )
850 main.log.error( repr( partitions ) )
851 pendingMap = main.ONOScli1.pendingMap()
852 try:
853 if pendingMap :
854 parsedPending = json.loads( pendingMap )
855 main.log.warn( json.dumps( parsedPending,
856 sort_keys=True,
857 indent=4,
858 separators=( ',', ': ' ) ) )
859 # TODO check something here?
860 else:
861 main.log.error( "pendingMap() returned None" )
862 except ( ValueError, TypeError ):
863 main.log.exception( "Error parsing pending map" )
864 main.log.error( repr( pendingMap ) )
865
866 def CASE4( self, main ):
867 """
868 Ping across added host intents
869 """
870 import json
871 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700872 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700873 assert main, "main not defined"
874 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700875 assert main.CLIs, "main.CLIs not defined"
876 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700877 main.case( "Verify connectivity by sendind traffic across Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700878 main.caseExplanation = "Ping across added host intents to check " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700879 "functionality and check the state of " +\
880 "the intent"
881 main.step( "Ping across added host intents" )
882 PingResult = main.TRUE
883 for i in range( 8, 18 ):
884 ping = main.Mininet1.pingHost( src="h" + str( i ),
885 target="h" + str( i + 10 ) )
886 PingResult = PingResult and ping
887 if ping == main.FALSE:
888 main.log.warn( "Ping failed between h" + str( i ) +
889 " and h" + str( i + 10 ) )
890 elif ping == main.TRUE:
891 main.log.info( "Ping test passed!" )
892 # Don't set PingResult or you'd override failures
893 if PingResult == main.FALSE:
894 main.log.error(
895 "Intents have not been installed correctly, pings failed." )
896 # TODO: pretty print
897 main.log.warn( "ONOS1 intents: " )
898 try:
899 tmpIntents = main.ONOScli1.intents()
900 main.log.warn( json.dumps( json.loads( tmpIntents ),
901 sort_keys=True,
902 indent=4,
903 separators=( ',', ': ' ) ) )
904 except ( ValueError, TypeError ):
905 main.log.warn( repr( tmpIntents ) )
906 utilities.assert_equals(
907 expect=main.TRUE,
908 actual=PingResult,
909 onpass="Intents have been installed correctly and pings work",
910 onfail="Intents have not been installed correctly, pings failed." )
911
912 main.step( "Check Intent state" )
913 installedCheck = False
914 loopCount = 0
915 while not installedCheck and loopCount < 40:
916 installedCheck = True
917 # Print the intent states
918 intents = main.ONOScli1.intents()
919 intentStates = []
920 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700921 count = 0
Jon Hall5cf14d52015-07-16 12:15:19 -0700922 # Iter through intents of a node
923 try:
924 for intent in json.loads( intents ):
925 state = intent.get( 'state', None )
926 if "INSTALLED" not in state:
927 installedCheck = False
928 intentId = intent.get( 'id', None )
929 intentStates.append( ( intentId, state ) )
930 except ( ValueError, TypeError ):
931 main.log.exception( "Error parsing intents." )
932 # Print states
933 intentStates.sort()
934 for i, s in intentStates:
935 count += 1
936 main.log.info( "%-6s%-15s%-15s" %
937 ( str( count ), str( i ), str( s ) ) )
938 if not installedCheck:
939 time.sleep( 1 )
940 loopCount += 1
941 utilities.assert_equals( expect=True, actual=installedCheck,
942 onpass="Intents are all INSTALLED",
943 onfail="Intents are not all in " +
944 "INSTALLED state" )
945
946 main.step( "Check leadership of topics" )
947 leaders = main.ONOScli1.leaders()
948 topicCheck = main.TRUE
949 try:
950 if leaders:
951 parsedLeaders = json.loads( leaders )
952 main.log.warn( json.dumps( parsedLeaders,
953 sort_keys=True,
954 indent=4,
955 separators=( ',', ': ' ) ) )
956 # check for all intent partitions
957 # check for election
958 # TODO: Look at Devices as topics now that it uses this system
959 topics = []
960 for i in range( 14 ):
961 topics.append( "intent-partition-" + str( i ) )
962 # FIXME: this should only be after we start the app
963 # FIXME: topics.append( "org.onosproject.election" )
964 # Print leaders output
965 main.log.debug( topics )
966 ONOStopics = [ j['topic'] for j in parsedLeaders ]
967 for topic in topics:
968 if topic not in ONOStopics:
969 main.log.error( "Error: " + topic +
970 " not in leaders" )
971 topicCheck = main.FALSE
972 else:
973 main.log.error( "leaders() returned None" )
974 topicCheck = main.FALSE
975 except ( ValueError, TypeError ):
976 topicCheck = main.FALSE
977 main.log.exception( "Error parsing leaders" )
978 main.log.error( repr( leaders ) )
979 # TODO: Check for a leader of these topics
980 # Check all nodes
981 if topicCheck:
Jon Halle1a3b752015-07-22 13:02:46 -0700982 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700983 response = node.leaders( jsonFormat=False)
984 main.log.warn( str( node.name ) + " leaders output: \n" +
985 str( response ) )
986
987 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
988 onpass="intent Partitions is in leaders",
989 onfail="Some topics were lost " )
990 # Print partitions
991 partitions = main.ONOScli1.partitions()
992 try:
993 if partitions :
994 parsedPartitions = json.loads( partitions )
995 main.log.warn( json.dumps( parsedPartitions,
996 sort_keys=True,
997 indent=4,
998 separators=( ',', ': ' ) ) )
999 # TODO check for a leader in all paritions
1000 # TODO check for consistency among nodes
1001 else:
1002 main.log.error( "partitions() returned None" )
1003 except ( ValueError, TypeError ):
1004 main.log.exception( "Error parsing partitions" )
1005 main.log.error( repr( partitions ) )
1006 # Print Pending Map
1007 pendingMap = main.ONOScli1.pendingMap()
1008 try:
1009 if pendingMap :
1010 parsedPending = json.loads( pendingMap )
1011 main.log.warn( json.dumps( parsedPending,
1012 sort_keys=True,
1013 indent=4,
1014 separators=( ',', ': ' ) ) )
1015 # TODO check something here?
1016 else:
1017 main.log.error( "pendingMap() returned None" )
1018 except ( ValueError, TypeError ):
1019 main.log.exception( "Error parsing pending map" )
1020 main.log.error( repr( pendingMap ) )
1021
1022 if not installedCheck:
1023 main.log.info( "Waiting 60 seconds to see if the state of " +
1024 "intents change" )
1025 time.sleep( 60 )
1026 # Print the intent states
1027 intents = main.ONOScli1.intents()
1028 intentStates = []
1029 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
1030 count = 0
1031 # Iter through intents of a node
1032 try:
1033 for intent in json.loads( intents ):
1034 state = intent.get( 'state', None )
1035 if "INSTALLED" not in state:
1036 installedCheck = False
1037 intentId = intent.get( 'id', None )
1038 intentStates.append( ( intentId, state ) )
1039 except ( ValueError, TypeError ):
1040 main.log.exception( "Error parsing intents." )
1041 intentStates.sort()
1042 for i, s in intentStates:
1043 count += 1
1044 main.log.info( "%-6s%-15s%-15s" %
1045 ( str( count ), str( i ), str( s ) ) )
1046 leaders = main.ONOScli1.leaders()
1047 try:
1048 missing = False
1049 if leaders:
1050 parsedLeaders = json.loads( leaders )
1051 main.log.warn( json.dumps( parsedLeaders,
1052 sort_keys=True,
1053 indent=4,
1054 separators=( ',', ': ' ) ) )
1055 # check for all intent partitions
1056 # check for election
1057 topics = []
1058 for i in range( 14 ):
1059 topics.append( "intent-partition-" + str( i ) )
1060 # FIXME: this should only be after we start the app
1061 topics.append( "org.onosproject.election" )
1062 main.log.debug( topics )
1063 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1064 for topic in topics:
1065 if topic not in ONOStopics:
1066 main.log.error( "Error: " + topic +
1067 " not in leaders" )
1068 missing = True
1069 else:
1070 main.log.error( "leaders() returned None" )
1071 except ( ValueError, TypeError ):
1072 main.log.exception( "Error parsing leaders" )
1073 main.log.error( repr( leaders ) )
1074 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -07001075 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07001076 response = node.leaders( jsonFormat=False)
1077 main.log.warn( str( node.name ) + " leaders output: \n" +
1078 str( response ) )
1079
1080 partitions = main.ONOScli1.partitions()
1081 try:
1082 if partitions :
1083 parsedPartitions = json.loads( partitions )
1084 main.log.warn( json.dumps( parsedPartitions,
1085 sort_keys=True,
1086 indent=4,
1087 separators=( ',', ': ' ) ) )
1088 # TODO check for a leader in all paritions
1089 # TODO check for consistency among nodes
1090 else:
1091 main.log.error( "partitions() returned None" )
1092 except ( ValueError, TypeError ):
1093 main.log.exception( "Error parsing partitions" )
1094 main.log.error( repr( partitions ) )
1095 pendingMap = main.ONOScli1.pendingMap()
1096 try:
1097 if pendingMap :
1098 parsedPending = json.loads( pendingMap )
1099 main.log.warn( json.dumps( parsedPending,
1100 sort_keys=True,
1101 indent=4,
1102 separators=( ',', ': ' ) ) )
1103 # TODO check something here?
1104 else:
1105 main.log.error( "pendingMap() returned None" )
1106 except ( ValueError, TypeError ):
1107 main.log.exception( "Error parsing pending map" )
1108 main.log.error( repr( pendingMap ) )
1109 # Print flowrules
Jon Halle1a3b752015-07-22 13:02:46 -07001110 main.log.debug( main.CLIs[0].flows( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001111 main.step( "Wait a minute then ping again" )
1112 # the wait is above
1113 PingResult = main.TRUE
1114 for i in range( 8, 18 ):
1115 ping = main.Mininet1.pingHost( src="h" + str( i ),
1116 target="h" + str( i + 10 ) )
1117 PingResult = PingResult and ping
1118 if ping == main.FALSE:
1119 main.log.warn( "Ping failed between h" + str( i ) +
1120 " and h" + str( i + 10 ) )
1121 elif ping == main.TRUE:
1122 main.log.info( "Ping test passed!" )
1123 # Don't set PingResult or you'd override failures
1124 if PingResult == main.FALSE:
1125 main.log.error(
1126 "Intents have not been installed correctly, pings failed." )
1127 # TODO: pretty print
1128 main.log.warn( "ONOS1 intents: " )
1129 try:
1130 tmpIntents = main.ONOScli1.intents()
1131 main.log.warn( json.dumps( json.loads( tmpIntents ),
1132 sort_keys=True,
1133 indent=4,
1134 separators=( ',', ': ' ) ) )
1135 except ( ValueError, TypeError ):
1136 main.log.warn( repr( tmpIntents ) )
1137 utilities.assert_equals(
1138 expect=main.TRUE,
1139 actual=PingResult,
1140 onpass="Intents have been installed correctly and pings work",
1141 onfail="Intents have not been installed correctly, pings failed." )
1142
1143 def CASE5( self, main ):
1144 """
1145 Reading state of ONOS
1146 """
1147 import json
1148 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001149 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001150 assert main, "main not defined"
1151 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001152 assert main.CLIs, "main.CLIs not defined"
1153 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001154
1155 main.case( "Setting up and gathering data for current state" )
1156 # The general idea for this test case is to pull the state of
1157 # ( intents,flows, topology,... ) from each ONOS node
1158 # We can then compare them with each other and also with past states
1159
1160 main.step( "Check that each switch has a master" )
1161 global mastershipState
1162 mastershipState = '[]'
1163
1164 # Assert that each device has a master
1165 rolesNotNull = main.TRUE
1166 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001167 for i in range( main.numCtrls ):
1168 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001169 name="rolesNotNull-" + str( i ),
1170 args=[] )
1171 threads.append( t )
1172 t.start()
1173
1174 for t in threads:
1175 t.join()
1176 rolesNotNull = rolesNotNull and t.result
1177 utilities.assert_equals(
1178 expect=main.TRUE,
1179 actual=rolesNotNull,
1180 onpass="Each device has a master",
1181 onfail="Some devices don't have a master assigned" )
1182
1183 main.step( "Get the Mastership of each switch from each controller" )
1184 ONOSMastership = []
1185 mastershipCheck = main.FALSE
1186 consistentMastership = True
1187 rolesResults = True
1188 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001189 for i in range( main.numCtrls ):
1190 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001191 name="roles-" + str( i ),
1192 args=[] )
1193 threads.append( t )
1194 t.start()
1195
1196 for t in threads:
1197 t.join()
1198 ONOSMastership.append( t.result )
1199
Jon Halle1a3b752015-07-22 13:02:46 -07001200 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001201 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1202 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1203 " roles" )
1204 main.log.warn(
1205 "ONOS" + str( i + 1 ) + " mastership response: " +
1206 repr( ONOSMastership[i] ) )
1207 rolesResults = False
1208 utilities.assert_equals(
1209 expect=True,
1210 actual=rolesResults,
1211 onpass="No error in reading roles output",
1212 onfail="Error in reading roles from ONOS" )
1213
1214 main.step( "Check for consistency in roles from each controller" )
1215 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1216 main.log.info(
1217 "Switch roles are consistent across all ONOS nodes" )
1218 else:
1219 consistentMastership = False
1220 utilities.assert_equals(
1221 expect=True,
1222 actual=consistentMastership,
1223 onpass="Switch roles are consistent across all ONOS nodes",
1224 onfail="ONOS nodes have different views of switch roles" )
1225
1226 if rolesResults and not consistentMastership:
Jon Halle1a3b752015-07-22 13:02:46 -07001227 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001228 try:
1229 main.log.warn(
1230 "ONOS" + str( i + 1 ) + " roles: ",
1231 json.dumps(
1232 json.loads( ONOSMastership[ i ] ),
1233 sort_keys=True,
1234 indent=4,
1235 separators=( ',', ': ' ) ) )
1236 except ( ValueError, TypeError ):
1237 main.log.warn( repr( ONOSMastership[ i ] ) )
1238 elif rolesResults and consistentMastership:
1239 mastershipCheck = main.TRUE
1240 mastershipState = ONOSMastership[ 0 ]
1241
1242 main.step( "Get the intents from each controller" )
1243 global intentState
1244 intentState = []
1245 ONOSIntents = []
1246 intentCheck = main.FALSE
1247 consistentIntents = True
1248 intentsResults = True
1249 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001250 for i in range( main.numCtrls ):
1251 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001252 name="intents-" + str( i ),
1253 args=[],
1254 kwargs={ 'jsonFormat': True } )
1255 threads.append( t )
1256 t.start()
1257
1258 for t in threads:
1259 t.join()
1260 ONOSIntents.append( t.result )
1261
Jon Halle1a3b752015-07-22 13:02:46 -07001262 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001263 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1264 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1265 " intents" )
1266 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1267 repr( ONOSIntents[ i ] ) )
1268 intentsResults = False
1269 utilities.assert_equals(
1270 expect=True,
1271 actual=intentsResults,
1272 onpass="No error in reading intents output",
1273 onfail="Error in reading intents from ONOS" )
1274
1275 main.step( "Check for consistency in Intents from each controller" )
1276 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1277 main.log.info( "Intents are consistent across all ONOS " +
1278 "nodes" )
1279 else:
1280 consistentIntents = False
1281 main.log.error( "Intents not consistent" )
1282 utilities.assert_equals(
1283 expect=True,
1284 actual=consistentIntents,
1285 onpass="Intents are consistent across all ONOS nodes",
1286 onfail="ONOS nodes have different views of intents" )
1287
1288 if intentsResults:
1289 # Try to make it easy to figure out what is happening
1290 #
1291 # Intent ONOS1 ONOS2 ...
1292 # 0x01 INSTALLED INSTALLING
1293 # ... ... ...
1294 # ... ... ...
1295 title = " Id"
Jon Halle1a3b752015-07-22 13:02:46 -07001296 for n in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001297 title += " " * 10 + "ONOS" + str( n + 1 )
1298 main.log.warn( title )
1299 # get all intent keys in the cluster
1300 keys = []
1301 for nodeStr in ONOSIntents:
1302 node = json.loads( nodeStr )
1303 for intent in node:
1304 keys.append( intent.get( 'id' ) )
1305 keys = set( keys )
1306 for key in keys:
1307 row = "%-13s" % key
1308 for nodeStr in ONOSIntents:
1309 node = json.loads( nodeStr )
1310 for intent in node:
1311 if intent.get( 'id', "Error" ) == key:
1312 row += "%-15s" % intent.get( 'state' )
1313 main.log.warn( row )
1314 # End table view
1315
1316 if intentsResults and not consistentIntents:
1317 # print the json objects
1318 n = len(ONOSIntents)
1319 main.log.debug( "ONOS" + str( n ) + " intents: " )
1320 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1321 sort_keys=True,
1322 indent=4,
1323 separators=( ',', ': ' ) ) )
Jon Halle1a3b752015-07-22 13:02:46 -07001324 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001325 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
1326 main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
1327 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1328 sort_keys=True,
1329 indent=4,
1330 separators=( ',', ': ' ) ) )
1331 else:
Jon Halle1a3b752015-07-22 13:02:46 -07001332 main.log.debug( main.nodes[ i ].name + " intents match ONOS" +
Jon Hall5cf14d52015-07-16 12:15:19 -07001333 str( n ) + " intents" )
1334 elif intentsResults and consistentIntents:
1335 intentCheck = main.TRUE
1336 intentState = ONOSIntents[ 0 ]
1337
1338 main.step( "Get the flows from each controller" )
1339 global flowState
1340 flowState = []
1341 ONOSFlows = []
1342 ONOSFlowsJson = []
1343 flowCheck = main.FALSE
1344 consistentFlows = True
1345 flowsResults = True
1346 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001347 for i in range( main.numCtrls ):
1348 t = main.Thread( target=main.CLIs[i].flows,
Jon Hall5cf14d52015-07-16 12:15:19 -07001349 name="flows-" + str( i ),
1350 args=[],
1351 kwargs={ 'jsonFormat': True } )
1352 threads.append( t )
1353 t.start()
1354
1355 # NOTE: Flows command can take some time to run
1356 time.sleep(30)
1357 for t in threads:
1358 t.join()
1359 result = t.result
1360 ONOSFlows.append( result )
1361
Jon Halle1a3b752015-07-22 13:02:46 -07001362 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001363 num = str( i + 1 )
1364 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1365 main.log.error( "Error in getting ONOS" + num + " flows" )
1366 main.log.warn( "ONOS" + num + " flows response: " +
1367 repr( ONOSFlows[ i ] ) )
1368 flowsResults = False
1369 ONOSFlowsJson.append( None )
1370 else:
1371 try:
1372 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1373 except ( ValueError, TypeError ):
1374 # FIXME: change this to log.error?
1375 main.log.exception( "Error in parsing ONOS" + num +
1376 " response as json." )
1377 main.log.error( repr( ONOSFlows[ i ] ) )
1378 ONOSFlowsJson.append( None )
1379 flowsResults = False
1380 utilities.assert_equals(
1381 expect=True,
1382 actual=flowsResults,
1383 onpass="No error in reading flows output",
1384 onfail="Error in reading flows from ONOS" )
1385
1386 main.step( "Check for consistency in Flows from each controller" )
1387 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1388 if all( tmp ):
1389 main.log.info( "Flow count is consistent across all ONOS nodes" )
1390 else:
1391 consistentFlows = False
1392 utilities.assert_equals(
1393 expect=True,
1394 actual=consistentFlows,
1395 onpass="The flow count is consistent across all ONOS nodes",
1396 onfail="ONOS nodes have different flow counts" )
1397
1398 if flowsResults and not consistentFlows:
Jon Halle1a3b752015-07-22 13:02:46 -07001399 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001400 try:
1401 main.log.warn(
1402 "ONOS" + str( i + 1 ) + " flows: " +
1403 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1404 indent=4, separators=( ',', ': ' ) ) )
1405 except ( ValueError, TypeError ):
1406 main.log.warn(
1407 "ONOS" + str( i + 1 ) + " flows: " +
1408 repr( ONOSFlows[ i ] ) )
1409 elif flowsResults and consistentFlows:
1410 flowCheck = main.TRUE
1411 flowState = ONOSFlows[ 0 ]
1412
1413 main.step( "Get the OF Table entries" )
1414 global flows
1415 flows = []
1416 for i in range( 1, 29 ):
Jon Hallca7ac292015-11-11 09:28:12 -08001417 flows.append( main.Mininet1.getFlowTable( "s" + str( i ), version="1.3" ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001418 if flowCheck == main.FALSE:
1419 for table in flows:
1420 main.log.warn( table )
1421 # TODO: Compare switch flow tables with ONOS flow tables
1422
1423 main.step( "Start continuous pings" )
1424 main.Mininet2.pingLong(
1425 src=main.params[ 'PING' ][ 'source1' ],
1426 target=main.params[ 'PING' ][ 'target1' ],
1427 pingTime=500 )
1428 main.Mininet2.pingLong(
1429 src=main.params[ 'PING' ][ 'source2' ],
1430 target=main.params[ 'PING' ][ 'target2' ],
1431 pingTime=500 )
1432 main.Mininet2.pingLong(
1433 src=main.params[ 'PING' ][ 'source3' ],
1434 target=main.params[ 'PING' ][ 'target3' ],
1435 pingTime=500 )
1436 main.Mininet2.pingLong(
1437 src=main.params[ 'PING' ][ 'source4' ],
1438 target=main.params[ 'PING' ][ 'target4' ],
1439 pingTime=500 )
1440 main.Mininet2.pingLong(
1441 src=main.params[ 'PING' ][ 'source5' ],
1442 target=main.params[ 'PING' ][ 'target5' ],
1443 pingTime=500 )
1444 main.Mininet2.pingLong(
1445 src=main.params[ 'PING' ][ 'source6' ],
1446 target=main.params[ 'PING' ][ 'target6' ],
1447 pingTime=500 )
1448 main.Mininet2.pingLong(
1449 src=main.params[ 'PING' ][ 'source7' ],
1450 target=main.params[ 'PING' ][ 'target7' ],
1451 pingTime=500 )
1452 main.Mininet2.pingLong(
1453 src=main.params[ 'PING' ][ 'source8' ],
1454 target=main.params[ 'PING' ][ 'target8' ],
1455 pingTime=500 )
1456 main.Mininet2.pingLong(
1457 src=main.params[ 'PING' ][ 'source9' ],
1458 target=main.params[ 'PING' ][ 'target9' ],
1459 pingTime=500 )
1460 main.Mininet2.pingLong(
1461 src=main.params[ 'PING' ][ 'source10' ],
1462 target=main.params[ 'PING' ][ 'target10' ],
1463 pingTime=500 )
1464
1465 main.step( "Collecting topology information from ONOS" )
1466 devices = []
1467 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001468 for i in range( main.numCtrls ):
1469 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07001470 name="devices-" + str( i ),
1471 args=[ ] )
1472 threads.append( t )
1473 t.start()
1474
1475 for t in threads:
1476 t.join()
1477 devices.append( t.result )
1478 hosts = []
1479 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001480 for i in range( main.numCtrls ):
1481 t = main.Thread( target=main.CLIs[i].hosts,
Jon Hall5cf14d52015-07-16 12:15:19 -07001482 name="hosts-" + str( i ),
1483 args=[ ] )
1484 threads.append( t )
1485 t.start()
1486
1487 for t in threads:
1488 t.join()
1489 try:
1490 hosts.append( json.loads( t.result ) )
1491 except ( ValueError, TypeError ):
1492 # FIXME: better handling of this, print which node
1493 # Maybe use thread name?
1494 main.log.exception( "Error parsing json output of hosts" )
Jon Hall3afe4c92015-12-14 19:30:38 -08001495 main.log.warn( repr( t.result ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001496 hosts.append( None )
1497
1498 ports = []
1499 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001500 for i in range( main.numCtrls ):
1501 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07001502 name="ports-" + str( i ),
1503 args=[ ] )
1504 threads.append( t )
1505 t.start()
1506
1507 for t in threads:
1508 t.join()
1509 ports.append( t.result )
1510 links = []
1511 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001512 for i in range( main.numCtrls ):
1513 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07001514 name="links-" + str( i ),
1515 args=[ ] )
1516 threads.append( t )
1517 t.start()
1518
1519 for t in threads:
1520 t.join()
1521 links.append( t.result )
1522 clusters = []
1523 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001524 for i in range( main.numCtrls ):
1525 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07001526 name="clusters-" + str( i ),
1527 args=[ ] )
1528 threads.append( t )
1529 t.start()
1530
1531 for t in threads:
1532 t.join()
1533 clusters.append( t.result )
1534 # Compare json objects for hosts and dataplane clusters
1535
1536 # hosts
1537 main.step( "Host view is consistent across ONOS nodes" )
1538 consistentHostsResult = main.TRUE
1539 for controller in range( len( hosts ) ):
1540 controllerStr = str( controller + 1 )
Jon Hall3afe4c92015-12-14 19:30:38 -08001541 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001542 if hosts[ controller ] == hosts[ 0 ]:
1543 continue
1544 else: # hosts not consistent
1545 main.log.error( "hosts from ONOS" +
1546 controllerStr +
1547 " is inconsistent with ONOS1" )
1548 main.log.warn( repr( hosts[ controller ] ) )
1549 consistentHostsResult = main.FALSE
1550
1551 else:
1552 main.log.error( "Error in getting ONOS hosts from ONOS" +
1553 controllerStr )
1554 consistentHostsResult = main.FALSE
1555 main.log.warn( "ONOS" + controllerStr +
1556 " hosts response: " +
1557 repr( hosts[ controller ] ) )
1558 utilities.assert_equals(
1559 expect=main.TRUE,
1560 actual=consistentHostsResult,
1561 onpass="Hosts view is consistent across all ONOS nodes",
1562 onfail="ONOS nodes have different views of hosts" )
1563
1564 main.step( "Each host has an IP address" )
1565 ipResult = main.TRUE
1566 for controller in range( 0, len( hosts ) ):
1567 controllerStr = str( controller + 1 )
Jon Hall3afe4c92015-12-14 19:30:38 -08001568 if hosts[ controller ]:
1569 for host in hosts[ controller ]:
1570 if not host.get( 'ipAddresses', [ ] ):
Jon Hallf3d16e72015-12-16 17:45:08 -08001571 main.log.error( "Error with host ips on controller" +
Jon Hall3afe4c92015-12-14 19:30:38 -08001572 controllerStr + ": " + str( host ) )
1573 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07001574 utilities.assert_equals(
1575 expect=main.TRUE,
1576 actual=ipResult,
1577 onpass="The ips of the hosts aren't empty",
1578 onfail="The ip of at least one host is missing" )
1579
1580 # Strongly connected clusters of devices
1581 main.step( "Cluster view is consistent across ONOS nodes" )
1582 consistentClustersResult = main.TRUE
1583 for controller in range( len( clusters ) ):
1584 controllerStr = str( controller + 1 )
1585 if "Error" not in clusters[ controller ]:
1586 if clusters[ controller ] == clusters[ 0 ]:
1587 continue
1588 else: # clusters not consistent
1589 main.log.error( "clusters from ONOS" + controllerStr +
1590 " is inconsistent with ONOS1" )
1591 consistentClustersResult = main.FALSE
1592
1593 else:
1594 main.log.error( "Error in getting dataplane clusters " +
1595 "from ONOS" + controllerStr )
1596 consistentClustersResult = main.FALSE
1597 main.log.warn( "ONOS" + controllerStr +
1598 " clusters response: " +
1599 repr( clusters[ controller ] ) )
1600 utilities.assert_equals(
1601 expect=main.TRUE,
1602 actual=consistentClustersResult,
1603 onpass="Clusters view is consistent across all ONOS nodes",
1604 onfail="ONOS nodes have different views of clusters" )
1605 # there should always only be one cluster
1606 main.step( "Cluster view correct across ONOS nodes" )
1607 try:
1608 numClusters = len( json.loads( clusters[ 0 ] ) )
1609 except ( ValueError, TypeError ):
1610 main.log.exception( "Error parsing clusters[0]: " +
1611 repr( clusters[ 0 ] ) )
1612 clusterResults = main.FALSE
1613 if numClusters == 1:
1614 clusterResults = main.TRUE
1615 utilities.assert_equals(
1616 expect=1,
1617 actual=numClusters,
1618 onpass="ONOS shows 1 SCC",
1619 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1620
1621 main.step( "Comparing ONOS topology to MN" )
1622 devicesResults = main.TRUE
1623 linksResults = main.TRUE
1624 hostsResults = main.TRUE
1625 mnSwitches = main.Mininet1.getSwitches()
1626 mnLinks = main.Mininet1.getLinks()
1627 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07001628 for controller in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001629 controllerStr = str( controller + 1 )
1630 if devices[ controller ] and ports[ controller ] and\
1631 "Error" not in devices[ controller ] and\
1632 "Error" not in ports[ controller ]:
Jon Halle1a3b752015-07-22 13:02:46 -07001633 currentDevicesResult = main.Mininet1.compareSwitches(
1634 mnSwitches,
1635 json.loads( devices[ controller ] ),
1636 json.loads( ports[ controller ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001637 else:
1638 currentDevicesResult = main.FALSE
1639 utilities.assert_equals( expect=main.TRUE,
1640 actual=currentDevicesResult,
1641 onpass="ONOS" + controllerStr +
1642 " Switches view is correct",
1643 onfail="ONOS" + controllerStr +
1644 " Switches view is incorrect" )
1645 if links[ controller ] and "Error" not in links[ controller ]:
1646 currentLinksResult = main.Mininet1.compareLinks(
1647 mnSwitches, mnLinks,
1648 json.loads( links[ controller ] ) )
1649 else:
1650 currentLinksResult = main.FALSE
1651 utilities.assert_equals( expect=main.TRUE,
1652 actual=currentLinksResult,
1653 onpass="ONOS" + controllerStr +
1654 " links view is correct",
1655 onfail="ONOS" + controllerStr +
1656 " links view is incorrect" )
1657
Jon Hall657cdf62015-12-17 14:40:51 -08001658 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001659 currentHostsResult = main.Mininet1.compareHosts(
1660 mnHosts,
1661 hosts[ controller ] )
1662 else:
1663 currentHostsResult = main.FALSE
1664 utilities.assert_equals( expect=main.TRUE,
1665 actual=currentHostsResult,
1666 onpass="ONOS" + controllerStr +
1667 " hosts exist in Mininet",
1668 onfail="ONOS" + controllerStr +
1669 " hosts don't match Mininet" )
1670
1671 devicesResults = devicesResults and currentDevicesResult
1672 linksResults = linksResults and currentLinksResult
1673 hostsResults = hostsResults and currentHostsResult
1674
1675 main.step( "Device information is correct" )
1676 utilities.assert_equals(
1677 expect=main.TRUE,
1678 actual=devicesResults,
1679 onpass="Device information is correct",
1680 onfail="Device information is incorrect" )
1681
1682 main.step( "Links are correct" )
1683 utilities.assert_equals(
1684 expect=main.TRUE,
1685 actual=linksResults,
1686 onpass="Link are correct",
1687 onfail="Links are incorrect" )
1688
1689 main.step( "Hosts are correct" )
1690 utilities.assert_equals(
1691 expect=main.TRUE,
1692 actual=hostsResults,
1693 onpass="Hosts are correct",
1694 onfail="Hosts are incorrect" )
1695
1696 def CASE6( self, main ):
1697 """
1698 The Failure case.
1699 """
1700 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001701 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001702 assert main, "main not defined"
1703 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001704 assert main.CLIs, "main.CLIs not defined"
1705 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001706 try:
1707 labels
1708 except NameError:
1709 main.log.error( "labels not defined, setting to []" )
1710 global labels
1711 labels = []
1712 try:
1713 data
1714 except NameError:
1715 main.log.error( "data not defined, setting to []" )
1716 global data
1717 data = []
1718 # Reset non-persistent variables
1719 try:
1720 iCounterValue = 0
1721 except NameError:
1722 main.log.error( "iCounterValue not defined, setting to 0" )
1723 iCounterValue = 0
1724
1725 main.case( "Restart entire ONOS cluster" )
1726
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001727 main.step( "Checking ONOS Logs for errors" )
1728 for node in main.nodes:
1729 main.log.debug( "Checking logs for errors on " + node.name + ":" )
1730 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
1731
Jon Hall5cf14d52015-07-16 12:15:19 -07001732 main.step( "Killing ONOS nodes" )
1733 killResults = main.TRUE
1734 killTime = time.time()
Jon Halle1a3b752015-07-22 13:02:46 -07001735 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001736 killed = main.ONOSbench.onosKill( node.ip_address )
1737 killResults = killResults and killed
1738 utilities.assert_equals( expect=main.TRUE, actual=killResults,
1739 onpass="ONOS nodes killed",
1740 onfail="ONOS kill unsuccessful" )
1741
1742 main.step( "Checking if ONOS is up yet" )
1743 for i in range( 2 ):
1744 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001745 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001746 started = main.ONOSbench.isup( node.ip_address )
1747 if not started:
1748 main.log.error( node.name + " didn't start!" )
1749 onosIsupResult = onosIsupResult and started
1750 if onosIsupResult == main.TRUE:
1751 break
1752 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1753 onpass="ONOS restarted",
1754 onfail="ONOS restart NOT successful" )
1755
1756 main.log.step( "Starting ONOS CLI sessions" )
1757 cliResults = main.TRUE
1758 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001759 for i in range( main.numCtrls ):
1760 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -07001761 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -07001762 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -07001763 threads.append( t )
1764 t.start()
1765
1766 for t in threads:
1767 t.join()
1768 cliResults = cliResults and t.result
1769 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1770 onpass="ONOS cli started",
1771 onfail="ONOS clis did not restart" )
1772
1773 # Grab the time of restart so we chan check how long the gossip
1774 # protocol has had time to work
1775 main.restartTime = time.time() - killTime
1776 main.log.debug( "Restart time: " + str( main.restartTime ) )
1777 labels.append( "Restart" )
1778 data.append( str( main.restartTime ) )
1779
1780 # FIXME: revisit test plan for election with madan
1781 # Rerun for election on restarted nodes
1782 runResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001783 for cli in main.CLIs:
1784 run = main.CLIs[0].electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07001785 if run != main.TRUE:
1786 main.log.error( "Error running for election on " + cli.name )
1787 runResults = runResults and run
1788 utilities.assert_equals( expect=main.TRUE, actual=runResults,
1789 onpass="Reran for election",
1790 onfail="Failed to rerun for election" )
1791
1792 # TODO: Make this configurable
1793 time.sleep( 60 )
Jon Halle1a3b752015-07-22 13:02:46 -07001794 main.log.debug( main.CLIs[0].nodes( jsonFormat=False ) )
1795 main.log.debug( main.CLIs[0].leaders( jsonFormat=False ) )
1796 main.log.debug( main.CLIs[0].partitions( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001797
1798 def CASE7( self, main ):
1799 """
1800 Check state after ONOS failure
1801 """
1802 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001803 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001804 assert main, "main not defined"
1805 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001806 assert main.CLIs, "main.CLIs not defined"
1807 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001808 main.case( "Running ONOS Constant State Tests" )
1809
1810 main.step( "Check that each switch has a master" )
1811 # Assert that each device has a master
1812 rolesNotNull = main.TRUE
1813 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001814 for i in range( main.numCtrls ):
1815 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001816 name="rolesNotNull-" + str( i ),
1817 args=[ ] )
1818 threads.append( t )
1819 t.start()
1820
1821 for t in threads:
1822 t.join()
1823 rolesNotNull = rolesNotNull and t.result
1824 utilities.assert_equals(
1825 expect=main.TRUE,
1826 actual=rolesNotNull,
1827 onpass="Each device has a master",
1828 onfail="Some devices don't have a master assigned" )
1829
1830 main.step( "Read device roles from ONOS" )
1831 ONOSMastership = []
1832 mastershipCheck = main.FALSE
1833 consistentMastership = True
1834 rolesResults = True
1835 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001836 for i in range( main.numCtrls ):
1837 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001838 name="roles-" + str( i ),
1839 args=[] )
1840 threads.append( t )
1841 t.start()
1842
1843 for t in threads:
1844 t.join()
1845 ONOSMastership.append( t.result )
1846
Jon Halle1a3b752015-07-22 13:02:46 -07001847 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001848 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1849 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1850 " roles" )
1851 main.log.warn(
1852 "ONOS" + str( i + 1 ) + " mastership response: " +
1853 repr( ONOSMastership[i] ) )
1854 rolesResults = False
1855 utilities.assert_equals(
1856 expect=True,
1857 actual=rolesResults,
1858 onpass="No error in reading roles output",
1859 onfail="Error in reading roles from ONOS" )
1860
1861 main.step( "Check for consistency in roles from each controller" )
1862 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1863 main.log.info(
1864 "Switch roles are consistent across all ONOS nodes" )
1865 else:
1866 consistentMastership = False
1867 utilities.assert_equals(
1868 expect=True,
1869 actual=consistentMastership,
1870 onpass="Switch roles are consistent across all ONOS nodes",
1871 onfail="ONOS nodes have different views of switch roles" )
1872
1873 if rolesResults and not consistentMastership:
Jon Halle1a3b752015-07-22 13:02:46 -07001874 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001875 main.log.warn(
1876 "ONOS" + str( i + 1 ) + " roles: ",
1877 json.dumps(
1878 json.loads( ONOSMastership[ i ] ),
1879 sort_keys=True,
1880 indent=4,
1881 separators=( ',', ': ' ) ) )
1882 elif rolesResults and not consistentMastership:
1883 mastershipCheck = main.TRUE
1884
1885 '''
1886 description2 = "Compare switch roles from before failure"
1887 main.step( description2 )
1888 try:
1889 currentJson = json.loads( ONOSMastership[0] )
1890 oldJson = json.loads( mastershipState )
1891 except ( ValueError, TypeError ):
1892 main.log.exception( "Something is wrong with parsing " +
1893 "ONOSMastership[0] or mastershipState" )
1894 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1895 main.log.error( "mastershipState" + repr( mastershipState ) )
1896 main.cleanup()
1897 main.exit()
1898 mastershipCheck = main.TRUE
1899 for i in range( 1, 29 ):
1900 switchDPID = str(
1901 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
1902 current = [ switch[ 'master' ] for switch in currentJson
1903 if switchDPID in switch[ 'id' ] ]
1904 old = [ switch[ 'master' ] for switch in oldJson
1905 if switchDPID in switch[ 'id' ] ]
1906 if current == old:
1907 mastershipCheck = mastershipCheck and main.TRUE
1908 else:
1909 main.log.warn( "Mastership of switch %s changed" % switchDPID )
1910 mastershipCheck = main.FALSE
1911 utilities.assert_equals(
1912 expect=main.TRUE,
1913 actual=mastershipCheck,
1914 onpass="Mastership of Switches was not changed",
1915 onfail="Mastership of some switches changed" )
1916 '''
1917 # NOTE: we expect mastership to change on controller failure
1918
1919 main.step( "Get the intents and compare across all nodes" )
1920 ONOSIntents = []
1921 intentCheck = main.FALSE
1922 consistentIntents = True
1923 intentsResults = True
1924 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001925 for i in range( main.numCtrls ):
1926 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001927 name="intents-" + str( i ),
1928 args=[],
1929 kwargs={ 'jsonFormat': True } )
1930 threads.append( t )
1931 t.start()
1932
1933 for t in threads:
1934 t.join()
1935 ONOSIntents.append( t.result )
1936
Jon Halle1a3b752015-07-22 13:02:46 -07001937 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001938 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1939 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1940 " intents" )
1941 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1942 repr( ONOSIntents[ i ] ) )
1943 intentsResults = False
1944 utilities.assert_equals(
1945 expect=True,
1946 actual=intentsResults,
1947 onpass="No error in reading intents output",
1948 onfail="Error in reading intents from ONOS" )
1949
1950 main.step( "Check for consistency in Intents from each controller" )
1951 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1952 main.log.info( "Intents are consistent across all ONOS " +
1953 "nodes" )
1954 else:
1955 consistentIntents = False
1956
1957 # Try to make it easy to figure out what is happening
1958 #
1959 # Intent ONOS1 ONOS2 ...
1960 # 0x01 INSTALLED INSTALLING
1961 # ... ... ...
1962 # ... ... ...
1963 title = " ID"
Jon Halle1a3b752015-07-22 13:02:46 -07001964 for n in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001965 title += " " * 10 + "ONOS" + str( n + 1 )
1966 main.log.warn( title )
1967 # get all intent keys in the cluster
1968 keys = []
1969 for nodeStr in ONOSIntents:
1970 node = json.loads( nodeStr )
1971 for intent in node:
1972 keys.append( intent.get( 'id' ) )
1973 keys = set( keys )
1974 for key in keys:
1975 row = "%-13s" % key
1976 for nodeStr in ONOSIntents:
1977 node = json.loads( nodeStr )
1978 for intent in node:
1979 if intent.get( 'id' ) == key:
1980 row += "%-15s" % intent.get( 'state' )
1981 main.log.warn( row )
1982 # End table view
1983
1984 utilities.assert_equals(
1985 expect=True,
1986 actual=consistentIntents,
1987 onpass="Intents are consistent across all ONOS nodes",
1988 onfail="ONOS nodes have different views of intents" )
1989 intentStates = []
1990 for node in ONOSIntents: # Iter through ONOS nodes
1991 nodeStates = []
1992 # Iter through intents of a node
1993 try:
1994 for intent in json.loads( node ):
1995 nodeStates.append( intent[ 'state' ] )
1996 except ( ValueError, TypeError ):
1997 main.log.exception( "Error in parsing intents" )
1998 main.log.error( repr( node ) )
1999 intentStates.append( nodeStates )
2000 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
2001 main.log.info( dict( out ) )
2002
2003 if intentsResults and not consistentIntents:
Jon Halle1a3b752015-07-22 13:02:46 -07002004 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07002005 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
2006 main.log.warn( json.dumps(
2007 json.loads( ONOSIntents[ i ] ),
2008 sort_keys=True,
2009 indent=4,
2010 separators=( ',', ': ' ) ) )
2011 elif intentsResults and consistentIntents:
2012 intentCheck = main.TRUE
2013
2014 # NOTE: Store has no durability, so intents are lost across system
2015 # restarts
2016 """
2017 main.step( "Compare current intents with intents before the failure" )
2018 # NOTE: this requires case 5 to pass for intentState to be set.
2019 # maybe we should stop the test if that fails?
2020 sameIntents = main.FALSE
2021 if intentState and intentState == ONOSIntents[ 0 ]:
2022 sameIntents = main.TRUE
2023 main.log.info( "Intents are consistent with before failure" )
2024 # TODO: possibly the states have changed? we may need to figure out
2025 # what the acceptable states are
2026 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
2027 sameIntents = main.TRUE
2028 try:
2029 before = json.loads( intentState )
2030 after = json.loads( ONOSIntents[ 0 ] )
2031 for intent in before:
2032 if intent not in after:
2033 sameIntents = main.FALSE
2034 main.log.debug( "Intent is not currently in ONOS " +
2035 "(at least in the same form):" )
2036 main.log.debug( json.dumps( intent ) )
2037 except ( ValueError, TypeError ):
2038 main.log.exception( "Exception printing intents" )
2039 main.log.debug( repr( ONOSIntents[0] ) )
2040 main.log.debug( repr( intentState ) )
2041 if sameIntents == main.FALSE:
2042 try:
2043 main.log.debug( "ONOS intents before: " )
2044 main.log.debug( json.dumps( json.loads( intentState ),
2045 sort_keys=True, indent=4,
2046 separators=( ',', ': ' ) ) )
2047 main.log.debug( "Current ONOS intents: " )
2048 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
2049 sort_keys=True, indent=4,
2050 separators=( ',', ': ' ) ) )
2051 except ( ValueError, TypeError ):
2052 main.log.exception( "Exception printing intents" )
2053 main.log.debug( repr( ONOSIntents[0] ) )
2054 main.log.debug( repr( intentState ) )
2055 utilities.assert_equals(
2056 expect=main.TRUE,
2057 actual=sameIntents,
2058 onpass="Intents are consistent with before failure",
2059 onfail="The Intents changed during failure" )
2060 intentCheck = intentCheck and sameIntents
2061 """
2062 main.step( "Get the OF Table entries and compare to before " +
2063 "component failure" )
2064 FlowTables = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002065 for i in range( 28 ):
2066 main.log.info( "Checking flow table on s" + str( i + 1 ) )
GlennRC68467eb2015-11-16 18:01:01 -08002067 tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
2068 FlowTables = FlowTables and main.Mininet1.flowTableComp( flows[i], tmpFlows )
Jon Hall5cf14d52015-07-16 12:15:19 -07002069 if FlowTables == main.FALSE:
GlennRC68467eb2015-11-16 18:01:01 -08002070 main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
2071
Jon Hall5cf14d52015-07-16 12:15:19 -07002072 utilities.assert_equals(
2073 expect=main.TRUE,
2074 actual=FlowTables,
2075 onpass="No changes were found in the flow tables",
2076 onfail="Changes were found in the flow tables" )
2077
2078 main.Mininet2.pingLongKill()
2079 '''
2080 # main.step( "Check the continuous pings to ensure that no packets " +
2081 # "were dropped during component failure" )
2082 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
2083 main.params[ 'TESTONIP' ] )
2084 LossInPings = main.FALSE
2085 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
2086 for i in range( 8, 18 ):
2087 main.log.info(
2088 "Checking for a loss in pings along flow from s" +
2089 str( i ) )
2090 LossInPings = main.Mininet2.checkForLoss(
2091 "/tmp/ping.h" +
2092 str( i ) ) or LossInPings
2093 if LossInPings == main.TRUE:
2094 main.log.info( "Loss in ping detected" )
2095 elif LossInPings == main.ERROR:
2096 main.log.info( "There are multiple mininet process running" )
2097 elif LossInPings == main.FALSE:
2098 main.log.info( "No Loss in the pings" )
2099 main.log.info( "No loss of dataplane connectivity" )
2100 # utilities.assert_equals(
2101 # expect=main.FALSE,
2102 # actual=LossInPings,
2103 # onpass="No Loss of connectivity",
2104 # onfail="Loss of dataplane connectivity detected" )
2105
2106 # NOTE: Since intents are not persisted with IntnentStore,
2107 # we expect loss in dataplane connectivity
2108 LossInPings = main.FALSE
2109 '''
2110
2111 main.step( "Leadership Election is still functional" )
2112 # Test of LeadershipElection
2113 leaderList = []
2114 leaderResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002115 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002116 leaderN = cli.electionTestLeader()
2117 leaderList.append( leaderN )
2118 if leaderN == main.FALSE:
2119 # error in response
2120 main.log.error( "Something is wrong with " +
2121 "electionTestLeader function, check the" +
2122 " error logs" )
2123 leaderResult = main.FALSE
2124 elif leaderN is None:
2125 main.log.error( cli.name +
2126 " shows no leader for the election-app." )
2127 leaderResult = main.FALSE
2128 if len( set( leaderList ) ) != 1:
2129 leaderResult = main.FALSE
2130 main.log.error(
2131 "Inconsistent view of leader for the election test app" )
2132 # TODO: print the list
2133 utilities.assert_equals(
2134 expect=main.TRUE,
2135 actual=leaderResult,
2136 onpass="Leadership election passed",
2137 onfail="Something went wrong with Leadership election" )
2138
2139 def CASE8( self, main ):
2140 """
2141 Compare topo
2142 """
2143 import json
2144 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002145 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002146 assert main, "main not defined"
2147 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002148 assert main.CLIs, "main.CLIs not defined"
2149 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002150
2151 main.case( "Compare ONOS Topology view to Mininet topology" )
Jon Hall783bbf92015-07-23 14:33:19 -07002152 main.caseExplanation = "Compare topology objects between Mininet" +\
Jon Hall5cf14d52015-07-16 12:15:19 -07002153 " and ONOS"
Jon Hall5cf14d52015-07-16 12:15:19 -07002154 topoResult = main.FALSE
2155 elapsed = 0
2156 count = 0
Jon Halle9b1fa32015-12-08 15:32:21 -08002157 main.step( "Comparing ONOS topology to MN topology" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002158 startTime = time.time()
2159 # Give time for Gossip to work
Jon Halle9b1fa32015-12-08 15:32:21 -08002160 while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
Jon Hallba609822015-09-18 12:00:21 -07002161 devicesResults = main.TRUE
2162 linksResults = main.TRUE
2163 hostsResults = main.TRUE
2164 hostAttachmentResults = True
Jon Hall5cf14d52015-07-16 12:15:19 -07002165 count += 1
2166 cliStart = time.time()
2167 devices = []
2168 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002169 for i in range( main.numCtrls ):
2170 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07002171 name="devices-" + str( i ),
2172 args=[ ] )
2173 threads.append( t )
2174 t.start()
2175
2176 for t in threads:
2177 t.join()
2178 devices.append( t.result )
2179 hosts = []
2180 ipResult = main.TRUE
2181 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002182 for i in range( main.numCtrls ):
Jon Halld8f6de82015-12-17 17:04:34 -08002183 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002184 name="hosts-" + str( i ),
Jon Halld8f6de82015-12-17 17:04:34 -08002185 args=[ main.CLIs[i].hosts, [ None ] ],
2186 kwargs= { 'sleep': 5, 'attempts': 5,
2187 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002188 threads.append( t )
2189 t.start()
2190
2191 for t in threads:
2192 t.join()
2193 try:
2194 hosts.append( json.loads( t.result ) )
2195 except ( ValueError, TypeError ):
2196 main.log.exception( "Error parsing hosts results" )
2197 main.log.error( repr( t.result ) )
Jon Hall3afe4c92015-12-14 19:30:38 -08002198 hosts.append( None )
Jon Hall5cf14d52015-07-16 12:15:19 -07002199 for controller in range( 0, len( hosts ) ):
2200 controllerStr = str( controller + 1 )
Jon Hallacd1b182015-12-17 11:43:20 -08002201 if hosts[ controller ]:
2202 for host in hosts[ controller ]:
2203 if host is None or host.get( 'ipAddresses', [] ) == []:
2204 main.log.error(
2205 "Error with host ipAddresses on controller" +
2206 controllerStr + ": " + str( host ) )
2207 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002208 ports = []
2209 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002210 for i in range( main.numCtrls ):
2211 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07002212 name="ports-" + str( i ),
2213 args=[ ] )
2214 threads.append( t )
2215 t.start()
2216
2217 for t in threads:
2218 t.join()
2219 ports.append( t.result )
2220 links = []
2221 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002222 for i in range( main.numCtrls ):
2223 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07002224 name="links-" + str( i ),
2225 args=[ ] )
2226 threads.append( t )
2227 t.start()
2228
2229 for t in threads:
2230 t.join()
2231 links.append( t.result )
2232 clusters = []
2233 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002234 for i in range( main.numCtrls ):
2235 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07002236 name="clusters-" + str( i ),
2237 args=[ ] )
2238 threads.append( t )
2239 t.start()
2240
2241 for t in threads:
2242 t.join()
2243 clusters.append( t.result )
2244
2245 elapsed = time.time() - startTime
2246 cliTime = time.time() - cliStart
2247 print "Elapsed time: " + str( elapsed )
2248 print "CLI time: " + str( cliTime )
2249
2250 mnSwitches = main.Mininet1.getSwitches()
2251 mnLinks = main.Mininet1.getLinks()
2252 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07002253 for controller in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07002254 controllerStr = str( controller + 1 )
2255 if devices[ controller ] and ports[ controller ] and\
2256 "Error" not in devices[ controller ] and\
2257 "Error" not in ports[ controller ]:
2258
Jon Hallc6793552016-01-19 14:18:37 -08002259 try:
2260 currentDevicesResult = main.Mininet1.compareSwitches(
2261 mnSwitches,
2262 json.loads( devices[ controller ] ),
2263 json.loads( ports[ controller ] ) )
2264 except ( TypeError, ValueError ) as e:
2265 main.log.exception( "Object not as expected; devices={!r}\nports={!r}".format(
2266 devices[ controller ], ports[ controller ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002267 else:
2268 currentDevicesResult = main.FALSE
2269 utilities.assert_equals( expect=main.TRUE,
2270 actual=currentDevicesResult,
2271 onpass="ONOS" + controllerStr +
2272 " Switches view is correct",
2273 onfail="ONOS" + controllerStr +
2274 " Switches view is incorrect" )
2275
2276 if links[ controller ] and "Error" not in links[ controller ]:
2277 currentLinksResult = main.Mininet1.compareLinks(
2278 mnSwitches, mnLinks,
2279 json.loads( links[ controller ] ) )
2280 else:
2281 currentLinksResult = main.FALSE
2282 utilities.assert_equals( expect=main.TRUE,
2283 actual=currentLinksResult,
2284 onpass="ONOS" + controllerStr +
2285 " links view is correct",
2286 onfail="ONOS" + controllerStr +
2287 " links view is incorrect" )
Jon Hall657cdf62015-12-17 14:40:51 -08002288 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002289 currentHostsResult = main.Mininet1.compareHosts(
2290 mnHosts,
2291 hosts[ controller ] )
Jon Hall13b446e2016-01-05 12:17:01 -08002292 elif hosts[ controller ] == []:
2293 currentHostsResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002294 else:
2295 currentHostsResult = main.FALSE
2296 utilities.assert_equals( expect=main.TRUE,
2297 actual=currentHostsResult,
2298 onpass="ONOS" + controllerStr +
2299 " hosts exist in Mininet",
2300 onfail="ONOS" + controllerStr +
2301 " hosts don't match Mininet" )
2302 # CHECKING HOST ATTACHMENT POINTS
2303 hostAttachment = True
2304 noHosts = False
2305 # FIXME: topo-HA/obelisk specific mappings:
2306 # key is mac and value is dpid
2307 mappings = {}
2308 for i in range( 1, 29 ): # hosts 1 through 28
2309 # set up correct variables:
2310 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2311 if i == 1:
2312 deviceId = "1000".zfill(16)
2313 elif i == 2:
2314 deviceId = "2000".zfill(16)
2315 elif i == 3:
2316 deviceId = "3000".zfill(16)
2317 elif i == 4:
2318 deviceId = "3004".zfill(16)
2319 elif i == 5:
2320 deviceId = "5000".zfill(16)
2321 elif i == 6:
2322 deviceId = "6000".zfill(16)
2323 elif i == 7:
2324 deviceId = "6007".zfill(16)
2325 elif i >= 8 and i <= 17:
2326 dpid = '3' + str( i ).zfill( 3 )
2327 deviceId = dpid.zfill(16)
2328 elif i >= 18 and i <= 27:
2329 dpid = '6' + str( i ).zfill( 3 )
2330 deviceId = dpid.zfill(16)
2331 elif i == 28:
2332 deviceId = "2800".zfill(16)
2333 mappings[ macId ] = deviceId
Jon Halld8f6de82015-12-17 17:04:34 -08002334 if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002335 if hosts[ controller ] == []:
2336 main.log.warn( "There are no hosts discovered" )
2337 noHosts = True
2338 else:
2339 for host in hosts[ controller ]:
2340 mac = None
2341 location = None
2342 device = None
2343 port = None
2344 try:
2345 mac = host.get( 'mac' )
2346 assert mac, "mac field could not be found for this host object"
2347
2348 location = host.get( 'location' )
2349 assert location, "location field could not be found for this host object"
2350
2351 # Trim the protocol identifier off deviceId
2352 device = str( location.get( 'elementId' ) ).split(':')[1]
2353 assert device, "elementId field could not be found for this host location object"
2354
2355 port = location.get( 'port' )
2356 assert port, "port field could not be found for this host location object"
2357
2358 # Now check if this matches where they should be
2359 if mac and device and port:
2360 if str( port ) != "1":
2361 main.log.error( "The attachment port is incorrect for " +
2362 "host " + str( mac ) +
2363 ". Expected: 1 Actual: " + str( port) )
2364 hostAttachment = False
2365 if device != mappings[ str( mac ) ]:
2366 main.log.error( "The attachment device is incorrect for " +
2367 "host " + str( mac ) +
2368 ". Expected: " + mappings[ str( mac ) ] +
2369 " Actual: " + device )
2370 hostAttachment = False
2371 else:
2372 hostAttachment = False
2373 except AssertionError:
2374 main.log.exception( "Json object not as expected" )
2375 main.log.error( repr( host ) )
2376 hostAttachment = False
2377 else:
2378 main.log.error( "No hosts json output or \"Error\"" +
2379 " in output. hosts = " +
2380 repr( hosts[ controller ] ) )
2381 if noHosts is False:
2382 # TODO: Find a way to know if there should be hosts in a
2383 # given point of the test
2384 hostAttachment = True
2385
2386 # END CHECKING HOST ATTACHMENT POINTS
2387 devicesResults = devicesResults and currentDevicesResult
2388 linksResults = linksResults and currentLinksResult
2389 hostsResults = hostsResults and currentHostsResult
2390 hostAttachmentResults = hostAttachmentResults and\
2391 hostAttachment
2392 topoResult = ( devicesResults and linksResults
2393 and hostsResults and ipResult and
2394 hostAttachmentResults )
Jon Halle9b1fa32015-12-08 15:32:21 -08002395 utilities.assert_equals( expect=True,
2396 actual=topoResult,
2397 onpass="ONOS topology matches Mininet",
2398 onfail="ONOS topology don't match Mininet" )
2399 # End of While loop to pull ONOS state
Jon Hall5cf14d52015-07-16 12:15:19 -07002400
2401 # Compare json objects for hosts and dataplane clusters
2402
2403 # hosts
2404 main.step( "Hosts view is consistent across all ONOS nodes" )
2405 consistentHostsResult = main.TRUE
2406 for controller in range( len( hosts ) ):
2407 controllerStr = str( controller + 1 )
Jon Hall13b446e2016-01-05 12:17:01 -08002408 if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002409 if hosts[ controller ] == hosts[ 0 ]:
2410 continue
2411 else: # hosts not consistent
2412 main.log.error( "hosts from ONOS" + controllerStr +
2413 " is inconsistent with ONOS1" )
2414 main.log.warn( repr( hosts[ controller ] ) )
2415 consistentHostsResult = main.FALSE
2416
2417 else:
2418 main.log.error( "Error in getting ONOS hosts from ONOS" +
2419 controllerStr )
2420 consistentHostsResult = main.FALSE
2421 main.log.warn( "ONOS" + controllerStr +
2422 " hosts response: " +
2423 repr( hosts[ controller ] ) )
2424 utilities.assert_equals(
2425 expect=main.TRUE,
2426 actual=consistentHostsResult,
2427 onpass="Hosts view is consistent across all ONOS nodes",
2428 onfail="ONOS nodes have different views of hosts" )
2429
2430 main.step( "Hosts information is correct" )
2431 hostsResults = hostsResults and ipResult
2432 utilities.assert_equals(
2433 expect=main.TRUE,
2434 actual=hostsResults,
2435 onpass="Host information is correct",
2436 onfail="Host information is incorrect" )
2437
2438 main.step( "Host attachment points to the network" )
2439 utilities.assert_equals(
2440 expect=True,
2441 actual=hostAttachmentResults,
2442 onpass="Hosts are correctly attached to the network",
2443 onfail="ONOS did not correctly attach hosts to the network" )
2444
2445 # Strongly connected clusters of devices
2446 main.step( "Clusters view is consistent across all ONOS nodes" )
2447 consistentClustersResult = main.TRUE
2448 for controller in range( len( clusters ) ):
2449 controllerStr = str( controller + 1 )
2450 if "Error" not in clusters[ controller ]:
2451 if clusters[ controller ] == clusters[ 0 ]:
2452 continue
2453 else: # clusters not consistent
2454 main.log.error( "clusters from ONOS" +
2455 controllerStr +
2456 " is inconsistent with ONOS1" )
2457 consistentClustersResult = main.FALSE
2458
2459 else:
2460 main.log.error( "Error in getting dataplane clusters " +
2461 "from ONOS" + controllerStr )
2462 consistentClustersResult = main.FALSE
2463 main.log.warn( "ONOS" + controllerStr +
2464 " clusters response: " +
2465 repr( clusters[ controller ] ) )
2466 utilities.assert_equals(
2467 expect=main.TRUE,
2468 actual=consistentClustersResult,
2469 onpass="Clusters view is consistent across all ONOS nodes",
2470 onfail="ONOS nodes have different views of clusters" )
2471
2472 main.step( "There is only one SCC" )
2473 # there should always only be one cluster
2474 try:
2475 numClusters = len( json.loads( clusters[ 0 ] ) )
2476 except ( ValueError, TypeError ):
2477 main.log.exception( "Error parsing clusters[0]: " +
2478 repr( clusters[0] ) )
2479 clusterResults = main.FALSE
2480 if numClusters == 1:
2481 clusterResults = main.TRUE
2482 utilities.assert_equals(
2483 expect=1,
2484 actual=numClusters,
2485 onpass="ONOS shows 1 SCC",
2486 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2487
2488 topoResult = ( devicesResults and linksResults
2489 and hostsResults and consistentHostsResult
2490 and consistentClustersResult and clusterResults
2491 and ipResult and hostAttachmentResults )
2492
2493 topoResult = topoResult and int( count <= 2 )
2494 note = "note it takes about " + str( int( cliTime ) ) + \
2495 " seconds for the test to make all the cli calls to fetch " +\
2496 "the topology from each ONOS instance"
2497 main.log.info(
2498 "Very crass estimate for topology discovery/convergence( " +
2499 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2500 str( count ) + " tries" )
2501
2502 main.step( "Device information is correct" )
2503 utilities.assert_equals(
2504 expect=main.TRUE,
2505 actual=devicesResults,
2506 onpass="Device information is correct",
2507 onfail="Device information is incorrect" )
2508
2509 main.step( "Links are correct" )
2510 utilities.assert_equals(
2511 expect=main.TRUE,
2512 actual=linksResults,
2513 onpass="Link are correct",
2514 onfail="Links are incorrect" )
2515
2516 # FIXME: move this to an ONOS state case
2517 main.step( "Checking ONOS nodes" )
2518 nodesOutput = []
2519 nodeResults = main.TRUE
2520 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002521 for i in range( main.numCtrls ):
2522 t = main.Thread( target=main.CLIs[i].nodes,
Jon Hall5cf14d52015-07-16 12:15:19 -07002523 name="nodes-" + str( i ),
2524 args=[ ] )
2525 threads.append( t )
2526 t.start()
2527
2528 for t in threads:
2529 t.join()
2530 nodesOutput.append( t.result )
Jon Halle1a3b752015-07-22 13:02:46 -07002531 ips = [ node.ip_address for node in main.nodes ]
Jon Halle9b1fa32015-12-08 15:32:21 -08002532 ips.sort()
Jon Hall5cf14d52015-07-16 12:15:19 -07002533 for i in nodesOutput:
2534 try:
2535 current = json.loads( i )
Jon Halle9b1fa32015-12-08 15:32:21 -08002536 activeIps = []
2537 currentResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002538 for node in current:
Jon Halle9b1fa32015-12-08 15:32:21 -08002539 if node['state'] == 'ACTIVE':
2540 activeIps.append( node['ip'] )
2541 activeIps.sort()
2542 if ips == activeIps:
2543 currentResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002544 except ( ValueError, TypeError ):
2545 main.log.error( "Error parsing nodes output" )
2546 main.log.warn( repr( i ) )
Jon Halle9b1fa32015-12-08 15:32:21 -08002547 currentResult = main.FALSE
2548 nodeResults = nodeResults and currentResult
Jon Hall5cf14d52015-07-16 12:15:19 -07002549 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2550 onpass="Nodes check successful",
2551 onfail="Nodes check NOT successful" )
2552
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"
2624 main.case( description )
2625 switch = main.params[ 'kill' ][ 'switch' ]
2626 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2627
2628 # TODO: Make this switch parameterizable
2629 main.step( "Kill " + switch )
2630 main.log.info( "Deleting " + switch )
2631 main.Mininet1.delSwitch( switch )
2632 main.log.info( "Waiting " + str( switchSleep ) +
2633 " seconds for switch down to be discovered" )
2634 time.sleep( switchSleep )
2635 device = main.ONOScli1.getDevice( dpid=switchDPID )
2636 # Peek at the deleted switch
2637 main.log.warn( str( device ) )
2638 result = main.FALSE
2639 if device and device[ 'available' ] is False:
2640 result = main.TRUE
2641 utilities.assert_equals( expect=main.TRUE, actual=result,
2642 onpass="Kill switch successful",
2643 onfail="Failed to kill switch?" )
2644
2645 def CASE12( self, main ):
2646 """
2647 Switch Up
2648 """
2649 # NOTE: You should probably run a topology check after this
2650 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002651 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002652 assert main, "main not defined"
2653 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002654 assert main.CLIs, "main.CLIs not defined"
2655 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002656 assert ONOS1Port, "ONOS1Port not defined"
2657 assert ONOS2Port, "ONOS2Port not defined"
2658 assert ONOS3Port, "ONOS3Port not defined"
2659 assert ONOS4Port, "ONOS4Port not defined"
2660 assert ONOS5Port, "ONOS5Port not defined"
2661 assert ONOS6Port, "ONOS6Port not defined"
2662 assert ONOS7Port, "ONOS7Port not defined"
2663
2664 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2665 switch = main.params[ 'kill' ][ 'switch' ]
2666 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2667 links = main.params[ 'kill' ][ 'links' ].split()
2668 description = "Adding a switch to ensure it is discovered correctly"
2669 main.case( description )
2670
2671 main.step( "Add back " + switch )
2672 main.Mininet1.addSwitch( switch, dpid=switchDPID )
2673 for peer in links:
2674 main.Mininet1.addLink( switch, peer )
2675 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -07002676 for i in range( main.numCtrls ):
2677 ipList.append( main.nodes[ i ].ip_address )
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 )
2682 device = main.ONOScli1.getDevice( dpid=switchDPID )
2683 # 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 Hall5ec6b1b2015-09-17 18:20:14 -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 Hall96091e62015-09-21 17:34:17 -07002728 dstName = main.logdir + "/" + node.name + "-" + f
2729 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 Hall96091e62015-09-21 17:34:17 -07002738 dstName = main.logdir + "/" + node.name + "-" + f
2739 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2740 logFolder + f, dstName )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002741 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 Hall5ec6b1b2015-09-17 18:20:14 -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 main.log.error( ", ".join( labels ) + "\n" + ", ".join( data ) )
2758 timerLog.write( ", ".join( labels ) + "\n" + ", ".join( data ) )
2759 timerLog.close()
2760 except NameError, e:
2761 main.log.exception(e)
2762
2763 def CASE14( self, main ):
2764 """
2765 start election app on all onos nodes
2766 """
Jon Halle1a3b752015-07-22 13:02:46 -07002767 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002768 assert main, "main not defined"
2769 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002770 assert main.CLIs, "main.CLIs not defined"
2771 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002772
2773 main.case("Start Leadership Election app")
2774 main.step( "Install leadership election app" )
2775 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
2776 utilities.assert_equals(
2777 expect=main.TRUE,
2778 actual=appResult,
2779 onpass="Election app installed",
2780 onfail="Something went wrong with installing Leadership election" )
2781
2782 main.step( "Run for election on each node" )
2783 leaderResult = main.TRUE
2784 leaders = []
Jon Halle1a3b752015-07-22 13:02:46 -07002785 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002786 cli.electionTestRun()
Jon Halle1a3b752015-07-22 13:02:46 -07002787 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002788 leader = cli.electionTestLeader()
2789 if leader is None or leader == main.FALSE:
2790 main.log.error( cli.name + ": Leader for the election app " +
2791 "should be an ONOS node, instead got '" +
2792 str( leader ) + "'" )
2793 leaderResult = main.FALSE
2794 leaders.append( leader )
2795 utilities.assert_equals(
2796 expect=main.TRUE,
2797 actual=leaderResult,
2798 onpass="Successfully ran for leadership",
2799 onfail="Failed to run for leadership" )
2800
2801 main.step( "Check that each node shows the same leader" )
2802 sameLeader = main.TRUE
2803 if len( set( leaders ) ) != 1:
2804 sameLeader = main.FALSE
2805 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2806 str( leaders ) )
2807 utilities.assert_equals(
2808 expect=main.TRUE,
2809 actual=sameLeader,
2810 onpass="Leadership is consistent for the election topic",
2811 onfail="Nodes have different leaders" )
2812
2813 def CASE15( self, main ):
2814 """
2815 Check that Leadership Election is still functional
acsmars9475b1c2015-08-28 18:02:08 -07002816 15.1 Run election on each node
2817 15.2 Check that each node has the same leaders and candidates
2818 15.3 Find current leader and withdraw
2819 15.4 Check that a new node was elected leader
2820 15.5 Check that that new leader was the candidate of old leader
2821 15.6 Run for election on old leader
2822 15.7 Check that oldLeader is a candidate, and leader if only 1 node
2823 15.8 Make sure that the old leader was added to the candidate list
2824
2825 old and new variable prefixes refer to data from before vs after
2826 withdrawl and later before withdrawl vs after re-election
Jon Hall5cf14d52015-07-16 12:15:19 -07002827 """
2828 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002829 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002830 assert main, "main not defined"
2831 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002832 assert main.CLIs, "main.CLIs not defined"
2833 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002834
Jon Hall5cf14d52015-07-16 12:15:19 -07002835 description = "Check that Leadership Election is still functional"
2836 main.case( description )
2837 # NOTE: Need to re-run since being a canidate is not persistant
acsmars9475b1c2015-08-28 18:02:08 -07002838 # TODO: add check for "Command not found:" in the driver, this
2839 # means the election test app isn't loaded
2840
2841 oldLeaders = [] # leaders by node before withdrawl from candidates
2842 newLeaders = [] # leaders by node after withdrawl from candidates
2843 oldAllCandidates = [] # list of lists of each nodes' candidates before
2844 newAllCandidates = [] # list of lists of each nodes' candidates after
2845 oldCandidates = [] # list of candidates from node 0 before withdrawl
2846 newCandidates = [] # list of candidates from node 0 after withdrawl
2847 oldLeader = '' # the old leader from oldLeaders, None if not same
2848 newLeader = '' # the new leaders fron newLoeaders, None if not same
2849 oldLeaderCLI = None # the CLI of the old leader used for re-electing
acsmars71adceb2015-08-31 15:09:26 -07002850 expectNoLeader = False # True when there is only one leader
2851 if main.numCtrls == 1:
2852 expectNoLeader = True
acsmars9475b1c2015-08-28 18:02:08 -07002853
Jon Hall5cf14d52015-07-16 12:15:19 -07002854 main.step( "Run for election on each node" )
acsmars9475b1c2015-08-28 18:02:08 -07002855 electionResult = main.TRUE
2856
2857 for cli in main.CLIs: # run test election on each node
2858 if cli.electionTestRun() == main.FALSE:
2859 electionResult = main.FALSE
2860
Jon Hall5cf14d52015-07-16 12:15:19 -07002861 utilities.assert_equals(
2862 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07002863 actual=electionResult,
2864 onpass="All nodes successfully ran for leadership",
2865 onfail="At least one node failed to run for leadership" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002866
acsmars3a72bde2015-09-02 14:16:22 -07002867 if electionResult == main.FALSE:
2868 main.log.error(
2869 "Skipping Test Case because Election Test App isn't loaded" )
2870 main.skipCase()
2871
acsmars9475b1c2015-08-28 18:02:08 -07002872 main.step( "Check that each node shows the same leader and candidates" )
2873 sameResult = main.TRUE
2874 failMessage = "Nodes have different leaders"
2875 for cli in main.CLIs:
2876 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2877 oldAllCandidates.append( node )
2878 oldLeaders.append( node[ 0 ] )
2879 oldCandidates = oldAllCandidates[ 0 ]
2880
2881 # Check that each node has the same leader. Defines oldLeader
2882 if len( set( oldLeaders ) ) != 1:
2883 sameResult = main.FALSE
acsmars71adceb2015-08-31 15:09:26 -07002884 main.log.error( "More than one leader present:" + str( oldLeaders ) )
acsmars9475b1c2015-08-28 18:02:08 -07002885 oldLeader = None
2886 else:
2887 oldLeader = oldLeaders[ 0 ]
2888
2889 # Check that each node's candidate list is the same
acsmars29233db2015-11-04 11:15:00 -08002890 candidateDiscrepancy = False # Boolean of candidate mismatches
acsmars9475b1c2015-08-28 18:02:08 -07002891 for candidates in oldAllCandidates:
2892 if set( candidates ) != set( oldCandidates ):
2893 sameResult = main.FALSE
acsmars29233db2015-11-04 11:15:00 -08002894 candidateDiscrepancy = True
2895
2896 if candidateDiscrepancy:
2897 failMessage += " and candidates"
acsmars9475b1c2015-08-28 18:02:08 -07002898
Jon Hall5cf14d52015-07-16 12:15:19 -07002899 utilities.assert_equals(
2900 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002901 actual=sameResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002902 onpass="Leadership is consistent for the election topic",
acsmars9475b1c2015-08-28 18:02:08 -07002903 onfail=failMessage )
Jon Hall5cf14d52015-07-16 12:15:19 -07002904
2905 main.step( "Find current leader and withdraw" )
acsmars9475b1c2015-08-28 18:02:08 -07002906 withdrawResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002907 # do some sanity checking on leader before using it
acsmars9475b1c2015-08-28 18:02:08 -07002908 if oldLeader is None:
2909 main.log.error( "Leadership isn't consistent." )
2910 withdrawResult = main.FALSE
2911 # Get the CLI of the oldLeader
Jon Halle1a3b752015-07-22 13:02:46 -07002912 for i in range( len( main.CLIs ) ):
acsmars9475b1c2015-08-28 18:02:08 -07002913 if oldLeader == main.nodes[ i ].ip_address:
2914 oldLeaderCLI = main.CLIs[ i ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002915 break
2916 else: # FOR/ELSE statement
2917 main.log.error( "Leader election, could not find current leader" )
2918 if oldLeader:
acsmars9475b1c2015-08-28 18:02:08 -07002919 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall5cf14d52015-07-16 12:15:19 -07002920 utilities.assert_equals(
2921 expect=main.TRUE,
2922 actual=withdrawResult,
2923 onpass="Node was withdrawn from election",
2924 onfail="Node was not withdrawn from election" )
2925
acsmars9475b1c2015-08-28 18:02:08 -07002926 main.step( "Check that a new node was elected leader" )
acsmars71adceb2015-08-31 15:09:26 -07002927
Jon Hall5cf14d52015-07-16 12:15:19 -07002928 # FIXME: use threads
acsmars9475b1c2015-08-28 18:02:08 -07002929 newLeaderResult = main.TRUE
2930 failMessage = "Nodes have different leaders"
2931
2932 # Get new leaders and candidates
Jon Halle1a3b752015-07-22 13:02:46 -07002933 for cli in main.CLIs:
acsmars9475b1c2015-08-28 18:02:08 -07002934 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
acsmars71adceb2015-08-31 15:09:26 -07002935 # elections might no have finished yet
2936 if node[ 0 ] == 'none' and not expectNoLeader:
acsmars9475b1c2015-08-28 18:02:08 -07002937 main.log.info( "Node has no leader, waiting 5 seconds to be " +
2938 "sure elections are complete." )
2939 time.sleep(5)
2940 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
acsmars71adceb2015-08-31 15:09:26 -07002941 # election still isn't done or there is a problem
2942 if node[ 0 ] == 'none':
2943 main.log.error( "No leader was elected on at least 1 node" )
2944 newLeaderResult = main.FALSE
acsmars9475b1c2015-08-28 18:02:08 -07002945 newAllCandidates.append( node )
2946 newLeaders.append( node[ 0 ] )
2947 newCandidates = newAllCandidates[ 0 ]
2948
2949 # Check that each node has the same leader. Defines newLeader
2950 if len( set( newLeaders ) ) != 1:
2951 newLeaderResult = main.FALSE
2952 main.log.error( "Nodes have different leaders: " +
2953 str( newLeaders ) )
2954 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07002955 else:
acsmars9475b1c2015-08-28 18:02:08 -07002956 newLeader = newLeaders[ 0 ]
2957
acsmars71adceb2015-08-31 15:09:26 -07002958 # Check that each node's candidate list is the same
2959 for candidates in newAllCandidates:
2960 if set( candidates ) != set( newCandidates ):
2961 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07002962 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07002963
acsmars9475b1c2015-08-28 18:02:08 -07002964 # Check that the new leader is not the older leader, which was withdrawn
2965 if newLeader == oldLeader:
2966 newLeaderResult = main.FALSE
2967 main.log.error( "All nodes still see old leader: " + oldLeader +
2968 " as the current leader" )
2969
Jon Hall5cf14d52015-07-16 12:15:19 -07002970 utilities.assert_equals(
2971 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07002972 actual=newLeaderResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002973 onpass="Leadership election passed",
2974 onfail="Something went wrong with Leadership election" )
2975
acsmars9475b1c2015-08-28 18:02:08 -07002976 main.step( "Check that that new leader was the candidate of old leader")
2977 # candidates[ 2 ] should be come the top candidate after withdrawl
2978 correctCandidateResult = main.TRUE
acsmars71adceb2015-08-31 15:09:26 -07002979 if expectNoLeader:
2980 if newLeader == 'none':
2981 main.log.info( "No leader expected. None found. Pass" )
2982 correctCandidateResult = main.TRUE
2983 else:
2984 main.log.info( "Expected no leader, got: " + str( newLeader ) )
2985 correctCandidateResult = main.FALSE
2986 elif newLeader != oldCandidates[ 2 ]:
acsmars9475b1c2015-08-28 18:02:08 -07002987 correctCandidateResult = main.FALSE
2988 main.log.error( "Candidate " + newLeader + " was elected. " +
2989 oldCandidates[ 2 ] + " should have had priority." )
2990
2991 utilities.assert_equals(
2992 expect=main.TRUE,
2993 actual=correctCandidateResult,
2994 onpass="Correct Candidate Elected",
2995 onfail="Incorrect Candidate Elected" )
2996
Jon Hall5cf14d52015-07-16 12:15:19 -07002997 main.step( "Run for election on old leader( just so everyone " +
2998 "is in the hat )" )
acsmars9475b1c2015-08-28 18:02:08 -07002999 if oldLeaderCLI is not None:
3000 runResult = oldLeaderCLI.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07003001 else:
acsmars9475b1c2015-08-28 18:02:08 -07003002 main.log.error( "No old leader to re-elect" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003003 runResult = main.FALSE
3004 utilities.assert_equals(
3005 expect=main.TRUE,
3006 actual=runResult,
3007 onpass="App re-ran for election",
3008 onfail="App failed to run for election" )
acsmars9475b1c2015-08-28 18:02:08 -07003009 main.step(
3010 "Check that oldLeader is a candidate, and leader if only 1 node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003011 # verify leader didn't just change
acsmars9475b1c2015-08-28 18:02:08 -07003012 positionResult = main.TRUE
3013 # Get new leaders and candidates, wait if oldLeader is not a candidate yet
3014
3015 # Reset and reuse the new candidate and leaders lists
3016 newAllCandidates = []
3017 newCandidates = []
3018 newLeaders = []
3019 for cli in main.CLIs:
3020 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
3021 if oldLeader not in node: # election might no have finished yet
3022 main.log.info( "Old Leader not elected, waiting 5 seconds to " +
3023 "be sure elections are complete" )
3024 time.sleep(5)
3025 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
3026 if oldLeader not in node: # election still isn't done, errors
3027 main.log.error(
3028 "Old leader was not elected on at least one node" )
3029 positionResult = main.FALSE
3030 newAllCandidates.append( node )
3031 newLeaders.append( node[ 0 ] )
3032 newCandidates = newAllCandidates[ 0 ]
3033
3034 # Check that each node has the same leader. Defines newLeader
3035 if len( set( newLeaders ) ) != 1:
3036 positionResult = main.FALSE
3037 main.log.error( "Nodes have different leaders: " +
3038 str( newLeaders ) )
3039 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07003040 else:
acsmars9475b1c2015-08-28 18:02:08 -07003041 newLeader = newLeaders[ 0 ]
3042
acsmars71adceb2015-08-31 15:09:26 -07003043 # Check that each node's candidate list is the same
3044 for candidates in newAllCandidates:
3045 if set( candidates ) != set( newCandidates ):
3046 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07003047 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07003048
acsmars9475b1c2015-08-28 18:02:08 -07003049 # Check that the re-elected node is last on the candidate List
3050 if oldLeader != newCandidates[ -1 ]:
3051 main.log.error( "Old Leader (" + oldLeader + ") not in the proper position " +
3052 str( newCandidates ) )
3053 positionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07003054
3055 utilities.assert_equals(
3056 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07003057 actual=positionResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07003058 onpass="Old leader successfully re-ran for election",
3059 onfail="Something went wrong with Leadership election after " +
3060 "the old leader re-ran for election" )
3061
3062 def CASE16( self, main ):
3063 """
3064 Install Distributed Primitives app
3065 """
3066 import time
Jon Halle1a3b752015-07-22 13:02:46 -07003067 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003068 assert main, "main not defined"
3069 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003070 assert main.CLIs, "main.CLIs not defined"
3071 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003072
3073 # Variables for the distributed primitives tests
3074 global pCounterName
3075 global iCounterName
3076 global pCounterValue
3077 global iCounterValue
3078 global onosSet
3079 global onosSetName
3080 pCounterName = "TestON-Partitions"
3081 iCounterName = "TestON-inMemory"
3082 pCounterValue = 0
3083 iCounterValue = 0
3084 onosSet = set([])
3085 onosSetName = "TestON-set"
3086
3087 description = "Install Primitives app"
3088 main.case( description )
3089 main.step( "Install Primitives app" )
3090 appName = "org.onosproject.distributedprimitives"
Jon Halle1a3b752015-07-22 13:02:46 -07003091 appResults = main.CLIs[0].activateApp( appName )
Jon Hall5cf14d52015-07-16 12:15:19 -07003092 utilities.assert_equals( expect=main.TRUE,
3093 actual=appResults,
3094 onpass="Primitives app activated",
3095 onfail="Primitives app not activated" )
3096 time.sleep( 5 ) # To allow all nodes to activate
3097
3098 def CASE17( self, main ):
3099 """
3100 Check for basic functionality with distributed primitives
3101 """
Jon Hall5cf14d52015-07-16 12:15:19 -07003102 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07003103 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003104 assert main, "main not defined"
3105 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003106 assert main.CLIs, "main.CLIs not defined"
3107 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003108 assert pCounterName, "pCounterName not defined"
3109 assert iCounterName, "iCounterName not defined"
3110 assert onosSetName, "onosSetName not defined"
3111 # NOTE: assert fails if value is 0/None/Empty/False
3112 try:
3113 pCounterValue
3114 except NameError:
3115 main.log.error( "pCounterValue not defined, setting to 0" )
3116 pCounterValue = 0
3117 try:
3118 iCounterValue
3119 except NameError:
3120 main.log.error( "iCounterValue not defined, setting to 0" )
3121 iCounterValue = 0
3122 try:
3123 onosSet
3124 except NameError:
3125 main.log.error( "onosSet not defined, setting to empty Set" )
3126 onosSet = set([])
3127 # Variables for the distributed primitives tests. These are local only
3128 addValue = "a"
3129 addAllValue = "a b c d e f"
3130 retainValue = "c d e f"
3131
3132 description = "Check for basic functionality with distributed " +\
3133 "primitives"
3134 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07003135 main.caseExplanation = "Test the methods of the distributed " +\
3136 "primitives (counters and sets) throught the cli"
Jon Hall5cf14d52015-07-16 12:15:19 -07003137 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07003138 # Partitioned counters
3139 main.step( "Increment then get a default counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003140 pCounters = []
3141 threads = []
3142 addedPValues = []
Jon Halle1a3b752015-07-22 13:02:46 -07003143 for i in range( main.numCtrls ):
3144 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3145 name="counterAddAndGet-" + str( i ),
Jon Hall5cf14d52015-07-16 12:15:19 -07003146 args=[ pCounterName ] )
3147 pCounterValue += 1
3148 addedPValues.append( pCounterValue )
3149 threads.append( t )
3150 t.start()
3151
3152 for t in threads:
3153 t.join()
3154 pCounters.append( t.result )
3155 # Check that counter incremented numController times
3156 pCounterResults = True
3157 for i in addedPValues:
3158 tmpResult = i in pCounters
3159 pCounterResults = pCounterResults and tmpResult
3160 if not tmpResult:
3161 main.log.error( str( i ) + " is not in partitioned "
3162 "counter incremented results" )
3163 utilities.assert_equals( expect=True,
3164 actual=pCounterResults,
3165 onpass="Default counter incremented",
3166 onfail="Error incrementing default" +
3167 " counter" )
3168
Jon Halle1a3b752015-07-22 13:02:46 -07003169 main.step( "Get then Increment a default counter on each node" )
3170 pCounters = []
3171 threads = []
3172 addedPValues = []
3173 for i in range( main.numCtrls ):
3174 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3175 name="counterGetAndAdd-" + str( i ),
3176 args=[ pCounterName ] )
3177 addedPValues.append( pCounterValue )
3178 pCounterValue += 1
3179 threads.append( t )
3180 t.start()
3181
3182 for t in threads:
3183 t.join()
3184 pCounters.append( t.result )
3185 # Check that counter incremented numController times
3186 pCounterResults = True
3187 for i in addedPValues:
3188 tmpResult = i in pCounters
3189 pCounterResults = pCounterResults and tmpResult
3190 if not tmpResult:
3191 main.log.error( str( i ) + " is not in partitioned "
3192 "counter incremented results" )
3193 utilities.assert_equals( expect=True,
3194 actual=pCounterResults,
3195 onpass="Default counter incremented",
3196 onfail="Error incrementing default" +
3197 " counter" )
3198
3199 main.step( "Counters we added have the correct values" )
3200 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3201 utilities.assert_equals( expect=main.TRUE,
3202 actual=incrementCheck,
3203 onpass="Added counters are correct",
3204 onfail="Added counters are incorrect" )
3205
3206 main.step( "Add -8 to then get a default counter on each node" )
3207 pCounters = []
3208 threads = []
3209 addedPValues = []
3210 for i in range( main.numCtrls ):
3211 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3212 name="counterIncrement-" + str( i ),
3213 args=[ pCounterName ],
3214 kwargs={ "delta": -8 } )
3215 pCounterValue += -8
3216 addedPValues.append( pCounterValue )
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( "Add 5 to then get a default counter on each node" )
3238 pCounters = []
3239 threads = []
3240 addedPValues = []
3241 for i in range( main.numCtrls ):
3242 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3243 name="counterIncrement-" + str( i ),
3244 args=[ pCounterName ],
3245 kwargs={ "delta": 5 } )
3246 pCounterValue += 5
3247 addedPValues.append( pCounterValue )
3248 threads.append( t )
3249 t.start()
3250
3251 for t in threads:
3252 t.join()
3253 pCounters.append( t.result )
3254 # Check that counter incremented numController times
3255 pCounterResults = True
3256 for i in addedPValues:
3257 tmpResult = i in pCounters
3258 pCounterResults = pCounterResults and tmpResult
3259 if not tmpResult:
3260 main.log.error( str( i ) + " is not in partitioned "
3261 "counter incremented results" )
3262 utilities.assert_equals( expect=True,
3263 actual=pCounterResults,
3264 onpass="Default counter incremented",
3265 onfail="Error incrementing default" +
3266 " counter" )
3267
3268 main.step( "Get then add 5 to a default counter on each node" )
3269 pCounters = []
3270 threads = []
3271 addedPValues = []
3272 for i in range( main.numCtrls ):
3273 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3274 name="counterIncrement-" + str( i ),
3275 args=[ pCounterName ],
3276 kwargs={ "delta": 5 } )
3277 addedPValues.append( pCounterValue )
3278 pCounterValue += 5
3279 threads.append( t )
3280 t.start()
3281
3282 for t in threads:
3283 t.join()
3284 pCounters.append( t.result )
3285 # Check that counter incremented numController times
3286 pCounterResults = True
3287 for i in addedPValues:
3288 tmpResult = i in pCounters
3289 pCounterResults = pCounterResults and tmpResult
3290 if not tmpResult:
3291 main.log.error( str( i ) + " is not in partitioned "
3292 "counter incremented results" )
3293 utilities.assert_equals( expect=True,
3294 actual=pCounterResults,
3295 onpass="Default counter incremented",
3296 onfail="Error incrementing default" +
3297 " counter" )
3298
3299 main.step( "Counters we added have the correct values" )
3300 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3301 utilities.assert_equals( expect=main.TRUE,
3302 actual=incrementCheck,
3303 onpass="Added counters are correct",
3304 onfail="Added counters are incorrect" )
3305
3306 # In-Memory counters
3307 main.step( "Increment and get an in-memory counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003308 iCounters = []
3309 addedIValues = []
3310 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003311 for i in range( main.numCtrls ):
3312 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003313 name="icounterIncrement-" + str( i ),
3314 args=[ iCounterName ],
3315 kwargs={ "inMemory": True } )
3316 iCounterValue += 1
3317 addedIValues.append( iCounterValue )
3318 threads.append( t )
3319 t.start()
3320
3321 for t in threads:
3322 t.join()
3323 iCounters.append( t.result )
3324 # Check that counter incremented numController times
3325 iCounterResults = True
3326 for i in addedIValues:
3327 tmpResult = i in iCounters
3328 iCounterResults = iCounterResults and tmpResult
3329 if not tmpResult:
3330 main.log.error( str( i ) + " is not in the in-memory "
3331 "counter incremented results" )
3332 utilities.assert_equals( expect=True,
3333 actual=iCounterResults,
Jon Halle1a3b752015-07-22 13:02:46 -07003334 onpass="In-memory counter incremented",
3335 onfail="Error incrementing in-memory" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003336 " counter" )
3337
Jon Halle1a3b752015-07-22 13:02:46 -07003338 main.step( "Get then Increment a in-memory counter on each node" )
3339 iCounters = []
3340 threads = []
3341 addedIValues = []
3342 for i in range( main.numCtrls ):
3343 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3344 name="counterGetAndAdd-" + str( i ),
3345 args=[ iCounterName ],
3346 kwargs={ "inMemory": True } )
3347 addedIValues.append( iCounterValue )
3348 iCounterValue += 1
3349 threads.append( t )
3350 t.start()
3351
3352 for t in threads:
3353 t.join()
3354 iCounters.append( t.result )
3355 # Check that counter incremented numController times
3356 iCounterResults = True
3357 for i in addedIValues:
3358 tmpResult = i in iCounters
3359 iCounterResults = iCounterResults and tmpResult
3360 if not tmpResult:
3361 main.log.error( str( i ) + " is not in in-memory "
3362 "counter incremented results" )
3363 utilities.assert_equals( expect=True,
3364 actual=iCounterResults,
3365 onpass="In-memory counter incremented",
3366 onfail="Error incrementing in-memory" +
3367 " counter" )
3368
3369 main.step( "Counters we added have the correct values" )
3370 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3371 utilities.assert_equals( expect=main.TRUE,
3372 actual=incrementCheck,
3373 onpass="Added counters are correct",
3374 onfail="Added counters are incorrect" )
3375
3376 main.step( "Add -8 to then get a in-memory counter on each node" )
3377 iCounters = []
3378 threads = []
3379 addedIValues = []
3380 for i in range( main.numCtrls ):
3381 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3382 name="counterIncrement-" + str( i ),
3383 args=[ iCounterName ],
3384 kwargs={ "delta": -8, "inMemory": True } )
3385 iCounterValue += -8
3386 addedIValues.append( iCounterValue )
3387 threads.append( t )
3388 t.start()
3389
3390 for t in threads:
3391 t.join()
3392 iCounters.append( t.result )
3393 # Check that counter incremented numController times
3394 iCounterResults = True
3395 for i in addedIValues:
3396 tmpResult = i in iCounters
3397 iCounterResults = iCounterResults and tmpResult
3398 if not tmpResult:
3399 main.log.error( str( i ) + " is not in in-memory "
3400 "counter incremented results" )
3401 utilities.assert_equals( expect=True,
3402 actual=pCounterResults,
3403 onpass="In-memory counter incremented",
3404 onfail="Error incrementing in-memory" +
3405 " counter" )
3406
3407 main.step( "Add 5 to then get a in-memory counter on each node" )
3408 iCounters = []
3409 threads = []
3410 addedIValues = []
3411 for i in range( main.numCtrls ):
3412 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3413 name="counterIncrement-" + str( i ),
3414 args=[ iCounterName ],
3415 kwargs={ "delta": 5, "inMemory": True } )
3416 iCounterValue += 5
3417 addedIValues.append( iCounterValue )
3418 threads.append( t )
3419 t.start()
3420
3421 for t in threads:
3422 t.join()
3423 iCounters.append( t.result )
3424 # Check that counter incremented numController times
3425 iCounterResults = True
3426 for i in addedIValues:
3427 tmpResult = i in iCounters
3428 iCounterResults = iCounterResults and tmpResult
3429 if not tmpResult:
3430 main.log.error( str( i ) + " is not in in-memory "
3431 "counter incremented results" )
3432 utilities.assert_equals( expect=True,
3433 actual=pCounterResults,
3434 onpass="In-memory counter incremented",
3435 onfail="Error incrementing in-memory" +
3436 " counter" )
3437
3438 main.step( "Get then add 5 to a in-memory counter on each node" )
3439 iCounters = []
3440 threads = []
3441 addedIValues = []
3442 for i in range( main.numCtrls ):
3443 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3444 name="counterIncrement-" + str( i ),
3445 args=[ iCounterName ],
3446 kwargs={ "delta": 5, "inMemory": True } )
3447 addedIValues.append( iCounterValue )
3448 iCounterValue += 5
3449 threads.append( t )
3450 t.start()
3451
3452 for t in threads:
3453 t.join()
3454 iCounters.append( t.result )
3455 # Check that counter incremented numController times
3456 iCounterResults = True
3457 for i in addedIValues:
3458 tmpResult = i in iCounters
3459 iCounterResults = iCounterResults and tmpResult
3460 if not tmpResult:
3461 main.log.error( str( i ) + " is not in in-memory "
3462 "counter incremented results" )
3463 utilities.assert_equals( expect=True,
3464 actual=iCounterResults,
3465 onpass="In-memory counter incremented",
3466 onfail="Error incrementing in-memory" +
3467 " counter" )
3468
3469 main.step( "Counters we added have the correct values" )
3470 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3471 utilities.assert_equals( expect=main.TRUE,
3472 actual=incrementCheck,
3473 onpass="Added counters are correct",
3474 onfail="Added counters are incorrect" )
3475
Jon Hall5cf14d52015-07-16 12:15:19 -07003476 main.step( "Check counters are consistant across nodes" )
Jon Hall57b50432015-10-22 10:20:10 -07003477 onosCounters, consistentCounterResults = main.Counters.consistentCheck()
Jon Hall5cf14d52015-07-16 12:15:19 -07003478 utilities.assert_equals( expect=main.TRUE,
3479 actual=consistentCounterResults,
3480 onpass="ONOS counters are consistent " +
3481 "across nodes",
3482 onfail="ONOS Counters are inconsistent " +
3483 "across nodes" )
3484
3485 main.step( "Counters we added have the correct values" )
Jon Halle1a3b752015-07-22 13:02:46 -07003486 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3487 incrementCheck = incrementCheck and \
3488 main.Counters.counterCheck( iCounterName, iCounterValue )
Jon Hall5cf14d52015-07-16 12:15:19 -07003489 utilities.assert_equals( expect=main.TRUE,
Jon Halle1a3b752015-07-22 13:02:46 -07003490 actual=incrementCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -07003491 onpass="Added counters are correct",
3492 onfail="Added counters are incorrect" )
3493 # DISTRIBUTED SETS
3494 main.step( "Distributed Set get" )
3495 size = len( onosSet )
3496 getResponses = []
3497 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003498 for i in range( main.numCtrls ):
3499 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003500 name="setTestGet-" + str( i ),
3501 args=[ onosSetName ] )
3502 threads.append( t )
3503 t.start()
3504 for t in threads:
3505 t.join()
3506 getResponses.append( t.result )
3507
3508 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003509 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003510 if isinstance( getResponses[ i ], list):
3511 current = set( getResponses[ i ] )
3512 if len( current ) == len( getResponses[ i ] ):
3513 # no repeats
3514 if onosSet != current:
3515 main.log.error( "ONOS" + str( i + 1 ) +
3516 " has incorrect view" +
3517 " of set " + onosSetName + ":\n" +
3518 str( getResponses[ i ] ) )
3519 main.log.debug( "Expected: " + str( onosSet ) )
3520 main.log.debug( "Actual: " + str( current ) )
3521 getResults = main.FALSE
3522 else:
3523 # error, set is not a set
3524 main.log.error( "ONOS" + str( i + 1 ) +
3525 " has repeat elements in" +
3526 " set " + onosSetName + ":\n" +
3527 str( getResponses[ i ] ) )
3528 getResults = main.FALSE
3529 elif getResponses[ i ] == main.ERROR:
3530 getResults = main.FALSE
3531 utilities.assert_equals( expect=main.TRUE,
3532 actual=getResults,
3533 onpass="Set elements are correct",
3534 onfail="Set elements are incorrect" )
3535
3536 main.step( "Distributed Set size" )
3537 sizeResponses = []
3538 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003539 for i in range( main.numCtrls ):
3540 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003541 name="setTestSize-" + str( i ),
3542 args=[ onosSetName ] )
3543 threads.append( t )
3544 t.start()
3545 for t in threads:
3546 t.join()
3547 sizeResponses.append( t.result )
3548
3549 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003550 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003551 if size != sizeResponses[ i ]:
3552 sizeResults = main.FALSE
3553 main.log.error( "ONOS" + str( i + 1 ) +
3554 " expected a size of " + str( size ) +
3555 " for set " + onosSetName +
3556 " but got " + str( sizeResponses[ i ] ) )
3557 utilities.assert_equals( expect=main.TRUE,
3558 actual=sizeResults,
3559 onpass="Set sizes are correct",
3560 onfail="Set sizes are incorrect" )
3561
3562 main.step( "Distributed Set add()" )
3563 onosSet.add( addValue )
3564 addResponses = []
3565 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003566 for i in range( main.numCtrls ):
3567 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003568 name="setTestAdd-" + str( i ),
3569 args=[ onosSetName, addValue ] )
3570 threads.append( t )
3571 t.start()
3572 for t in threads:
3573 t.join()
3574 addResponses.append( t.result )
3575
3576 # main.TRUE = successfully changed the set
3577 # main.FALSE = action resulted in no change in set
3578 # main.ERROR - Some error in executing the function
3579 addResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003580 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003581 if addResponses[ i ] == main.TRUE:
3582 # All is well
3583 pass
3584 elif addResponses[ i ] == main.FALSE:
3585 # Already in set, probably fine
3586 pass
3587 elif addResponses[ i ] == main.ERROR:
3588 # Error in execution
3589 addResults = main.FALSE
3590 else:
3591 # unexpected result
3592 addResults = main.FALSE
3593 if addResults != main.TRUE:
3594 main.log.error( "Error executing set add" )
3595
3596 # Check if set is still correct
3597 size = len( onosSet )
3598 getResponses = []
3599 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003600 for i in range( main.numCtrls ):
3601 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003602 name="setTestGet-" + str( i ),
3603 args=[ onosSetName ] )
3604 threads.append( t )
3605 t.start()
3606 for t in threads:
3607 t.join()
3608 getResponses.append( t.result )
3609 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003610 for i in range( main.numCtrls ):
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:
3616 main.log.error( "ONOS" + str( i + 1 ) +
3617 " 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
3625 main.log.error( "ONOS" + str( i + 1 ) +
3626 " 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 Halle1a3b752015-07-22 13:02:46 -07003634 for i in range( main.numCtrls ):
3635 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 Halle1a3b752015-07-22 13:02:46 -07003644 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003645 if size != sizeResponses[ i ]:
3646 sizeResults = main.FALSE
3647 main.log.error( "ONOS" + str( i + 1 ) +
3648 " expected a size of " + str( size ) +
3649 " for set " + onosSetName +
3650 " but got " + str( sizeResponses[ i ] ) )
3651 addResults = addResults and getResults and sizeResults
3652 utilities.assert_equals( expect=main.TRUE,
3653 actual=addResults,
3654 onpass="Set add correct",
3655 onfail="Set add was incorrect" )
3656
3657 main.step( "Distributed Set addAll()" )
3658 onosSet.update( addAllValue.split() )
3659 addResponses = []
3660 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003661 for i in range( main.numCtrls ):
3662 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003663 name="setTestAddAll-" + str( i ),
3664 args=[ onosSetName, addAllValue ] )
3665 threads.append( t )
3666 t.start()
3667 for t in threads:
3668 t.join()
3669 addResponses.append( t.result )
3670
3671 # main.TRUE = successfully changed the set
3672 # main.FALSE = action resulted in no change in set
3673 # main.ERROR - Some error in executing the function
3674 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003675 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003676 if addResponses[ i ] == main.TRUE:
3677 # All is well
3678 pass
3679 elif addResponses[ i ] == main.FALSE:
3680 # Already in set, probably fine
3681 pass
3682 elif addResponses[ i ] == main.ERROR:
3683 # Error in execution
3684 addAllResults = main.FALSE
3685 else:
3686 # unexpected result
3687 addAllResults = main.FALSE
3688 if addAllResults != main.TRUE:
3689 main.log.error( "Error executing set addAll" )
3690
3691 # Check if set is still correct
3692 size = len( onosSet )
3693 getResponses = []
3694 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003695 for i in range( main.numCtrls ):
3696 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003697 name="setTestGet-" + str( i ),
3698 args=[ onosSetName ] )
3699 threads.append( t )
3700 t.start()
3701 for t in threads:
3702 t.join()
3703 getResponses.append( t.result )
3704 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003705 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003706 if isinstance( getResponses[ i ], list):
3707 current = set( getResponses[ i ] )
3708 if len( current ) == len( getResponses[ i ] ):
3709 # no repeats
3710 if onosSet != current:
3711 main.log.error( "ONOS" + str( i + 1 ) +
3712 " has incorrect view" +
3713 " of set " + onosSetName + ":\n" +
3714 str( getResponses[ i ] ) )
3715 main.log.debug( "Expected: " + str( onosSet ) )
3716 main.log.debug( "Actual: " + str( current ) )
3717 getResults = main.FALSE
3718 else:
3719 # error, set is not a set
3720 main.log.error( "ONOS" + str( i + 1 ) +
3721 " has repeat elements in" +
3722 " set " + onosSetName + ":\n" +
3723 str( getResponses[ i ] ) )
3724 getResults = main.FALSE
3725 elif getResponses[ i ] == main.ERROR:
3726 getResults = main.FALSE
3727 sizeResponses = []
3728 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003729 for i in range( main.numCtrls ):
3730 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003731 name="setTestSize-" + str( i ),
3732 args=[ onosSetName ] )
3733 threads.append( t )
3734 t.start()
3735 for t in threads:
3736 t.join()
3737 sizeResponses.append( t.result )
3738 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003739 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003740 if size != sizeResponses[ i ]:
3741 sizeResults = main.FALSE
3742 main.log.error( "ONOS" + str( i + 1 ) +
3743 " expected a size of " + str( size ) +
3744 " for set " + onosSetName +
3745 " but got " + str( sizeResponses[ i ] ) )
3746 addAllResults = addAllResults and getResults and sizeResults
3747 utilities.assert_equals( expect=main.TRUE,
3748 actual=addAllResults,
3749 onpass="Set addAll correct",
3750 onfail="Set addAll was incorrect" )
3751
3752 main.step( "Distributed Set contains()" )
3753 containsResponses = []
3754 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003755 for i in range( main.numCtrls ):
3756 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003757 name="setContains-" + str( i ),
3758 args=[ onosSetName ],
3759 kwargs={ "values": addValue } )
3760 threads.append( t )
3761 t.start()
3762 for t in threads:
3763 t.join()
3764 # NOTE: This is the tuple
3765 containsResponses.append( t.result )
3766
3767 containsResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003768 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003769 if containsResponses[ i ] == main.ERROR:
3770 containsResults = main.FALSE
3771 else:
3772 containsResults = containsResults and\
3773 containsResponses[ i ][ 1 ]
3774 utilities.assert_equals( expect=main.TRUE,
3775 actual=containsResults,
3776 onpass="Set contains is functional",
3777 onfail="Set contains failed" )
3778
3779 main.step( "Distributed Set containsAll()" )
3780 containsAllResponses = []
3781 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003782 for i in range( main.numCtrls ):
3783 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003784 name="setContainsAll-" + str( i ),
3785 args=[ onosSetName ],
3786 kwargs={ "values": addAllValue } )
3787 threads.append( t )
3788 t.start()
3789 for t in threads:
3790 t.join()
3791 # NOTE: This is the tuple
3792 containsAllResponses.append( t.result )
3793
3794 containsAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003795 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003796 if containsResponses[ i ] == main.ERROR:
3797 containsResults = main.FALSE
3798 else:
3799 containsResults = containsResults and\
3800 containsResponses[ i ][ 1 ]
3801 utilities.assert_equals( expect=main.TRUE,
3802 actual=containsAllResults,
3803 onpass="Set containsAll is functional",
3804 onfail="Set containsAll failed" )
3805
3806 main.step( "Distributed Set remove()" )
3807 onosSet.remove( addValue )
3808 removeResponses = []
3809 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003810 for i in range( main.numCtrls ):
3811 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003812 name="setTestRemove-" + str( i ),
3813 args=[ onosSetName, addValue ] )
3814 threads.append( t )
3815 t.start()
3816 for t in threads:
3817 t.join()
3818 removeResponses.append( t.result )
3819
3820 # main.TRUE = successfully changed the set
3821 # main.FALSE = action resulted in no change in set
3822 # main.ERROR - Some error in executing the function
3823 removeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003824 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003825 if removeResponses[ i ] == main.TRUE:
3826 # All is well
3827 pass
3828 elif removeResponses[ i ] == main.FALSE:
3829 # not in set, probably fine
3830 pass
3831 elif removeResponses[ i ] == main.ERROR:
3832 # Error in execution
3833 removeResults = main.FALSE
3834 else:
3835 # unexpected result
3836 removeResults = main.FALSE
3837 if removeResults != main.TRUE:
3838 main.log.error( "Error executing set remove" )
3839
3840 # Check if set is still correct
3841 size = len( onosSet )
3842 getResponses = []
3843 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003844 for i in range( main.numCtrls ):
3845 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003846 name="setTestGet-" + str( i ),
3847 args=[ onosSetName ] )
3848 threads.append( t )
3849 t.start()
3850 for t in threads:
3851 t.join()
3852 getResponses.append( t.result )
3853 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003854 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003855 if isinstance( getResponses[ i ], list):
3856 current = set( getResponses[ i ] )
3857 if len( current ) == len( getResponses[ i ] ):
3858 # no repeats
3859 if onosSet != current:
3860 main.log.error( "ONOS" + str( i + 1 ) +
3861 " has incorrect view" +
3862 " of set " + onosSetName + ":\n" +
3863 str( getResponses[ i ] ) )
3864 main.log.debug( "Expected: " + str( onosSet ) )
3865 main.log.debug( "Actual: " + str( current ) )
3866 getResults = main.FALSE
3867 else:
3868 # error, set is not a set
3869 main.log.error( "ONOS" + str( i + 1 ) +
3870 " has repeat elements in" +
3871 " set " + onosSetName + ":\n" +
3872 str( getResponses[ i ] ) )
3873 getResults = main.FALSE
3874 elif getResponses[ i ] == main.ERROR:
3875 getResults = main.FALSE
3876 sizeResponses = []
3877 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003878 for i in range( main.numCtrls ):
3879 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003880 name="setTestSize-" + str( i ),
3881 args=[ onosSetName ] )
3882 threads.append( t )
3883 t.start()
3884 for t in threads:
3885 t.join()
3886 sizeResponses.append( t.result )
3887 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003888 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003889 if size != sizeResponses[ i ]:
3890 sizeResults = main.FALSE
3891 main.log.error( "ONOS" + str( i + 1 ) +
3892 " expected a size of " + str( size ) +
3893 " for set " + onosSetName +
3894 " but got " + str( sizeResponses[ i ] ) )
3895 removeResults = removeResults and getResults and sizeResults
3896 utilities.assert_equals( expect=main.TRUE,
3897 actual=removeResults,
3898 onpass="Set remove correct",
3899 onfail="Set remove was incorrect" )
3900
3901 main.step( "Distributed Set removeAll()" )
3902 onosSet.difference_update( addAllValue.split() )
3903 removeAllResponses = []
3904 threads = []
3905 try:
Jon Halle1a3b752015-07-22 13:02:46 -07003906 for i in range( main.numCtrls ):
3907 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003908 name="setTestRemoveAll-" + str( i ),
3909 args=[ onosSetName, addAllValue ] )
3910 threads.append( t )
3911 t.start()
3912 for t in threads:
3913 t.join()
3914 removeAllResponses.append( t.result )
3915 except Exception, e:
3916 main.log.exception(e)
3917
3918 # main.TRUE = successfully changed the set
3919 # main.FALSE = action resulted in no change in set
3920 # main.ERROR - Some error in executing the function
3921 removeAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003922 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003923 if removeAllResponses[ i ] == main.TRUE:
3924 # All is well
3925 pass
3926 elif removeAllResponses[ i ] == main.FALSE:
3927 # not in set, probably fine
3928 pass
3929 elif removeAllResponses[ i ] == main.ERROR:
3930 # Error in execution
3931 removeAllResults = main.FALSE
3932 else:
3933 # unexpected result
3934 removeAllResults = main.FALSE
3935 if removeAllResults != main.TRUE:
3936 main.log.error( "Error executing set removeAll" )
3937
3938 # Check if set is still correct
3939 size = len( onosSet )
3940 getResponses = []
3941 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003942 for i in range( main.numCtrls ):
3943 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003944 name="setTestGet-" + str( i ),
3945 args=[ onosSetName ] )
3946 threads.append( t )
3947 t.start()
3948 for t in threads:
3949 t.join()
3950 getResponses.append( t.result )
3951 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003952 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003953 if isinstance( getResponses[ i ], list):
3954 current = set( getResponses[ i ] )
3955 if len( current ) == len( getResponses[ i ] ):
3956 # no repeats
3957 if onosSet != current:
3958 main.log.error( "ONOS" + str( i + 1 ) +
3959 " has incorrect view" +
3960 " of set " + onosSetName + ":\n" +
3961 str( getResponses[ i ] ) )
3962 main.log.debug( "Expected: " + str( onosSet ) )
3963 main.log.debug( "Actual: " + str( current ) )
3964 getResults = main.FALSE
3965 else:
3966 # error, set is not a set
3967 main.log.error( "ONOS" + str( i + 1 ) +
3968 " has repeat elements in" +
3969 " set " + onosSetName + ":\n" +
3970 str( getResponses[ i ] ) )
3971 getResults = main.FALSE
3972 elif getResponses[ i ] == main.ERROR:
3973 getResults = main.FALSE
3974 sizeResponses = []
3975 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003976 for i in range( main.numCtrls ):
3977 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003978 name="setTestSize-" + str( i ),
3979 args=[ onosSetName ] )
3980 threads.append( t )
3981 t.start()
3982 for t in threads:
3983 t.join()
3984 sizeResponses.append( t.result )
3985 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003986 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003987 if size != sizeResponses[ i ]:
3988 sizeResults = main.FALSE
3989 main.log.error( "ONOS" + str( i + 1 ) +
3990 " expected a size of " + str( size ) +
3991 " for set " + onosSetName +
3992 " but got " + str( sizeResponses[ i ] ) )
3993 removeAllResults = removeAllResults and getResults and sizeResults
3994 utilities.assert_equals( expect=main.TRUE,
3995 actual=removeAllResults,
3996 onpass="Set removeAll correct",
3997 onfail="Set removeAll was incorrect" )
3998
3999 main.step( "Distributed Set addAll()" )
4000 onosSet.update( addAllValue.split() )
4001 addResponses = []
4002 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004003 for i in range( main.numCtrls ):
4004 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004005 name="setTestAddAll-" + str( i ),
4006 args=[ onosSetName, addAllValue ] )
4007 threads.append( t )
4008 t.start()
4009 for t in threads:
4010 t.join()
4011 addResponses.append( t.result )
4012
4013 # main.TRUE = successfully changed the set
4014 # main.FALSE = action resulted in no change in set
4015 # main.ERROR - Some error in executing the function
4016 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004017 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004018 if addResponses[ i ] == main.TRUE:
4019 # All is well
4020 pass
4021 elif addResponses[ i ] == main.FALSE:
4022 # Already in set, probably fine
4023 pass
4024 elif addResponses[ i ] == main.ERROR:
4025 # Error in execution
4026 addAllResults = main.FALSE
4027 else:
4028 # unexpected result
4029 addAllResults = main.FALSE
4030 if addAllResults != main.TRUE:
4031 main.log.error( "Error executing set addAll" )
4032
4033 # Check if set is still correct
4034 size = len( onosSet )
4035 getResponses = []
4036 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004037 for i in range( main.numCtrls ):
4038 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004039 name="setTestGet-" + str( i ),
4040 args=[ onosSetName ] )
4041 threads.append( t )
4042 t.start()
4043 for t in threads:
4044 t.join()
4045 getResponses.append( t.result )
4046 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004047 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004048 if isinstance( getResponses[ i ], list):
4049 current = set( getResponses[ i ] )
4050 if len( current ) == len( getResponses[ i ] ):
4051 # no repeats
4052 if onosSet != current:
4053 main.log.error( "ONOS" + str( i + 1 ) +
4054 " has incorrect view" +
4055 " of set " + onosSetName + ":\n" +
4056 str( getResponses[ i ] ) )
4057 main.log.debug( "Expected: " + str( onosSet ) )
4058 main.log.debug( "Actual: " + str( current ) )
4059 getResults = main.FALSE
4060 else:
4061 # error, set is not a set
4062 main.log.error( "ONOS" + str( i + 1 ) +
4063 " has repeat elements in" +
4064 " set " + onosSetName + ":\n" +
4065 str( getResponses[ i ] ) )
4066 getResults = main.FALSE
4067 elif getResponses[ i ] == main.ERROR:
4068 getResults = main.FALSE
4069 sizeResponses = []
4070 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004071 for i in range( main.numCtrls ):
4072 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004073 name="setTestSize-" + str( i ),
4074 args=[ onosSetName ] )
4075 threads.append( t )
4076 t.start()
4077 for t in threads:
4078 t.join()
4079 sizeResponses.append( t.result )
4080 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004081 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004082 if size != sizeResponses[ i ]:
4083 sizeResults = main.FALSE
4084 main.log.error( "ONOS" + str( i + 1 ) +
4085 " expected a size of " + str( size ) +
4086 " for set " + onosSetName +
4087 " but got " + str( sizeResponses[ i ] ) )
4088 addAllResults = addAllResults and getResults and sizeResults
4089 utilities.assert_equals( expect=main.TRUE,
4090 actual=addAllResults,
4091 onpass="Set addAll correct",
4092 onfail="Set addAll was incorrect" )
4093
4094 main.step( "Distributed Set clear()" )
4095 onosSet.clear()
4096 clearResponses = []
4097 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004098 for i in range( main.numCtrls ):
4099 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004100 name="setTestClear-" + str( i ),
4101 args=[ onosSetName, " "], # Values doesn't matter
4102 kwargs={ "clear": True } )
4103 threads.append( t )
4104 t.start()
4105 for t in threads:
4106 t.join()
4107 clearResponses.append( t.result )
4108
4109 # main.TRUE = successfully changed the set
4110 # main.FALSE = action resulted in no change in set
4111 # main.ERROR - Some error in executing the function
4112 clearResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004113 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004114 if clearResponses[ i ] == main.TRUE:
4115 # All is well
4116 pass
4117 elif clearResponses[ i ] == main.FALSE:
4118 # Nothing set, probably fine
4119 pass
4120 elif clearResponses[ i ] == main.ERROR:
4121 # Error in execution
4122 clearResults = main.FALSE
4123 else:
4124 # unexpected result
4125 clearResults = main.FALSE
4126 if clearResults != main.TRUE:
4127 main.log.error( "Error executing set clear" )
4128
4129 # Check if set is still correct
4130 size = len( onosSet )
4131 getResponses = []
4132 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004133 for i in range( main.numCtrls ):
4134 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004135 name="setTestGet-" + str( i ),
4136 args=[ onosSetName ] )
4137 threads.append( t )
4138 t.start()
4139 for t in threads:
4140 t.join()
4141 getResponses.append( t.result )
4142 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004143 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004144 if isinstance( getResponses[ i ], list):
4145 current = set( getResponses[ i ] )
4146 if len( current ) == len( getResponses[ i ] ):
4147 # no repeats
4148 if onosSet != current:
4149 main.log.error( "ONOS" + str( i + 1 ) +
4150 " has incorrect view" +
4151 " of set " + onosSetName + ":\n" +
4152 str( getResponses[ i ] ) )
4153 main.log.debug( "Expected: " + str( onosSet ) )
4154 main.log.debug( "Actual: " + str( current ) )
4155 getResults = main.FALSE
4156 else:
4157 # error, set is not a set
4158 main.log.error( "ONOS" + str( i + 1 ) +
4159 " has repeat elements in" +
4160 " set " + onosSetName + ":\n" +
4161 str( getResponses[ i ] ) )
4162 getResults = main.FALSE
4163 elif getResponses[ i ] == main.ERROR:
4164 getResults = main.FALSE
4165 sizeResponses = []
4166 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004167 for i in range( main.numCtrls ):
4168 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004169 name="setTestSize-" + str( i ),
4170 args=[ onosSetName ] )
4171 threads.append( t )
4172 t.start()
4173 for t in threads:
4174 t.join()
4175 sizeResponses.append( t.result )
4176 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004177 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004178 if size != sizeResponses[ i ]:
4179 sizeResults = main.FALSE
4180 main.log.error( "ONOS" + str( i + 1 ) +
4181 " expected a size of " + str( size ) +
4182 " for set " + onosSetName +
4183 " but got " + str( sizeResponses[ i ] ) )
4184 clearResults = clearResults and getResults and sizeResults
4185 utilities.assert_equals( expect=main.TRUE,
4186 actual=clearResults,
4187 onpass="Set clear correct",
4188 onfail="Set clear was incorrect" )
4189
4190 main.step( "Distributed Set addAll()" )
4191 onosSet.update( addAllValue.split() )
4192 addResponses = []
4193 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004194 for i in range( main.numCtrls ):
4195 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004196 name="setTestAddAll-" + str( i ),
4197 args=[ onosSetName, addAllValue ] )
4198 threads.append( t )
4199 t.start()
4200 for t in threads:
4201 t.join()
4202 addResponses.append( t.result )
4203
4204 # main.TRUE = successfully changed the set
4205 # main.FALSE = action resulted in no change in set
4206 # main.ERROR - Some error in executing the function
4207 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004208 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004209 if addResponses[ i ] == main.TRUE:
4210 # All is well
4211 pass
4212 elif addResponses[ i ] == main.FALSE:
4213 # Already in set, probably fine
4214 pass
4215 elif addResponses[ i ] == main.ERROR:
4216 # Error in execution
4217 addAllResults = main.FALSE
4218 else:
4219 # unexpected result
4220 addAllResults = main.FALSE
4221 if addAllResults != main.TRUE:
4222 main.log.error( "Error executing set addAll" )
4223
4224 # Check if set is still correct
4225 size = len( onosSet )
4226 getResponses = []
4227 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004228 for i in range( main.numCtrls ):
4229 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004230 name="setTestGet-" + str( i ),
4231 args=[ onosSetName ] )
4232 threads.append( t )
4233 t.start()
4234 for t in threads:
4235 t.join()
4236 getResponses.append( t.result )
4237 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004238 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004239 if isinstance( getResponses[ i ], list):
4240 current = set( getResponses[ i ] )
4241 if len( current ) == len( getResponses[ i ] ):
4242 # no repeats
4243 if onosSet != current:
4244 main.log.error( "ONOS" + str( i + 1 ) +
4245 " has incorrect view" +
4246 " of set " + onosSetName + ":\n" +
4247 str( getResponses[ i ] ) )
4248 main.log.debug( "Expected: " + str( onosSet ) )
4249 main.log.debug( "Actual: " + str( current ) )
4250 getResults = main.FALSE
4251 else:
4252 # error, set is not a set
4253 main.log.error( "ONOS" + str( i + 1 ) +
4254 " has repeat elements in" +
4255 " set " + onosSetName + ":\n" +
4256 str( getResponses[ i ] ) )
4257 getResults = main.FALSE
4258 elif getResponses[ i ] == main.ERROR:
4259 getResults = main.FALSE
4260 sizeResponses = []
4261 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004262 for i in range( main.numCtrls ):
4263 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004264 name="setTestSize-" + str( i ),
4265 args=[ onosSetName ] )
4266 threads.append( t )
4267 t.start()
4268 for t in threads:
4269 t.join()
4270 sizeResponses.append( t.result )
4271 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004272 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004273 if size != sizeResponses[ i ]:
4274 sizeResults = main.FALSE
4275 main.log.error( "ONOS" + str( i + 1 ) +
4276 " expected a size of " + str( size ) +
4277 " for set " + onosSetName +
4278 " but got " + str( sizeResponses[ i ] ) )
4279 addAllResults = addAllResults and getResults and sizeResults
4280 utilities.assert_equals( expect=main.TRUE,
4281 actual=addAllResults,
4282 onpass="Set addAll correct",
4283 onfail="Set addAll was incorrect" )
4284
4285 main.step( "Distributed Set retain()" )
4286 onosSet.intersection_update( retainValue.split() )
4287 retainResponses = []
4288 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004289 for i in range( main.numCtrls ):
4290 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004291 name="setTestRetain-" + str( i ),
4292 args=[ onosSetName, retainValue ],
4293 kwargs={ "retain": True } )
4294 threads.append( t )
4295 t.start()
4296 for t in threads:
4297 t.join()
4298 retainResponses.append( t.result )
4299
4300 # main.TRUE = successfully changed the set
4301 # main.FALSE = action resulted in no change in set
4302 # main.ERROR - Some error in executing the function
4303 retainResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004304 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004305 if retainResponses[ i ] == main.TRUE:
4306 # All is well
4307 pass
4308 elif retainResponses[ i ] == main.FALSE:
4309 # Already in set, probably fine
4310 pass
4311 elif retainResponses[ i ] == main.ERROR:
4312 # Error in execution
4313 retainResults = main.FALSE
4314 else:
4315 # unexpected result
4316 retainResults = main.FALSE
4317 if retainResults != main.TRUE:
4318 main.log.error( "Error executing set retain" )
4319
4320 # Check if set is still correct
4321 size = len( onosSet )
4322 getResponses = []
4323 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004324 for i in range( main.numCtrls ):
4325 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004326 name="setTestGet-" + str( i ),
4327 args=[ onosSetName ] )
4328 threads.append( t )
4329 t.start()
4330 for t in threads:
4331 t.join()
4332 getResponses.append( t.result )
4333 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004334 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004335 if isinstance( getResponses[ i ], list):
4336 current = set( getResponses[ i ] )
4337 if len( current ) == len( getResponses[ i ] ):
4338 # no repeats
4339 if onosSet != current:
4340 main.log.error( "ONOS" + str( i + 1 ) +
4341 " has incorrect view" +
4342 " of set " + onosSetName + ":\n" +
4343 str( getResponses[ i ] ) )
4344 main.log.debug( "Expected: " + str( onosSet ) )
4345 main.log.debug( "Actual: " + str( current ) )
4346 getResults = main.FALSE
4347 else:
4348 # error, set is not a set
4349 main.log.error( "ONOS" + str( i + 1 ) +
4350 " has repeat elements in" +
4351 " set " + onosSetName + ":\n" +
4352 str( getResponses[ i ] ) )
4353 getResults = main.FALSE
4354 elif getResponses[ i ] == main.ERROR:
4355 getResults = main.FALSE
4356 sizeResponses = []
4357 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004358 for i in range( main.numCtrls ):
4359 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004360 name="setTestSize-" + str( i ),
4361 args=[ onosSetName ] )
4362 threads.append( t )
4363 t.start()
4364 for t in threads:
4365 t.join()
4366 sizeResponses.append( t.result )
4367 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004368 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004369 if size != sizeResponses[ i ]:
4370 sizeResults = main.FALSE
4371 main.log.error( "ONOS" + str( i + 1 ) +
4372 " expected a size of " +
4373 str( size ) + " for set " + onosSetName +
4374 " but got " + str( sizeResponses[ i ] ) )
4375 retainResults = retainResults and getResults and sizeResults
4376 utilities.assert_equals( expect=main.TRUE,
4377 actual=retainResults,
4378 onpass="Set retain correct",
4379 onfail="Set retain was incorrect" )
4380
Jon Hall2a5002c2015-08-21 16:49:11 -07004381 # Transactional maps
4382 main.step( "Partitioned Transactional maps put" )
4383 tMapValue = "Testing"
4384 numKeys = 100
4385 putResult = True
4386 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue )
4387 if len( putResponses ) == 100:
4388 for i in putResponses:
4389 if putResponses[ i ][ 'value' ] != tMapValue:
4390 putResult = False
4391 else:
4392 putResult = False
4393 if not putResult:
4394 main.log.debug( "Put response values: " + str( putResponses ) )
4395 utilities.assert_equals( expect=True,
4396 actual=putResult,
4397 onpass="Partitioned Transactional Map put successful",
4398 onfail="Partitioned Transactional Map put values are incorrect" )
4399
4400 main.step( "Partitioned Transactional maps get" )
4401 getCheck = True
4402 for n in range( 1, numKeys + 1 ):
4403 getResponses = []
4404 threads = []
4405 valueCheck = True
4406 for i in range( main.numCtrls ):
4407 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4408 name="TMap-get-" + str( i ),
4409 args=[ "Key" + str ( n ) ] )
4410 threads.append( t )
4411 t.start()
4412 for t in threads:
4413 t.join()
4414 getResponses.append( t.result )
4415 for node in getResponses:
4416 if node != tMapValue:
4417 valueCheck = False
4418 if not valueCheck:
4419 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4420 main.log.warn( getResponses )
4421 getCheck = getCheck and valueCheck
4422 utilities.assert_equals( expect=True,
4423 actual=getCheck,
4424 onpass="Partitioned Transactional Map get values were correct",
4425 onfail="Partitioned Transactional Map values incorrect" )
4426
4427 main.step( "In-memory Transactional maps put" )
4428 tMapValue = "Testing"
4429 numKeys = 100
4430 putResult = True
4431 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue, inMemory=True )
4432 if len( putResponses ) == 100:
4433 for i in putResponses:
4434 if putResponses[ i ][ 'value' ] != tMapValue:
4435 putResult = False
4436 else:
4437 putResult = False
4438 if not putResult:
4439 main.log.debug( "Put response values: " + str( putResponses ) )
4440 utilities.assert_equals( expect=True,
4441 actual=putResult,
4442 onpass="In-Memory Transactional Map put successful",
4443 onfail="In-Memory Transactional Map put values are incorrect" )
4444
4445 main.step( "In-Memory Transactional maps get" )
4446 getCheck = True
4447 for n in range( 1, numKeys + 1 ):
4448 getResponses = []
4449 threads = []
4450 valueCheck = True
4451 for i in range( main.numCtrls ):
4452 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4453 name="TMap-get-" + str( i ),
4454 args=[ "Key" + str ( n ) ],
4455 kwargs={ "inMemory": True } )
4456 threads.append( t )
4457 t.start()
4458 for t in threads:
4459 t.join()
4460 getResponses.append( t.result )
4461 for node in getResponses:
4462 if node != tMapValue:
4463 valueCheck = False
4464 if not valueCheck:
4465 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4466 main.log.warn( getResponses )
4467 getCheck = getCheck and valueCheck
4468 utilities.assert_equals( expect=True,
4469 actual=getCheck,
4470 onpass="In-Memory Transactional Map get values were correct",
4471 onfail="In-Memory Transactional Map values incorrect" )