blob: f9ab800afb1c5273eb0f40b7a2fcbb425e6379ec [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"
185 graphs = '<ac:structured-macro ac:name="html">\n'
186 graphs += '<ac:plain-text-body><![CDATA[\n'
187 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
188 '/plot/' + plotName + '/getPlot?index=0' +\
189 '&width=500&height=300"' +\
190 'noborder="0" width="500" height="300" scrolling="yes" ' +\
191 'seamless="seamless"></iframe>\n'
192 graphs += ']]></ac:plain-text-body>\n'
193 graphs += '</ac:structured-macro>\n'
194 main.log.wiki(graphs)
195
196 main.step( "Creating ONOS package" )
197 packageResult = main.ONOSbench.onosPackage()
198 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
199 onpass="ONOS package successful",
200 onfail="ONOS package failed" )
201
202 main.step( "Installing ONOS package" )
203 onosInstallResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700204 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700205 tmpResult = main.ONOSbench.onosInstall( options="-f",
206 node=node.ip_address )
207 onosInstallResult = onosInstallResult and tmpResult
208 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
209 onpass="ONOS install successful",
210 onfail="ONOS install failed" )
211
212 main.step( "Checking if ONOS is up yet" )
213 for i in range( 2 ):
214 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700215 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700216 started = main.ONOSbench.isup( node.ip_address )
217 if not started:
218 main.log.error( node.name + " didn't start!" )
219 main.ONOSbench.onosStop( node.ip_address )
220 main.ONOSbench.onosStart( node.ip_address )
221 onosIsupResult = onosIsupResult and started
222 if onosIsupResult == main.TRUE:
223 break
224 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
225 onpass="ONOS startup successful",
226 onfail="ONOS startup failed" )
227
228 main.log.step( "Starting ONOS CLI sessions" )
229 cliResults = main.TRUE
230 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700231 for i in range( main.numCtrls ):
232 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -0700233 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -0700234 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -0700235 threads.append( t )
236 t.start()
237
238 for t in threads:
239 t.join()
240 cliResults = cliResults and t.result
241 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
242 onpass="ONOS cli startup successful",
243 onfail="ONOS cli startup failed" )
244
245 if main.params[ 'tcpdump' ].lower() == "true":
246 main.step( "Start Packet Capture MN" )
247 main.Mininet2.startTcpdump(
248 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
249 + "-MN.pcap",
250 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
251 port=main.params[ 'MNtcpdump' ][ 'port' ] )
252
253 main.step( "App Ids check" )
Jon Hallf3d16e72015-12-16 17:45:08 -0800254 time.sleep(60)
Jon Hall5cf14d52015-07-16 12:15:19 -0700255 appCheck = main.TRUE
256 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700257 for i in range( main.numCtrls ):
258 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700259 name="appToIDCheck-" + str( i ),
260 args=[] )
261 threads.append( t )
262 t.start()
263
264 for t in threads:
265 t.join()
266 appCheck = appCheck and t.result
267 if appCheck != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700268 main.log.warn( main.CLIs[0].apps() )
269 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700270 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
271 onpass="App Ids seem to be correct",
272 onfail="Something is wrong with app Ids" )
273
274 if cliResults == main.FALSE:
275 main.log.error( "Failed to start ONOS, stopping test" )
276 main.cleanup()
277 main.exit()
278
279 def CASE2( self, main ):
280 """
281 Assign devices to controllers
282 """
283 import re
Jon Halle1a3b752015-07-22 13:02:46 -0700284 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700285 assert main, "main not defined"
286 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700287 assert main.CLIs, "main.CLIs not defined"
288 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700289 assert ONOS1Port, "ONOS1Port not defined"
290 assert ONOS2Port, "ONOS2Port not defined"
291 assert ONOS3Port, "ONOS3Port not defined"
292 assert ONOS4Port, "ONOS4Port not defined"
293 assert ONOS5Port, "ONOS5Port not defined"
294 assert ONOS6Port, "ONOS6Port not defined"
295 assert ONOS7Port, "ONOS7Port not defined"
296
297 main.case( "Assigning devices to controllers" )
Jon Hall783bbf92015-07-23 14:33:19 -0700298 main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700299 "and check that an ONOS node becomes the " +\
300 "master of the device."
301 main.step( "Assign switches to controllers" )
302
303 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700304 for i in range( main.numCtrls ):
305 ipList.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -0700306 swList = []
307 for i in range( 1, 29 ):
308 swList.append( "s" + str( i ) )
309 main.Mininet1.assignSwController( sw=swList, ip=ipList )
310
311 mastershipCheck = main.TRUE
312 for i in range( 1, 29 ):
313 response = main.Mininet1.getSwController( "s" + str( i ) )
314 try:
315 main.log.info( str( response ) )
316 except Exception:
317 main.log.info( repr( response ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700318 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700319 if re.search( "tcp:" + node.ip_address, response ):
320 mastershipCheck = mastershipCheck and main.TRUE
321 else:
322 main.log.error( "Error, node " + node.ip_address + " is " +
323 "not in the list of controllers s" +
324 str( i ) + " is connecting to." )
325 mastershipCheck = main.FALSE
326 utilities.assert_equals(
327 expect=main.TRUE,
328 actual=mastershipCheck,
329 onpass="Switch mastership assigned correctly",
330 onfail="Switches not assigned correctly to controllers" )
331
332 def CASE21( self, main ):
333 """
334 Assign mastership to controllers
335 """
Jon Hall5cf14d52015-07-16 12:15:19 -0700336 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700337 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700338 assert main, "main not defined"
339 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700340 assert main.CLIs, "main.CLIs not defined"
341 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700342 assert ONOS1Port, "ONOS1Port not defined"
343 assert ONOS2Port, "ONOS2Port not defined"
344 assert ONOS3Port, "ONOS3Port not defined"
345 assert ONOS4Port, "ONOS4Port not defined"
346 assert ONOS5Port, "ONOS5Port not defined"
347 assert ONOS6Port, "ONOS6Port not defined"
348 assert ONOS7Port, "ONOS7Port not defined"
349
350 main.case( "Assigning Controller roles for switches" )
Jon Hall783bbf92015-07-23 14:33:19 -0700351 main.caseExplanation = "Check that ONOS is connected to each " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700352 "device. Then manually assign" +\
353 " mastership to specific ONOS nodes using" +\
354 " 'device-role'"
355 main.step( "Assign mastership of switches to specific controllers" )
356 # Manually assign mastership to the controller we want
357 roleCall = main.TRUE
358
359 ipList = [ ]
360 deviceList = []
361 try:
362 # Assign mastership to specific controllers. This assignment was
363 # determined for a 7 node cluser, but will work with any sized
364 # cluster
365 for i in range( 1, 29 ): # switches 1 through 28
366 # set up correct variables:
367 if i == 1:
368 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700369 ip = main.nodes[ c ].ip_address # ONOS1
Jon Hall5cf14d52015-07-16 12:15:19 -0700370 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
371 elif i == 2:
Jon Halle1a3b752015-07-22 13:02:46 -0700372 c = 1 % main.numCtrls
373 ip = main.nodes[ c ].ip_address # ONOS2
Jon Hall5cf14d52015-07-16 12:15:19 -0700374 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
375 elif i == 3:
Jon Halle1a3b752015-07-22 13:02:46 -0700376 c = 1 % main.numCtrls
377 ip = main.nodes[ c ].ip_address # ONOS2
Jon Hall5cf14d52015-07-16 12:15:19 -0700378 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
379 elif i == 4:
Jon Halle1a3b752015-07-22 13:02:46 -0700380 c = 3 % main.numCtrls
381 ip = main.nodes[ c ].ip_address # ONOS4
Jon Hall5cf14d52015-07-16 12:15:19 -0700382 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
383 elif i == 5:
Jon Halle1a3b752015-07-22 13:02:46 -0700384 c = 2 % main.numCtrls
385 ip = main.nodes[ c ].ip_address # ONOS3
Jon Hall5cf14d52015-07-16 12:15:19 -0700386 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
387 elif i == 6:
Jon Halle1a3b752015-07-22 13:02:46 -0700388 c = 2 % main.numCtrls
389 ip = main.nodes[ c ].ip_address # ONOS3
Jon Hall5cf14d52015-07-16 12:15:19 -0700390 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
391 elif i == 7:
Jon Halle1a3b752015-07-22 13:02:46 -0700392 c = 5 % main.numCtrls
393 ip = main.nodes[ c ].ip_address # ONOS6
Jon Hall5cf14d52015-07-16 12:15:19 -0700394 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
395 elif i >= 8 and i <= 17:
Jon Halle1a3b752015-07-22 13:02:46 -0700396 c = 4 % main.numCtrls
397 ip = main.nodes[ c ].ip_address # ONOS5
Jon Hall5cf14d52015-07-16 12:15:19 -0700398 dpid = '3' + str( i ).zfill( 3 )
399 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
400 elif i >= 18 and i <= 27:
Jon Halle1a3b752015-07-22 13:02:46 -0700401 c = 6 % main.numCtrls
402 ip = main.nodes[ c ].ip_address # ONOS7
Jon Hall5cf14d52015-07-16 12:15:19 -0700403 dpid = '6' + str( i ).zfill( 3 )
404 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
405 elif i == 28:
406 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700407 ip = main.nodes[ c ].ip_address # ONOS1
Jon Hall5cf14d52015-07-16 12:15:19 -0700408 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
409 else:
410 main.log.error( "You didn't write an else statement for " +
411 "switch s" + str( i ) )
412 roleCall = main.FALSE
413 # Assign switch
414 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
415 # TODO: make this controller dynamic
416 roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
417 ip )
418 ipList.append( ip )
419 deviceList.append( deviceId )
420 except ( AttributeError, AssertionError ):
421 main.log.exception( "Something is wrong with ONOS device view" )
422 main.log.info( main.ONOScli1.devices() )
423 utilities.assert_equals(
424 expect=main.TRUE,
425 actual=roleCall,
426 onpass="Re-assigned switch mastership to designated controller",
427 onfail="Something wrong with deviceRole calls" )
428
429 main.step( "Check mastership was correctly assigned" )
430 roleCheck = main.TRUE
431 # NOTE: This is due to the fact that device mastership change is not
432 # atomic and is actually a multi step process
433 time.sleep( 5 )
434 for i in range( len( ipList ) ):
435 ip = ipList[i]
436 deviceId = deviceList[i]
437 # Check assignment
438 master = main.ONOScli1.getRole( deviceId ).get( 'master' )
439 if ip in master:
440 roleCheck = roleCheck and main.TRUE
441 else:
442 roleCheck = roleCheck and main.FALSE
443 main.log.error( "Error, controller " + ip + " is not" +
444 " master " + "of device " +
445 str( deviceId ) + ". Master is " +
446 repr( master ) + "." )
447 utilities.assert_equals(
448 expect=main.TRUE,
449 actual=roleCheck,
450 onpass="Switches were successfully reassigned to designated " +
451 "controller",
452 onfail="Switches were not successfully reassigned" )
453
454 def CASE3( self, main ):
455 """
456 Assign intents
457 """
458 import time
459 import json
Jon Halle1a3b752015-07-22 13:02:46 -0700460 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700461 assert main, "main not defined"
462 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700463 assert main.CLIs, "main.CLIs not defined"
464 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700465 try:
466 labels
467 except NameError:
468 main.log.error( "labels not defined, setting to []" )
469 labels = []
470 try:
471 data
472 except NameError:
473 main.log.error( "data not defined, setting to []" )
474 data = []
475 # NOTE: we must reinstall intents until we have a persistant intent
476 # datastore!
477 main.case( "Adding host Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700478 main.caseExplanation = "Discover hosts by using pingall then " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700479 "assign predetermined host-to-host intents." +\
480 " After installation, check that the intent" +\
481 " is distributed to all nodes and the state" +\
482 " is INSTALLED"
483
484 # install onos-app-fwd
485 main.step( "Install reactive forwarding app" )
Jon Halle1a3b752015-07-22 13:02:46 -0700486 installResults = main.CLIs[0].activateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700487 utilities.assert_equals( expect=main.TRUE, actual=installResults,
488 onpass="Install fwd successful",
489 onfail="Install fwd failed" )
490
491 main.step( "Check app ids" )
492 appCheck = main.TRUE
493 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700494 for i in range( main.numCtrls ):
495 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700496 name="appToIDCheck-" + str( i ),
497 args=[] )
498 threads.append( t )
499 t.start()
500
501 for t in threads:
502 t.join()
503 appCheck = appCheck and t.result
504 if appCheck != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700505 main.log.warn( main.CLIs[0].apps() )
506 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700507 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
508 onpass="App Ids seem to be correct",
509 onfail="Something is wrong with app Ids" )
510
511 main.step( "Discovering Hosts( Via pingall for now )" )
512 # FIXME: Once we have a host discovery mechanism, use that instead
513 # REACTIVE FWD test
514 pingResult = main.FALSE
Jon Hall96091e62015-09-21 17:34:17 -0700515 passMsg = "Reactive Pingall test passed"
516 time1 = time.time()
517 pingResult = main.Mininet1.pingall()
518 time2 = time.time()
519 if not pingResult:
520 main.log.warn("First pingall failed. Trying again...")
Jon Hall5cf14d52015-07-16 12:15:19 -0700521 pingResult = main.Mininet1.pingall()
Jon Hall96091e62015-09-21 17:34:17 -0700522 passMsg += " on the second try"
523 utilities.assert_equals(
524 expect=main.TRUE,
525 actual=pingResult,
526 onpass= passMsg,
527 onfail="Reactive Pingall failed, " +
528 "one or more ping pairs failed" )
529 main.log.info( "Time for pingall: %2f seconds" %
530 ( time2 - time1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -0700531 # timeout for fwd flows
532 time.sleep( 11 )
533 # uninstall onos-app-fwd
534 main.step( "Uninstall reactive forwarding app" )
Jon Halle1a3b752015-07-22 13:02:46 -0700535 uninstallResult = main.CLIs[0].deactivateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700536 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
537 onpass="Uninstall fwd successful",
538 onfail="Uninstall fwd failed" )
539
540 main.step( "Check app ids" )
541 threads = []
542 appCheck2 = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700543 for i in range( main.numCtrls ):
544 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700545 name="appToIDCheck-" + str( i ),
546 args=[] )
547 threads.append( t )
548 t.start()
549
550 for t in threads:
551 t.join()
552 appCheck2 = appCheck2 and t.result
553 if appCheck2 != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700554 main.log.warn( main.CLIs[0].apps() )
555 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700556 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
557 onpass="App Ids seem to be correct",
558 onfail="Something is wrong with app Ids" )
559
560 main.step( "Add host intents via cli" )
561 intentIds = []
562 # TODO: move the host numbers to params
563 # Maybe look at all the paths we ping?
564 intentAddResult = True
565 hostResult = main.TRUE
566 for i in range( 8, 18 ):
567 main.log.info( "Adding host intent between h" + str( i ) +
568 " and h" + str( i + 10 ) )
569 host1 = "00:00:00:00:00:" + \
570 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
571 host2 = "00:00:00:00:00:" + \
572 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
573 # NOTE: getHost can return None
574 host1Dict = main.ONOScli1.getHost( host1 )
575 host2Dict = main.ONOScli1.getHost( host2 )
576 host1Id = None
577 host2Id = None
578 if host1Dict and host2Dict:
579 host1Id = host1Dict.get( 'id', None )
580 host2Id = host2Dict.get( 'id', None )
581 if host1Id and host2Id:
Jon Halle1a3b752015-07-22 13:02:46 -0700582 nodeNum = ( i % main.numCtrls )
583 tmpId = main.CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
Jon Hall5cf14d52015-07-16 12:15:19 -0700584 if tmpId:
585 main.log.info( "Added intent with id: " + tmpId )
586 intentIds.append( tmpId )
587 else:
588 main.log.error( "addHostIntent returned: " +
589 repr( tmpId ) )
590 else:
591 main.log.error( "Error, getHost() failed for h" + str( i ) +
592 " and/or h" + str( i + 10 ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700593 hosts = main.CLIs[ 0 ].hosts()
Jon Hall5cf14d52015-07-16 12:15:19 -0700594 main.log.warn( "Hosts output: " )
595 try:
596 main.log.warn( json.dumps( json.loads( hosts ),
597 sort_keys=True,
598 indent=4,
599 separators=( ',', ': ' ) ) )
600 except ( ValueError, TypeError ):
601 main.log.warn( repr( hosts ) )
602 hostResult = main.FALSE
603 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
604 onpass="Found a host id for each host",
605 onfail="Error looking up host ids" )
606
607 intentStart = time.time()
608 onosIds = main.ONOScli1.getAllIntentsId()
609 main.log.info( "Submitted intents: " + str( intentIds ) )
610 main.log.info( "Intents in ONOS: " + str( onosIds ) )
611 for intent in intentIds:
612 if intent in onosIds:
613 pass # intent submitted is in onos
614 else:
615 intentAddResult = False
616 if intentAddResult:
617 intentStop = time.time()
618 else:
619 intentStop = None
620 # Print the intent states
621 intents = main.ONOScli1.intents()
622 intentStates = []
623 installedCheck = True
624 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
625 count = 0
626 try:
627 for intent in json.loads( intents ):
628 state = intent.get( 'state', None )
629 if "INSTALLED" not in state:
630 installedCheck = False
631 intentId = intent.get( 'id', None )
632 intentStates.append( ( intentId, state ) )
633 except ( ValueError, TypeError ):
634 main.log.exception( "Error parsing intents" )
635 # add submitted intents not in the store
636 tmplist = [ i for i, s in intentStates ]
637 missingIntents = False
638 for i in intentIds:
639 if i not in tmplist:
640 intentStates.append( ( i, " - " ) )
641 missingIntents = True
642 intentStates.sort()
643 for i, s in intentStates:
644 count += 1
645 main.log.info( "%-6s%-15s%-15s" %
646 ( str( count ), str( i ), str( s ) ) )
647 leaders = main.ONOScli1.leaders()
648 try:
649 missing = False
650 if leaders:
651 parsedLeaders = json.loads( leaders )
652 main.log.warn( json.dumps( parsedLeaders,
653 sort_keys=True,
654 indent=4,
655 separators=( ',', ': ' ) ) )
656 # check for all intent partitions
657 topics = []
658 for i in range( 14 ):
659 topics.append( "intent-partition-" + str( i ) )
660 main.log.debug( topics )
661 ONOStopics = [ j['topic'] for j in parsedLeaders ]
662 for topic in topics:
663 if topic not in ONOStopics:
664 main.log.error( "Error: " + topic +
665 " not in leaders" )
666 missing = True
667 else:
668 main.log.error( "leaders() returned None" )
669 except ( ValueError, TypeError ):
670 main.log.exception( "Error parsing leaders" )
671 main.log.error( repr( leaders ) )
672 # Check all nodes
673 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -0700674 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700675 response = node.leaders( jsonFormat=False)
676 main.log.warn( str( node.name ) + " leaders output: \n" +
677 str( response ) )
678
679 partitions = main.ONOScli1.partitions()
680 try:
681 if partitions :
682 parsedPartitions = json.loads( partitions )
683 main.log.warn( json.dumps( parsedPartitions,
684 sort_keys=True,
685 indent=4,
686 separators=( ',', ': ' ) ) )
687 # TODO check for a leader in all paritions
688 # TODO check for consistency among nodes
689 else:
690 main.log.error( "partitions() returned None" )
691 except ( ValueError, TypeError ):
692 main.log.exception( "Error parsing partitions" )
693 main.log.error( repr( partitions ) )
694 pendingMap = main.ONOScli1.pendingMap()
695 try:
696 if pendingMap :
697 parsedPending = json.loads( pendingMap )
698 main.log.warn( json.dumps( parsedPending,
699 sort_keys=True,
700 indent=4,
701 separators=( ',', ': ' ) ) )
702 # TODO check something here?
703 else:
704 main.log.error( "pendingMap() returned None" )
705 except ( ValueError, TypeError ):
706 main.log.exception( "Error parsing pending map" )
707 main.log.error( repr( pendingMap ) )
708
709 intentAddResult = bool( intentAddResult and not missingIntents and
710 installedCheck )
711 if not intentAddResult:
712 main.log.error( "Error in pushing host intents to ONOS" )
713
714 main.step( "Intent Anti-Entropy dispersion" )
715 for i in range(100):
716 correct = True
717 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700718 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700719 onosIds = []
720 ids = cli.getAllIntentsId()
721 onosIds.append( ids )
722 main.log.debug( "Intents in " + cli.name + ": " +
723 str( sorted( onosIds ) ) )
724 if sorted( ids ) != sorted( intentIds ):
725 main.log.warn( "Set of intent IDs doesn't match" )
726 correct = False
727 break
728 else:
729 intents = json.loads( cli.intents() )
730 for intent in intents:
731 if intent[ 'state' ] != "INSTALLED":
732 main.log.warn( "Intent " + intent[ 'id' ] +
733 " is " + intent[ 'state' ] )
734 correct = False
735 break
736 if correct:
737 break
738 else:
739 time.sleep(1)
740 if not intentStop:
741 intentStop = time.time()
742 global gossipTime
743 gossipTime = intentStop - intentStart
744 main.log.info( "It took about " + str( gossipTime ) +
745 " seconds for all intents to appear in each node" )
746 append = False
747 title = "Gossip Intents"
748 count = 1
749 while append is False:
750 curTitle = title + str( count )
751 if curTitle not in labels:
752 labels.append( curTitle )
753 data.append( str( gossipTime ) )
754 append = True
755 else:
756 count += 1
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700757 gossipPeriod = int( main.params['timers']['gossip'] )
758 maxGossipTime = gossipPeriod * len( main.nodes )
Jon Hall5cf14d52015-07-16 12:15:19 -0700759 utilities.assert_greater_equals(
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700760 expect=maxGossipTime, actual=gossipTime,
Jon Hall5cf14d52015-07-16 12:15:19 -0700761 onpass="ECM anti-entropy for intents worked within " +
762 "expected time",
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700763 onfail="Intent ECM anti-entropy took too long. " +
764 "Expected time:{}, Actual time:{}".format( maxGossipTime,
765 gossipTime ) )
766 if gossipTime <= maxGossipTime:
Jon Hall5cf14d52015-07-16 12:15:19 -0700767 intentAddResult = True
768
769 if not intentAddResult or "key" in pendingMap:
770 import time
771 installedCheck = True
772 main.log.info( "Sleeping 60 seconds to see if intents are found" )
773 time.sleep( 60 )
774 onosIds = main.ONOScli1.getAllIntentsId()
775 main.log.info( "Submitted intents: " + str( intentIds ) )
776 main.log.info( "Intents in ONOS: " + str( onosIds ) )
777 # Print the intent states
778 intents = main.ONOScli1.intents()
779 intentStates = []
780 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
781 count = 0
782 try:
783 for intent in json.loads( intents ):
784 # Iter through intents of a node
785 state = intent.get( 'state', None )
786 if "INSTALLED" not in state:
787 installedCheck = False
788 intentId = intent.get( 'id', None )
789 intentStates.append( ( intentId, state ) )
790 except ( ValueError, TypeError ):
791 main.log.exception( "Error parsing intents" )
792 # add submitted intents not in the store
793 tmplist = [ i for i, s in intentStates ]
794 for i in intentIds:
795 if i not in tmplist:
796 intentStates.append( ( i, " - " ) )
797 intentStates.sort()
798 for i, s in intentStates:
799 count += 1
800 main.log.info( "%-6s%-15s%-15s" %
801 ( str( count ), str( i ), str( s ) ) )
802 leaders = main.ONOScli1.leaders()
803 try:
804 missing = False
805 if leaders:
806 parsedLeaders = json.loads( leaders )
807 main.log.warn( json.dumps( parsedLeaders,
808 sort_keys=True,
809 indent=4,
810 separators=( ',', ': ' ) ) )
811 # check for all intent partitions
812 # check for election
813 topics = []
814 for i in range( 14 ):
815 topics.append( "intent-partition-" + str( i ) )
816 # FIXME: this should only be after we start the app
817 topics.append( "org.onosproject.election" )
818 main.log.debug( topics )
819 ONOStopics = [ j['topic'] for j in parsedLeaders ]
820 for topic in topics:
821 if topic not in ONOStopics:
822 main.log.error( "Error: " + topic +
823 " not in leaders" )
824 missing = True
825 else:
826 main.log.error( "leaders() returned None" )
827 except ( ValueError, TypeError ):
828 main.log.exception( "Error parsing leaders" )
829 main.log.error( repr( leaders ) )
830 # Check all nodes
831 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -0700832 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700833 response = node.leaders( jsonFormat=False)
834 main.log.warn( str( node.name ) + " leaders output: \n" +
835 str( response ) )
836
837 partitions = main.ONOScli1.partitions()
838 try:
839 if partitions :
840 parsedPartitions = json.loads( partitions )
841 main.log.warn( json.dumps( parsedPartitions,
842 sort_keys=True,
843 indent=4,
844 separators=( ',', ': ' ) ) )
845 # TODO check for a leader in all paritions
846 # TODO check for consistency among nodes
847 else:
848 main.log.error( "partitions() returned None" )
849 except ( ValueError, TypeError ):
850 main.log.exception( "Error parsing partitions" )
851 main.log.error( repr( partitions ) )
852 pendingMap = main.ONOScli1.pendingMap()
853 try:
854 if pendingMap :
855 parsedPending = json.loads( pendingMap )
856 main.log.warn( json.dumps( parsedPending,
857 sort_keys=True,
858 indent=4,
859 separators=( ',', ': ' ) ) )
860 # TODO check something here?
861 else:
862 main.log.error( "pendingMap() returned None" )
863 except ( ValueError, TypeError ):
864 main.log.exception( "Error parsing pending map" )
865 main.log.error( repr( pendingMap ) )
866
867 def CASE4( self, main ):
868 """
869 Ping across added host intents
870 """
871 import json
872 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700873 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700874 assert main, "main not defined"
875 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700876 assert main.CLIs, "main.CLIs not defined"
877 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700878 main.case( "Verify connectivity by sendind traffic across Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700879 main.caseExplanation = "Ping across added host intents to check " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700880 "functionality and check the state of " +\
881 "the intent"
882 main.step( "Ping across added host intents" )
883 PingResult = main.TRUE
884 for i in range( 8, 18 ):
885 ping = main.Mininet1.pingHost( src="h" + str( i ),
886 target="h" + str( i + 10 ) )
887 PingResult = PingResult and ping
888 if ping == main.FALSE:
889 main.log.warn( "Ping failed between h" + str( i ) +
890 " and h" + str( i + 10 ) )
891 elif ping == main.TRUE:
892 main.log.info( "Ping test passed!" )
893 # Don't set PingResult or you'd override failures
894 if PingResult == main.FALSE:
895 main.log.error(
896 "Intents have not been installed correctly, pings failed." )
897 # TODO: pretty print
898 main.log.warn( "ONOS1 intents: " )
899 try:
900 tmpIntents = main.ONOScli1.intents()
901 main.log.warn( json.dumps( json.loads( tmpIntents ),
902 sort_keys=True,
903 indent=4,
904 separators=( ',', ': ' ) ) )
905 except ( ValueError, TypeError ):
906 main.log.warn( repr( tmpIntents ) )
907 utilities.assert_equals(
908 expect=main.TRUE,
909 actual=PingResult,
910 onpass="Intents have been installed correctly and pings work",
911 onfail="Intents have not been installed correctly, pings failed." )
912
913 main.step( "Check Intent state" )
914 installedCheck = False
915 loopCount = 0
916 while not installedCheck and loopCount < 40:
917 installedCheck = True
918 # Print the intent states
919 intents = main.ONOScli1.intents()
920 intentStates = []
921 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700922 count = 0
Jon Hall5cf14d52015-07-16 12:15:19 -0700923 # Iter through intents of a node
924 try:
925 for intent in json.loads( intents ):
926 state = intent.get( 'state', None )
927 if "INSTALLED" not in state:
928 installedCheck = False
929 intentId = intent.get( 'id', None )
930 intentStates.append( ( intentId, state ) )
931 except ( ValueError, TypeError ):
932 main.log.exception( "Error parsing intents." )
933 # Print states
934 intentStates.sort()
935 for i, s in intentStates:
936 count += 1
937 main.log.info( "%-6s%-15s%-15s" %
938 ( str( count ), str( i ), str( s ) ) )
939 if not installedCheck:
940 time.sleep( 1 )
941 loopCount += 1
942 utilities.assert_equals( expect=True, actual=installedCheck,
943 onpass="Intents are all INSTALLED",
944 onfail="Intents are not all in " +
945 "INSTALLED state" )
946
947 main.step( "Check leadership of topics" )
948 leaders = main.ONOScli1.leaders()
949 topicCheck = main.TRUE
950 try:
951 if leaders:
952 parsedLeaders = json.loads( leaders )
953 main.log.warn( json.dumps( parsedLeaders,
954 sort_keys=True,
955 indent=4,
956 separators=( ',', ': ' ) ) )
957 # check for all intent partitions
958 # check for election
959 # TODO: Look at Devices as topics now that it uses this system
960 topics = []
961 for i in range( 14 ):
962 topics.append( "intent-partition-" + str( i ) )
963 # FIXME: this should only be after we start the app
964 # FIXME: topics.append( "org.onosproject.election" )
965 # Print leaders output
966 main.log.debug( topics )
967 ONOStopics = [ j['topic'] for j in parsedLeaders ]
968 for topic in topics:
969 if topic not in ONOStopics:
970 main.log.error( "Error: " + topic +
971 " not in leaders" )
972 topicCheck = main.FALSE
973 else:
974 main.log.error( "leaders() returned None" )
975 topicCheck = main.FALSE
976 except ( ValueError, TypeError ):
977 topicCheck = main.FALSE
978 main.log.exception( "Error parsing leaders" )
979 main.log.error( repr( leaders ) )
980 # TODO: Check for a leader of these topics
981 # Check all nodes
982 if topicCheck:
Jon Halle1a3b752015-07-22 13:02:46 -0700983 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700984 response = node.leaders( jsonFormat=False)
985 main.log.warn( str( node.name ) + " leaders output: \n" +
986 str( response ) )
987
988 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
989 onpass="intent Partitions is in leaders",
990 onfail="Some topics were lost " )
991 # Print partitions
992 partitions = main.ONOScli1.partitions()
993 try:
994 if partitions :
995 parsedPartitions = json.loads( partitions )
996 main.log.warn( json.dumps( parsedPartitions,
997 sort_keys=True,
998 indent=4,
999 separators=( ',', ': ' ) ) )
1000 # TODO check for a leader in all paritions
1001 # TODO check for consistency among nodes
1002 else:
1003 main.log.error( "partitions() returned None" )
1004 except ( ValueError, TypeError ):
1005 main.log.exception( "Error parsing partitions" )
1006 main.log.error( repr( partitions ) )
1007 # Print Pending Map
1008 pendingMap = main.ONOScli1.pendingMap()
1009 try:
1010 if pendingMap :
1011 parsedPending = json.loads( pendingMap )
1012 main.log.warn( json.dumps( parsedPending,
1013 sort_keys=True,
1014 indent=4,
1015 separators=( ',', ': ' ) ) )
1016 # TODO check something here?
1017 else:
1018 main.log.error( "pendingMap() returned None" )
1019 except ( ValueError, TypeError ):
1020 main.log.exception( "Error parsing pending map" )
1021 main.log.error( repr( pendingMap ) )
1022
1023 if not installedCheck:
1024 main.log.info( "Waiting 60 seconds to see if the state of " +
1025 "intents change" )
1026 time.sleep( 60 )
1027 # Print the intent states
1028 intents = main.ONOScli1.intents()
1029 intentStates = []
1030 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
1031 count = 0
1032 # Iter through intents of a node
1033 try:
1034 for intent in json.loads( intents ):
1035 state = intent.get( 'state', None )
1036 if "INSTALLED" not in state:
1037 installedCheck = False
1038 intentId = intent.get( 'id', None )
1039 intentStates.append( ( intentId, state ) )
1040 except ( ValueError, TypeError ):
1041 main.log.exception( "Error parsing intents." )
1042 intentStates.sort()
1043 for i, s in intentStates:
1044 count += 1
1045 main.log.info( "%-6s%-15s%-15s" %
1046 ( str( count ), str( i ), str( s ) ) )
1047 leaders = main.ONOScli1.leaders()
1048 try:
1049 missing = False
1050 if leaders:
1051 parsedLeaders = json.loads( leaders )
1052 main.log.warn( json.dumps( parsedLeaders,
1053 sort_keys=True,
1054 indent=4,
1055 separators=( ',', ': ' ) ) )
1056 # check for all intent partitions
1057 # check for election
1058 topics = []
1059 for i in range( 14 ):
1060 topics.append( "intent-partition-" + str( i ) )
1061 # FIXME: this should only be after we start the app
1062 topics.append( "org.onosproject.election" )
1063 main.log.debug( topics )
1064 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1065 for topic in topics:
1066 if topic not in ONOStopics:
1067 main.log.error( "Error: " + topic +
1068 " not in leaders" )
1069 missing = True
1070 else:
1071 main.log.error( "leaders() returned None" )
1072 except ( ValueError, TypeError ):
1073 main.log.exception( "Error parsing leaders" )
1074 main.log.error( repr( leaders ) )
1075 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -07001076 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07001077 response = node.leaders( jsonFormat=False)
1078 main.log.warn( str( node.name ) + " leaders output: \n" +
1079 str( response ) )
1080
1081 partitions = main.ONOScli1.partitions()
1082 try:
1083 if partitions :
1084 parsedPartitions = json.loads( partitions )
1085 main.log.warn( json.dumps( parsedPartitions,
1086 sort_keys=True,
1087 indent=4,
1088 separators=( ',', ': ' ) ) )
1089 # TODO check for a leader in all paritions
1090 # TODO check for consistency among nodes
1091 else:
1092 main.log.error( "partitions() returned None" )
1093 except ( ValueError, TypeError ):
1094 main.log.exception( "Error parsing partitions" )
1095 main.log.error( repr( partitions ) )
1096 pendingMap = main.ONOScli1.pendingMap()
1097 try:
1098 if pendingMap :
1099 parsedPending = json.loads( pendingMap )
1100 main.log.warn( json.dumps( parsedPending,
1101 sort_keys=True,
1102 indent=4,
1103 separators=( ',', ': ' ) ) )
1104 # TODO check something here?
1105 else:
1106 main.log.error( "pendingMap() returned None" )
1107 except ( ValueError, TypeError ):
1108 main.log.exception( "Error parsing pending map" )
1109 main.log.error( repr( pendingMap ) )
1110 # Print flowrules
Jon Halle1a3b752015-07-22 13:02:46 -07001111 main.log.debug( main.CLIs[0].flows( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001112 main.step( "Wait a minute then ping again" )
1113 # the wait is above
1114 PingResult = main.TRUE
1115 for i in range( 8, 18 ):
1116 ping = main.Mininet1.pingHost( src="h" + str( i ),
1117 target="h" + str( i + 10 ) )
1118 PingResult = PingResult and ping
1119 if ping == main.FALSE:
1120 main.log.warn( "Ping failed between h" + str( i ) +
1121 " and h" + str( i + 10 ) )
1122 elif ping == main.TRUE:
1123 main.log.info( "Ping test passed!" )
1124 # Don't set PingResult or you'd override failures
1125 if PingResult == main.FALSE:
1126 main.log.error(
1127 "Intents have not been installed correctly, pings failed." )
1128 # TODO: pretty print
1129 main.log.warn( "ONOS1 intents: " )
1130 try:
1131 tmpIntents = main.ONOScli1.intents()
1132 main.log.warn( json.dumps( json.loads( tmpIntents ),
1133 sort_keys=True,
1134 indent=4,
1135 separators=( ',', ': ' ) ) )
1136 except ( ValueError, TypeError ):
1137 main.log.warn( repr( tmpIntents ) )
1138 utilities.assert_equals(
1139 expect=main.TRUE,
1140 actual=PingResult,
1141 onpass="Intents have been installed correctly and pings work",
1142 onfail="Intents have not been installed correctly, pings failed." )
1143
1144 def CASE5( self, main ):
1145 """
1146 Reading state of ONOS
1147 """
1148 import json
1149 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001150 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001151 assert main, "main not defined"
1152 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001153 assert main.CLIs, "main.CLIs not defined"
1154 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001155
1156 main.case( "Setting up and gathering data for current state" )
1157 # The general idea for this test case is to pull the state of
1158 # ( intents,flows, topology,... ) from each ONOS node
1159 # We can then compare them with each other and also with past states
1160
1161 main.step( "Check that each switch has a master" )
1162 global mastershipState
1163 mastershipState = '[]'
1164
1165 # Assert that each device has a master
1166 rolesNotNull = main.TRUE
1167 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001168 for i in range( main.numCtrls ):
1169 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001170 name="rolesNotNull-" + str( i ),
1171 args=[] )
1172 threads.append( t )
1173 t.start()
1174
1175 for t in threads:
1176 t.join()
1177 rolesNotNull = rolesNotNull and t.result
1178 utilities.assert_equals(
1179 expect=main.TRUE,
1180 actual=rolesNotNull,
1181 onpass="Each device has a master",
1182 onfail="Some devices don't have a master assigned" )
1183
1184 main.step( "Get the Mastership of each switch from each controller" )
1185 ONOSMastership = []
1186 mastershipCheck = main.FALSE
1187 consistentMastership = True
1188 rolesResults = True
1189 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001190 for i in range( main.numCtrls ):
1191 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001192 name="roles-" + str( i ),
1193 args=[] )
1194 threads.append( t )
1195 t.start()
1196
1197 for t in threads:
1198 t.join()
1199 ONOSMastership.append( t.result )
1200
Jon Halle1a3b752015-07-22 13:02:46 -07001201 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001202 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1203 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1204 " roles" )
1205 main.log.warn(
1206 "ONOS" + str( i + 1 ) + " mastership response: " +
1207 repr( ONOSMastership[i] ) )
1208 rolesResults = False
1209 utilities.assert_equals(
1210 expect=True,
1211 actual=rolesResults,
1212 onpass="No error in reading roles output",
1213 onfail="Error in reading roles from ONOS" )
1214
1215 main.step( "Check for consistency in roles from each controller" )
1216 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1217 main.log.info(
1218 "Switch roles are consistent across all ONOS nodes" )
1219 else:
1220 consistentMastership = False
1221 utilities.assert_equals(
1222 expect=True,
1223 actual=consistentMastership,
1224 onpass="Switch roles are consistent across all ONOS nodes",
1225 onfail="ONOS nodes have different views of switch roles" )
1226
1227 if rolesResults and not consistentMastership:
Jon Halle1a3b752015-07-22 13:02:46 -07001228 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001229 try:
1230 main.log.warn(
1231 "ONOS" + str( i + 1 ) + " roles: ",
1232 json.dumps(
1233 json.loads( ONOSMastership[ i ] ),
1234 sort_keys=True,
1235 indent=4,
1236 separators=( ',', ': ' ) ) )
1237 except ( ValueError, TypeError ):
1238 main.log.warn( repr( ONOSMastership[ i ] ) )
1239 elif rolesResults and consistentMastership:
1240 mastershipCheck = main.TRUE
1241 mastershipState = ONOSMastership[ 0 ]
1242
1243 main.step( "Get the intents from each controller" )
1244 global intentState
1245 intentState = []
1246 ONOSIntents = []
1247 intentCheck = main.FALSE
1248 consistentIntents = True
1249 intentsResults = True
1250 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001251 for i in range( main.numCtrls ):
1252 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001253 name="intents-" + str( i ),
1254 args=[],
1255 kwargs={ 'jsonFormat': True } )
1256 threads.append( t )
1257 t.start()
1258
1259 for t in threads:
1260 t.join()
1261 ONOSIntents.append( t.result )
1262
Jon Halle1a3b752015-07-22 13:02:46 -07001263 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001264 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1265 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1266 " intents" )
1267 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1268 repr( ONOSIntents[ i ] ) )
1269 intentsResults = False
1270 utilities.assert_equals(
1271 expect=True,
1272 actual=intentsResults,
1273 onpass="No error in reading intents output",
1274 onfail="Error in reading intents from ONOS" )
1275
1276 main.step( "Check for consistency in Intents from each controller" )
1277 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1278 main.log.info( "Intents are consistent across all ONOS " +
1279 "nodes" )
1280 else:
1281 consistentIntents = False
1282 main.log.error( "Intents not consistent" )
1283 utilities.assert_equals(
1284 expect=True,
1285 actual=consistentIntents,
1286 onpass="Intents are consistent across all ONOS nodes",
1287 onfail="ONOS nodes have different views of intents" )
1288
1289 if intentsResults:
1290 # Try to make it easy to figure out what is happening
1291 #
1292 # Intent ONOS1 ONOS2 ...
1293 # 0x01 INSTALLED INSTALLING
1294 # ... ... ...
1295 # ... ... ...
1296 title = " Id"
Jon Halle1a3b752015-07-22 13:02:46 -07001297 for n in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001298 title += " " * 10 + "ONOS" + str( n + 1 )
1299 main.log.warn( title )
1300 # get all intent keys in the cluster
1301 keys = []
1302 for nodeStr in ONOSIntents:
1303 node = json.loads( nodeStr )
1304 for intent in node:
1305 keys.append( intent.get( 'id' ) )
1306 keys = set( keys )
1307 for key in keys:
1308 row = "%-13s" % key
1309 for nodeStr in ONOSIntents:
1310 node = json.loads( nodeStr )
1311 for intent in node:
1312 if intent.get( 'id', "Error" ) == key:
1313 row += "%-15s" % intent.get( 'state' )
1314 main.log.warn( row )
1315 # End table view
1316
1317 if intentsResults and not consistentIntents:
1318 # print the json objects
1319 n = len(ONOSIntents)
1320 main.log.debug( "ONOS" + str( n ) + " intents: " )
1321 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1322 sort_keys=True,
1323 indent=4,
1324 separators=( ',', ': ' ) ) )
Jon Halle1a3b752015-07-22 13:02:46 -07001325 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001326 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
1327 main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
1328 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1329 sort_keys=True,
1330 indent=4,
1331 separators=( ',', ': ' ) ) )
1332 else:
Jon Halle1a3b752015-07-22 13:02:46 -07001333 main.log.debug( main.nodes[ i ].name + " intents match ONOS" +
Jon Hall5cf14d52015-07-16 12:15:19 -07001334 str( n ) + " intents" )
1335 elif intentsResults and consistentIntents:
1336 intentCheck = main.TRUE
1337 intentState = ONOSIntents[ 0 ]
1338
1339 main.step( "Get the flows from each controller" )
1340 global flowState
1341 flowState = []
1342 ONOSFlows = []
1343 ONOSFlowsJson = []
1344 flowCheck = main.FALSE
1345 consistentFlows = True
1346 flowsResults = True
1347 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001348 for i in range( main.numCtrls ):
1349 t = main.Thread( target=main.CLIs[i].flows,
Jon Hall5cf14d52015-07-16 12:15:19 -07001350 name="flows-" + str( i ),
1351 args=[],
1352 kwargs={ 'jsonFormat': True } )
1353 threads.append( t )
1354 t.start()
1355
1356 # NOTE: Flows command can take some time to run
1357 time.sleep(30)
1358 for t in threads:
1359 t.join()
1360 result = t.result
1361 ONOSFlows.append( result )
1362
Jon Halle1a3b752015-07-22 13:02:46 -07001363 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001364 num = str( i + 1 )
1365 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1366 main.log.error( "Error in getting ONOS" + num + " flows" )
1367 main.log.warn( "ONOS" + num + " flows response: " +
1368 repr( ONOSFlows[ i ] ) )
1369 flowsResults = False
1370 ONOSFlowsJson.append( None )
1371 else:
1372 try:
1373 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1374 except ( ValueError, TypeError ):
1375 # FIXME: change this to log.error?
1376 main.log.exception( "Error in parsing ONOS" + num +
1377 " response as json." )
1378 main.log.error( repr( ONOSFlows[ i ] ) )
1379 ONOSFlowsJson.append( None )
1380 flowsResults = False
1381 utilities.assert_equals(
1382 expect=True,
1383 actual=flowsResults,
1384 onpass="No error in reading flows output",
1385 onfail="Error in reading flows from ONOS" )
1386
1387 main.step( "Check for consistency in Flows from each controller" )
1388 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1389 if all( tmp ):
1390 main.log.info( "Flow count is consistent across all ONOS nodes" )
1391 else:
1392 consistentFlows = False
1393 utilities.assert_equals(
1394 expect=True,
1395 actual=consistentFlows,
1396 onpass="The flow count is consistent across all ONOS nodes",
1397 onfail="ONOS nodes have different flow counts" )
1398
1399 if flowsResults and not consistentFlows:
Jon Halle1a3b752015-07-22 13:02:46 -07001400 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001401 try:
1402 main.log.warn(
1403 "ONOS" + str( i + 1 ) + " flows: " +
1404 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1405 indent=4, separators=( ',', ': ' ) ) )
1406 except ( ValueError, TypeError ):
1407 main.log.warn(
1408 "ONOS" + str( i + 1 ) + " flows: " +
1409 repr( ONOSFlows[ i ] ) )
1410 elif flowsResults and consistentFlows:
1411 flowCheck = main.TRUE
1412 flowState = ONOSFlows[ 0 ]
1413
1414 main.step( "Get the OF Table entries" )
1415 global flows
1416 flows = []
1417 for i in range( 1, 29 ):
Jon Hallca7ac292015-11-11 09:28:12 -08001418 flows.append( main.Mininet1.getFlowTable( "s" + str( i ), version="1.3" ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001419 if flowCheck == main.FALSE:
1420 for table in flows:
1421 main.log.warn( table )
1422 # TODO: Compare switch flow tables with ONOS flow tables
1423
1424 main.step( "Start continuous pings" )
1425 main.Mininet2.pingLong(
1426 src=main.params[ 'PING' ][ 'source1' ],
1427 target=main.params[ 'PING' ][ 'target1' ],
1428 pingTime=500 )
1429 main.Mininet2.pingLong(
1430 src=main.params[ 'PING' ][ 'source2' ],
1431 target=main.params[ 'PING' ][ 'target2' ],
1432 pingTime=500 )
1433 main.Mininet2.pingLong(
1434 src=main.params[ 'PING' ][ 'source3' ],
1435 target=main.params[ 'PING' ][ 'target3' ],
1436 pingTime=500 )
1437 main.Mininet2.pingLong(
1438 src=main.params[ 'PING' ][ 'source4' ],
1439 target=main.params[ 'PING' ][ 'target4' ],
1440 pingTime=500 )
1441 main.Mininet2.pingLong(
1442 src=main.params[ 'PING' ][ 'source5' ],
1443 target=main.params[ 'PING' ][ 'target5' ],
1444 pingTime=500 )
1445 main.Mininet2.pingLong(
1446 src=main.params[ 'PING' ][ 'source6' ],
1447 target=main.params[ 'PING' ][ 'target6' ],
1448 pingTime=500 )
1449 main.Mininet2.pingLong(
1450 src=main.params[ 'PING' ][ 'source7' ],
1451 target=main.params[ 'PING' ][ 'target7' ],
1452 pingTime=500 )
1453 main.Mininet2.pingLong(
1454 src=main.params[ 'PING' ][ 'source8' ],
1455 target=main.params[ 'PING' ][ 'target8' ],
1456 pingTime=500 )
1457 main.Mininet2.pingLong(
1458 src=main.params[ 'PING' ][ 'source9' ],
1459 target=main.params[ 'PING' ][ 'target9' ],
1460 pingTime=500 )
1461 main.Mininet2.pingLong(
1462 src=main.params[ 'PING' ][ 'source10' ],
1463 target=main.params[ 'PING' ][ 'target10' ],
1464 pingTime=500 )
1465
1466 main.step( "Collecting topology information from ONOS" )
1467 devices = []
1468 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001469 for i in range( main.numCtrls ):
1470 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07001471 name="devices-" + str( i ),
1472 args=[ ] )
1473 threads.append( t )
1474 t.start()
1475
1476 for t in threads:
1477 t.join()
1478 devices.append( t.result )
1479 hosts = []
1480 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001481 for i in range( main.numCtrls ):
1482 t = main.Thread( target=main.CLIs[i].hosts,
Jon Hall5cf14d52015-07-16 12:15:19 -07001483 name="hosts-" + str( i ),
1484 args=[ ] )
1485 threads.append( t )
1486 t.start()
1487
1488 for t in threads:
1489 t.join()
1490 try:
1491 hosts.append( json.loads( t.result ) )
1492 except ( ValueError, TypeError ):
1493 # FIXME: better handling of this, print which node
1494 # Maybe use thread name?
1495 main.log.exception( "Error parsing json output of hosts" )
Jon Hall3afe4c92015-12-14 19:30:38 -08001496 main.log.warn( repr( t.result ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001497 hosts.append( None )
1498
1499 ports = []
1500 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001501 for i in range( main.numCtrls ):
1502 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07001503 name="ports-" + str( i ),
1504 args=[ ] )
1505 threads.append( t )
1506 t.start()
1507
1508 for t in threads:
1509 t.join()
1510 ports.append( t.result )
1511 links = []
1512 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001513 for i in range( main.numCtrls ):
1514 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07001515 name="links-" + str( i ),
1516 args=[ ] )
1517 threads.append( t )
1518 t.start()
1519
1520 for t in threads:
1521 t.join()
1522 links.append( t.result )
1523 clusters = []
1524 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001525 for i in range( main.numCtrls ):
1526 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07001527 name="clusters-" + str( i ),
1528 args=[ ] )
1529 threads.append( t )
1530 t.start()
1531
1532 for t in threads:
1533 t.join()
1534 clusters.append( t.result )
1535 # Compare json objects for hosts and dataplane clusters
1536
1537 # hosts
1538 main.step( "Host view is consistent across ONOS nodes" )
1539 consistentHostsResult = main.TRUE
1540 for controller in range( len( hosts ) ):
1541 controllerStr = str( controller + 1 )
Jon Hall3afe4c92015-12-14 19:30:38 -08001542 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001543 if hosts[ controller ] == hosts[ 0 ]:
1544 continue
1545 else: # hosts not consistent
1546 main.log.error( "hosts from ONOS" +
1547 controllerStr +
1548 " is inconsistent with ONOS1" )
1549 main.log.warn( repr( hosts[ controller ] ) )
1550 consistentHostsResult = main.FALSE
1551
1552 else:
1553 main.log.error( "Error in getting ONOS hosts from ONOS" +
1554 controllerStr )
1555 consistentHostsResult = main.FALSE
1556 main.log.warn( "ONOS" + controllerStr +
1557 " hosts response: " +
1558 repr( hosts[ controller ] ) )
1559 utilities.assert_equals(
1560 expect=main.TRUE,
1561 actual=consistentHostsResult,
1562 onpass="Hosts view is consistent across all ONOS nodes",
1563 onfail="ONOS nodes have different views of hosts" )
1564
1565 main.step( "Each host has an IP address" )
1566 ipResult = main.TRUE
1567 for controller in range( 0, len( hosts ) ):
1568 controllerStr = str( controller + 1 )
Jon Hall3afe4c92015-12-14 19:30:38 -08001569 if hosts[ controller ]:
1570 for host in hosts[ controller ]:
1571 if not host.get( 'ipAddresses', [ ] ):
Jon Hallf3d16e72015-12-16 17:45:08 -08001572 main.log.error( "Error with host ips on controller" +
Jon Hall3afe4c92015-12-14 19:30:38 -08001573 controllerStr + ": " + str( host ) )
1574 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07001575 utilities.assert_equals(
1576 expect=main.TRUE,
1577 actual=ipResult,
1578 onpass="The ips of the hosts aren't empty",
1579 onfail="The ip of at least one host is missing" )
1580
1581 # Strongly connected clusters of devices
1582 main.step( "Cluster view is consistent across ONOS nodes" )
1583 consistentClustersResult = main.TRUE
1584 for controller in range( len( clusters ) ):
1585 controllerStr = str( controller + 1 )
1586 if "Error" not in clusters[ controller ]:
1587 if clusters[ controller ] == clusters[ 0 ]:
1588 continue
1589 else: # clusters not consistent
1590 main.log.error( "clusters from ONOS" + controllerStr +
1591 " is inconsistent with ONOS1" )
1592 consistentClustersResult = main.FALSE
1593
1594 else:
1595 main.log.error( "Error in getting dataplane clusters " +
1596 "from ONOS" + controllerStr )
1597 consistentClustersResult = main.FALSE
1598 main.log.warn( "ONOS" + controllerStr +
1599 " clusters response: " +
1600 repr( clusters[ controller ] ) )
1601 utilities.assert_equals(
1602 expect=main.TRUE,
1603 actual=consistentClustersResult,
1604 onpass="Clusters view is consistent across all ONOS nodes",
1605 onfail="ONOS nodes have different views of clusters" )
1606 # there should always only be one cluster
1607 main.step( "Cluster view correct across ONOS nodes" )
1608 try:
1609 numClusters = len( json.loads( clusters[ 0 ] ) )
1610 except ( ValueError, TypeError ):
1611 main.log.exception( "Error parsing clusters[0]: " +
1612 repr( clusters[ 0 ] ) )
1613 clusterResults = main.FALSE
1614 if numClusters == 1:
1615 clusterResults = main.TRUE
1616 utilities.assert_equals(
1617 expect=1,
1618 actual=numClusters,
1619 onpass="ONOS shows 1 SCC",
1620 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1621
1622 main.step( "Comparing ONOS topology to MN" )
1623 devicesResults = main.TRUE
1624 linksResults = main.TRUE
1625 hostsResults = main.TRUE
1626 mnSwitches = main.Mininet1.getSwitches()
1627 mnLinks = main.Mininet1.getLinks()
1628 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07001629 for controller in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001630 controllerStr = str( controller + 1 )
1631 if devices[ controller ] and ports[ controller ] and\
1632 "Error" not in devices[ controller ] and\
1633 "Error" not in ports[ controller ]:
Jon Halle1a3b752015-07-22 13:02:46 -07001634 currentDevicesResult = main.Mininet1.compareSwitches(
1635 mnSwitches,
1636 json.loads( devices[ controller ] ),
1637 json.loads( ports[ controller ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001638 else:
1639 currentDevicesResult = main.FALSE
1640 utilities.assert_equals( expect=main.TRUE,
1641 actual=currentDevicesResult,
1642 onpass="ONOS" + controllerStr +
1643 " Switches view is correct",
1644 onfail="ONOS" + controllerStr +
1645 " Switches view is incorrect" )
1646 if links[ controller ] and "Error" not in links[ controller ]:
1647 currentLinksResult = main.Mininet1.compareLinks(
1648 mnSwitches, mnLinks,
1649 json.loads( links[ controller ] ) )
1650 else:
1651 currentLinksResult = main.FALSE
1652 utilities.assert_equals( expect=main.TRUE,
1653 actual=currentLinksResult,
1654 onpass="ONOS" + controllerStr +
1655 " links view is correct",
1656 onfail="ONOS" + controllerStr +
1657 " links view is incorrect" )
1658
Jon Hall657cdf62015-12-17 14:40:51 -08001659 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001660 currentHostsResult = main.Mininet1.compareHosts(
1661 mnHosts,
1662 hosts[ controller ] )
1663 else:
1664 currentHostsResult = main.FALSE
1665 utilities.assert_equals( expect=main.TRUE,
1666 actual=currentHostsResult,
1667 onpass="ONOS" + controllerStr +
1668 " hosts exist in Mininet",
1669 onfail="ONOS" + controllerStr +
1670 " hosts don't match Mininet" )
1671
1672 devicesResults = devicesResults and currentDevicesResult
1673 linksResults = linksResults and currentLinksResult
1674 hostsResults = hostsResults and currentHostsResult
1675
1676 main.step( "Device information is correct" )
1677 utilities.assert_equals(
1678 expect=main.TRUE,
1679 actual=devicesResults,
1680 onpass="Device information is correct",
1681 onfail="Device information is incorrect" )
1682
1683 main.step( "Links are correct" )
1684 utilities.assert_equals(
1685 expect=main.TRUE,
1686 actual=linksResults,
1687 onpass="Link are correct",
1688 onfail="Links are incorrect" )
1689
1690 main.step( "Hosts are correct" )
1691 utilities.assert_equals(
1692 expect=main.TRUE,
1693 actual=hostsResults,
1694 onpass="Hosts are correct",
1695 onfail="Hosts are incorrect" )
1696
1697 def CASE6( self, main ):
1698 """
1699 The Failure case.
1700 """
1701 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001702 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001703 assert main, "main not defined"
1704 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001705 assert main.CLIs, "main.CLIs not defined"
1706 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001707 try:
1708 labels
1709 except NameError:
1710 main.log.error( "labels not defined, setting to []" )
1711 global labels
1712 labels = []
1713 try:
1714 data
1715 except NameError:
1716 main.log.error( "data not defined, setting to []" )
1717 global data
1718 data = []
1719 # Reset non-persistent variables
1720 try:
1721 iCounterValue = 0
1722 except NameError:
1723 main.log.error( "iCounterValue not defined, setting to 0" )
1724 iCounterValue = 0
1725
1726 main.case( "Restart entire ONOS cluster" )
1727
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001728 main.step( "Checking ONOS Logs for errors" )
1729 for node in main.nodes:
1730 main.log.debug( "Checking logs for errors on " + node.name + ":" )
1731 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
1732
Jon Hall5cf14d52015-07-16 12:15:19 -07001733 main.step( "Killing ONOS nodes" )
1734 killResults = main.TRUE
1735 killTime = time.time()
Jon Halle1a3b752015-07-22 13:02:46 -07001736 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001737 killed = main.ONOSbench.onosKill( node.ip_address )
1738 killResults = killResults and killed
1739 utilities.assert_equals( expect=main.TRUE, actual=killResults,
1740 onpass="ONOS nodes killed",
1741 onfail="ONOS kill unsuccessful" )
1742
1743 main.step( "Checking if ONOS is up yet" )
1744 for i in range( 2 ):
1745 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001746 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001747 started = main.ONOSbench.isup( node.ip_address )
1748 if not started:
1749 main.log.error( node.name + " didn't start!" )
1750 onosIsupResult = onosIsupResult and started
1751 if onosIsupResult == main.TRUE:
1752 break
1753 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1754 onpass="ONOS restarted",
1755 onfail="ONOS restart NOT successful" )
1756
1757 main.log.step( "Starting ONOS CLI sessions" )
1758 cliResults = main.TRUE
1759 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001760 for i in range( main.numCtrls ):
1761 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -07001762 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -07001763 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -07001764 threads.append( t )
1765 t.start()
1766
1767 for t in threads:
1768 t.join()
1769 cliResults = cliResults and t.result
1770 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1771 onpass="ONOS cli started",
1772 onfail="ONOS clis did not restart" )
1773
1774 # Grab the time of restart so we chan check how long the gossip
1775 # protocol has had time to work
1776 main.restartTime = time.time() - killTime
1777 main.log.debug( "Restart time: " + str( main.restartTime ) )
1778 labels.append( "Restart" )
1779 data.append( str( main.restartTime ) )
1780
1781 # FIXME: revisit test plan for election with madan
1782 # Rerun for election on restarted nodes
1783 runResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001784 for cli in main.CLIs:
1785 run = main.CLIs[0].electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07001786 if run != main.TRUE:
1787 main.log.error( "Error running for election on " + cli.name )
1788 runResults = runResults and run
1789 utilities.assert_equals( expect=main.TRUE, actual=runResults,
1790 onpass="Reran for election",
1791 onfail="Failed to rerun for election" )
1792
1793 # TODO: Make this configurable
1794 time.sleep( 60 )
Jon Halle1a3b752015-07-22 13:02:46 -07001795 main.log.debug( main.CLIs[0].nodes( jsonFormat=False ) )
1796 main.log.debug( main.CLIs[0].leaders( jsonFormat=False ) )
1797 main.log.debug( main.CLIs[0].partitions( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001798
1799 def CASE7( self, main ):
1800 """
1801 Check state after ONOS failure
1802 """
1803 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001804 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001805 assert main, "main not defined"
1806 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001807 assert main.CLIs, "main.CLIs not defined"
1808 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001809 main.case( "Running ONOS Constant State Tests" )
1810
1811 main.step( "Check that each switch has a master" )
1812 # Assert that each device has a master
1813 rolesNotNull = main.TRUE
1814 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001815 for i in range( main.numCtrls ):
1816 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001817 name="rolesNotNull-" + str( i ),
1818 args=[ ] )
1819 threads.append( t )
1820 t.start()
1821
1822 for t in threads:
1823 t.join()
1824 rolesNotNull = rolesNotNull and t.result
1825 utilities.assert_equals(
1826 expect=main.TRUE,
1827 actual=rolesNotNull,
1828 onpass="Each device has a master",
1829 onfail="Some devices don't have a master assigned" )
1830
1831 main.step( "Read device roles from ONOS" )
1832 ONOSMastership = []
1833 mastershipCheck = main.FALSE
1834 consistentMastership = True
1835 rolesResults = True
1836 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001837 for i in range( main.numCtrls ):
1838 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001839 name="roles-" + str( i ),
1840 args=[] )
1841 threads.append( t )
1842 t.start()
1843
1844 for t in threads:
1845 t.join()
1846 ONOSMastership.append( t.result )
1847
Jon Halle1a3b752015-07-22 13:02:46 -07001848 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001849 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1850 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1851 " roles" )
1852 main.log.warn(
1853 "ONOS" + str( i + 1 ) + " mastership response: " +
1854 repr( ONOSMastership[i] ) )
1855 rolesResults = False
1856 utilities.assert_equals(
1857 expect=True,
1858 actual=rolesResults,
1859 onpass="No error in reading roles output",
1860 onfail="Error in reading roles from ONOS" )
1861
1862 main.step( "Check for consistency in roles from each controller" )
1863 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1864 main.log.info(
1865 "Switch roles are consistent across all ONOS nodes" )
1866 else:
1867 consistentMastership = False
1868 utilities.assert_equals(
1869 expect=True,
1870 actual=consistentMastership,
1871 onpass="Switch roles are consistent across all ONOS nodes",
1872 onfail="ONOS nodes have different views of switch roles" )
1873
1874 if rolesResults and not consistentMastership:
Jon Halle1a3b752015-07-22 13:02:46 -07001875 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001876 main.log.warn(
1877 "ONOS" + str( i + 1 ) + " roles: ",
1878 json.dumps(
1879 json.loads( ONOSMastership[ i ] ),
1880 sort_keys=True,
1881 indent=4,
1882 separators=( ',', ': ' ) ) )
1883 elif rolesResults and not consistentMastership:
1884 mastershipCheck = main.TRUE
1885
1886 '''
1887 description2 = "Compare switch roles from before failure"
1888 main.step( description2 )
1889 try:
1890 currentJson = json.loads( ONOSMastership[0] )
1891 oldJson = json.loads( mastershipState )
1892 except ( ValueError, TypeError ):
1893 main.log.exception( "Something is wrong with parsing " +
1894 "ONOSMastership[0] or mastershipState" )
1895 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1896 main.log.error( "mastershipState" + repr( mastershipState ) )
1897 main.cleanup()
1898 main.exit()
1899 mastershipCheck = main.TRUE
1900 for i in range( 1, 29 ):
1901 switchDPID = str(
1902 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
1903 current = [ switch[ 'master' ] for switch in currentJson
1904 if switchDPID in switch[ 'id' ] ]
1905 old = [ switch[ 'master' ] for switch in oldJson
1906 if switchDPID in switch[ 'id' ] ]
1907 if current == old:
1908 mastershipCheck = mastershipCheck and main.TRUE
1909 else:
1910 main.log.warn( "Mastership of switch %s changed" % switchDPID )
1911 mastershipCheck = main.FALSE
1912 utilities.assert_equals(
1913 expect=main.TRUE,
1914 actual=mastershipCheck,
1915 onpass="Mastership of Switches was not changed",
1916 onfail="Mastership of some switches changed" )
1917 '''
1918 # NOTE: we expect mastership to change on controller failure
1919
1920 main.step( "Get the intents and compare across all nodes" )
1921 ONOSIntents = []
1922 intentCheck = main.FALSE
1923 consistentIntents = True
1924 intentsResults = True
1925 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001926 for i in range( main.numCtrls ):
1927 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001928 name="intents-" + str( i ),
1929 args=[],
1930 kwargs={ 'jsonFormat': True } )
1931 threads.append( t )
1932 t.start()
1933
1934 for t in threads:
1935 t.join()
1936 ONOSIntents.append( t.result )
1937
Jon Halle1a3b752015-07-22 13:02:46 -07001938 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001939 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1940 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1941 " intents" )
1942 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1943 repr( ONOSIntents[ i ] ) )
1944 intentsResults = False
1945 utilities.assert_equals(
1946 expect=True,
1947 actual=intentsResults,
1948 onpass="No error in reading intents output",
1949 onfail="Error in reading intents from ONOS" )
1950
1951 main.step( "Check for consistency in Intents from each controller" )
1952 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1953 main.log.info( "Intents are consistent across all ONOS " +
1954 "nodes" )
1955 else:
1956 consistentIntents = False
1957
1958 # Try to make it easy to figure out what is happening
1959 #
1960 # Intent ONOS1 ONOS2 ...
1961 # 0x01 INSTALLED INSTALLING
1962 # ... ... ...
1963 # ... ... ...
1964 title = " ID"
Jon Halle1a3b752015-07-22 13:02:46 -07001965 for n in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001966 title += " " * 10 + "ONOS" + str( n + 1 )
1967 main.log.warn( title )
1968 # get all intent keys in the cluster
1969 keys = []
1970 for nodeStr in ONOSIntents:
1971 node = json.loads( nodeStr )
1972 for intent in node:
1973 keys.append( intent.get( 'id' ) )
1974 keys = set( keys )
1975 for key in keys:
1976 row = "%-13s" % key
1977 for nodeStr in ONOSIntents:
1978 node = json.loads( nodeStr )
1979 for intent in node:
1980 if intent.get( 'id' ) == key:
1981 row += "%-15s" % intent.get( 'state' )
1982 main.log.warn( row )
1983 # End table view
1984
1985 utilities.assert_equals(
1986 expect=True,
1987 actual=consistentIntents,
1988 onpass="Intents are consistent across all ONOS nodes",
1989 onfail="ONOS nodes have different views of intents" )
1990 intentStates = []
1991 for node in ONOSIntents: # Iter through ONOS nodes
1992 nodeStates = []
1993 # Iter through intents of a node
1994 try:
1995 for intent in json.loads( node ):
1996 nodeStates.append( intent[ 'state' ] )
1997 except ( ValueError, TypeError ):
1998 main.log.exception( "Error in parsing intents" )
1999 main.log.error( repr( node ) )
2000 intentStates.append( nodeStates )
2001 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
2002 main.log.info( dict( out ) )
2003
2004 if intentsResults and not consistentIntents:
Jon Halle1a3b752015-07-22 13:02:46 -07002005 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07002006 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
2007 main.log.warn( json.dumps(
2008 json.loads( ONOSIntents[ i ] ),
2009 sort_keys=True,
2010 indent=4,
2011 separators=( ',', ': ' ) ) )
2012 elif intentsResults and consistentIntents:
2013 intentCheck = main.TRUE
2014
2015 # NOTE: Store has no durability, so intents are lost across system
2016 # restarts
2017 """
2018 main.step( "Compare current intents with intents before the failure" )
2019 # NOTE: this requires case 5 to pass for intentState to be set.
2020 # maybe we should stop the test if that fails?
2021 sameIntents = main.FALSE
2022 if intentState and intentState == ONOSIntents[ 0 ]:
2023 sameIntents = main.TRUE
2024 main.log.info( "Intents are consistent with before failure" )
2025 # TODO: possibly the states have changed? we may need to figure out
2026 # what the acceptable states are
2027 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
2028 sameIntents = main.TRUE
2029 try:
2030 before = json.loads( intentState )
2031 after = json.loads( ONOSIntents[ 0 ] )
2032 for intent in before:
2033 if intent not in after:
2034 sameIntents = main.FALSE
2035 main.log.debug( "Intent is not currently in ONOS " +
2036 "(at least in the same form):" )
2037 main.log.debug( json.dumps( intent ) )
2038 except ( ValueError, TypeError ):
2039 main.log.exception( "Exception printing intents" )
2040 main.log.debug( repr( ONOSIntents[0] ) )
2041 main.log.debug( repr( intentState ) )
2042 if sameIntents == main.FALSE:
2043 try:
2044 main.log.debug( "ONOS intents before: " )
2045 main.log.debug( json.dumps( json.loads( intentState ),
2046 sort_keys=True, indent=4,
2047 separators=( ',', ': ' ) ) )
2048 main.log.debug( "Current ONOS intents: " )
2049 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
2050 sort_keys=True, indent=4,
2051 separators=( ',', ': ' ) ) )
2052 except ( ValueError, TypeError ):
2053 main.log.exception( "Exception printing intents" )
2054 main.log.debug( repr( ONOSIntents[0] ) )
2055 main.log.debug( repr( intentState ) )
2056 utilities.assert_equals(
2057 expect=main.TRUE,
2058 actual=sameIntents,
2059 onpass="Intents are consistent with before failure",
2060 onfail="The Intents changed during failure" )
2061 intentCheck = intentCheck and sameIntents
2062 """
2063 main.step( "Get the OF Table entries and compare to before " +
2064 "component failure" )
2065 FlowTables = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002066 for i in range( 28 ):
2067 main.log.info( "Checking flow table on s" + str( i + 1 ) )
GlennRC68467eb2015-11-16 18:01:01 -08002068 tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
2069 FlowTables = FlowTables and main.Mininet1.flowTableComp( flows[i], tmpFlows )
Jon Hall5cf14d52015-07-16 12:15:19 -07002070 if FlowTables == main.FALSE:
GlennRC68467eb2015-11-16 18:01:01 -08002071 main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
2072
Jon Hall5cf14d52015-07-16 12:15:19 -07002073 utilities.assert_equals(
2074 expect=main.TRUE,
2075 actual=FlowTables,
2076 onpass="No changes were found in the flow tables",
2077 onfail="Changes were found in the flow tables" )
2078
2079 main.Mininet2.pingLongKill()
2080 '''
2081 # main.step( "Check the continuous pings to ensure that no packets " +
2082 # "were dropped during component failure" )
2083 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
2084 main.params[ 'TESTONIP' ] )
2085 LossInPings = main.FALSE
2086 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
2087 for i in range( 8, 18 ):
2088 main.log.info(
2089 "Checking for a loss in pings along flow from s" +
2090 str( i ) )
2091 LossInPings = main.Mininet2.checkForLoss(
2092 "/tmp/ping.h" +
2093 str( i ) ) or LossInPings
2094 if LossInPings == main.TRUE:
2095 main.log.info( "Loss in ping detected" )
2096 elif LossInPings == main.ERROR:
2097 main.log.info( "There are multiple mininet process running" )
2098 elif LossInPings == main.FALSE:
2099 main.log.info( "No Loss in the pings" )
2100 main.log.info( "No loss of dataplane connectivity" )
2101 # utilities.assert_equals(
2102 # expect=main.FALSE,
2103 # actual=LossInPings,
2104 # onpass="No Loss of connectivity",
2105 # onfail="Loss of dataplane connectivity detected" )
2106
2107 # NOTE: Since intents are not persisted with IntnentStore,
2108 # we expect loss in dataplane connectivity
2109 LossInPings = main.FALSE
2110 '''
2111
2112 main.step( "Leadership Election is still functional" )
2113 # Test of LeadershipElection
2114 leaderList = []
2115 leaderResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002116 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002117 leaderN = cli.electionTestLeader()
2118 leaderList.append( leaderN )
2119 if leaderN == main.FALSE:
2120 # error in response
2121 main.log.error( "Something is wrong with " +
2122 "electionTestLeader function, check the" +
2123 " error logs" )
2124 leaderResult = main.FALSE
2125 elif leaderN is None:
2126 main.log.error( cli.name +
2127 " shows no leader for the election-app." )
2128 leaderResult = main.FALSE
2129 if len( set( leaderList ) ) != 1:
2130 leaderResult = main.FALSE
2131 main.log.error(
2132 "Inconsistent view of leader for the election test app" )
2133 # TODO: print the list
2134 utilities.assert_equals(
2135 expect=main.TRUE,
2136 actual=leaderResult,
2137 onpass="Leadership election passed",
2138 onfail="Something went wrong with Leadership election" )
2139
2140 def CASE8( self, main ):
2141 """
2142 Compare topo
2143 """
2144 import json
2145 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002146 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002147 assert main, "main not defined"
2148 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002149 assert main.CLIs, "main.CLIs not defined"
2150 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002151
2152 main.case( "Compare ONOS Topology view to Mininet topology" )
Jon Hall783bbf92015-07-23 14:33:19 -07002153 main.caseExplanation = "Compare topology objects between Mininet" +\
Jon Hall5cf14d52015-07-16 12:15:19 -07002154 " and ONOS"
Jon Hall5cf14d52015-07-16 12:15:19 -07002155 topoResult = main.FALSE
2156 elapsed = 0
2157 count = 0
Jon Halle9b1fa32015-12-08 15:32:21 -08002158 main.step( "Comparing ONOS topology to MN topology" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002159 startTime = time.time()
2160 # Give time for Gossip to work
Jon Halle9b1fa32015-12-08 15:32:21 -08002161 while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
Jon Hallba609822015-09-18 12:00:21 -07002162 devicesResults = main.TRUE
2163 linksResults = main.TRUE
2164 hostsResults = main.TRUE
2165 hostAttachmentResults = True
Jon Hall5cf14d52015-07-16 12:15:19 -07002166 count += 1
2167 cliStart = time.time()
2168 devices = []
2169 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002170 for i in range( main.numCtrls ):
2171 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07002172 name="devices-" + str( i ),
2173 args=[ ] )
2174 threads.append( t )
2175 t.start()
2176
2177 for t in threads:
2178 t.join()
2179 devices.append( t.result )
2180 hosts = []
2181 ipResult = main.TRUE
2182 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002183 for i in range( main.numCtrls ):
Jon Halld8f6de82015-12-17 17:04:34 -08002184 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002185 name="hosts-" + str( i ),
Jon Halld8f6de82015-12-17 17:04:34 -08002186 args=[ main.CLIs[i].hosts, [ None ] ],
2187 kwargs= { 'sleep': 5, 'attempts': 5,
2188 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002189 threads.append( t )
2190 t.start()
2191
2192 for t in threads:
2193 t.join()
2194 try:
2195 hosts.append( json.loads( t.result ) )
2196 except ( ValueError, TypeError ):
2197 main.log.exception( "Error parsing hosts results" )
2198 main.log.error( repr( t.result ) )
Jon Hall3afe4c92015-12-14 19:30:38 -08002199 hosts.append( None )
Jon Hall5cf14d52015-07-16 12:15:19 -07002200 for controller in range( 0, len( hosts ) ):
2201 controllerStr = str( controller + 1 )
Jon Hallacd1b182015-12-17 11:43:20 -08002202 if hosts[ controller ]:
2203 for host in hosts[ controller ]:
2204 if host is None or host.get( 'ipAddresses', [] ) == []:
2205 main.log.error(
2206 "Error with host ipAddresses on controller" +
2207 controllerStr + ": " + str( host ) )
2208 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002209 ports = []
2210 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002211 for i in range( main.numCtrls ):
2212 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07002213 name="ports-" + str( i ),
2214 args=[ ] )
2215 threads.append( t )
2216 t.start()
2217
2218 for t in threads:
2219 t.join()
2220 ports.append( t.result )
2221 links = []
2222 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002223 for i in range( main.numCtrls ):
2224 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07002225 name="links-" + str( i ),
2226 args=[ ] )
2227 threads.append( t )
2228 t.start()
2229
2230 for t in threads:
2231 t.join()
2232 links.append( t.result )
2233 clusters = []
2234 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002235 for i in range( main.numCtrls ):
2236 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07002237 name="clusters-" + str( i ),
2238 args=[ ] )
2239 threads.append( t )
2240 t.start()
2241
2242 for t in threads:
2243 t.join()
2244 clusters.append( t.result )
2245
2246 elapsed = time.time() - startTime
2247 cliTime = time.time() - cliStart
2248 print "Elapsed time: " + str( elapsed )
2249 print "CLI time: " + str( cliTime )
2250
2251 mnSwitches = main.Mininet1.getSwitches()
2252 mnLinks = main.Mininet1.getLinks()
2253 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07002254 for controller in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07002255 controllerStr = str( controller + 1 )
2256 if devices[ controller ] and ports[ controller ] and\
2257 "Error" not in devices[ controller ] and\
2258 "Error" not in ports[ controller ]:
2259
2260 currentDevicesResult = main.Mininet1.compareSwitches(
2261 mnSwitches,
2262 json.loads( devices[ controller ] ),
2263 json.loads( ports[ controller ] ) )
2264 else:
2265 currentDevicesResult = main.FALSE
2266 utilities.assert_equals( expect=main.TRUE,
2267 actual=currentDevicesResult,
2268 onpass="ONOS" + controllerStr +
2269 " Switches view is correct",
2270 onfail="ONOS" + controllerStr +
2271 " Switches view is incorrect" )
2272
2273 if links[ controller ] and "Error" not in links[ controller ]:
2274 currentLinksResult = main.Mininet1.compareLinks(
2275 mnSwitches, mnLinks,
2276 json.loads( links[ controller ] ) )
2277 else:
2278 currentLinksResult = main.FALSE
2279 utilities.assert_equals( expect=main.TRUE,
2280 actual=currentLinksResult,
2281 onpass="ONOS" + controllerStr +
2282 " links view is correct",
2283 onfail="ONOS" + controllerStr +
2284 " links view is incorrect" )
Jon Hall657cdf62015-12-17 14:40:51 -08002285 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002286 currentHostsResult = main.Mininet1.compareHosts(
2287 mnHosts,
2288 hosts[ controller ] )
Jon Hall13b446e2016-01-05 12:17:01 -08002289 elif hosts[ controller ] == []:
2290 currentHostsResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002291 else:
2292 currentHostsResult = main.FALSE
2293 utilities.assert_equals( expect=main.TRUE,
2294 actual=currentHostsResult,
2295 onpass="ONOS" + controllerStr +
2296 " hosts exist in Mininet",
2297 onfail="ONOS" + controllerStr +
2298 " hosts don't match Mininet" )
2299 # CHECKING HOST ATTACHMENT POINTS
2300 hostAttachment = True
2301 noHosts = False
2302 # FIXME: topo-HA/obelisk specific mappings:
2303 # key is mac and value is dpid
2304 mappings = {}
2305 for i in range( 1, 29 ): # hosts 1 through 28
2306 # set up correct variables:
2307 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2308 if i == 1:
2309 deviceId = "1000".zfill(16)
2310 elif i == 2:
2311 deviceId = "2000".zfill(16)
2312 elif i == 3:
2313 deviceId = "3000".zfill(16)
2314 elif i == 4:
2315 deviceId = "3004".zfill(16)
2316 elif i == 5:
2317 deviceId = "5000".zfill(16)
2318 elif i == 6:
2319 deviceId = "6000".zfill(16)
2320 elif i == 7:
2321 deviceId = "6007".zfill(16)
2322 elif i >= 8 and i <= 17:
2323 dpid = '3' + str( i ).zfill( 3 )
2324 deviceId = dpid.zfill(16)
2325 elif i >= 18 and i <= 27:
2326 dpid = '6' + str( i ).zfill( 3 )
2327 deviceId = dpid.zfill(16)
2328 elif i == 28:
2329 deviceId = "2800".zfill(16)
2330 mappings[ macId ] = deviceId
Jon Halld8f6de82015-12-17 17:04:34 -08002331 if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002332 if hosts[ controller ] == []:
2333 main.log.warn( "There are no hosts discovered" )
2334 noHosts = True
2335 else:
2336 for host in hosts[ controller ]:
2337 mac = None
2338 location = None
2339 device = None
2340 port = None
2341 try:
2342 mac = host.get( 'mac' )
2343 assert mac, "mac field could not be found for this host object"
2344
2345 location = host.get( 'location' )
2346 assert location, "location field could not be found for this host object"
2347
2348 # Trim the protocol identifier off deviceId
2349 device = str( location.get( 'elementId' ) ).split(':')[1]
2350 assert device, "elementId field could not be found for this host location object"
2351
2352 port = location.get( 'port' )
2353 assert port, "port field could not be found for this host location object"
2354
2355 # Now check if this matches where they should be
2356 if mac and device and port:
2357 if str( port ) != "1":
2358 main.log.error( "The attachment port is incorrect for " +
2359 "host " + str( mac ) +
2360 ". Expected: 1 Actual: " + str( port) )
2361 hostAttachment = False
2362 if device != mappings[ str( mac ) ]:
2363 main.log.error( "The attachment device is incorrect for " +
2364 "host " + str( mac ) +
2365 ". Expected: " + mappings[ str( mac ) ] +
2366 " Actual: " + device )
2367 hostAttachment = False
2368 else:
2369 hostAttachment = False
2370 except AssertionError:
2371 main.log.exception( "Json object not as expected" )
2372 main.log.error( repr( host ) )
2373 hostAttachment = False
2374 else:
2375 main.log.error( "No hosts json output or \"Error\"" +
2376 " in output. hosts = " +
2377 repr( hosts[ controller ] ) )
2378 if noHosts is False:
2379 # TODO: Find a way to know if there should be hosts in a
2380 # given point of the test
2381 hostAttachment = True
2382
2383 # END CHECKING HOST ATTACHMENT POINTS
2384 devicesResults = devicesResults and currentDevicesResult
2385 linksResults = linksResults and currentLinksResult
2386 hostsResults = hostsResults and currentHostsResult
2387 hostAttachmentResults = hostAttachmentResults and\
2388 hostAttachment
2389 topoResult = ( devicesResults and linksResults
2390 and hostsResults and ipResult and
2391 hostAttachmentResults )
Jon Halle9b1fa32015-12-08 15:32:21 -08002392 utilities.assert_equals( expect=True,
2393 actual=topoResult,
2394 onpass="ONOS topology matches Mininet",
2395 onfail="ONOS topology don't match Mininet" )
2396 # End of While loop to pull ONOS state
Jon Hall5cf14d52015-07-16 12:15:19 -07002397
2398 # Compare json objects for hosts and dataplane clusters
2399
2400 # hosts
2401 main.step( "Hosts view is consistent across all ONOS nodes" )
2402 consistentHostsResult = main.TRUE
2403 for controller in range( len( hosts ) ):
2404 controllerStr = str( controller + 1 )
Jon Hall13b446e2016-01-05 12:17:01 -08002405 if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002406 if hosts[ controller ] == hosts[ 0 ]:
2407 continue
2408 else: # hosts not consistent
2409 main.log.error( "hosts from ONOS" + controllerStr +
2410 " is inconsistent with ONOS1" )
2411 main.log.warn( repr( hosts[ controller ] ) )
2412 consistentHostsResult = main.FALSE
2413
2414 else:
2415 main.log.error( "Error in getting ONOS hosts from ONOS" +
2416 controllerStr )
2417 consistentHostsResult = main.FALSE
2418 main.log.warn( "ONOS" + controllerStr +
2419 " hosts response: " +
2420 repr( hosts[ controller ] ) )
2421 utilities.assert_equals(
2422 expect=main.TRUE,
2423 actual=consistentHostsResult,
2424 onpass="Hosts view is consistent across all ONOS nodes",
2425 onfail="ONOS nodes have different views of hosts" )
2426
2427 main.step( "Hosts information is correct" )
2428 hostsResults = hostsResults and ipResult
2429 utilities.assert_equals(
2430 expect=main.TRUE,
2431 actual=hostsResults,
2432 onpass="Host information is correct",
2433 onfail="Host information is incorrect" )
2434
2435 main.step( "Host attachment points to the network" )
2436 utilities.assert_equals(
2437 expect=True,
2438 actual=hostAttachmentResults,
2439 onpass="Hosts are correctly attached to the network",
2440 onfail="ONOS did not correctly attach hosts to the network" )
2441
2442 # Strongly connected clusters of devices
2443 main.step( "Clusters view is consistent across all ONOS nodes" )
2444 consistentClustersResult = main.TRUE
2445 for controller in range( len( clusters ) ):
2446 controllerStr = str( controller + 1 )
2447 if "Error" not in clusters[ controller ]:
2448 if clusters[ controller ] == clusters[ 0 ]:
2449 continue
2450 else: # clusters not consistent
2451 main.log.error( "clusters from ONOS" +
2452 controllerStr +
2453 " is inconsistent with ONOS1" )
2454 consistentClustersResult = main.FALSE
2455
2456 else:
2457 main.log.error( "Error in getting dataplane clusters " +
2458 "from ONOS" + controllerStr )
2459 consistentClustersResult = main.FALSE
2460 main.log.warn( "ONOS" + controllerStr +
2461 " clusters response: " +
2462 repr( clusters[ controller ] ) )
2463 utilities.assert_equals(
2464 expect=main.TRUE,
2465 actual=consistentClustersResult,
2466 onpass="Clusters view is consistent across all ONOS nodes",
2467 onfail="ONOS nodes have different views of clusters" )
2468
2469 main.step( "There is only one SCC" )
2470 # there should always only be one cluster
2471 try:
2472 numClusters = len( json.loads( clusters[ 0 ] ) )
2473 except ( ValueError, TypeError ):
2474 main.log.exception( "Error parsing clusters[0]: " +
2475 repr( clusters[0] ) )
2476 clusterResults = main.FALSE
2477 if numClusters == 1:
2478 clusterResults = main.TRUE
2479 utilities.assert_equals(
2480 expect=1,
2481 actual=numClusters,
2482 onpass="ONOS shows 1 SCC",
2483 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2484
2485 topoResult = ( devicesResults and linksResults
2486 and hostsResults and consistentHostsResult
2487 and consistentClustersResult and clusterResults
2488 and ipResult and hostAttachmentResults )
2489
2490 topoResult = topoResult and int( count <= 2 )
2491 note = "note it takes about " + str( int( cliTime ) ) + \
2492 " seconds for the test to make all the cli calls to fetch " +\
2493 "the topology from each ONOS instance"
2494 main.log.info(
2495 "Very crass estimate for topology discovery/convergence( " +
2496 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2497 str( count ) + " tries" )
2498
2499 main.step( "Device information is correct" )
2500 utilities.assert_equals(
2501 expect=main.TRUE,
2502 actual=devicesResults,
2503 onpass="Device information is correct",
2504 onfail="Device information is incorrect" )
2505
2506 main.step( "Links are correct" )
2507 utilities.assert_equals(
2508 expect=main.TRUE,
2509 actual=linksResults,
2510 onpass="Link are correct",
2511 onfail="Links are incorrect" )
2512
2513 # FIXME: move this to an ONOS state case
2514 main.step( "Checking ONOS nodes" )
2515 nodesOutput = []
2516 nodeResults = main.TRUE
2517 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002518 for i in range( main.numCtrls ):
2519 t = main.Thread( target=main.CLIs[i].nodes,
Jon Hall5cf14d52015-07-16 12:15:19 -07002520 name="nodes-" + str( i ),
2521 args=[ ] )
2522 threads.append( t )
2523 t.start()
2524
2525 for t in threads:
2526 t.join()
2527 nodesOutput.append( t.result )
Jon Halle1a3b752015-07-22 13:02:46 -07002528 ips = [ node.ip_address for node in main.nodes ]
Jon Halle9b1fa32015-12-08 15:32:21 -08002529 ips.sort()
Jon Hall5cf14d52015-07-16 12:15:19 -07002530 for i in nodesOutput:
2531 try:
2532 current = json.loads( i )
Jon Halle9b1fa32015-12-08 15:32:21 -08002533 activeIps = []
2534 currentResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002535 for node in current:
Jon Halle9b1fa32015-12-08 15:32:21 -08002536 if node['state'] == 'ACTIVE':
2537 activeIps.append( node['ip'] )
2538 activeIps.sort()
2539 if ips == activeIps:
2540 currentResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002541 except ( ValueError, TypeError ):
2542 main.log.error( "Error parsing nodes output" )
2543 main.log.warn( repr( i ) )
Jon Halle9b1fa32015-12-08 15:32:21 -08002544 currentResult = main.FALSE
2545 nodeResults = nodeResults and currentResult
Jon Hall5cf14d52015-07-16 12:15:19 -07002546 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2547 onpass="Nodes check successful",
2548 onfail="Nodes check NOT successful" )
2549
2550 def CASE9( self, main ):
2551 """
2552 Link s3-s28 down
2553 """
2554 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002555 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002556 assert main, "main not defined"
2557 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002558 assert main.CLIs, "main.CLIs not defined"
2559 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002560 # NOTE: You should probably run a topology check after this
2561
2562 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2563
2564 description = "Turn off a link to ensure that Link Discovery " +\
2565 "is working properly"
2566 main.case( description )
2567
2568 main.step( "Kill Link between s3 and s28" )
2569 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
2570 main.log.info( "Waiting " + str( linkSleep ) +
2571 " seconds for link down to be discovered" )
2572 time.sleep( linkSleep )
2573 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
2574 onpass="Link down successful",
2575 onfail="Failed to bring link down" )
2576 # TODO do some sort of check here
2577
2578 def CASE10( self, main ):
2579 """
2580 Link s3-s28 up
2581 """
2582 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002583 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002584 assert main, "main not defined"
2585 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002586 assert main.CLIs, "main.CLIs not defined"
2587 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002588 # NOTE: You should probably run a topology check after this
2589
2590 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2591
2592 description = "Restore a link to ensure that Link Discovery is " + \
2593 "working properly"
2594 main.case( description )
2595
2596 main.step( "Bring link between s3 and s28 back up" )
2597 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
2598 main.log.info( "Waiting " + str( linkSleep ) +
2599 " seconds for link up to be discovered" )
2600 time.sleep( linkSleep )
2601 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
2602 onpass="Link up successful",
2603 onfail="Failed to bring link up" )
2604 # TODO do some sort of check here
2605
2606 def CASE11( self, main ):
2607 """
2608 Switch Down
2609 """
2610 # NOTE: You should probably run a topology check after this
2611 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002612 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002613 assert main, "main not defined"
2614 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002615 assert main.CLIs, "main.CLIs not defined"
2616 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002617
2618 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2619
2620 description = "Killing a switch to ensure it is discovered correctly"
2621 main.case( description )
2622 switch = main.params[ 'kill' ][ 'switch' ]
2623 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2624
2625 # TODO: Make this switch parameterizable
2626 main.step( "Kill " + switch )
2627 main.log.info( "Deleting " + switch )
2628 main.Mininet1.delSwitch( switch )
2629 main.log.info( "Waiting " + str( switchSleep ) +
2630 " seconds for switch down to be discovered" )
2631 time.sleep( switchSleep )
2632 device = main.ONOScli1.getDevice( dpid=switchDPID )
2633 # Peek at the deleted switch
2634 main.log.warn( str( device ) )
2635 result = main.FALSE
2636 if device and device[ 'available' ] is False:
2637 result = main.TRUE
2638 utilities.assert_equals( expect=main.TRUE, actual=result,
2639 onpass="Kill switch successful",
2640 onfail="Failed to kill switch?" )
2641
2642 def CASE12( self, main ):
2643 """
2644 Switch Up
2645 """
2646 # NOTE: You should probably run a topology check after this
2647 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002648 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002649 assert main, "main not defined"
2650 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002651 assert main.CLIs, "main.CLIs not defined"
2652 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002653 assert ONOS1Port, "ONOS1Port not defined"
2654 assert ONOS2Port, "ONOS2Port not defined"
2655 assert ONOS3Port, "ONOS3Port not defined"
2656 assert ONOS4Port, "ONOS4Port not defined"
2657 assert ONOS5Port, "ONOS5Port not defined"
2658 assert ONOS6Port, "ONOS6Port not defined"
2659 assert ONOS7Port, "ONOS7Port not defined"
2660
2661 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2662 switch = main.params[ 'kill' ][ 'switch' ]
2663 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2664 links = main.params[ 'kill' ][ 'links' ].split()
2665 description = "Adding a switch to ensure it is discovered correctly"
2666 main.case( description )
2667
2668 main.step( "Add back " + switch )
2669 main.Mininet1.addSwitch( switch, dpid=switchDPID )
2670 for peer in links:
2671 main.Mininet1.addLink( switch, peer )
2672 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -07002673 for i in range( main.numCtrls ):
2674 ipList.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -07002675 main.Mininet1.assignSwController( sw=switch, ip=ipList )
2676 main.log.info( "Waiting " + str( switchSleep ) +
2677 " seconds for switch up to be discovered" )
2678 time.sleep( switchSleep )
2679 device = main.ONOScli1.getDevice( dpid=switchDPID )
2680 # Peek at the deleted switch
2681 main.log.warn( str( device ) )
2682 result = main.FALSE
2683 if device and device[ 'available' ]:
2684 result = main.TRUE
2685 utilities.assert_equals( expect=main.TRUE, actual=result,
2686 onpass="add switch successful",
2687 onfail="Failed to add switch?" )
2688
2689 def CASE13( self, main ):
2690 """
2691 Clean up
2692 """
2693 import os
2694 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002695 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002696 assert main, "main not defined"
2697 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002698 assert main.CLIs, "main.CLIs not defined"
2699 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002700
2701 # printing colors to terminal
2702 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2703 'blue': '\033[94m', 'green': '\033[92m',
2704 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
2705 main.case( "Test Cleanup" )
2706 main.step( "Killing tcpdumps" )
2707 main.Mininet2.stopTcpdump()
2708
2709 testname = main.TEST
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002710 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall5cf14d52015-07-16 12:15:19 -07002711 main.step( "Copying MN pcap and ONOS log files to test station" )
2712 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
2713 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
Jon Hall96091e62015-09-21 17:34:17 -07002714 # NOTE: MN Pcap file is being saved to logdir.
2715 # We scp this file as MN and TestON aren't necessarily the same vm
2716
2717 # FIXME: To be replaced with a Jenkin's post script
Jon Hall5cf14d52015-07-16 12:15:19 -07002718 # TODO: Load these from params
2719 # NOTE: must end in /
2720 logFolder = "/opt/onos/log/"
2721 logFiles = [ "karaf.log", "karaf.log.1" ]
2722 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002723 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002724 for node in main.nodes:
Jon Hall96091e62015-09-21 17:34:17 -07002725 dstName = main.logdir + "/" + node.name + "-" + f
2726 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2727 logFolder + f, dstName )
Jon Hall5cf14d52015-07-16 12:15:19 -07002728 # std*.log's
2729 # NOTE: must end in /
2730 logFolder = "/opt/onos/var/"
2731 logFiles = [ "stderr.log", "stdout.log" ]
2732 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002733 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002734 for node in main.nodes:
Jon Hall96091e62015-09-21 17:34:17 -07002735 dstName = main.logdir + "/" + node.name + "-" + f
2736 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2737 logFolder + f, dstName )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002738 else:
2739 main.log.debug( "skipping saving log files" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002740
2741 main.step( "Stopping Mininet" )
2742 mnResult = main.Mininet1.stopNet()
2743 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2744 onpass="Mininet stopped",
2745 onfail="MN cleanup NOT successful" )
2746
2747 main.step( "Checking ONOS Logs for errors" )
Jon Halle1a3b752015-07-22 13:02:46 -07002748 for node in main.nodes:
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002749 main.log.debug( "Checking logs for errors on " + node.name + ":" )
2750 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002751
2752 try:
2753 timerLog = open( main.logdir + "/Timers.csv", 'w')
2754 main.log.error( ", ".join( labels ) + "\n" + ", ".join( data ) )
2755 timerLog.write( ", ".join( labels ) + "\n" + ", ".join( data ) )
2756 timerLog.close()
2757 except NameError, e:
2758 main.log.exception(e)
2759
2760 def CASE14( self, main ):
2761 """
2762 start election app on all onos nodes
2763 """
Jon Halle1a3b752015-07-22 13:02:46 -07002764 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002765 assert main, "main not defined"
2766 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002767 assert main.CLIs, "main.CLIs not defined"
2768 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002769
2770 main.case("Start Leadership Election app")
2771 main.step( "Install leadership election app" )
2772 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
2773 utilities.assert_equals(
2774 expect=main.TRUE,
2775 actual=appResult,
2776 onpass="Election app installed",
2777 onfail="Something went wrong with installing Leadership election" )
2778
2779 main.step( "Run for election on each node" )
2780 leaderResult = main.TRUE
2781 leaders = []
Jon Halle1a3b752015-07-22 13:02:46 -07002782 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002783 cli.electionTestRun()
Jon Halle1a3b752015-07-22 13:02:46 -07002784 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002785 leader = cli.electionTestLeader()
2786 if leader is None or leader == main.FALSE:
2787 main.log.error( cli.name + ": Leader for the election app " +
2788 "should be an ONOS node, instead got '" +
2789 str( leader ) + "'" )
2790 leaderResult = main.FALSE
2791 leaders.append( leader )
2792 utilities.assert_equals(
2793 expect=main.TRUE,
2794 actual=leaderResult,
2795 onpass="Successfully ran for leadership",
2796 onfail="Failed to run for leadership" )
2797
2798 main.step( "Check that each node shows the same leader" )
2799 sameLeader = main.TRUE
2800 if len( set( leaders ) ) != 1:
2801 sameLeader = main.FALSE
2802 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2803 str( leaders ) )
2804 utilities.assert_equals(
2805 expect=main.TRUE,
2806 actual=sameLeader,
2807 onpass="Leadership is consistent for the election topic",
2808 onfail="Nodes have different leaders" )
2809
2810 def CASE15( self, main ):
2811 """
2812 Check that Leadership Election is still functional
acsmars9475b1c2015-08-28 18:02:08 -07002813 15.1 Run election on each node
2814 15.2 Check that each node has the same leaders and candidates
2815 15.3 Find current leader and withdraw
2816 15.4 Check that a new node was elected leader
2817 15.5 Check that that new leader was the candidate of old leader
2818 15.6 Run for election on old leader
2819 15.7 Check that oldLeader is a candidate, and leader if only 1 node
2820 15.8 Make sure that the old leader was added to the candidate list
2821
2822 old and new variable prefixes refer to data from before vs after
2823 withdrawl and later before withdrawl vs after re-election
Jon Hall5cf14d52015-07-16 12:15:19 -07002824 """
2825 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002826 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002827 assert main, "main not defined"
2828 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002829 assert main.CLIs, "main.CLIs not defined"
2830 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002831
Jon Hall5cf14d52015-07-16 12:15:19 -07002832 description = "Check that Leadership Election is still functional"
2833 main.case( description )
2834 # NOTE: Need to re-run since being a canidate is not persistant
acsmars9475b1c2015-08-28 18:02:08 -07002835 # TODO: add check for "Command not found:" in the driver, this
2836 # means the election test app isn't loaded
2837
2838 oldLeaders = [] # leaders by node before withdrawl from candidates
2839 newLeaders = [] # leaders by node after withdrawl from candidates
2840 oldAllCandidates = [] # list of lists of each nodes' candidates before
2841 newAllCandidates = [] # list of lists of each nodes' candidates after
2842 oldCandidates = [] # list of candidates from node 0 before withdrawl
2843 newCandidates = [] # list of candidates from node 0 after withdrawl
2844 oldLeader = '' # the old leader from oldLeaders, None if not same
2845 newLeader = '' # the new leaders fron newLoeaders, None if not same
2846 oldLeaderCLI = None # the CLI of the old leader used for re-electing
acsmars71adceb2015-08-31 15:09:26 -07002847 expectNoLeader = False # True when there is only one leader
2848 if main.numCtrls == 1:
2849 expectNoLeader = True
acsmars9475b1c2015-08-28 18:02:08 -07002850
Jon Hall5cf14d52015-07-16 12:15:19 -07002851 main.step( "Run for election on each node" )
acsmars9475b1c2015-08-28 18:02:08 -07002852 electionResult = main.TRUE
2853
2854 for cli in main.CLIs: # run test election on each node
2855 if cli.electionTestRun() == main.FALSE:
2856 electionResult = main.FALSE
2857
Jon Hall5cf14d52015-07-16 12:15:19 -07002858 utilities.assert_equals(
2859 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07002860 actual=electionResult,
2861 onpass="All nodes successfully ran for leadership",
2862 onfail="At least one node failed to run for leadership" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002863
acsmars3a72bde2015-09-02 14:16:22 -07002864 if electionResult == main.FALSE:
2865 main.log.error(
2866 "Skipping Test Case because Election Test App isn't loaded" )
2867 main.skipCase()
2868
acsmars9475b1c2015-08-28 18:02:08 -07002869 main.step( "Check that each node shows the same leader and candidates" )
2870 sameResult = main.TRUE
2871 failMessage = "Nodes have different leaders"
2872 for cli in main.CLIs:
2873 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2874 oldAllCandidates.append( node )
2875 oldLeaders.append( node[ 0 ] )
2876 oldCandidates = oldAllCandidates[ 0 ]
2877
2878 # Check that each node has the same leader. Defines oldLeader
2879 if len( set( oldLeaders ) ) != 1:
2880 sameResult = main.FALSE
acsmars71adceb2015-08-31 15:09:26 -07002881 main.log.error( "More than one leader present:" + str( oldLeaders ) )
acsmars9475b1c2015-08-28 18:02:08 -07002882 oldLeader = None
2883 else:
2884 oldLeader = oldLeaders[ 0 ]
2885
2886 # Check that each node's candidate list is the same
acsmars29233db2015-11-04 11:15:00 -08002887 candidateDiscrepancy = False # Boolean of candidate mismatches
acsmars9475b1c2015-08-28 18:02:08 -07002888 for candidates in oldAllCandidates:
2889 if set( candidates ) != set( oldCandidates ):
2890 sameResult = main.FALSE
acsmars29233db2015-11-04 11:15:00 -08002891 candidateDiscrepancy = True
2892
2893 if candidateDiscrepancy:
2894 failMessage += " and candidates"
acsmars9475b1c2015-08-28 18:02:08 -07002895
Jon Hall5cf14d52015-07-16 12:15:19 -07002896 utilities.assert_equals(
2897 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002898 actual=sameResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002899 onpass="Leadership is consistent for the election topic",
acsmars9475b1c2015-08-28 18:02:08 -07002900 onfail=failMessage )
Jon Hall5cf14d52015-07-16 12:15:19 -07002901
2902 main.step( "Find current leader and withdraw" )
acsmars9475b1c2015-08-28 18:02:08 -07002903 withdrawResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002904 # do some sanity checking on leader before using it
acsmars9475b1c2015-08-28 18:02:08 -07002905 if oldLeader is None:
2906 main.log.error( "Leadership isn't consistent." )
2907 withdrawResult = main.FALSE
2908 # Get the CLI of the oldLeader
Jon Halle1a3b752015-07-22 13:02:46 -07002909 for i in range( len( main.CLIs ) ):
acsmars9475b1c2015-08-28 18:02:08 -07002910 if oldLeader == main.nodes[ i ].ip_address:
2911 oldLeaderCLI = main.CLIs[ i ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002912 break
2913 else: # FOR/ELSE statement
2914 main.log.error( "Leader election, could not find current leader" )
2915 if oldLeader:
acsmars9475b1c2015-08-28 18:02:08 -07002916 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall5cf14d52015-07-16 12:15:19 -07002917 utilities.assert_equals(
2918 expect=main.TRUE,
2919 actual=withdrawResult,
2920 onpass="Node was withdrawn from election",
2921 onfail="Node was not withdrawn from election" )
2922
acsmars9475b1c2015-08-28 18:02:08 -07002923 main.step( "Check that a new node was elected leader" )
acsmars71adceb2015-08-31 15:09:26 -07002924
Jon Hall5cf14d52015-07-16 12:15:19 -07002925 # FIXME: use threads
acsmars9475b1c2015-08-28 18:02:08 -07002926 newLeaderResult = main.TRUE
2927 failMessage = "Nodes have different leaders"
2928
2929 # Get new leaders and candidates
Jon Halle1a3b752015-07-22 13:02:46 -07002930 for cli in main.CLIs:
acsmars9475b1c2015-08-28 18:02:08 -07002931 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
acsmars71adceb2015-08-31 15:09:26 -07002932 # elections might no have finished yet
2933 if node[ 0 ] == 'none' and not expectNoLeader:
acsmars9475b1c2015-08-28 18:02:08 -07002934 main.log.info( "Node has no leader, waiting 5 seconds to be " +
2935 "sure elections are complete." )
2936 time.sleep(5)
2937 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
acsmars71adceb2015-08-31 15:09:26 -07002938 # election still isn't done or there is a problem
2939 if node[ 0 ] == 'none':
2940 main.log.error( "No leader was elected on at least 1 node" )
2941 newLeaderResult = main.FALSE
acsmars9475b1c2015-08-28 18:02:08 -07002942 newAllCandidates.append( node )
2943 newLeaders.append( node[ 0 ] )
2944 newCandidates = newAllCandidates[ 0 ]
2945
2946 # Check that each node has the same leader. Defines newLeader
2947 if len( set( newLeaders ) ) != 1:
2948 newLeaderResult = main.FALSE
2949 main.log.error( "Nodes have different leaders: " +
2950 str( newLeaders ) )
2951 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07002952 else:
acsmars9475b1c2015-08-28 18:02:08 -07002953 newLeader = newLeaders[ 0 ]
2954
acsmars71adceb2015-08-31 15:09:26 -07002955 # Check that each node's candidate list is the same
2956 for candidates in newAllCandidates:
2957 if set( candidates ) != set( newCandidates ):
2958 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07002959 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07002960
acsmars9475b1c2015-08-28 18:02:08 -07002961 # Check that the new leader is not the older leader, which was withdrawn
2962 if newLeader == oldLeader:
2963 newLeaderResult = main.FALSE
2964 main.log.error( "All nodes still see old leader: " + oldLeader +
2965 " as the current leader" )
2966
Jon Hall5cf14d52015-07-16 12:15:19 -07002967 utilities.assert_equals(
2968 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07002969 actual=newLeaderResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002970 onpass="Leadership election passed",
2971 onfail="Something went wrong with Leadership election" )
2972
acsmars9475b1c2015-08-28 18:02:08 -07002973 main.step( "Check that that new leader was the candidate of old leader")
2974 # candidates[ 2 ] should be come the top candidate after withdrawl
2975 correctCandidateResult = main.TRUE
acsmars71adceb2015-08-31 15:09:26 -07002976 if expectNoLeader:
2977 if newLeader == 'none':
2978 main.log.info( "No leader expected. None found. Pass" )
2979 correctCandidateResult = main.TRUE
2980 else:
2981 main.log.info( "Expected no leader, got: " + str( newLeader ) )
2982 correctCandidateResult = main.FALSE
2983 elif newLeader != oldCandidates[ 2 ]:
acsmars9475b1c2015-08-28 18:02:08 -07002984 correctCandidateResult = main.FALSE
2985 main.log.error( "Candidate " + newLeader + " was elected. " +
2986 oldCandidates[ 2 ] + " should have had priority." )
2987
2988 utilities.assert_equals(
2989 expect=main.TRUE,
2990 actual=correctCandidateResult,
2991 onpass="Correct Candidate Elected",
2992 onfail="Incorrect Candidate Elected" )
2993
Jon Hall5cf14d52015-07-16 12:15:19 -07002994 main.step( "Run for election on old leader( just so everyone " +
2995 "is in the hat )" )
acsmars9475b1c2015-08-28 18:02:08 -07002996 if oldLeaderCLI is not None:
2997 runResult = oldLeaderCLI.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07002998 else:
acsmars9475b1c2015-08-28 18:02:08 -07002999 main.log.error( "No old leader to re-elect" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003000 runResult = main.FALSE
3001 utilities.assert_equals(
3002 expect=main.TRUE,
3003 actual=runResult,
3004 onpass="App re-ran for election",
3005 onfail="App failed to run for election" )
acsmars9475b1c2015-08-28 18:02:08 -07003006 main.step(
3007 "Check that oldLeader is a candidate, and leader if only 1 node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003008 # verify leader didn't just change
acsmars9475b1c2015-08-28 18:02:08 -07003009 positionResult = main.TRUE
3010 # Get new leaders and candidates, wait if oldLeader is not a candidate yet
3011
3012 # Reset and reuse the new candidate and leaders lists
3013 newAllCandidates = []
3014 newCandidates = []
3015 newLeaders = []
3016 for cli in main.CLIs:
3017 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
3018 if oldLeader not in node: # election might no have finished yet
3019 main.log.info( "Old Leader not elected, waiting 5 seconds to " +
3020 "be sure elections are complete" )
3021 time.sleep(5)
3022 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
3023 if oldLeader not in node: # election still isn't done, errors
3024 main.log.error(
3025 "Old leader was not elected on at least one node" )
3026 positionResult = main.FALSE
3027 newAllCandidates.append( node )
3028 newLeaders.append( node[ 0 ] )
3029 newCandidates = newAllCandidates[ 0 ]
3030
3031 # Check that each node has the same leader. Defines newLeader
3032 if len( set( newLeaders ) ) != 1:
3033 positionResult = main.FALSE
3034 main.log.error( "Nodes have different leaders: " +
3035 str( newLeaders ) )
3036 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07003037 else:
acsmars9475b1c2015-08-28 18:02:08 -07003038 newLeader = newLeaders[ 0 ]
3039
acsmars71adceb2015-08-31 15:09:26 -07003040 # Check that each node's candidate list is the same
3041 for candidates in newAllCandidates:
3042 if set( candidates ) != set( newCandidates ):
3043 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07003044 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07003045
acsmars9475b1c2015-08-28 18:02:08 -07003046 # Check that the re-elected node is last on the candidate List
3047 if oldLeader != newCandidates[ -1 ]:
3048 main.log.error( "Old Leader (" + oldLeader + ") not in the proper position " +
3049 str( newCandidates ) )
3050 positionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07003051
3052 utilities.assert_equals(
3053 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07003054 actual=positionResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07003055 onpass="Old leader successfully re-ran for election",
3056 onfail="Something went wrong with Leadership election after " +
3057 "the old leader re-ran for election" )
3058
3059 def CASE16( self, main ):
3060 """
3061 Install Distributed Primitives app
3062 """
3063 import time
Jon Halle1a3b752015-07-22 13:02:46 -07003064 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003065 assert main, "main not defined"
3066 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003067 assert main.CLIs, "main.CLIs not defined"
3068 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003069
3070 # Variables for the distributed primitives tests
3071 global pCounterName
3072 global iCounterName
3073 global pCounterValue
3074 global iCounterValue
3075 global onosSet
3076 global onosSetName
3077 pCounterName = "TestON-Partitions"
3078 iCounterName = "TestON-inMemory"
3079 pCounterValue = 0
3080 iCounterValue = 0
3081 onosSet = set([])
3082 onosSetName = "TestON-set"
3083
3084 description = "Install Primitives app"
3085 main.case( description )
3086 main.step( "Install Primitives app" )
3087 appName = "org.onosproject.distributedprimitives"
Jon Halle1a3b752015-07-22 13:02:46 -07003088 appResults = main.CLIs[0].activateApp( appName )
Jon Hall5cf14d52015-07-16 12:15:19 -07003089 utilities.assert_equals( expect=main.TRUE,
3090 actual=appResults,
3091 onpass="Primitives app activated",
3092 onfail="Primitives app not activated" )
3093 time.sleep( 5 ) # To allow all nodes to activate
3094
3095 def CASE17( self, main ):
3096 """
3097 Check for basic functionality with distributed primitives
3098 """
Jon Hall5cf14d52015-07-16 12:15:19 -07003099 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07003100 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003101 assert main, "main not defined"
3102 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003103 assert main.CLIs, "main.CLIs not defined"
3104 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003105 assert pCounterName, "pCounterName not defined"
3106 assert iCounterName, "iCounterName not defined"
3107 assert onosSetName, "onosSetName not defined"
3108 # NOTE: assert fails if value is 0/None/Empty/False
3109 try:
3110 pCounterValue
3111 except NameError:
3112 main.log.error( "pCounterValue not defined, setting to 0" )
3113 pCounterValue = 0
3114 try:
3115 iCounterValue
3116 except NameError:
3117 main.log.error( "iCounterValue not defined, setting to 0" )
3118 iCounterValue = 0
3119 try:
3120 onosSet
3121 except NameError:
3122 main.log.error( "onosSet not defined, setting to empty Set" )
3123 onosSet = set([])
3124 # Variables for the distributed primitives tests. These are local only
3125 addValue = "a"
3126 addAllValue = "a b c d e f"
3127 retainValue = "c d e f"
3128
3129 description = "Check for basic functionality with distributed " +\
3130 "primitives"
3131 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07003132 main.caseExplanation = "Test the methods of the distributed " +\
3133 "primitives (counters and sets) throught the cli"
Jon Hall5cf14d52015-07-16 12:15:19 -07003134 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07003135 # Partitioned counters
3136 main.step( "Increment then get a default counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003137 pCounters = []
3138 threads = []
3139 addedPValues = []
Jon Halle1a3b752015-07-22 13:02:46 -07003140 for i in range( main.numCtrls ):
3141 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3142 name="counterAddAndGet-" + str( i ),
Jon Hall5cf14d52015-07-16 12:15:19 -07003143 args=[ pCounterName ] )
3144 pCounterValue += 1
3145 addedPValues.append( pCounterValue )
3146 threads.append( t )
3147 t.start()
3148
3149 for t in threads:
3150 t.join()
3151 pCounters.append( t.result )
3152 # Check that counter incremented numController times
3153 pCounterResults = True
3154 for i in addedPValues:
3155 tmpResult = i in pCounters
3156 pCounterResults = pCounterResults and tmpResult
3157 if not tmpResult:
3158 main.log.error( str( i ) + " is not in partitioned "
3159 "counter incremented results" )
3160 utilities.assert_equals( expect=True,
3161 actual=pCounterResults,
3162 onpass="Default counter incremented",
3163 onfail="Error incrementing default" +
3164 " counter" )
3165
Jon Halle1a3b752015-07-22 13:02:46 -07003166 main.step( "Get then Increment a default counter on each node" )
3167 pCounters = []
3168 threads = []
3169 addedPValues = []
3170 for i in range( main.numCtrls ):
3171 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3172 name="counterGetAndAdd-" + str( i ),
3173 args=[ pCounterName ] )
3174 addedPValues.append( pCounterValue )
3175 pCounterValue += 1
3176 threads.append( t )
3177 t.start()
3178
3179 for t in threads:
3180 t.join()
3181 pCounters.append( t.result )
3182 # Check that counter incremented numController times
3183 pCounterResults = True
3184 for i in addedPValues:
3185 tmpResult = i in pCounters
3186 pCounterResults = pCounterResults and tmpResult
3187 if not tmpResult:
3188 main.log.error( str( i ) + " is not in partitioned "
3189 "counter incremented results" )
3190 utilities.assert_equals( expect=True,
3191 actual=pCounterResults,
3192 onpass="Default counter incremented",
3193 onfail="Error incrementing default" +
3194 " counter" )
3195
3196 main.step( "Counters we added have the correct values" )
3197 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3198 utilities.assert_equals( expect=main.TRUE,
3199 actual=incrementCheck,
3200 onpass="Added counters are correct",
3201 onfail="Added counters are incorrect" )
3202
3203 main.step( "Add -8 to then get a default counter on each node" )
3204 pCounters = []
3205 threads = []
3206 addedPValues = []
3207 for i in range( main.numCtrls ):
3208 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3209 name="counterIncrement-" + str( i ),
3210 args=[ pCounterName ],
3211 kwargs={ "delta": -8 } )
3212 pCounterValue += -8
3213 addedPValues.append( pCounterValue )
3214 threads.append( t )
3215 t.start()
3216
3217 for t in threads:
3218 t.join()
3219 pCounters.append( t.result )
3220 # Check that counter incremented numController times
3221 pCounterResults = True
3222 for i in addedPValues:
3223 tmpResult = i in pCounters
3224 pCounterResults = pCounterResults and tmpResult
3225 if not tmpResult:
3226 main.log.error( str( i ) + " is not in partitioned "
3227 "counter incremented results" )
3228 utilities.assert_equals( expect=True,
3229 actual=pCounterResults,
3230 onpass="Default counter incremented",
3231 onfail="Error incrementing default" +
3232 " counter" )
3233
3234 main.step( "Add 5 to then get a default counter on each node" )
3235 pCounters = []
3236 threads = []
3237 addedPValues = []
3238 for i in range( main.numCtrls ):
3239 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3240 name="counterIncrement-" + str( i ),
3241 args=[ pCounterName ],
3242 kwargs={ "delta": 5 } )
3243 pCounterValue += 5
3244 addedPValues.append( pCounterValue )
3245 threads.append( t )
3246 t.start()
3247
3248 for t in threads:
3249 t.join()
3250 pCounters.append( t.result )
3251 # Check that counter incremented numController times
3252 pCounterResults = True
3253 for i in addedPValues:
3254 tmpResult = i in pCounters
3255 pCounterResults = pCounterResults and tmpResult
3256 if not tmpResult:
3257 main.log.error( str( i ) + " is not in partitioned "
3258 "counter incremented results" )
3259 utilities.assert_equals( expect=True,
3260 actual=pCounterResults,
3261 onpass="Default counter incremented",
3262 onfail="Error incrementing default" +
3263 " counter" )
3264
3265 main.step( "Get then add 5 to a default counter on each node" )
3266 pCounters = []
3267 threads = []
3268 addedPValues = []
3269 for i in range( main.numCtrls ):
3270 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3271 name="counterIncrement-" + str( i ),
3272 args=[ pCounterName ],
3273 kwargs={ "delta": 5 } )
3274 addedPValues.append( pCounterValue )
3275 pCounterValue += 5
3276 threads.append( t )
3277 t.start()
3278
3279 for t in threads:
3280 t.join()
3281 pCounters.append( t.result )
3282 # Check that counter incremented numController times
3283 pCounterResults = True
3284 for i in addedPValues:
3285 tmpResult = i in pCounters
3286 pCounterResults = pCounterResults and tmpResult
3287 if not tmpResult:
3288 main.log.error( str( i ) + " is not in partitioned "
3289 "counter incremented results" )
3290 utilities.assert_equals( expect=True,
3291 actual=pCounterResults,
3292 onpass="Default counter incremented",
3293 onfail="Error incrementing default" +
3294 " counter" )
3295
3296 main.step( "Counters we added have the correct values" )
3297 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3298 utilities.assert_equals( expect=main.TRUE,
3299 actual=incrementCheck,
3300 onpass="Added counters are correct",
3301 onfail="Added counters are incorrect" )
3302
3303 # In-Memory counters
3304 main.step( "Increment and get an in-memory counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003305 iCounters = []
3306 addedIValues = []
3307 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003308 for i in range( main.numCtrls ):
3309 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003310 name="icounterIncrement-" + str( i ),
3311 args=[ iCounterName ],
3312 kwargs={ "inMemory": True } )
3313 iCounterValue += 1
3314 addedIValues.append( iCounterValue )
3315 threads.append( t )
3316 t.start()
3317
3318 for t in threads:
3319 t.join()
3320 iCounters.append( t.result )
3321 # Check that counter incremented numController times
3322 iCounterResults = True
3323 for i in addedIValues:
3324 tmpResult = i in iCounters
3325 iCounterResults = iCounterResults and tmpResult
3326 if not tmpResult:
3327 main.log.error( str( i ) + " is not in the in-memory "
3328 "counter incremented results" )
3329 utilities.assert_equals( expect=True,
3330 actual=iCounterResults,
Jon Halle1a3b752015-07-22 13:02:46 -07003331 onpass="In-memory counter incremented",
3332 onfail="Error incrementing in-memory" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003333 " counter" )
3334
Jon Halle1a3b752015-07-22 13:02:46 -07003335 main.step( "Get then Increment a in-memory counter on each node" )
3336 iCounters = []
3337 threads = []
3338 addedIValues = []
3339 for i in range( main.numCtrls ):
3340 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3341 name="counterGetAndAdd-" + str( i ),
3342 args=[ iCounterName ],
3343 kwargs={ "inMemory": True } )
3344 addedIValues.append( iCounterValue )
3345 iCounterValue += 1
3346 threads.append( t )
3347 t.start()
3348
3349 for t in threads:
3350 t.join()
3351 iCounters.append( t.result )
3352 # Check that counter incremented numController times
3353 iCounterResults = True
3354 for i in addedIValues:
3355 tmpResult = i in iCounters
3356 iCounterResults = iCounterResults and tmpResult
3357 if not tmpResult:
3358 main.log.error( str( i ) + " is not in in-memory "
3359 "counter incremented results" )
3360 utilities.assert_equals( expect=True,
3361 actual=iCounterResults,
3362 onpass="In-memory counter incremented",
3363 onfail="Error incrementing in-memory" +
3364 " counter" )
3365
3366 main.step( "Counters we added have the correct values" )
3367 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3368 utilities.assert_equals( expect=main.TRUE,
3369 actual=incrementCheck,
3370 onpass="Added counters are correct",
3371 onfail="Added counters are incorrect" )
3372
3373 main.step( "Add -8 to then get a in-memory counter on each node" )
3374 iCounters = []
3375 threads = []
3376 addedIValues = []
3377 for i in range( main.numCtrls ):
3378 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3379 name="counterIncrement-" + str( i ),
3380 args=[ iCounterName ],
3381 kwargs={ "delta": -8, "inMemory": True } )
3382 iCounterValue += -8
3383 addedIValues.append( iCounterValue )
3384 threads.append( t )
3385 t.start()
3386
3387 for t in threads:
3388 t.join()
3389 iCounters.append( t.result )
3390 # Check that counter incremented numController times
3391 iCounterResults = True
3392 for i in addedIValues:
3393 tmpResult = i in iCounters
3394 iCounterResults = iCounterResults and tmpResult
3395 if not tmpResult:
3396 main.log.error( str( i ) + " is not in in-memory "
3397 "counter incremented results" )
3398 utilities.assert_equals( expect=True,
3399 actual=pCounterResults,
3400 onpass="In-memory counter incremented",
3401 onfail="Error incrementing in-memory" +
3402 " counter" )
3403
3404 main.step( "Add 5 to then get a in-memory counter on each node" )
3405 iCounters = []
3406 threads = []
3407 addedIValues = []
3408 for i in range( main.numCtrls ):
3409 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3410 name="counterIncrement-" + str( i ),
3411 args=[ iCounterName ],
3412 kwargs={ "delta": 5, "inMemory": True } )
3413 iCounterValue += 5
3414 addedIValues.append( iCounterValue )
3415 threads.append( t )
3416 t.start()
3417
3418 for t in threads:
3419 t.join()
3420 iCounters.append( t.result )
3421 # Check that counter incremented numController times
3422 iCounterResults = True
3423 for i in addedIValues:
3424 tmpResult = i in iCounters
3425 iCounterResults = iCounterResults and tmpResult
3426 if not tmpResult:
3427 main.log.error( str( i ) + " is not in in-memory "
3428 "counter incremented results" )
3429 utilities.assert_equals( expect=True,
3430 actual=pCounterResults,
3431 onpass="In-memory counter incremented",
3432 onfail="Error incrementing in-memory" +
3433 " counter" )
3434
3435 main.step( "Get then add 5 to a in-memory counter on each node" )
3436 iCounters = []
3437 threads = []
3438 addedIValues = []
3439 for i in range( main.numCtrls ):
3440 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3441 name="counterIncrement-" + str( i ),
3442 args=[ iCounterName ],
3443 kwargs={ "delta": 5, "inMemory": True } )
3444 addedIValues.append( iCounterValue )
3445 iCounterValue += 5
3446 threads.append( t )
3447 t.start()
3448
3449 for t in threads:
3450 t.join()
3451 iCounters.append( t.result )
3452 # Check that counter incremented numController times
3453 iCounterResults = True
3454 for i in addedIValues:
3455 tmpResult = i in iCounters
3456 iCounterResults = iCounterResults and tmpResult
3457 if not tmpResult:
3458 main.log.error( str( i ) + " is not in in-memory "
3459 "counter incremented results" )
3460 utilities.assert_equals( expect=True,
3461 actual=iCounterResults,
3462 onpass="In-memory counter incremented",
3463 onfail="Error incrementing in-memory" +
3464 " counter" )
3465
3466 main.step( "Counters we added have the correct values" )
3467 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3468 utilities.assert_equals( expect=main.TRUE,
3469 actual=incrementCheck,
3470 onpass="Added counters are correct",
3471 onfail="Added counters are incorrect" )
3472
Jon Hall5cf14d52015-07-16 12:15:19 -07003473 main.step( "Check counters are consistant across nodes" )
Jon Hall57b50432015-10-22 10:20:10 -07003474 onosCounters, consistentCounterResults = main.Counters.consistentCheck()
Jon Hall5cf14d52015-07-16 12:15:19 -07003475 utilities.assert_equals( expect=main.TRUE,
3476 actual=consistentCounterResults,
3477 onpass="ONOS counters are consistent " +
3478 "across nodes",
3479 onfail="ONOS Counters are inconsistent " +
3480 "across nodes" )
3481
3482 main.step( "Counters we added have the correct values" )
Jon Halle1a3b752015-07-22 13:02:46 -07003483 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3484 incrementCheck = incrementCheck and \
3485 main.Counters.counterCheck( iCounterName, iCounterValue )
Jon Hall5cf14d52015-07-16 12:15:19 -07003486 utilities.assert_equals( expect=main.TRUE,
Jon Halle1a3b752015-07-22 13:02:46 -07003487 actual=incrementCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -07003488 onpass="Added counters are correct",
3489 onfail="Added counters are incorrect" )
3490 # DISTRIBUTED SETS
3491 main.step( "Distributed Set get" )
3492 size = len( onosSet )
3493 getResponses = []
3494 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003495 for i in range( main.numCtrls ):
3496 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003497 name="setTestGet-" + str( i ),
3498 args=[ onosSetName ] )
3499 threads.append( t )
3500 t.start()
3501 for t in threads:
3502 t.join()
3503 getResponses.append( t.result )
3504
3505 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003506 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003507 if isinstance( getResponses[ i ], list):
3508 current = set( getResponses[ i ] )
3509 if len( current ) == len( getResponses[ i ] ):
3510 # no repeats
3511 if onosSet != current:
3512 main.log.error( "ONOS" + str( i + 1 ) +
3513 " has incorrect view" +
3514 " of set " + onosSetName + ":\n" +
3515 str( getResponses[ i ] ) )
3516 main.log.debug( "Expected: " + str( onosSet ) )
3517 main.log.debug( "Actual: " + str( current ) )
3518 getResults = main.FALSE
3519 else:
3520 # error, set is not a set
3521 main.log.error( "ONOS" + str( i + 1 ) +
3522 " has repeat elements in" +
3523 " set " + onosSetName + ":\n" +
3524 str( getResponses[ i ] ) )
3525 getResults = main.FALSE
3526 elif getResponses[ i ] == main.ERROR:
3527 getResults = main.FALSE
3528 utilities.assert_equals( expect=main.TRUE,
3529 actual=getResults,
3530 onpass="Set elements are correct",
3531 onfail="Set elements are incorrect" )
3532
3533 main.step( "Distributed Set size" )
3534 sizeResponses = []
3535 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003536 for i in range( main.numCtrls ):
3537 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003538 name="setTestSize-" + str( i ),
3539 args=[ onosSetName ] )
3540 threads.append( t )
3541 t.start()
3542 for t in threads:
3543 t.join()
3544 sizeResponses.append( t.result )
3545
3546 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003547 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003548 if size != sizeResponses[ i ]:
3549 sizeResults = main.FALSE
3550 main.log.error( "ONOS" + str( i + 1 ) +
3551 " expected a size of " + str( size ) +
3552 " for set " + onosSetName +
3553 " but got " + str( sizeResponses[ i ] ) )
3554 utilities.assert_equals( expect=main.TRUE,
3555 actual=sizeResults,
3556 onpass="Set sizes are correct",
3557 onfail="Set sizes are incorrect" )
3558
3559 main.step( "Distributed Set add()" )
3560 onosSet.add( addValue )
3561 addResponses = []
3562 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003563 for i in range( main.numCtrls ):
3564 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003565 name="setTestAdd-" + str( i ),
3566 args=[ onosSetName, addValue ] )
3567 threads.append( t )
3568 t.start()
3569 for t in threads:
3570 t.join()
3571 addResponses.append( t.result )
3572
3573 # main.TRUE = successfully changed the set
3574 # main.FALSE = action resulted in no change in set
3575 # main.ERROR - Some error in executing the function
3576 addResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003577 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003578 if addResponses[ i ] == main.TRUE:
3579 # All is well
3580 pass
3581 elif addResponses[ i ] == main.FALSE:
3582 # Already in set, probably fine
3583 pass
3584 elif addResponses[ i ] == main.ERROR:
3585 # Error in execution
3586 addResults = main.FALSE
3587 else:
3588 # unexpected result
3589 addResults = main.FALSE
3590 if addResults != main.TRUE:
3591 main.log.error( "Error executing set add" )
3592
3593 # Check if set is still correct
3594 size = len( onosSet )
3595 getResponses = []
3596 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003597 for i in range( main.numCtrls ):
3598 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003599 name="setTestGet-" + str( i ),
3600 args=[ onosSetName ] )
3601 threads.append( t )
3602 t.start()
3603 for t in threads:
3604 t.join()
3605 getResponses.append( t.result )
3606 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003607 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003608 if isinstance( getResponses[ i ], list):
3609 current = set( getResponses[ i ] )
3610 if len( current ) == len( getResponses[ i ] ):
3611 # no repeats
3612 if onosSet != current:
3613 main.log.error( "ONOS" + str( i + 1 ) +
3614 " has incorrect view" +
3615 " of set " + onosSetName + ":\n" +
3616 str( getResponses[ i ] ) )
3617 main.log.debug( "Expected: " + str( onosSet ) )
3618 main.log.debug( "Actual: " + str( current ) )
3619 getResults = main.FALSE
3620 else:
3621 # error, set is not a set
3622 main.log.error( "ONOS" + str( i + 1 ) +
3623 " has repeat elements in" +
3624 " set " + onosSetName + ":\n" +
3625 str( getResponses[ i ] ) )
3626 getResults = main.FALSE
3627 elif getResponses[ i ] == main.ERROR:
3628 getResults = main.FALSE
3629 sizeResponses = []
3630 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003631 for i in range( main.numCtrls ):
3632 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003633 name="setTestSize-" + str( i ),
3634 args=[ onosSetName ] )
3635 threads.append( t )
3636 t.start()
3637 for t in threads:
3638 t.join()
3639 sizeResponses.append( t.result )
3640 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003641 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003642 if size != sizeResponses[ i ]:
3643 sizeResults = main.FALSE
3644 main.log.error( "ONOS" + str( i + 1 ) +
3645 " expected a size of " + str( size ) +
3646 " for set " + onosSetName +
3647 " but got " + str( sizeResponses[ i ] ) )
3648 addResults = addResults and getResults and sizeResults
3649 utilities.assert_equals( expect=main.TRUE,
3650 actual=addResults,
3651 onpass="Set add correct",
3652 onfail="Set add was incorrect" )
3653
3654 main.step( "Distributed Set addAll()" )
3655 onosSet.update( addAllValue.split() )
3656 addResponses = []
3657 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003658 for i in range( main.numCtrls ):
3659 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003660 name="setTestAddAll-" + str( i ),
3661 args=[ onosSetName, addAllValue ] )
3662 threads.append( t )
3663 t.start()
3664 for t in threads:
3665 t.join()
3666 addResponses.append( t.result )
3667
3668 # main.TRUE = successfully changed the set
3669 # main.FALSE = action resulted in no change in set
3670 # main.ERROR - Some error in executing the function
3671 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003672 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003673 if addResponses[ i ] == main.TRUE:
3674 # All is well
3675 pass
3676 elif addResponses[ i ] == main.FALSE:
3677 # Already in set, probably fine
3678 pass
3679 elif addResponses[ i ] == main.ERROR:
3680 # Error in execution
3681 addAllResults = main.FALSE
3682 else:
3683 # unexpected result
3684 addAllResults = main.FALSE
3685 if addAllResults != main.TRUE:
3686 main.log.error( "Error executing set addAll" )
3687
3688 # Check if set is still correct
3689 size = len( onosSet )
3690 getResponses = []
3691 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003692 for i in range( main.numCtrls ):
3693 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003694 name="setTestGet-" + str( i ),
3695 args=[ onosSetName ] )
3696 threads.append( t )
3697 t.start()
3698 for t in threads:
3699 t.join()
3700 getResponses.append( t.result )
3701 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003702 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003703 if isinstance( getResponses[ i ], list):
3704 current = set( getResponses[ i ] )
3705 if len( current ) == len( getResponses[ i ] ):
3706 # no repeats
3707 if onosSet != current:
3708 main.log.error( "ONOS" + str( i + 1 ) +
3709 " has incorrect view" +
3710 " of set " + onosSetName + ":\n" +
3711 str( getResponses[ i ] ) )
3712 main.log.debug( "Expected: " + str( onosSet ) )
3713 main.log.debug( "Actual: " + str( current ) )
3714 getResults = main.FALSE
3715 else:
3716 # error, set is not a set
3717 main.log.error( "ONOS" + str( i + 1 ) +
3718 " has repeat elements in" +
3719 " set " + onosSetName + ":\n" +
3720 str( getResponses[ i ] ) )
3721 getResults = main.FALSE
3722 elif getResponses[ i ] == main.ERROR:
3723 getResults = main.FALSE
3724 sizeResponses = []
3725 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003726 for i in range( main.numCtrls ):
3727 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003728 name="setTestSize-" + str( i ),
3729 args=[ onosSetName ] )
3730 threads.append( t )
3731 t.start()
3732 for t in threads:
3733 t.join()
3734 sizeResponses.append( t.result )
3735 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003736 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003737 if size != sizeResponses[ i ]:
3738 sizeResults = main.FALSE
3739 main.log.error( "ONOS" + str( i + 1 ) +
3740 " expected a size of " + str( size ) +
3741 " for set " + onosSetName +
3742 " but got " + str( sizeResponses[ i ] ) )
3743 addAllResults = addAllResults and getResults and sizeResults
3744 utilities.assert_equals( expect=main.TRUE,
3745 actual=addAllResults,
3746 onpass="Set addAll correct",
3747 onfail="Set addAll was incorrect" )
3748
3749 main.step( "Distributed Set contains()" )
3750 containsResponses = []
3751 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003752 for i in range( main.numCtrls ):
3753 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003754 name="setContains-" + str( i ),
3755 args=[ onosSetName ],
3756 kwargs={ "values": addValue } )
3757 threads.append( t )
3758 t.start()
3759 for t in threads:
3760 t.join()
3761 # NOTE: This is the tuple
3762 containsResponses.append( t.result )
3763
3764 containsResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003765 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003766 if containsResponses[ i ] == main.ERROR:
3767 containsResults = main.FALSE
3768 else:
3769 containsResults = containsResults and\
3770 containsResponses[ i ][ 1 ]
3771 utilities.assert_equals( expect=main.TRUE,
3772 actual=containsResults,
3773 onpass="Set contains is functional",
3774 onfail="Set contains failed" )
3775
3776 main.step( "Distributed Set containsAll()" )
3777 containsAllResponses = []
3778 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003779 for i in range( main.numCtrls ):
3780 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003781 name="setContainsAll-" + str( i ),
3782 args=[ onosSetName ],
3783 kwargs={ "values": addAllValue } )
3784 threads.append( t )
3785 t.start()
3786 for t in threads:
3787 t.join()
3788 # NOTE: This is the tuple
3789 containsAllResponses.append( t.result )
3790
3791 containsAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003792 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003793 if containsResponses[ i ] == main.ERROR:
3794 containsResults = main.FALSE
3795 else:
3796 containsResults = containsResults and\
3797 containsResponses[ i ][ 1 ]
3798 utilities.assert_equals( expect=main.TRUE,
3799 actual=containsAllResults,
3800 onpass="Set containsAll is functional",
3801 onfail="Set containsAll failed" )
3802
3803 main.step( "Distributed Set remove()" )
3804 onosSet.remove( addValue )
3805 removeResponses = []
3806 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003807 for i in range( main.numCtrls ):
3808 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003809 name="setTestRemove-" + str( i ),
3810 args=[ onosSetName, addValue ] )
3811 threads.append( t )
3812 t.start()
3813 for t in threads:
3814 t.join()
3815 removeResponses.append( t.result )
3816
3817 # main.TRUE = successfully changed the set
3818 # main.FALSE = action resulted in no change in set
3819 # main.ERROR - Some error in executing the function
3820 removeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003821 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003822 if removeResponses[ i ] == main.TRUE:
3823 # All is well
3824 pass
3825 elif removeResponses[ i ] == main.FALSE:
3826 # not in set, probably fine
3827 pass
3828 elif removeResponses[ i ] == main.ERROR:
3829 # Error in execution
3830 removeResults = main.FALSE
3831 else:
3832 # unexpected result
3833 removeResults = main.FALSE
3834 if removeResults != main.TRUE:
3835 main.log.error( "Error executing set remove" )
3836
3837 # Check if set is still correct
3838 size = len( onosSet )
3839 getResponses = []
3840 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003841 for i in range( main.numCtrls ):
3842 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003843 name="setTestGet-" + str( i ),
3844 args=[ onosSetName ] )
3845 threads.append( t )
3846 t.start()
3847 for t in threads:
3848 t.join()
3849 getResponses.append( t.result )
3850 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003851 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003852 if isinstance( getResponses[ i ], list):
3853 current = set( getResponses[ i ] )
3854 if len( current ) == len( getResponses[ i ] ):
3855 # no repeats
3856 if onosSet != current:
3857 main.log.error( "ONOS" + str( i + 1 ) +
3858 " has incorrect view" +
3859 " of set " + onosSetName + ":\n" +
3860 str( getResponses[ i ] ) )
3861 main.log.debug( "Expected: " + str( onosSet ) )
3862 main.log.debug( "Actual: " + str( current ) )
3863 getResults = main.FALSE
3864 else:
3865 # error, set is not a set
3866 main.log.error( "ONOS" + str( i + 1 ) +
3867 " has repeat elements in" +
3868 " set " + onosSetName + ":\n" +
3869 str( getResponses[ i ] ) )
3870 getResults = main.FALSE
3871 elif getResponses[ i ] == main.ERROR:
3872 getResults = main.FALSE
3873 sizeResponses = []
3874 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003875 for i in range( main.numCtrls ):
3876 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003877 name="setTestSize-" + str( i ),
3878 args=[ onosSetName ] )
3879 threads.append( t )
3880 t.start()
3881 for t in threads:
3882 t.join()
3883 sizeResponses.append( t.result )
3884 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003885 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003886 if size != sizeResponses[ i ]:
3887 sizeResults = main.FALSE
3888 main.log.error( "ONOS" + str( i + 1 ) +
3889 " expected a size of " + str( size ) +
3890 " for set " + onosSetName +
3891 " but got " + str( sizeResponses[ i ] ) )
3892 removeResults = removeResults and getResults and sizeResults
3893 utilities.assert_equals( expect=main.TRUE,
3894 actual=removeResults,
3895 onpass="Set remove correct",
3896 onfail="Set remove was incorrect" )
3897
3898 main.step( "Distributed Set removeAll()" )
3899 onosSet.difference_update( addAllValue.split() )
3900 removeAllResponses = []
3901 threads = []
3902 try:
Jon Halle1a3b752015-07-22 13:02:46 -07003903 for i in range( main.numCtrls ):
3904 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003905 name="setTestRemoveAll-" + str( i ),
3906 args=[ onosSetName, addAllValue ] )
3907 threads.append( t )
3908 t.start()
3909 for t in threads:
3910 t.join()
3911 removeAllResponses.append( t.result )
3912 except Exception, e:
3913 main.log.exception(e)
3914
3915 # main.TRUE = successfully changed the set
3916 # main.FALSE = action resulted in no change in set
3917 # main.ERROR - Some error in executing the function
3918 removeAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003919 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003920 if removeAllResponses[ i ] == main.TRUE:
3921 # All is well
3922 pass
3923 elif removeAllResponses[ i ] == main.FALSE:
3924 # not in set, probably fine
3925 pass
3926 elif removeAllResponses[ i ] == main.ERROR:
3927 # Error in execution
3928 removeAllResults = main.FALSE
3929 else:
3930 # unexpected result
3931 removeAllResults = main.FALSE
3932 if removeAllResults != main.TRUE:
3933 main.log.error( "Error executing set removeAll" )
3934
3935 # Check if set is still correct
3936 size = len( onosSet )
3937 getResponses = []
3938 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003939 for i in range( main.numCtrls ):
3940 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003941 name="setTestGet-" + str( i ),
3942 args=[ onosSetName ] )
3943 threads.append( t )
3944 t.start()
3945 for t in threads:
3946 t.join()
3947 getResponses.append( t.result )
3948 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003949 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003950 if isinstance( getResponses[ i ], list):
3951 current = set( getResponses[ i ] )
3952 if len( current ) == len( getResponses[ i ] ):
3953 # no repeats
3954 if onosSet != current:
3955 main.log.error( "ONOS" + str( i + 1 ) +
3956 " has incorrect view" +
3957 " of set " + onosSetName + ":\n" +
3958 str( getResponses[ i ] ) )
3959 main.log.debug( "Expected: " + str( onosSet ) )
3960 main.log.debug( "Actual: " + str( current ) )
3961 getResults = main.FALSE
3962 else:
3963 # error, set is not a set
3964 main.log.error( "ONOS" + str( i + 1 ) +
3965 " has repeat elements in" +
3966 " set " + onosSetName + ":\n" +
3967 str( getResponses[ i ] ) )
3968 getResults = main.FALSE
3969 elif getResponses[ i ] == main.ERROR:
3970 getResults = main.FALSE
3971 sizeResponses = []
3972 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003973 for i in range( main.numCtrls ):
3974 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003975 name="setTestSize-" + str( i ),
3976 args=[ onosSetName ] )
3977 threads.append( t )
3978 t.start()
3979 for t in threads:
3980 t.join()
3981 sizeResponses.append( t.result )
3982 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003983 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003984 if size != sizeResponses[ i ]:
3985 sizeResults = main.FALSE
3986 main.log.error( "ONOS" + str( i + 1 ) +
3987 " expected a size of " + str( size ) +
3988 " for set " + onosSetName +
3989 " but got " + str( sizeResponses[ i ] ) )
3990 removeAllResults = removeAllResults and getResults and sizeResults
3991 utilities.assert_equals( expect=main.TRUE,
3992 actual=removeAllResults,
3993 onpass="Set removeAll correct",
3994 onfail="Set removeAll was incorrect" )
3995
3996 main.step( "Distributed Set addAll()" )
3997 onosSet.update( addAllValue.split() )
3998 addResponses = []
3999 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004000 for i in range( main.numCtrls ):
4001 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004002 name="setTestAddAll-" + str( i ),
4003 args=[ onosSetName, addAllValue ] )
4004 threads.append( t )
4005 t.start()
4006 for t in threads:
4007 t.join()
4008 addResponses.append( t.result )
4009
4010 # main.TRUE = successfully changed the set
4011 # main.FALSE = action resulted in no change in set
4012 # main.ERROR - Some error in executing the function
4013 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004014 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004015 if addResponses[ i ] == main.TRUE:
4016 # All is well
4017 pass
4018 elif addResponses[ i ] == main.FALSE:
4019 # Already in set, probably fine
4020 pass
4021 elif addResponses[ i ] == main.ERROR:
4022 # Error in execution
4023 addAllResults = main.FALSE
4024 else:
4025 # unexpected result
4026 addAllResults = main.FALSE
4027 if addAllResults != main.TRUE:
4028 main.log.error( "Error executing set addAll" )
4029
4030 # Check if set is still correct
4031 size = len( onosSet )
4032 getResponses = []
4033 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004034 for i in range( main.numCtrls ):
4035 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004036 name="setTestGet-" + str( i ),
4037 args=[ onosSetName ] )
4038 threads.append( t )
4039 t.start()
4040 for t in threads:
4041 t.join()
4042 getResponses.append( t.result )
4043 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004044 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004045 if isinstance( getResponses[ i ], list):
4046 current = set( getResponses[ i ] )
4047 if len( current ) == len( getResponses[ i ] ):
4048 # no repeats
4049 if onosSet != current:
4050 main.log.error( "ONOS" + str( i + 1 ) +
4051 " has incorrect view" +
4052 " of set " + onosSetName + ":\n" +
4053 str( getResponses[ i ] ) )
4054 main.log.debug( "Expected: " + str( onosSet ) )
4055 main.log.debug( "Actual: " + str( current ) )
4056 getResults = main.FALSE
4057 else:
4058 # error, set is not a set
4059 main.log.error( "ONOS" + str( i + 1 ) +
4060 " has repeat elements in" +
4061 " set " + onosSetName + ":\n" +
4062 str( getResponses[ i ] ) )
4063 getResults = main.FALSE
4064 elif getResponses[ i ] == main.ERROR:
4065 getResults = main.FALSE
4066 sizeResponses = []
4067 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004068 for i in range( main.numCtrls ):
4069 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004070 name="setTestSize-" + str( i ),
4071 args=[ onosSetName ] )
4072 threads.append( t )
4073 t.start()
4074 for t in threads:
4075 t.join()
4076 sizeResponses.append( t.result )
4077 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004078 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004079 if size != sizeResponses[ i ]:
4080 sizeResults = main.FALSE
4081 main.log.error( "ONOS" + str( i + 1 ) +
4082 " expected a size of " + str( size ) +
4083 " for set " + onosSetName +
4084 " but got " + str( sizeResponses[ i ] ) )
4085 addAllResults = addAllResults and getResults and sizeResults
4086 utilities.assert_equals( expect=main.TRUE,
4087 actual=addAllResults,
4088 onpass="Set addAll correct",
4089 onfail="Set addAll was incorrect" )
4090
4091 main.step( "Distributed Set clear()" )
4092 onosSet.clear()
4093 clearResponses = []
4094 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004095 for i in range( main.numCtrls ):
4096 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004097 name="setTestClear-" + str( i ),
4098 args=[ onosSetName, " "], # Values doesn't matter
4099 kwargs={ "clear": True } )
4100 threads.append( t )
4101 t.start()
4102 for t in threads:
4103 t.join()
4104 clearResponses.append( t.result )
4105
4106 # main.TRUE = successfully changed the set
4107 # main.FALSE = action resulted in no change in set
4108 # main.ERROR - Some error in executing the function
4109 clearResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004110 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004111 if clearResponses[ i ] == main.TRUE:
4112 # All is well
4113 pass
4114 elif clearResponses[ i ] == main.FALSE:
4115 # Nothing set, probably fine
4116 pass
4117 elif clearResponses[ i ] == main.ERROR:
4118 # Error in execution
4119 clearResults = main.FALSE
4120 else:
4121 # unexpected result
4122 clearResults = main.FALSE
4123 if clearResults != main.TRUE:
4124 main.log.error( "Error executing set clear" )
4125
4126 # Check if set is still correct
4127 size = len( onosSet )
4128 getResponses = []
4129 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004130 for i in range( main.numCtrls ):
4131 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004132 name="setTestGet-" + str( i ),
4133 args=[ onosSetName ] )
4134 threads.append( t )
4135 t.start()
4136 for t in threads:
4137 t.join()
4138 getResponses.append( t.result )
4139 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004140 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004141 if isinstance( getResponses[ i ], list):
4142 current = set( getResponses[ i ] )
4143 if len( current ) == len( getResponses[ i ] ):
4144 # no repeats
4145 if onosSet != current:
4146 main.log.error( "ONOS" + str( i + 1 ) +
4147 " has incorrect view" +
4148 " of set " + onosSetName + ":\n" +
4149 str( getResponses[ i ] ) )
4150 main.log.debug( "Expected: " + str( onosSet ) )
4151 main.log.debug( "Actual: " + str( current ) )
4152 getResults = main.FALSE
4153 else:
4154 # error, set is not a set
4155 main.log.error( "ONOS" + str( i + 1 ) +
4156 " has repeat elements in" +
4157 " set " + onosSetName + ":\n" +
4158 str( getResponses[ i ] ) )
4159 getResults = main.FALSE
4160 elif getResponses[ i ] == main.ERROR:
4161 getResults = main.FALSE
4162 sizeResponses = []
4163 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004164 for i in range( main.numCtrls ):
4165 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004166 name="setTestSize-" + str( i ),
4167 args=[ onosSetName ] )
4168 threads.append( t )
4169 t.start()
4170 for t in threads:
4171 t.join()
4172 sizeResponses.append( t.result )
4173 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004174 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004175 if size != sizeResponses[ i ]:
4176 sizeResults = main.FALSE
4177 main.log.error( "ONOS" + str( i + 1 ) +
4178 " expected a size of " + str( size ) +
4179 " for set " + onosSetName +
4180 " but got " + str( sizeResponses[ i ] ) )
4181 clearResults = clearResults and getResults and sizeResults
4182 utilities.assert_equals( expect=main.TRUE,
4183 actual=clearResults,
4184 onpass="Set clear correct",
4185 onfail="Set clear was incorrect" )
4186
4187 main.step( "Distributed Set addAll()" )
4188 onosSet.update( addAllValue.split() )
4189 addResponses = []
4190 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004191 for i in range( main.numCtrls ):
4192 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004193 name="setTestAddAll-" + str( i ),
4194 args=[ onosSetName, addAllValue ] )
4195 threads.append( t )
4196 t.start()
4197 for t in threads:
4198 t.join()
4199 addResponses.append( t.result )
4200
4201 # main.TRUE = successfully changed the set
4202 # main.FALSE = action resulted in no change in set
4203 # main.ERROR - Some error in executing the function
4204 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004205 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004206 if addResponses[ i ] == main.TRUE:
4207 # All is well
4208 pass
4209 elif addResponses[ i ] == main.FALSE:
4210 # Already in set, probably fine
4211 pass
4212 elif addResponses[ i ] == main.ERROR:
4213 # Error in execution
4214 addAllResults = main.FALSE
4215 else:
4216 # unexpected result
4217 addAllResults = main.FALSE
4218 if addAllResults != main.TRUE:
4219 main.log.error( "Error executing set addAll" )
4220
4221 # Check if set is still correct
4222 size = len( onosSet )
4223 getResponses = []
4224 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004225 for i in range( main.numCtrls ):
4226 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004227 name="setTestGet-" + str( i ),
4228 args=[ onosSetName ] )
4229 threads.append( t )
4230 t.start()
4231 for t in threads:
4232 t.join()
4233 getResponses.append( t.result )
4234 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004235 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004236 if isinstance( getResponses[ i ], list):
4237 current = set( getResponses[ i ] )
4238 if len( current ) == len( getResponses[ i ] ):
4239 # no repeats
4240 if onosSet != current:
4241 main.log.error( "ONOS" + str( i + 1 ) +
4242 " has incorrect view" +
4243 " of set " + onosSetName + ":\n" +
4244 str( getResponses[ i ] ) )
4245 main.log.debug( "Expected: " + str( onosSet ) )
4246 main.log.debug( "Actual: " + str( current ) )
4247 getResults = main.FALSE
4248 else:
4249 # error, set is not a set
4250 main.log.error( "ONOS" + str( i + 1 ) +
4251 " has repeat elements in" +
4252 " set " + onosSetName + ":\n" +
4253 str( getResponses[ i ] ) )
4254 getResults = main.FALSE
4255 elif getResponses[ i ] == main.ERROR:
4256 getResults = main.FALSE
4257 sizeResponses = []
4258 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004259 for i in range( main.numCtrls ):
4260 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004261 name="setTestSize-" + str( i ),
4262 args=[ onosSetName ] )
4263 threads.append( t )
4264 t.start()
4265 for t in threads:
4266 t.join()
4267 sizeResponses.append( t.result )
4268 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004269 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004270 if size != sizeResponses[ i ]:
4271 sizeResults = main.FALSE
4272 main.log.error( "ONOS" + str( i + 1 ) +
4273 " expected a size of " + str( size ) +
4274 " for set " + onosSetName +
4275 " but got " + str( sizeResponses[ i ] ) )
4276 addAllResults = addAllResults and getResults and sizeResults
4277 utilities.assert_equals( expect=main.TRUE,
4278 actual=addAllResults,
4279 onpass="Set addAll correct",
4280 onfail="Set addAll was incorrect" )
4281
4282 main.step( "Distributed Set retain()" )
4283 onosSet.intersection_update( retainValue.split() )
4284 retainResponses = []
4285 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004286 for i in range( main.numCtrls ):
4287 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004288 name="setTestRetain-" + str( i ),
4289 args=[ onosSetName, retainValue ],
4290 kwargs={ "retain": True } )
4291 threads.append( t )
4292 t.start()
4293 for t in threads:
4294 t.join()
4295 retainResponses.append( t.result )
4296
4297 # main.TRUE = successfully changed the set
4298 # main.FALSE = action resulted in no change in set
4299 # main.ERROR - Some error in executing the function
4300 retainResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004301 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004302 if retainResponses[ i ] == main.TRUE:
4303 # All is well
4304 pass
4305 elif retainResponses[ i ] == main.FALSE:
4306 # Already in set, probably fine
4307 pass
4308 elif retainResponses[ i ] == main.ERROR:
4309 # Error in execution
4310 retainResults = main.FALSE
4311 else:
4312 # unexpected result
4313 retainResults = main.FALSE
4314 if retainResults != main.TRUE:
4315 main.log.error( "Error executing set retain" )
4316
4317 # Check if set is still correct
4318 size = len( onosSet )
4319 getResponses = []
4320 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004321 for i in range( main.numCtrls ):
4322 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004323 name="setTestGet-" + str( i ),
4324 args=[ onosSetName ] )
4325 threads.append( t )
4326 t.start()
4327 for t in threads:
4328 t.join()
4329 getResponses.append( t.result )
4330 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004331 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004332 if isinstance( getResponses[ i ], list):
4333 current = set( getResponses[ i ] )
4334 if len( current ) == len( getResponses[ i ] ):
4335 # no repeats
4336 if onosSet != current:
4337 main.log.error( "ONOS" + str( i + 1 ) +
4338 " has incorrect view" +
4339 " of set " + onosSetName + ":\n" +
4340 str( getResponses[ i ] ) )
4341 main.log.debug( "Expected: " + str( onosSet ) )
4342 main.log.debug( "Actual: " + str( current ) )
4343 getResults = main.FALSE
4344 else:
4345 # error, set is not a set
4346 main.log.error( "ONOS" + str( i + 1 ) +
4347 " has repeat elements in" +
4348 " set " + onosSetName + ":\n" +
4349 str( getResponses[ i ] ) )
4350 getResults = main.FALSE
4351 elif getResponses[ i ] == main.ERROR:
4352 getResults = main.FALSE
4353 sizeResponses = []
4354 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004355 for i in range( main.numCtrls ):
4356 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004357 name="setTestSize-" + str( i ),
4358 args=[ onosSetName ] )
4359 threads.append( t )
4360 t.start()
4361 for t in threads:
4362 t.join()
4363 sizeResponses.append( t.result )
4364 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004365 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004366 if size != sizeResponses[ i ]:
4367 sizeResults = main.FALSE
4368 main.log.error( "ONOS" + str( i + 1 ) +
4369 " expected a size of " +
4370 str( size ) + " for set " + onosSetName +
4371 " but got " + str( sizeResponses[ i ] ) )
4372 retainResults = retainResults and getResults and sizeResults
4373 utilities.assert_equals( expect=main.TRUE,
4374 actual=retainResults,
4375 onpass="Set retain correct",
4376 onfail="Set retain was incorrect" )
4377
Jon Hall2a5002c2015-08-21 16:49:11 -07004378 # Transactional maps
4379 main.step( "Partitioned Transactional maps put" )
4380 tMapValue = "Testing"
4381 numKeys = 100
4382 putResult = True
4383 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue )
4384 if len( putResponses ) == 100:
4385 for i in putResponses:
4386 if putResponses[ i ][ 'value' ] != tMapValue:
4387 putResult = False
4388 else:
4389 putResult = False
4390 if not putResult:
4391 main.log.debug( "Put response values: " + str( putResponses ) )
4392 utilities.assert_equals( expect=True,
4393 actual=putResult,
4394 onpass="Partitioned Transactional Map put successful",
4395 onfail="Partitioned Transactional Map put values are incorrect" )
4396
4397 main.step( "Partitioned Transactional maps get" )
4398 getCheck = True
4399 for n in range( 1, numKeys + 1 ):
4400 getResponses = []
4401 threads = []
4402 valueCheck = True
4403 for i in range( main.numCtrls ):
4404 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4405 name="TMap-get-" + str( i ),
4406 args=[ "Key" + str ( n ) ] )
4407 threads.append( t )
4408 t.start()
4409 for t in threads:
4410 t.join()
4411 getResponses.append( t.result )
4412 for node in getResponses:
4413 if node != tMapValue:
4414 valueCheck = False
4415 if not valueCheck:
4416 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4417 main.log.warn( getResponses )
4418 getCheck = getCheck and valueCheck
4419 utilities.assert_equals( expect=True,
4420 actual=getCheck,
4421 onpass="Partitioned Transactional Map get values were correct",
4422 onfail="Partitioned Transactional Map values incorrect" )
4423
4424 main.step( "In-memory Transactional maps put" )
4425 tMapValue = "Testing"
4426 numKeys = 100
4427 putResult = True
4428 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue, inMemory=True )
4429 if len( putResponses ) == 100:
4430 for i in putResponses:
4431 if putResponses[ i ][ 'value' ] != tMapValue:
4432 putResult = False
4433 else:
4434 putResult = False
4435 if not putResult:
4436 main.log.debug( "Put response values: " + str( putResponses ) )
4437 utilities.assert_equals( expect=True,
4438 actual=putResult,
4439 onpass="In-Memory Transactional Map put successful",
4440 onfail="In-Memory Transactional Map put values are incorrect" )
4441
4442 main.step( "In-Memory Transactional maps get" )
4443 getCheck = True
4444 for n in range( 1, numKeys + 1 ):
4445 getResponses = []
4446 threads = []
4447 valueCheck = True
4448 for i in range( main.numCtrls ):
4449 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4450 name="TMap-get-" + str( i ),
4451 args=[ "Key" + str ( n ) ],
4452 kwargs={ "inMemory": True } )
4453 threads.append( t )
4454 t.start()
4455 for t in threads:
4456 t.join()
4457 getResponses.append( t.result )
4458 for node in getResponses:
4459 if node != tMapValue:
4460 valueCheck = False
4461 if not valueCheck:
4462 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4463 main.log.warn( getResponses )
4464 getCheck = getCheck and valueCheck
4465 utilities.assert_equals( expect=True,
4466 actual=getCheck,
4467 onpass="In-Memory Transactional Map get values were correct",
4468 onfail="In-Memory Transactional Map values incorrect" )