blob: b5ebe7dde980faeed071ffdbd9a389dda7328dd2 [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 Hall5cf14d52015-07-16 12:15:19 -070051 main.log.info( "ONOS HA test: Restart all ONOS nodes - " +
52 "initialization" )
53 main.case( "Setting up test environment" )
Jon Hall783bbf92015-07-23 14:33:19 -070054 main.caseExplanation = "Setup the test environment including " +\
Jon Hall5cf14d52015-07-16 12:15:19 -070055 "installing ONOS, starting Mininet and ONOS" +\
56 "cli sessions."
57 # TODO: save all the timers and output them for plotting
58
59 # load some variables from the params file
60 PULLCODE = False
61 if main.params[ 'Git' ] == 'True':
62 PULLCODE = True
63 gitBranch = main.params[ 'branch' ]
64 cellName = main.params[ 'ENV' ][ 'cellName' ]
65
Jon Halle1a3b752015-07-22 13:02:46 -070066 main.numCtrls = int( main.params[ 'num_controllers' ] )
Jon Hall5cf14d52015-07-16 12:15:19 -070067 if main.ONOSbench.maxNodes:
Jon Halle1a3b752015-07-22 13:02:46 -070068 if main.ONOSbench.maxNodes < main.numCtrls:
69 main.numCtrls = int( main.ONOSbench.maxNodes )
70 # set global variables
Jon Hall5cf14d52015-07-16 12:15:19 -070071 global ONOS1Port
72 global ONOS2Port
73 global ONOS3Port
74 global ONOS4Port
75 global ONOS5Port
76 global ONOS6Port
77 global ONOS7Port
78 # These are for csv plotting in jenkins
79 global labels
80 global data
81 labels = []
82 data = []
83
84 # FIXME: just get controller port from params?
85 # TODO: do we really need all these?
86 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
87 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
88 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
89 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
90 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
91 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
92 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
93
Jon Halle1a3b752015-07-22 13:02:46 -070094 try:
95 fileName = "Counters"
96 path = main.params[ 'imports' ][ 'path' ]
97 main.Counters = imp.load_source( fileName,
98 path + fileName + ".py" )
99 except Exception as e:
100 main.log.exception( e )
101 main.cleanup()
102 main.exit()
103
104 main.CLIs = []
105 main.nodes = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700106 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700107 for i in range( 1, main.numCtrls + 1 ):
108 try:
109 main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
110 main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
111 ipList.append( main.nodes[ -1 ].ip_address )
112 except AttributeError:
113 break
Jon Hall5cf14d52015-07-16 12:15:19 -0700114
115 main.step( "Create cell file" )
116 cellAppString = main.params[ 'ENV' ][ 'appString' ]
117 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
118 main.Mininet1.ip_address,
119 cellAppString, ipList )
120 main.step( "Applying cell variable to environment" )
121 cellResult = main.ONOSbench.setCell( cellName )
122 verifyResult = main.ONOSbench.verifyCell()
123
124 # FIXME:this is short term fix
125 main.log.info( "Removing raft logs" )
126 main.ONOSbench.onosRemoveRaftLogs()
127
128 main.log.info( "Uninstalling ONOS" )
Jon Halle1a3b752015-07-22 13:02:46 -0700129 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700130 main.ONOSbench.onosUninstall( node.ip_address )
131
132 # Make sure ONOS is DEAD
133 main.log.info( "Killing any ONOS processes" )
134 killResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700135 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700136 killed = main.ONOSbench.onosKill( node.ip_address )
137 killResults = killResults and killed
138
139 cleanInstallResult = main.TRUE
140 gitPullResult = main.TRUE
141
142 main.step( "Starting Mininet" )
143 # scp topo file to mininet
144 # TODO: move to params?
145 topoName = "obelisk.py"
146 filePath = main.ONOSbench.home + "/tools/test/topos/"
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700147 main.ONOSbench.scp( main.Mininet1,
148 filePath + topoName,
149 main.Mininet1.home,
150 direction="to" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700151 mnResult = main.Mininet1.startNet( )
152 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
153 onpass="Mininet Started",
154 onfail="Error starting Mininet" )
155
156 main.step( "Git checkout and pull " + gitBranch )
157 if PULLCODE:
158 main.ONOSbench.gitCheckout( gitBranch )
159 gitPullResult = main.ONOSbench.gitPull()
160 # values of 1 or 3 are good
161 utilities.assert_lesser( expect=0, actual=gitPullResult,
162 onpass="Git pull successful",
163 onfail="Git pull failed" )
164 main.ONOSbench.getVersion( report=True )
165
166 main.step( "Using mvn clean install" )
167 cleanInstallResult = main.TRUE
168 if PULLCODE and gitPullResult == main.TRUE:
169 cleanInstallResult = main.ONOSbench.cleanInstall()
170 else:
171 main.log.warn( "Did not pull new code so skipping mvn " +
172 "clean install" )
173 utilities.assert_equals( expect=main.TRUE,
174 actual=cleanInstallResult,
175 onpass="MCI successful",
176 onfail="MCI failed" )
177 # GRAPHS
178 # NOTE: important params here:
179 # job = name of Jenkins job
180 # Plot Name = Plot-HA, only can be used if multiple plots
181 # index = The number of the graph under plot name
182 job = "HAclusterRestart"
183 plotName = "Plot-HA"
184 graphs = '<ac:structured-macro ac:name="html">\n'
185 graphs += '<ac:plain-text-body><![CDATA[\n'
186 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
187 '/plot/' + plotName + '/getPlot?index=0' +\
188 '&width=500&height=300"' +\
189 'noborder="0" width="500" height="300" scrolling="yes" ' +\
190 'seamless="seamless"></iframe>\n'
191 graphs += ']]></ac:plain-text-body>\n'
192 graphs += '</ac:structured-macro>\n'
193 main.log.wiki(graphs)
194
195 main.step( "Creating ONOS package" )
196 packageResult = main.ONOSbench.onosPackage()
197 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
198 onpass="ONOS package successful",
199 onfail="ONOS package failed" )
200
201 main.step( "Installing ONOS package" )
202 onosInstallResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700203 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700204 tmpResult = main.ONOSbench.onosInstall( options="-f",
205 node=node.ip_address )
206 onosInstallResult = onosInstallResult and tmpResult
207 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
208 onpass="ONOS install successful",
209 onfail="ONOS install failed" )
210
211 main.step( "Checking if ONOS is up yet" )
212 for i in range( 2 ):
213 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700214 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700215 started = main.ONOSbench.isup( node.ip_address )
216 if not started:
217 main.log.error( node.name + " didn't start!" )
218 main.ONOSbench.onosStop( node.ip_address )
219 main.ONOSbench.onosStart( node.ip_address )
220 onosIsupResult = onosIsupResult and started
221 if onosIsupResult == main.TRUE:
222 break
223 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
224 onpass="ONOS startup successful",
225 onfail="ONOS startup failed" )
226
227 main.log.step( "Starting ONOS CLI sessions" )
228 cliResults = main.TRUE
229 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700230 for i in range( main.numCtrls ):
231 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -0700232 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -0700233 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -0700234 threads.append( t )
235 t.start()
236
237 for t in threads:
238 t.join()
239 cliResults = cliResults and t.result
240 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
241 onpass="ONOS cli startup successful",
242 onfail="ONOS cli startup failed" )
243
244 if main.params[ 'tcpdump' ].lower() == "true":
245 main.step( "Start Packet Capture MN" )
246 main.Mininet2.startTcpdump(
247 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
248 + "-MN.pcap",
249 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
250 port=main.params[ 'MNtcpdump' ][ 'port' ] )
251
252 main.step( "App Ids check" )
253 appCheck = main.TRUE
254 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700255 for i in range( main.numCtrls ):
256 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700257 name="appToIDCheck-" + str( i ),
258 args=[] )
259 threads.append( t )
260 t.start()
261
262 for t in threads:
263 t.join()
264 appCheck = appCheck and t.result
265 if appCheck != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700266 main.log.warn( main.CLIs[0].apps() )
267 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700268 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
269 onpass="App Ids seem to be correct",
270 onfail="Something is wrong with app Ids" )
271
272 if cliResults == main.FALSE:
273 main.log.error( "Failed to start ONOS, stopping test" )
274 main.cleanup()
275 main.exit()
276
277 def CASE2( self, main ):
278 """
279 Assign devices to controllers
280 """
281 import re
Jon Halle1a3b752015-07-22 13:02:46 -0700282 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700283 assert main, "main not defined"
284 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700285 assert main.CLIs, "main.CLIs not defined"
286 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700287 assert ONOS1Port, "ONOS1Port not defined"
288 assert ONOS2Port, "ONOS2Port not defined"
289 assert ONOS3Port, "ONOS3Port not defined"
290 assert ONOS4Port, "ONOS4Port not defined"
291 assert ONOS5Port, "ONOS5Port not defined"
292 assert ONOS6Port, "ONOS6Port not defined"
293 assert ONOS7Port, "ONOS7Port not defined"
294
295 main.case( "Assigning devices to controllers" )
Jon Hall783bbf92015-07-23 14:33:19 -0700296 main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700297 "and check that an ONOS node becomes the " +\
298 "master of the device."
299 main.step( "Assign switches to controllers" )
300
301 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700302 for i in range( main.numCtrls ):
303 ipList.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -0700304 swList = []
305 for i in range( 1, 29 ):
306 swList.append( "s" + str( i ) )
307 main.Mininet1.assignSwController( sw=swList, ip=ipList )
308
309 mastershipCheck = main.TRUE
310 for i in range( 1, 29 ):
311 response = main.Mininet1.getSwController( "s" + str( i ) )
312 try:
313 main.log.info( str( response ) )
314 except Exception:
315 main.log.info( repr( response ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700316 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700317 if re.search( "tcp:" + node.ip_address, response ):
318 mastershipCheck = mastershipCheck and main.TRUE
319 else:
320 main.log.error( "Error, node " + node.ip_address + " is " +
321 "not in the list of controllers s" +
322 str( i ) + " is connecting to." )
323 mastershipCheck = main.FALSE
324 utilities.assert_equals(
325 expect=main.TRUE,
326 actual=mastershipCheck,
327 onpass="Switch mastership assigned correctly",
328 onfail="Switches not assigned correctly to controllers" )
329
330 def CASE21( self, main ):
331 """
332 Assign mastership to controllers
333 """
Jon Hall5cf14d52015-07-16 12:15:19 -0700334 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700335 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700336 assert main, "main not defined"
337 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700338 assert main.CLIs, "main.CLIs not defined"
339 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700340 assert ONOS1Port, "ONOS1Port not defined"
341 assert ONOS2Port, "ONOS2Port not defined"
342 assert ONOS3Port, "ONOS3Port not defined"
343 assert ONOS4Port, "ONOS4Port not defined"
344 assert ONOS5Port, "ONOS5Port not defined"
345 assert ONOS6Port, "ONOS6Port not defined"
346 assert ONOS7Port, "ONOS7Port not defined"
347
348 main.case( "Assigning Controller roles for switches" )
Jon Hall783bbf92015-07-23 14:33:19 -0700349 main.caseExplanation = "Check that ONOS is connected to each " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700350 "device. Then manually assign" +\
351 " mastership to specific ONOS nodes using" +\
352 " 'device-role'"
353 main.step( "Assign mastership of switches to specific controllers" )
354 # Manually assign mastership to the controller we want
355 roleCall = main.TRUE
356
357 ipList = [ ]
358 deviceList = []
359 try:
360 # Assign mastership to specific controllers. This assignment was
361 # determined for a 7 node cluser, but will work with any sized
362 # cluster
363 for i in range( 1, 29 ): # switches 1 through 28
364 # set up correct variables:
365 if i == 1:
366 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700367 ip = main.nodes[ c ].ip_address # ONOS1
Jon Hall5cf14d52015-07-16 12:15:19 -0700368 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
369 elif i == 2:
Jon Halle1a3b752015-07-22 13:02:46 -0700370 c = 1 % main.numCtrls
371 ip = main.nodes[ c ].ip_address # ONOS2
Jon Hall5cf14d52015-07-16 12:15:19 -0700372 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
373 elif i == 3:
Jon Halle1a3b752015-07-22 13:02:46 -0700374 c = 1 % main.numCtrls
375 ip = main.nodes[ c ].ip_address # ONOS2
Jon Hall5cf14d52015-07-16 12:15:19 -0700376 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
377 elif i == 4:
Jon Halle1a3b752015-07-22 13:02:46 -0700378 c = 3 % main.numCtrls
379 ip = main.nodes[ c ].ip_address # ONOS4
Jon Hall5cf14d52015-07-16 12:15:19 -0700380 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
381 elif i == 5:
Jon Halle1a3b752015-07-22 13:02:46 -0700382 c = 2 % main.numCtrls
383 ip = main.nodes[ c ].ip_address # ONOS3
Jon Hall5cf14d52015-07-16 12:15:19 -0700384 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
385 elif i == 6:
Jon Halle1a3b752015-07-22 13:02:46 -0700386 c = 2 % main.numCtrls
387 ip = main.nodes[ c ].ip_address # ONOS3
Jon Hall5cf14d52015-07-16 12:15:19 -0700388 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
389 elif i == 7:
Jon Halle1a3b752015-07-22 13:02:46 -0700390 c = 5 % main.numCtrls
391 ip = main.nodes[ c ].ip_address # ONOS6
Jon Hall5cf14d52015-07-16 12:15:19 -0700392 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
393 elif i >= 8 and i <= 17:
Jon Halle1a3b752015-07-22 13:02:46 -0700394 c = 4 % main.numCtrls
395 ip = main.nodes[ c ].ip_address # ONOS5
Jon Hall5cf14d52015-07-16 12:15:19 -0700396 dpid = '3' + str( i ).zfill( 3 )
397 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
398 elif i >= 18 and i <= 27:
Jon Halle1a3b752015-07-22 13:02:46 -0700399 c = 6 % main.numCtrls
400 ip = main.nodes[ c ].ip_address # ONOS7
Jon Hall5cf14d52015-07-16 12:15:19 -0700401 dpid = '6' + str( i ).zfill( 3 )
402 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
403 elif i == 28:
404 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700405 ip = main.nodes[ c ].ip_address # ONOS1
Jon Hall5cf14d52015-07-16 12:15:19 -0700406 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
407 else:
408 main.log.error( "You didn't write an else statement for " +
409 "switch s" + str( i ) )
410 roleCall = main.FALSE
411 # Assign switch
412 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
413 # TODO: make this controller dynamic
414 roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
415 ip )
416 ipList.append( ip )
417 deviceList.append( deviceId )
418 except ( AttributeError, AssertionError ):
419 main.log.exception( "Something is wrong with ONOS device view" )
420 main.log.info( main.ONOScli1.devices() )
421 utilities.assert_equals(
422 expect=main.TRUE,
423 actual=roleCall,
424 onpass="Re-assigned switch mastership to designated controller",
425 onfail="Something wrong with deviceRole calls" )
426
427 main.step( "Check mastership was correctly assigned" )
428 roleCheck = main.TRUE
429 # NOTE: This is due to the fact that device mastership change is not
430 # atomic and is actually a multi step process
431 time.sleep( 5 )
432 for i in range( len( ipList ) ):
433 ip = ipList[i]
434 deviceId = deviceList[i]
435 # Check assignment
436 master = main.ONOScli1.getRole( deviceId ).get( 'master' )
437 if ip in master:
438 roleCheck = roleCheck and main.TRUE
439 else:
440 roleCheck = roleCheck and main.FALSE
441 main.log.error( "Error, controller " + ip + " is not" +
442 " master " + "of device " +
443 str( deviceId ) + ". Master is " +
444 repr( master ) + "." )
445 utilities.assert_equals(
446 expect=main.TRUE,
447 actual=roleCheck,
448 onpass="Switches were successfully reassigned to designated " +
449 "controller",
450 onfail="Switches were not successfully reassigned" )
451
452 def CASE3( self, main ):
453 """
454 Assign intents
455 """
456 import time
457 import json
Jon Halle1a3b752015-07-22 13:02:46 -0700458 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700459 assert main, "main not defined"
460 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700461 assert main.CLIs, "main.CLIs not defined"
462 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700463 try:
464 labels
465 except NameError:
466 main.log.error( "labels not defined, setting to []" )
467 labels = []
468 try:
469 data
470 except NameError:
471 main.log.error( "data not defined, setting to []" )
472 data = []
473 # NOTE: we must reinstall intents until we have a persistant intent
474 # datastore!
475 main.case( "Adding host Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700476 main.caseExplanation = "Discover hosts by using pingall then " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700477 "assign predetermined host-to-host intents." +\
478 " After installation, check that the intent" +\
479 " is distributed to all nodes and the state" +\
480 " is INSTALLED"
481
482 # install onos-app-fwd
483 main.step( "Install reactive forwarding app" )
Jon Halle1a3b752015-07-22 13:02:46 -0700484 installResults = main.CLIs[0].activateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700485 utilities.assert_equals( expect=main.TRUE, actual=installResults,
486 onpass="Install fwd successful",
487 onfail="Install fwd failed" )
488
489 main.step( "Check app ids" )
490 appCheck = main.TRUE
491 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700492 for i in range( main.numCtrls ):
493 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700494 name="appToIDCheck-" + str( i ),
495 args=[] )
496 threads.append( t )
497 t.start()
498
499 for t in threads:
500 t.join()
501 appCheck = appCheck and t.result
502 if appCheck != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700503 main.log.warn( main.CLIs[0].apps() )
504 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700505 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
506 onpass="App Ids seem to be correct",
507 onfail="Something is wrong with app Ids" )
508
509 main.step( "Discovering Hosts( Via pingall for now )" )
510 # FIXME: Once we have a host discovery mechanism, use that instead
511 # REACTIVE FWD test
512 pingResult = main.FALSE
513 for i in range(2): # Retry if pingall fails first time
514 time1 = time.time()
515 pingResult = main.Mininet1.pingall()
516 if i == 0:
517 utilities.assert_equals(
518 expect=main.TRUE,
519 actual=pingResult,
520 onpass="Reactive Pingall test passed",
521 onfail="Reactive Pingall failed, " +
522 "one or more ping pairs failed" )
523 time2 = time.time()
524 main.log.info( "Time for pingall: %2f seconds" %
525 ( time2 - time1 ) )
526 # timeout for fwd flows
527 time.sleep( 11 )
528 # uninstall onos-app-fwd
529 main.step( "Uninstall reactive forwarding app" )
Jon Halle1a3b752015-07-22 13:02:46 -0700530 uninstallResult = main.CLIs[0].deactivateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700531 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
532 onpass="Uninstall fwd successful",
533 onfail="Uninstall fwd failed" )
534
535 main.step( "Check app ids" )
536 threads = []
537 appCheck2 = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700538 for i in range( main.numCtrls ):
539 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700540 name="appToIDCheck-" + str( i ),
541 args=[] )
542 threads.append( t )
543 t.start()
544
545 for t in threads:
546 t.join()
547 appCheck2 = appCheck2 and t.result
548 if appCheck2 != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700549 main.log.warn( main.CLIs[0].apps() )
550 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700551 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
552 onpass="App Ids seem to be correct",
553 onfail="Something is wrong with app Ids" )
554
555 main.step( "Add host intents via cli" )
556 intentIds = []
557 # TODO: move the host numbers to params
558 # Maybe look at all the paths we ping?
559 intentAddResult = True
560 hostResult = main.TRUE
561 for i in range( 8, 18 ):
562 main.log.info( "Adding host intent between h" + str( i ) +
563 " and h" + str( i + 10 ) )
564 host1 = "00:00:00:00:00:" + \
565 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
566 host2 = "00:00:00:00:00:" + \
567 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
568 # NOTE: getHost can return None
569 host1Dict = main.ONOScli1.getHost( host1 )
570 host2Dict = main.ONOScli1.getHost( host2 )
571 host1Id = None
572 host2Id = None
573 if host1Dict and host2Dict:
574 host1Id = host1Dict.get( 'id', None )
575 host2Id = host2Dict.get( 'id', None )
576 if host1Id and host2Id:
Jon Halle1a3b752015-07-22 13:02:46 -0700577 nodeNum = ( i % main.numCtrls )
578 tmpId = main.CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
Jon Hall5cf14d52015-07-16 12:15:19 -0700579 if tmpId:
580 main.log.info( "Added intent with id: " + tmpId )
581 intentIds.append( tmpId )
582 else:
583 main.log.error( "addHostIntent returned: " +
584 repr( tmpId ) )
585 else:
586 main.log.error( "Error, getHost() failed for h" + str( i ) +
587 " and/or h" + str( i + 10 ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700588 hosts = main.CLIs[ 0 ].hosts()
Jon Hall5cf14d52015-07-16 12:15:19 -0700589 main.log.warn( "Hosts output: " )
590 try:
591 main.log.warn( json.dumps( json.loads( hosts ),
592 sort_keys=True,
593 indent=4,
594 separators=( ',', ': ' ) ) )
595 except ( ValueError, TypeError ):
596 main.log.warn( repr( hosts ) )
597 hostResult = main.FALSE
598 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
599 onpass="Found a host id for each host",
600 onfail="Error looking up host ids" )
601
602 intentStart = time.time()
603 onosIds = main.ONOScli1.getAllIntentsId()
604 main.log.info( "Submitted intents: " + str( intentIds ) )
605 main.log.info( "Intents in ONOS: " + str( onosIds ) )
606 for intent in intentIds:
607 if intent in onosIds:
608 pass # intent submitted is in onos
609 else:
610 intentAddResult = False
611 if intentAddResult:
612 intentStop = time.time()
613 else:
614 intentStop = None
615 # Print the intent states
616 intents = main.ONOScli1.intents()
617 intentStates = []
618 installedCheck = True
619 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
620 count = 0
621 try:
622 for intent in json.loads( intents ):
623 state = intent.get( 'state', None )
624 if "INSTALLED" not in state:
625 installedCheck = False
626 intentId = intent.get( 'id', None )
627 intentStates.append( ( intentId, state ) )
628 except ( ValueError, TypeError ):
629 main.log.exception( "Error parsing intents" )
630 # add submitted intents not in the store
631 tmplist = [ i for i, s in intentStates ]
632 missingIntents = False
633 for i in intentIds:
634 if i not in tmplist:
635 intentStates.append( ( i, " - " ) )
636 missingIntents = True
637 intentStates.sort()
638 for i, s in intentStates:
639 count += 1
640 main.log.info( "%-6s%-15s%-15s" %
641 ( str( count ), str( i ), str( s ) ) )
642 leaders = main.ONOScli1.leaders()
643 try:
644 missing = False
645 if leaders:
646 parsedLeaders = json.loads( leaders )
647 main.log.warn( json.dumps( parsedLeaders,
648 sort_keys=True,
649 indent=4,
650 separators=( ',', ': ' ) ) )
651 # check for all intent partitions
652 topics = []
653 for i in range( 14 ):
654 topics.append( "intent-partition-" + str( i ) )
655 main.log.debug( topics )
656 ONOStopics = [ j['topic'] for j in parsedLeaders ]
657 for topic in topics:
658 if topic not in ONOStopics:
659 main.log.error( "Error: " + topic +
660 " not in leaders" )
661 missing = True
662 else:
663 main.log.error( "leaders() returned None" )
664 except ( ValueError, TypeError ):
665 main.log.exception( "Error parsing leaders" )
666 main.log.error( repr( leaders ) )
667 # Check all nodes
668 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -0700669 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700670 response = node.leaders( jsonFormat=False)
671 main.log.warn( str( node.name ) + " leaders output: \n" +
672 str( response ) )
673
674 partitions = main.ONOScli1.partitions()
675 try:
676 if partitions :
677 parsedPartitions = json.loads( partitions )
678 main.log.warn( json.dumps( parsedPartitions,
679 sort_keys=True,
680 indent=4,
681 separators=( ',', ': ' ) ) )
682 # TODO check for a leader in all paritions
683 # TODO check for consistency among nodes
684 else:
685 main.log.error( "partitions() returned None" )
686 except ( ValueError, TypeError ):
687 main.log.exception( "Error parsing partitions" )
688 main.log.error( repr( partitions ) )
689 pendingMap = main.ONOScli1.pendingMap()
690 try:
691 if pendingMap :
692 parsedPending = json.loads( pendingMap )
693 main.log.warn( json.dumps( parsedPending,
694 sort_keys=True,
695 indent=4,
696 separators=( ',', ': ' ) ) )
697 # TODO check something here?
698 else:
699 main.log.error( "pendingMap() returned None" )
700 except ( ValueError, TypeError ):
701 main.log.exception( "Error parsing pending map" )
702 main.log.error( repr( pendingMap ) )
703
704 intentAddResult = bool( intentAddResult and not missingIntents and
705 installedCheck )
706 if not intentAddResult:
707 main.log.error( "Error in pushing host intents to ONOS" )
708
709 main.step( "Intent Anti-Entropy dispersion" )
710 for i in range(100):
711 correct = True
712 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700713 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700714 onosIds = []
715 ids = cli.getAllIntentsId()
716 onosIds.append( ids )
717 main.log.debug( "Intents in " + cli.name + ": " +
718 str( sorted( onosIds ) ) )
719 if sorted( ids ) != sorted( intentIds ):
720 main.log.warn( "Set of intent IDs doesn't match" )
721 correct = False
722 break
723 else:
724 intents = json.loads( cli.intents() )
725 for intent in intents:
726 if intent[ 'state' ] != "INSTALLED":
727 main.log.warn( "Intent " + intent[ 'id' ] +
728 " is " + intent[ 'state' ] )
729 correct = False
730 break
731 if correct:
732 break
733 else:
734 time.sleep(1)
735 if not intentStop:
736 intentStop = time.time()
737 global gossipTime
738 gossipTime = intentStop - intentStart
739 main.log.info( "It took about " + str( gossipTime ) +
740 " seconds for all intents to appear in each node" )
741 append = False
742 title = "Gossip Intents"
743 count = 1
744 while append is False:
745 curTitle = title + str( count )
746 if curTitle not in labels:
747 labels.append( curTitle )
748 data.append( str( gossipTime ) )
749 append = True
750 else:
751 count += 1
752 # FIXME: make this time configurable/calculate based off of number of
753 # nodes and gossip rounds
754 utilities.assert_greater_equals(
755 expect=40, actual=gossipTime,
756 onpass="ECM anti-entropy for intents worked within " +
757 "expected time",
758 onfail="Intent ECM anti-entropy took too long" )
759 if gossipTime <= 40:
760 intentAddResult = True
761
762 if not intentAddResult or "key" in pendingMap:
763 import time
764 installedCheck = True
765 main.log.info( "Sleeping 60 seconds to see if intents are found" )
766 time.sleep( 60 )
767 onosIds = main.ONOScli1.getAllIntentsId()
768 main.log.info( "Submitted intents: " + str( intentIds ) )
769 main.log.info( "Intents in ONOS: " + str( onosIds ) )
770 # Print the intent states
771 intents = main.ONOScli1.intents()
772 intentStates = []
773 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
774 count = 0
775 try:
776 for intent in json.loads( intents ):
777 # Iter through intents of a node
778 state = intent.get( 'state', None )
779 if "INSTALLED" not in state:
780 installedCheck = False
781 intentId = intent.get( 'id', None )
782 intentStates.append( ( intentId, state ) )
783 except ( ValueError, TypeError ):
784 main.log.exception( "Error parsing intents" )
785 # add submitted intents not in the store
786 tmplist = [ i for i, s in intentStates ]
787 for i in intentIds:
788 if i not in tmplist:
789 intentStates.append( ( i, " - " ) )
790 intentStates.sort()
791 for i, s in intentStates:
792 count += 1
793 main.log.info( "%-6s%-15s%-15s" %
794 ( str( count ), str( i ), str( s ) ) )
795 leaders = main.ONOScli1.leaders()
796 try:
797 missing = False
798 if leaders:
799 parsedLeaders = json.loads( leaders )
800 main.log.warn( json.dumps( parsedLeaders,
801 sort_keys=True,
802 indent=4,
803 separators=( ',', ': ' ) ) )
804 # check for all intent partitions
805 # check for election
806 topics = []
807 for i in range( 14 ):
808 topics.append( "intent-partition-" + str( i ) )
809 # FIXME: this should only be after we start the app
810 topics.append( "org.onosproject.election" )
811 main.log.debug( topics )
812 ONOStopics = [ j['topic'] for j in parsedLeaders ]
813 for topic in topics:
814 if topic not in ONOStopics:
815 main.log.error( "Error: " + topic +
816 " not in leaders" )
817 missing = True
818 else:
819 main.log.error( "leaders() returned None" )
820 except ( ValueError, TypeError ):
821 main.log.exception( "Error parsing leaders" )
822 main.log.error( repr( leaders ) )
823 # Check all nodes
824 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -0700825 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700826 response = node.leaders( jsonFormat=False)
827 main.log.warn( str( node.name ) + " leaders output: \n" +
828 str( response ) )
829
830 partitions = main.ONOScli1.partitions()
831 try:
832 if partitions :
833 parsedPartitions = json.loads( partitions )
834 main.log.warn( json.dumps( parsedPartitions,
835 sort_keys=True,
836 indent=4,
837 separators=( ',', ': ' ) ) )
838 # TODO check for a leader in all paritions
839 # TODO check for consistency among nodes
840 else:
841 main.log.error( "partitions() returned None" )
842 except ( ValueError, TypeError ):
843 main.log.exception( "Error parsing partitions" )
844 main.log.error( repr( partitions ) )
845 pendingMap = main.ONOScli1.pendingMap()
846 try:
847 if pendingMap :
848 parsedPending = json.loads( pendingMap )
849 main.log.warn( json.dumps( parsedPending,
850 sort_keys=True,
851 indent=4,
852 separators=( ',', ': ' ) ) )
853 # TODO check something here?
854 else:
855 main.log.error( "pendingMap() returned None" )
856 except ( ValueError, TypeError ):
857 main.log.exception( "Error parsing pending map" )
858 main.log.error( repr( pendingMap ) )
859
860 def CASE4( self, main ):
861 """
862 Ping across added host intents
863 """
864 import json
865 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700866 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700867 assert main, "main not defined"
868 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700869 assert main.CLIs, "main.CLIs not defined"
870 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700871 main.case( "Verify connectivity by sendind traffic across Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700872 main.caseExplanation = "Ping across added host intents to check " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700873 "functionality and check the state of " +\
874 "the intent"
875 main.step( "Ping across added host intents" )
876 PingResult = main.TRUE
877 for i in range( 8, 18 ):
878 ping = main.Mininet1.pingHost( src="h" + str( i ),
879 target="h" + str( i + 10 ) )
880 PingResult = PingResult and ping
881 if ping == main.FALSE:
882 main.log.warn( "Ping failed between h" + str( i ) +
883 " and h" + str( i + 10 ) )
884 elif ping == main.TRUE:
885 main.log.info( "Ping test passed!" )
886 # Don't set PingResult or you'd override failures
887 if PingResult == main.FALSE:
888 main.log.error(
889 "Intents have not been installed correctly, pings failed." )
890 # TODO: pretty print
891 main.log.warn( "ONOS1 intents: " )
892 try:
893 tmpIntents = main.ONOScli1.intents()
894 main.log.warn( json.dumps( json.loads( tmpIntents ),
895 sort_keys=True,
896 indent=4,
897 separators=( ',', ': ' ) ) )
898 except ( ValueError, TypeError ):
899 main.log.warn( repr( tmpIntents ) )
900 utilities.assert_equals(
901 expect=main.TRUE,
902 actual=PingResult,
903 onpass="Intents have been installed correctly and pings work",
904 onfail="Intents have not been installed correctly, pings failed." )
905
906 main.step( "Check Intent state" )
907 installedCheck = False
908 loopCount = 0
909 while not installedCheck and loopCount < 40:
910 installedCheck = True
911 # Print the intent states
912 intents = main.ONOScli1.intents()
913 intentStates = []
914 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700915 count = 0
Jon Hall5cf14d52015-07-16 12:15:19 -0700916 # Iter through intents of a node
917 try:
918 for intent in json.loads( intents ):
919 state = intent.get( 'state', None )
920 if "INSTALLED" not in state:
921 installedCheck = False
922 intentId = intent.get( 'id', None )
923 intentStates.append( ( intentId, state ) )
924 except ( ValueError, TypeError ):
925 main.log.exception( "Error parsing intents." )
926 # Print states
927 intentStates.sort()
928 for i, s in intentStates:
929 count += 1
930 main.log.info( "%-6s%-15s%-15s" %
931 ( str( count ), str( i ), str( s ) ) )
932 if not installedCheck:
933 time.sleep( 1 )
934 loopCount += 1
935 utilities.assert_equals( expect=True, actual=installedCheck,
936 onpass="Intents are all INSTALLED",
937 onfail="Intents are not all in " +
938 "INSTALLED state" )
939
940 main.step( "Check leadership of topics" )
941 leaders = main.ONOScli1.leaders()
942 topicCheck = main.TRUE
943 try:
944 if leaders:
945 parsedLeaders = json.loads( leaders )
946 main.log.warn( json.dumps( parsedLeaders,
947 sort_keys=True,
948 indent=4,
949 separators=( ',', ': ' ) ) )
950 # check for all intent partitions
951 # check for election
952 # TODO: Look at Devices as topics now that it uses this system
953 topics = []
954 for i in range( 14 ):
955 topics.append( "intent-partition-" + str( i ) )
956 # FIXME: this should only be after we start the app
957 # FIXME: topics.append( "org.onosproject.election" )
958 # Print leaders output
959 main.log.debug( topics )
960 ONOStopics = [ j['topic'] for j in parsedLeaders ]
961 for topic in topics:
962 if topic not in ONOStopics:
963 main.log.error( "Error: " + topic +
964 " not in leaders" )
965 topicCheck = main.FALSE
966 else:
967 main.log.error( "leaders() returned None" )
968 topicCheck = main.FALSE
969 except ( ValueError, TypeError ):
970 topicCheck = main.FALSE
971 main.log.exception( "Error parsing leaders" )
972 main.log.error( repr( leaders ) )
973 # TODO: Check for a leader of these topics
974 # Check all nodes
975 if topicCheck:
Jon Halle1a3b752015-07-22 13:02:46 -0700976 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700977 response = node.leaders( jsonFormat=False)
978 main.log.warn( str( node.name ) + " leaders output: \n" +
979 str( response ) )
980
981 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
982 onpass="intent Partitions is in leaders",
983 onfail="Some topics were lost " )
984 # Print partitions
985 partitions = main.ONOScli1.partitions()
986 try:
987 if partitions :
988 parsedPartitions = json.loads( partitions )
989 main.log.warn( json.dumps( parsedPartitions,
990 sort_keys=True,
991 indent=4,
992 separators=( ',', ': ' ) ) )
993 # TODO check for a leader in all paritions
994 # TODO check for consistency among nodes
995 else:
996 main.log.error( "partitions() returned None" )
997 except ( ValueError, TypeError ):
998 main.log.exception( "Error parsing partitions" )
999 main.log.error( repr( partitions ) )
1000 # Print Pending Map
1001 pendingMap = main.ONOScli1.pendingMap()
1002 try:
1003 if pendingMap :
1004 parsedPending = json.loads( pendingMap )
1005 main.log.warn( json.dumps( parsedPending,
1006 sort_keys=True,
1007 indent=4,
1008 separators=( ',', ': ' ) ) )
1009 # TODO check something here?
1010 else:
1011 main.log.error( "pendingMap() returned None" )
1012 except ( ValueError, TypeError ):
1013 main.log.exception( "Error parsing pending map" )
1014 main.log.error( repr( pendingMap ) )
1015
1016 if not installedCheck:
1017 main.log.info( "Waiting 60 seconds to see if the state of " +
1018 "intents change" )
1019 time.sleep( 60 )
1020 # Print the intent states
1021 intents = main.ONOScli1.intents()
1022 intentStates = []
1023 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
1024 count = 0
1025 # Iter through intents of a node
1026 try:
1027 for intent in json.loads( intents ):
1028 state = intent.get( 'state', None )
1029 if "INSTALLED" not in state:
1030 installedCheck = False
1031 intentId = intent.get( 'id', None )
1032 intentStates.append( ( intentId, state ) )
1033 except ( ValueError, TypeError ):
1034 main.log.exception( "Error parsing intents." )
1035 intentStates.sort()
1036 for i, s in intentStates:
1037 count += 1
1038 main.log.info( "%-6s%-15s%-15s" %
1039 ( str( count ), str( i ), str( s ) ) )
1040 leaders = main.ONOScli1.leaders()
1041 try:
1042 missing = False
1043 if leaders:
1044 parsedLeaders = json.loads( leaders )
1045 main.log.warn( json.dumps( parsedLeaders,
1046 sort_keys=True,
1047 indent=4,
1048 separators=( ',', ': ' ) ) )
1049 # check for all intent partitions
1050 # check for election
1051 topics = []
1052 for i in range( 14 ):
1053 topics.append( "intent-partition-" + str( i ) )
1054 # FIXME: this should only be after we start the app
1055 topics.append( "org.onosproject.election" )
1056 main.log.debug( topics )
1057 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1058 for topic in topics:
1059 if topic not in ONOStopics:
1060 main.log.error( "Error: " + topic +
1061 " not in leaders" )
1062 missing = True
1063 else:
1064 main.log.error( "leaders() returned None" )
1065 except ( ValueError, TypeError ):
1066 main.log.exception( "Error parsing leaders" )
1067 main.log.error( repr( leaders ) )
1068 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -07001069 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07001070 response = node.leaders( jsonFormat=False)
1071 main.log.warn( str( node.name ) + " leaders output: \n" +
1072 str( response ) )
1073
1074 partitions = main.ONOScli1.partitions()
1075 try:
1076 if partitions :
1077 parsedPartitions = json.loads( partitions )
1078 main.log.warn( json.dumps( parsedPartitions,
1079 sort_keys=True,
1080 indent=4,
1081 separators=( ',', ': ' ) ) )
1082 # TODO check for a leader in all paritions
1083 # TODO check for consistency among nodes
1084 else:
1085 main.log.error( "partitions() returned None" )
1086 except ( ValueError, TypeError ):
1087 main.log.exception( "Error parsing partitions" )
1088 main.log.error( repr( partitions ) )
1089 pendingMap = main.ONOScli1.pendingMap()
1090 try:
1091 if pendingMap :
1092 parsedPending = json.loads( pendingMap )
1093 main.log.warn( json.dumps( parsedPending,
1094 sort_keys=True,
1095 indent=4,
1096 separators=( ',', ': ' ) ) )
1097 # TODO check something here?
1098 else:
1099 main.log.error( "pendingMap() returned None" )
1100 except ( ValueError, TypeError ):
1101 main.log.exception( "Error parsing pending map" )
1102 main.log.error( repr( pendingMap ) )
1103 # Print flowrules
Jon Halle1a3b752015-07-22 13:02:46 -07001104 main.log.debug( main.CLIs[0].flows( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001105 main.step( "Wait a minute then ping again" )
1106 # the wait is above
1107 PingResult = main.TRUE
1108 for i in range( 8, 18 ):
1109 ping = main.Mininet1.pingHost( src="h" + str( i ),
1110 target="h" + str( i + 10 ) )
1111 PingResult = PingResult and ping
1112 if ping == main.FALSE:
1113 main.log.warn( "Ping failed between h" + str( i ) +
1114 " and h" + str( i + 10 ) )
1115 elif ping == main.TRUE:
1116 main.log.info( "Ping test passed!" )
1117 # Don't set PingResult or you'd override failures
1118 if PingResult == main.FALSE:
1119 main.log.error(
1120 "Intents have not been installed correctly, pings failed." )
1121 # TODO: pretty print
1122 main.log.warn( "ONOS1 intents: " )
1123 try:
1124 tmpIntents = main.ONOScli1.intents()
1125 main.log.warn( json.dumps( json.loads( tmpIntents ),
1126 sort_keys=True,
1127 indent=4,
1128 separators=( ',', ': ' ) ) )
1129 except ( ValueError, TypeError ):
1130 main.log.warn( repr( tmpIntents ) )
1131 utilities.assert_equals(
1132 expect=main.TRUE,
1133 actual=PingResult,
1134 onpass="Intents have been installed correctly and pings work",
1135 onfail="Intents have not been installed correctly, pings failed." )
1136
1137 def CASE5( self, main ):
1138 """
1139 Reading state of ONOS
1140 """
1141 import json
1142 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001143 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001144 assert main, "main not defined"
1145 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001146 assert main.CLIs, "main.CLIs not defined"
1147 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001148
1149 main.case( "Setting up and gathering data for current state" )
1150 # The general idea for this test case is to pull the state of
1151 # ( intents,flows, topology,... ) from each ONOS node
1152 # We can then compare them with each other and also with past states
1153
1154 main.step( "Check that each switch has a master" )
1155 global mastershipState
1156 mastershipState = '[]'
1157
1158 # Assert that each device has a master
1159 rolesNotNull = main.TRUE
1160 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001161 for i in range( main.numCtrls ):
1162 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001163 name="rolesNotNull-" + str( i ),
1164 args=[] )
1165 threads.append( t )
1166 t.start()
1167
1168 for t in threads:
1169 t.join()
1170 rolesNotNull = rolesNotNull and t.result
1171 utilities.assert_equals(
1172 expect=main.TRUE,
1173 actual=rolesNotNull,
1174 onpass="Each device has a master",
1175 onfail="Some devices don't have a master assigned" )
1176
1177 main.step( "Get the Mastership of each switch from each controller" )
1178 ONOSMastership = []
1179 mastershipCheck = main.FALSE
1180 consistentMastership = True
1181 rolesResults = True
1182 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001183 for i in range( main.numCtrls ):
1184 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001185 name="roles-" + str( i ),
1186 args=[] )
1187 threads.append( t )
1188 t.start()
1189
1190 for t in threads:
1191 t.join()
1192 ONOSMastership.append( t.result )
1193
Jon Halle1a3b752015-07-22 13:02:46 -07001194 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001195 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1196 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1197 " roles" )
1198 main.log.warn(
1199 "ONOS" + str( i + 1 ) + " mastership response: " +
1200 repr( ONOSMastership[i] ) )
1201 rolesResults = False
1202 utilities.assert_equals(
1203 expect=True,
1204 actual=rolesResults,
1205 onpass="No error in reading roles output",
1206 onfail="Error in reading roles from ONOS" )
1207
1208 main.step( "Check for consistency in roles from each controller" )
1209 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1210 main.log.info(
1211 "Switch roles are consistent across all ONOS nodes" )
1212 else:
1213 consistentMastership = False
1214 utilities.assert_equals(
1215 expect=True,
1216 actual=consistentMastership,
1217 onpass="Switch roles are consistent across all ONOS nodes",
1218 onfail="ONOS nodes have different views of switch roles" )
1219
1220 if rolesResults and not consistentMastership:
Jon Halle1a3b752015-07-22 13:02:46 -07001221 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001222 try:
1223 main.log.warn(
1224 "ONOS" + str( i + 1 ) + " roles: ",
1225 json.dumps(
1226 json.loads( ONOSMastership[ i ] ),
1227 sort_keys=True,
1228 indent=4,
1229 separators=( ',', ': ' ) ) )
1230 except ( ValueError, TypeError ):
1231 main.log.warn( repr( ONOSMastership[ i ] ) )
1232 elif rolesResults and consistentMastership:
1233 mastershipCheck = main.TRUE
1234 mastershipState = ONOSMastership[ 0 ]
1235
1236 main.step( "Get the intents from each controller" )
1237 global intentState
1238 intentState = []
1239 ONOSIntents = []
1240 intentCheck = main.FALSE
1241 consistentIntents = True
1242 intentsResults = True
1243 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001244 for i in range( main.numCtrls ):
1245 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001246 name="intents-" + str( i ),
1247 args=[],
1248 kwargs={ 'jsonFormat': True } )
1249 threads.append( t )
1250 t.start()
1251
1252 for t in threads:
1253 t.join()
1254 ONOSIntents.append( t.result )
1255
Jon Halle1a3b752015-07-22 13:02:46 -07001256 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001257 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1258 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1259 " intents" )
1260 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1261 repr( ONOSIntents[ i ] ) )
1262 intentsResults = False
1263 utilities.assert_equals(
1264 expect=True,
1265 actual=intentsResults,
1266 onpass="No error in reading intents output",
1267 onfail="Error in reading intents from ONOS" )
1268
1269 main.step( "Check for consistency in Intents from each controller" )
1270 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1271 main.log.info( "Intents are consistent across all ONOS " +
1272 "nodes" )
1273 else:
1274 consistentIntents = False
1275 main.log.error( "Intents not consistent" )
1276 utilities.assert_equals(
1277 expect=True,
1278 actual=consistentIntents,
1279 onpass="Intents are consistent across all ONOS nodes",
1280 onfail="ONOS nodes have different views of intents" )
1281
1282 if intentsResults:
1283 # Try to make it easy to figure out what is happening
1284 #
1285 # Intent ONOS1 ONOS2 ...
1286 # 0x01 INSTALLED INSTALLING
1287 # ... ... ...
1288 # ... ... ...
1289 title = " Id"
Jon Halle1a3b752015-07-22 13:02:46 -07001290 for n in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001291 title += " " * 10 + "ONOS" + str( n + 1 )
1292 main.log.warn( title )
1293 # get all intent keys in the cluster
1294 keys = []
1295 for nodeStr in ONOSIntents:
1296 node = json.loads( nodeStr )
1297 for intent in node:
1298 keys.append( intent.get( 'id' ) )
1299 keys = set( keys )
1300 for key in keys:
1301 row = "%-13s" % key
1302 for nodeStr in ONOSIntents:
1303 node = json.loads( nodeStr )
1304 for intent in node:
1305 if intent.get( 'id', "Error" ) == key:
1306 row += "%-15s" % intent.get( 'state' )
1307 main.log.warn( row )
1308 # End table view
1309
1310 if intentsResults and not consistentIntents:
1311 # print the json objects
1312 n = len(ONOSIntents)
1313 main.log.debug( "ONOS" + str( n ) + " intents: " )
1314 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1315 sort_keys=True,
1316 indent=4,
1317 separators=( ',', ': ' ) ) )
Jon Halle1a3b752015-07-22 13:02:46 -07001318 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001319 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
1320 main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
1321 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1322 sort_keys=True,
1323 indent=4,
1324 separators=( ',', ': ' ) ) )
1325 else:
Jon Halle1a3b752015-07-22 13:02:46 -07001326 main.log.debug( main.nodes[ i ].name + " intents match ONOS" +
Jon Hall5cf14d52015-07-16 12:15:19 -07001327 str( n ) + " intents" )
1328 elif intentsResults and consistentIntents:
1329 intentCheck = main.TRUE
1330 intentState = ONOSIntents[ 0 ]
1331
1332 main.step( "Get the flows from each controller" )
1333 global flowState
1334 flowState = []
1335 ONOSFlows = []
1336 ONOSFlowsJson = []
1337 flowCheck = main.FALSE
1338 consistentFlows = True
1339 flowsResults = True
1340 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001341 for i in range( main.numCtrls ):
1342 t = main.Thread( target=main.CLIs[i].flows,
Jon Hall5cf14d52015-07-16 12:15:19 -07001343 name="flows-" + str( i ),
1344 args=[],
1345 kwargs={ 'jsonFormat': True } )
1346 threads.append( t )
1347 t.start()
1348
1349 # NOTE: Flows command can take some time to run
1350 time.sleep(30)
1351 for t in threads:
1352 t.join()
1353 result = t.result
1354 ONOSFlows.append( result )
1355
Jon Halle1a3b752015-07-22 13:02:46 -07001356 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001357 num = str( i + 1 )
1358 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1359 main.log.error( "Error in getting ONOS" + num + " flows" )
1360 main.log.warn( "ONOS" + num + " flows response: " +
1361 repr( ONOSFlows[ i ] ) )
1362 flowsResults = False
1363 ONOSFlowsJson.append( None )
1364 else:
1365 try:
1366 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1367 except ( ValueError, TypeError ):
1368 # FIXME: change this to log.error?
1369 main.log.exception( "Error in parsing ONOS" + num +
1370 " response as json." )
1371 main.log.error( repr( ONOSFlows[ i ] ) )
1372 ONOSFlowsJson.append( None )
1373 flowsResults = False
1374 utilities.assert_equals(
1375 expect=True,
1376 actual=flowsResults,
1377 onpass="No error in reading flows output",
1378 onfail="Error in reading flows from ONOS" )
1379
1380 main.step( "Check for consistency in Flows from each controller" )
1381 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1382 if all( tmp ):
1383 main.log.info( "Flow count is consistent across all ONOS nodes" )
1384 else:
1385 consistentFlows = False
1386 utilities.assert_equals(
1387 expect=True,
1388 actual=consistentFlows,
1389 onpass="The flow count is consistent across all ONOS nodes",
1390 onfail="ONOS nodes have different flow counts" )
1391
1392 if flowsResults and not consistentFlows:
Jon Halle1a3b752015-07-22 13:02:46 -07001393 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001394 try:
1395 main.log.warn(
1396 "ONOS" + str( i + 1 ) + " flows: " +
1397 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1398 indent=4, separators=( ',', ': ' ) ) )
1399 except ( ValueError, TypeError ):
1400 main.log.warn(
1401 "ONOS" + str( i + 1 ) + " flows: " +
1402 repr( ONOSFlows[ i ] ) )
1403 elif flowsResults and consistentFlows:
1404 flowCheck = main.TRUE
1405 flowState = ONOSFlows[ 0 ]
1406
1407 main.step( "Get the OF Table entries" )
1408 global flows
1409 flows = []
1410 for i in range( 1, 29 ):
Jon Hall9043c902015-07-30 14:23:44 -07001411 flows.append( main.Mininet1.getFlowTable( 1.3, "s" + str( i ) ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001412 if flowCheck == main.FALSE:
1413 for table in flows:
1414 main.log.warn( table )
1415 # TODO: Compare switch flow tables with ONOS flow tables
1416
1417 main.step( "Start continuous pings" )
1418 main.Mininet2.pingLong(
1419 src=main.params[ 'PING' ][ 'source1' ],
1420 target=main.params[ 'PING' ][ 'target1' ],
1421 pingTime=500 )
1422 main.Mininet2.pingLong(
1423 src=main.params[ 'PING' ][ 'source2' ],
1424 target=main.params[ 'PING' ][ 'target2' ],
1425 pingTime=500 )
1426 main.Mininet2.pingLong(
1427 src=main.params[ 'PING' ][ 'source3' ],
1428 target=main.params[ 'PING' ][ 'target3' ],
1429 pingTime=500 )
1430 main.Mininet2.pingLong(
1431 src=main.params[ 'PING' ][ 'source4' ],
1432 target=main.params[ 'PING' ][ 'target4' ],
1433 pingTime=500 )
1434 main.Mininet2.pingLong(
1435 src=main.params[ 'PING' ][ 'source5' ],
1436 target=main.params[ 'PING' ][ 'target5' ],
1437 pingTime=500 )
1438 main.Mininet2.pingLong(
1439 src=main.params[ 'PING' ][ 'source6' ],
1440 target=main.params[ 'PING' ][ 'target6' ],
1441 pingTime=500 )
1442 main.Mininet2.pingLong(
1443 src=main.params[ 'PING' ][ 'source7' ],
1444 target=main.params[ 'PING' ][ 'target7' ],
1445 pingTime=500 )
1446 main.Mininet2.pingLong(
1447 src=main.params[ 'PING' ][ 'source8' ],
1448 target=main.params[ 'PING' ][ 'target8' ],
1449 pingTime=500 )
1450 main.Mininet2.pingLong(
1451 src=main.params[ 'PING' ][ 'source9' ],
1452 target=main.params[ 'PING' ][ 'target9' ],
1453 pingTime=500 )
1454 main.Mininet2.pingLong(
1455 src=main.params[ 'PING' ][ 'source10' ],
1456 target=main.params[ 'PING' ][ 'target10' ],
1457 pingTime=500 )
1458
1459 main.step( "Collecting topology information from ONOS" )
1460 devices = []
1461 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001462 for i in range( main.numCtrls ):
1463 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07001464 name="devices-" + str( i ),
1465 args=[ ] )
1466 threads.append( t )
1467 t.start()
1468
1469 for t in threads:
1470 t.join()
1471 devices.append( t.result )
1472 hosts = []
1473 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001474 for i in range( main.numCtrls ):
1475 t = main.Thread( target=main.CLIs[i].hosts,
Jon Hall5cf14d52015-07-16 12:15:19 -07001476 name="hosts-" + str( i ),
1477 args=[ ] )
1478 threads.append( t )
1479 t.start()
1480
1481 for t in threads:
1482 t.join()
1483 try:
1484 hosts.append( json.loads( t.result ) )
1485 except ( ValueError, TypeError ):
1486 # FIXME: better handling of this, print which node
1487 # Maybe use thread name?
1488 main.log.exception( "Error parsing json output of hosts" )
1489 # FIXME: should this be an empty json object instead?
1490 hosts.append( None )
1491
1492 ports = []
1493 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001494 for i in range( main.numCtrls ):
1495 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07001496 name="ports-" + str( i ),
1497 args=[ ] )
1498 threads.append( t )
1499 t.start()
1500
1501 for t in threads:
1502 t.join()
1503 ports.append( t.result )
1504 links = []
1505 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001506 for i in range( main.numCtrls ):
1507 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07001508 name="links-" + str( i ),
1509 args=[ ] )
1510 threads.append( t )
1511 t.start()
1512
1513 for t in threads:
1514 t.join()
1515 links.append( t.result )
1516 clusters = []
1517 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001518 for i in range( main.numCtrls ):
1519 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07001520 name="clusters-" + str( i ),
1521 args=[ ] )
1522 threads.append( t )
1523 t.start()
1524
1525 for t in threads:
1526 t.join()
1527 clusters.append( t.result )
1528 # Compare json objects for hosts and dataplane clusters
1529
1530 # hosts
1531 main.step( "Host view is consistent across ONOS nodes" )
1532 consistentHostsResult = main.TRUE
1533 for controller in range( len( hosts ) ):
1534 controllerStr = str( controller + 1 )
1535 if "Error" not in hosts[ controller ]:
1536 if hosts[ controller ] == hosts[ 0 ]:
1537 continue
1538 else: # hosts not consistent
1539 main.log.error( "hosts from ONOS" +
1540 controllerStr +
1541 " is inconsistent with ONOS1" )
1542 main.log.warn( repr( hosts[ controller ] ) )
1543 consistentHostsResult = main.FALSE
1544
1545 else:
1546 main.log.error( "Error in getting ONOS hosts from ONOS" +
1547 controllerStr )
1548 consistentHostsResult = main.FALSE
1549 main.log.warn( "ONOS" + controllerStr +
1550 " hosts response: " +
1551 repr( hosts[ controller ] ) )
1552 utilities.assert_equals(
1553 expect=main.TRUE,
1554 actual=consistentHostsResult,
1555 onpass="Hosts view is consistent across all ONOS nodes",
1556 onfail="ONOS nodes have different views of hosts" )
1557
1558 main.step( "Each host has an IP address" )
1559 ipResult = main.TRUE
1560 for controller in range( 0, len( hosts ) ):
1561 controllerStr = str( controller + 1 )
1562 for host in hosts[ controller ]:
1563 if not host.get( 'ipAddresses', [ ] ):
1564 main.log.error( "DEBUG:Error with host ips on controller" +
1565 controllerStr + ": " + str( host ) )
1566 ipResult = main.FALSE
1567 utilities.assert_equals(
1568 expect=main.TRUE,
1569 actual=ipResult,
1570 onpass="The ips of the hosts aren't empty",
1571 onfail="The ip of at least one host is missing" )
1572
1573 # Strongly connected clusters of devices
1574 main.step( "Cluster view is consistent across ONOS nodes" )
1575 consistentClustersResult = main.TRUE
1576 for controller in range( len( clusters ) ):
1577 controllerStr = str( controller + 1 )
1578 if "Error" not in clusters[ controller ]:
1579 if clusters[ controller ] == clusters[ 0 ]:
1580 continue
1581 else: # clusters not consistent
1582 main.log.error( "clusters from ONOS" + controllerStr +
1583 " is inconsistent with ONOS1" )
1584 consistentClustersResult = main.FALSE
1585
1586 else:
1587 main.log.error( "Error in getting dataplane clusters " +
1588 "from ONOS" + controllerStr )
1589 consistentClustersResult = main.FALSE
1590 main.log.warn( "ONOS" + controllerStr +
1591 " clusters response: " +
1592 repr( clusters[ controller ] ) )
1593 utilities.assert_equals(
1594 expect=main.TRUE,
1595 actual=consistentClustersResult,
1596 onpass="Clusters view is consistent across all ONOS nodes",
1597 onfail="ONOS nodes have different views of clusters" )
1598 # there should always only be one cluster
1599 main.step( "Cluster view correct across ONOS nodes" )
1600 try:
1601 numClusters = len( json.loads( clusters[ 0 ] ) )
1602 except ( ValueError, TypeError ):
1603 main.log.exception( "Error parsing clusters[0]: " +
1604 repr( clusters[ 0 ] ) )
1605 clusterResults = main.FALSE
1606 if numClusters == 1:
1607 clusterResults = main.TRUE
1608 utilities.assert_equals(
1609 expect=1,
1610 actual=numClusters,
1611 onpass="ONOS shows 1 SCC",
1612 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1613
1614 main.step( "Comparing ONOS topology to MN" )
1615 devicesResults = main.TRUE
1616 linksResults = main.TRUE
1617 hostsResults = main.TRUE
1618 mnSwitches = main.Mininet1.getSwitches()
1619 mnLinks = main.Mininet1.getLinks()
1620 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07001621 for controller in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001622 controllerStr = str( controller + 1 )
1623 if devices[ controller ] and ports[ controller ] and\
1624 "Error" not in devices[ controller ] and\
1625 "Error" not in ports[ controller ]:
Jon Halle1a3b752015-07-22 13:02:46 -07001626 currentDevicesResult = main.Mininet1.compareSwitches(
1627 mnSwitches,
1628 json.loads( devices[ controller ] ),
1629 json.loads( ports[ controller ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001630 else:
1631 currentDevicesResult = main.FALSE
1632 utilities.assert_equals( expect=main.TRUE,
1633 actual=currentDevicesResult,
1634 onpass="ONOS" + controllerStr +
1635 " Switches view is correct",
1636 onfail="ONOS" + controllerStr +
1637 " Switches view is incorrect" )
1638 if links[ controller ] and "Error" not in links[ controller ]:
1639 currentLinksResult = main.Mininet1.compareLinks(
1640 mnSwitches, mnLinks,
1641 json.loads( links[ controller ] ) )
1642 else:
1643 currentLinksResult = main.FALSE
1644 utilities.assert_equals( expect=main.TRUE,
1645 actual=currentLinksResult,
1646 onpass="ONOS" + controllerStr +
1647 " links view is correct",
1648 onfail="ONOS" + controllerStr +
1649 " links view is incorrect" )
1650
1651 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1652 currentHostsResult = main.Mininet1.compareHosts(
1653 mnHosts,
1654 hosts[ controller ] )
1655 else:
1656 currentHostsResult = main.FALSE
1657 utilities.assert_equals( expect=main.TRUE,
1658 actual=currentHostsResult,
1659 onpass="ONOS" + controllerStr +
1660 " hosts exist in Mininet",
1661 onfail="ONOS" + controllerStr +
1662 " hosts don't match Mininet" )
1663
1664 devicesResults = devicesResults and currentDevicesResult
1665 linksResults = linksResults and currentLinksResult
1666 hostsResults = hostsResults and currentHostsResult
1667
1668 main.step( "Device information is correct" )
1669 utilities.assert_equals(
1670 expect=main.TRUE,
1671 actual=devicesResults,
1672 onpass="Device information is correct",
1673 onfail="Device information is incorrect" )
1674
1675 main.step( "Links are correct" )
1676 utilities.assert_equals(
1677 expect=main.TRUE,
1678 actual=linksResults,
1679 onpass="Link are correct",
1680 onfail="Links are incorrect" )
1681
1682 main.step( "Hosts are correct" )
1683 utilities.assert_equals(
1684 expect=main.TRUE,
1685 actual=hostsResults,
1686 onpass="Hosts are correct",
1687 onfail="Hosts are incorrect" )
1688
1689 def CASE6( self, main ):
1690 """
1691 The Failure case.
1692 """
1693 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001694 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001695 assert main, "main not defined"
1696 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001697 assert main.CLIs, "main.CLIs not defined"
1698 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001699 try:
1700 labels
1701 except NameError:
1702 main.log.error( "labels not defined, setting to []" )
1703 global labels
1704 labels = []
1705 try:
1706 data
1707 except NameError:
1708 main.log.error( "data not defined, setting to []" )
1709 global data
1710 data = []
1711 # Reset non-persistent variables
1712 try:
1713 iCounterValue = 0
1714 except NameError:
1715 main.log.error( "iCounterValue not defined, setting to 0" )
1716 iCounterValue = 0
1717
1718 main.case( "Restart entire ONOS cluster" )
1719
1720 main.step( "Killing ONOS nodes" )
1721 killResults = main.TRUE
1722 killTime = time.time()
Jon Halle1a3b752015-07-22 13:02:46 -07001723 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001724 killed = main.ONOSbench.onosKill( node.ip_address )
1725 killResults = killResults and killed
1726 utilities.assert_equals( expect=main.TRUE, actual=killResults,
1727 onpass="ONOS nodes killed",
1728 onfail="ONOS kill unsuccessful" )
1729
1730 main.step( "Checking if ONOS is up yet" )
1731 for i in range( 2 ):
1732 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001733 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001734 started = main.ONOSbench.isup( node.ip_address )
1735 if not started:
1736 main.log.error( node.name + " didn't start!" )
1737 onosIsupResult = onosIsupResult and started
1738 if onosIsupResult == main.TRUE:
1739 break
1740 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1741 onpass="ONOS restarted",
1742 onfail="ONOS restart NOT successful" )
1743
1744 main.log.step( "Starting ONOS CLI sessions" )
1745 cliResults = main.TRUE
1746 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001747 for i in range( main.numCtrls ):
1748 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -07001749 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -07001750 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -07001751 threads.append( t )
1752 t.start()
1753
1754 for t in threads:
1755 t.join()
1756 cliResults = cliResults and t.result
1757 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1758 onpass="ONOS cli started",
1759 onfail="ONOS clis did not restart" )
1760
1761 # Grab the time of restart so we chan check how long the gossip
1762 # protocol has had time to work
1763 main.restartTime = time.time() - killTime
1764 main.log.debug( "Restart time: " + str( main.restartTime ) )
1765 labels.append( "Restart" )
1766 data.append( str( main.restartTime ) )
1767
1768 # FIXME: revisit test plan for election with madan
1769 # Rerun for election on restarted nodes
1770 runResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001771 for cli in main.CLIs:
1772 run = main.CLIs[0].electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07001773 if run != main.TRUE:
1774 main.log.error( "Error running for election on " + cli.name )
1775 runResults = runResults and run
1776 utilities.assert_equals( expect=main.TRUE, actual=runResults,
1777 onpass="Reran for election",
1778 onfail="Failed to rerun for election" )
1779
1780 # TODO: Make this configurable
1781 time.sleep( 60 )
Jon Halle1a3b752015-07-22 13:02:46 -07001782 main.log.debug( main.CLIs[0].nodes( jsonFormat=False ) )
1783 main.log.debug( main.CLIs[0].leaders( jsonFormat=False ) )
1784 main.log.debug( main.CLIs[0].partitions( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001785
1786 def CASE7( self, main ):
1787 """
1788 Check state after ONOS failure
1789 """
1790 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001791 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001792 assert main, "main not defined"
1793 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001794 assert main.CLIs, "main.CLIs not defined"
1795 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001796 main.case( "Running ONOS Constant State Tests" )
1797
1798 main.step( "Check that each switch has a master" )
1799 # Assert that each device has a master
1800 rolesNotNull = main.TRUE
1801 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001802 for i in range( main.numCtrls ):
1803 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001804 name="rolesNotNull-" + str( i ),
1805 args=[ ] )
1806 threads.append( t )
1807 t.start()
1808
1809 for t in threads:
1810 t.join()
1811 rolesNotNull = rolesNotNull and t.result
1812 utilities.assert_equals(
1813 expect=main.TRUE,
1814 actual=rolesNotNull,
1815 onpass="Each device has a master",
1816 onfail="Some devices don't have a master assigned" )
1817
1818 main.step( "Read device roles from ONOS" )
1819 ONOSMastership = []
1820 mastershipCheck = main.FALSE
1821 consistentMastership = True
1822 rolesResults = True
1823 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001824 for i in range( main.numCtrls ):
1825 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001826 name="roles-" + str( i ),
1827 args=[] )
1828 threads.append( t )
1829 t.start()
1830
1831 for t in threads:
1832 t.join()
1833 ONOSMastership.append( t.result )
1834
Jon Halle1a3b752015-07-22 13:02:46 -07001835 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001836 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1837 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1838 " roles" )
1839 main.log.warn(
1840 "ONOS" + str( i + 1 ) + " mastership response: " +
1841 repr( ONOSMastership[i] ) )
1842 rolesResults = False
1843 utilities.assert_equals(
1844 expect=True,
1845 actual=rolesResults,
1846 onpass="No error in reading roles output",
1847 onfail="Error in reading roles from ONOS" )
1848
1849 main.step( "Check for consistency in roles from each controller" )
1850 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1851 main.log.info(
1852 "Switch roles are consistent across all ONOS nodes" )
1853 else:
1854 consistentMastership = False
1855 utilities.assert_equals(
1856 expect=True,
1857 actual=consistentMastership,
1858 onpass="Switch roles are consistent across all ONOS nodes",
1859 onfail="ONOS nodes have different views of switch roles" )
1860
1861 if rolesResults and not consistentMastership:
Jon Halle1a3b752015-07-22 13:02:46 -07001862 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001863 main.log.warn(
1864 "ONOS" + str( i + 1 ) + " roles: ",
1865 json.dumps(
1866 json.loads( ONOSMastership[ i ] ),
1867 sort_keys=True,
1868 indent=4,
1869 separators=( ',', ': ' ) ) )
1870 elif rolesResults and not consistentMastership:
1871 mastershipCheck = main.TRUE
1872
1873 '''
1874 description2 = "Compare switch roles from before failure"
1875 main.step( description2 )
1876 try:
1877 currentJson = json.loads( ONOSMastership[0] )
1878 oldJson = json.loads( mastershipState )
1879 except ( ValueError, TypeError ):
1880 main.log.exception( "Something is wrong with parsing " +
1881 "ONOSMastership[0] or mastershipState" )
1882 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1883 main.log.error( "mastershipState" + repr( mastershipState ) )
1884 main.cleanup()
1885 main.exit()
1886 mastershipCheck = main.TRUE
1887 for i in range( 1, 29 ):
1888 switchDPID = str(
1889 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
1890 current = [ switch[ 'master' ] for switch in currentJson
1891 if switchDPID in switch[ 'id' ] ]
1892 old = [ switch[ 'master' ] for switch in oldJson
1893 if switchDPID in switch[ 'id' ] ]
1894 if current == old:
1895 mastershipCheck = mastershipCheck and main.TRUE
1896 else:
1897 main.log.warn( "Mastership of switch %s changed" % switchDPID )
1898 mastershipCheck = main.FALSE
1899 utilities.assert_equals(
1900 expect=main.TRUE,
1901 actual=mastershipCheck,
1902 onpass="Mastership of Switches was not changed",
1903 onfail="Mastership of some switches changed" )
1904 '''
1905 # NOTE: we expect mastership to change on controller failure
1906
1907 main.step( "Get the intents and compare across all nodes" )
1908 ONOSIntents = []
1909 intentCheck = main.FALSE
1910 consistentIntents = True
1911 intentsResults = True
1912 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001913 for i in range( main.numCtrls ):
1914 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001915 name="intents-" + str( i ),
1916 args=[],
1917 kwargs={ 'jsonFormat': True } )
1918 threads.append( t )
1919 t.start()
1920
1921 for t in threads:
1922 t.join()
1923 ONOSIntents.append( t.result )
1924
Jon Halle1a3b752015-07-22 13:02:46 -07001925 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001926 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1927 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1928 " intents" )
1929 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1930 repr( ONOSIntents[ i ] ) )
1931 intentsResults = False
1932 utilities.assert_equals(
1933 expect=True,
1934 actual=intentsResults,
1935 onpass="No error in reading intents output",
1936 onfail="Error in reading intents from ONOS" )
1937
1938 main.step( "Check for consistency in Intents from each controller" )
1939 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1940 main.log.info( "Intents are consistent across all ONOS " +
1941 "nodes" )
1942 else:
1943 consistentIntents = False
1944
1945 # Try to make it easy to figure out what is happening
1946 #
1947 # Intent ONOS1 ONOS2 ...
1948 # 0x01 INSTALLED INSTALLING
1949 # ... ... ...
1950 # ... ... ...
1951 title = " ID"
Jon Halle1a3b752015-07-22 13:02:46 -07001952 for n in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001953 title += " " * 10 + "ONOS" + str( n + 1 )
1954 main.log.warn( title )
1955 # get all intent keys in the cluster
1956 keys = []
1957 for nodeStr in ONOSIntents:
1958 node = json.loads( nodeStr )
1959 for intent in node:
1960 keys.append( intent.get( 'id' ) )
1961 keys = set( keys )
1962 for key in keys:
1963 row = "%-13s" % key
1964 for nodeStr in ONOSIntents:
1965 node = json.loads( nodeStr )
1966 for intent in node:
1967 if intent.get( 'id' ) == key:
1968 row += "%-15s" % intent.get( 'state' )
1969 main.log.warn( row )
1970 # End table view
1971
1972 utilities.assert_equals(
1973 expect=True,
1974 actual=consistentIntents,
1975 onpass="Intents are consistent across all ONOS nodes",
1976 onfail="ONOS nodes have different views of intents" )
1977 intentStates = []
1978 for node in ONOSIntents: # Iter through ONOS nodes
1979 nodeStates = []
1980 # Iter through intents of a node
1981 try:
1982 for intent in json.loads( node ):
1983 nodeStates.append( intent[ 'state' ] )
1984 except ( ValueError, TypeError ):
1985 main.log.exception( "Error in parsing intents" )
1986 main.log.error( repr( node ) )
1987 intentStates.append( nodeStates )
1988 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1989 main.log.info( dict( out ) )
1990
1991 if intentsResults and not consistentIntents:
Jon Halle1a3b752015-07-22 13:02:46 -07001992 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001993 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1994 main.log.warn( json.dumps(
1995 json.loads( ONOSIntents[ i ] ),
1996 sort_keys=True,
1997 indent=4,
1998 separators=( ',', ': ' ) ) )
1999 elif intentsResults and consistentIntents:
2000 intentCheck = main.TRUE
2001
2002 # NOTE: Store has no durability, so intents are lost across system
2003 # restarts
2004 """
2005 main.step( "Compare current intents with intents before the failure" )
2006 # NOTE: this requires case 5 to pass for intentState to be set.
2007 # maybe we should stop the test if that fails?
2008 sameIntents = main.FALSE
2009 if intentState and intentState == ONOSIntents[ 0 ]:
2010 sameIntents = main.TRUE
2011 main.log.info( "Intents are consistent with before failure" )
2012 # TODO: possibly the states have changed? we may need to figure out
2013 # what the acceptable states are
2014 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
2015 sameIntents = main.TRUE
2016 try:
2017 before = json.loads( intentState )
2018 after = json.loads( ONOSIntents[ 0 ] )
2019 for intent in before:
2020 if intent not in after:
2021 sameIntents = main.FALSE
2022 main.log.debug( "Intent is not currently in ONOS " +
2023 "(at least in the same form):" )
2024 main.log.debug( json.dumps( intent ) )
2025 except ( ValueError, TypeError ):
2026 main.log.exception( "Exception printing intents" )
2027 main.log.debug( repr( ONOSIntents[0] ) )
2028 main.log.debug( repr( intentState ) )
2029 if sameIntents == main.FALSE:
2030 try:
2031 main.log.debug( "ONOS intents before: " )
2032 main.log.debug( json.dumps( json.loads( intentState ),
2033 sort_keys=True, indent=4,
2034 separators=( ',', ': ' ) ) )
2035 main.log.debug( "Current ONOS intents: " )
2036 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
2037 sort_keys=True, indent=4,
2038 separators=( ',', ': ' ) ) )
2039 except ( ValueError, TypeError ):
2040 main.log.exception( "Exception printing intents" )
2041 main.log.debug( repr( ONOSIntents[0] ) )
2042 main.log.debug( repr( intentState ) )
2043 utilities.assert_equals(
2044 expect=main.TRUE,
2045 actual=sameIntents,
2046 onpass="Intents are consistent with before failure",
2047 onfail="The Intents changed during failure" )
2048 intentCheck = intentCheck and sameIntents
2049 """
2050 main.step( "Get the OF Table entries and compare to before " +
2051 "component failure" )
2052 FlowTables = main.TRUE
2053 flows2 = []
2054 for i in range( 28 ):
2055 main.log.info( "Checking flow table on s" + str( i + 1 ) )
Jon Hall9043c902015-07-30 14:23:44 -07002056 tmpFlows = main.Mininet1.getFlowTable( 1.3, "s" + str( i + 1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002057 flows2.append( tmpFlows )
Jon Hall9043c902015-07-30 14:23:44 -07002058 tempResult = main.Mininet1.flowComp(
Jon Hall5cf14d52015-07-16 12:15:19 -07002059 flow1=flows[ i ],
2060 flow2=tmpFlows )
2061 FlowTables = FlowTables and tempResult
2062 if FlowTables == main.FALSE:
2063 main.log.info( "Differences in flow table for switch: s" +
2064 str( i + 1 ) )
2065 utilities.assert_equals(
2066 expect=main.TRUE,
2067 actual=FlowTables,
2068 onpass="No changes were found in the flow tables",
2069 onfail="Changes were found in the flow tables" )
2070
2071 main.Mininet2.pingLongKill()
2072 '''
2073 # main.step( "Check the continuous pings to ensure that no packets " +
2074 # "were dropped during component failure" )
2075 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
2076 main.params[ 'TESTONIP' ] )
2077 LossInPings = main.FALSE
2078 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
2079 for i in range( 8, 18 ):
2080 main.log.info(
2081 "Checking for a loss in pings along flow from s" +
2082 str( i ) )
2083 LossInPings = main.Mininet2.checkForLoss(
2084 "/tmp/ping.h" +
2085 str( i ) ) or LossInPings
2086 if LossInPings == main.TRUE:
2087 main.log.info( "Loss in ping detected" )
2088 elif LossInPings == main.ERROR:
2089 main.log.info( "There are multiple mininet process running" )
2090 elif LossInPings == main.FALSE:
2091 main.log.info( "No Loss in the pings" )
2092 main.log.info( "No loss of dataplane connectivity" )
2093 # utilities.assert_equals(
2094 # expect=main.FALSE,
2095 # actual=LossInPings,
2096 # onpass="No Loss of connectivity",
2097 # onfail="Loss of dataplane connectivity detected" )
2098
2099 # NOTE: Since intents are not persisted with IntnentStore,
2100 # we expect loss in dataplane connectivity
2101 LossInPings = main.FALSE
2102 '''
2103
2104 main.step( "Leadership Election is still functional" )
2105 # Test of LeadershipElection
2106 leaderList = []
2107 leaderResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002108 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002109 leaderN = cli.electionTestLeader()
2110 leaderList.append( leaderN )
2111 if leaderN == main.FALSE:
2112 # error in response
2113 main.log.error( "Something is wrong with " +
2114 "electionTestLeader function, check the" +
2115 " error logs" )
2116 leaderResult = main.FALSE
2117 elif leaderN is None:
2118 main.log.error( cli.name +
2119 " shows no leader for the election-app." )
2120 leaderResult = main.FALSE
2121 if len( set( leaderList ) ) != 1:
2122 leaderResult = main.FALSE
2123 main.log.error(
2124 "Inconsistent view of leader for the election test app" )
2125 # TODO: print the list
2126 utilities.assert_equals(
2127 expect=main.TRUE,
2128 actual=leaderResult,
2129 onpass="Leadership election passed",
2130 onfail="Something went wrong with Leadership election" )
2131
2132 def CASE8( self, main ):
2133 """
2134 Compare topo
2135 """
2136 import json
2137 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002138 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002139 assert main, "main not defined"
2140 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002141 assert main.CLIs, "main.CLIs not defined"
2142 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002143
2144 main.case( "Compare ONOS Topology view to Mininet topology" )
Jon Hall783bbf92015-07-23 14:33:19 -07002145 main.caseExplanation = "Compare topology objects between Mininet" +\
Jon Hall5cf14d52015-07-16 12:15:19 -07002146 " and ONOS"
2147
2148 main.step( "Comparing ONOS topology to MN" )
2149 devicesResults = main.TRUE
2150 linksResults = main.TRUE
2151 hostsResults = main.TRUE
2152 hostAttachmentResults = True
2153 topoResult = main.FALSE
2154 elapsed = 0
2155 count = 0
2156 main.step( "Collecting topology information from ONOS" )
2157 startTime = time.time()
2158 # Give time for Gossip to work
2159 while topoResult == main.FALSE and elapsed < 60:
2160 count += 1
2161 cliStart = time.time()
2162 devices = []
2163 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002164 for i in range( main.numCtrls ):
2165 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07002166 name="devices-" + str( i ),
2167 args=[ ] )
2168 threads.append( t )
2169 t.start()
2170
2171 for t in threads:
2172 t.join()
2173 devices.append( t.result )
2174 hosts = []
2175 ipResult = main.TRUE
2176 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002177 for i in range( main.numCtrls ):
2178 t = main.Thread( target=main.CLIs[i].hosts,
Jon Hall5cf14d52015-07-16 12:15:19 -07002179 name="hosts-" + str( i ),
2180 args=[ ] )
2181 threads.append( t )
2182 t.start()
2183
2184 for t in threads:
2185 t.join()
2186 try:
2187 hosts.append( json.loads( t.result ) )
2188 except ( ValueError, TypeError ):
2189 main.log.exception( "Error parsing hosts results" )
2190 main.log.error( repr( t.result ) )
2191 for controller in range( 0, len( hosts ) ):
2192 controllerStr = str( controller + 1 )
2193 for host in hosts[ controller ]:
2194 if host is None or host.get( 'ipAddresses', [] ) == []:
2195 main.log.error(
2196 "DEBUG:Error with host ipAddresses on controller" +
2197 controllerStr + ": " + str( host ) )
2198 ipResult = main.FALSE
2199 ports = []
2200 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002201 for i in range( main.numCtrls ):
2202 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07002203 name="ports-" + str( i ),
2204 args=[ ] )
2205 threads.append( t )
2206 t.start()
2207
2208 for t in threads:
2209 t.join()
2210 ports.append( t.result )
2211 links = []
2212 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002213 for i in range( main.numCtrls ):
2214 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07002215 name="links-" + str( i ),
2216 args=[ ] )
2217 threads.append( t )
2218 t.start()
2219
2220 for t in threads:
2221 t.join()
2222 links.append( t.result )
2223 clusters = []
2224 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002225 for i in range( main.numCtrls ):
2226 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07002227 name="clusters-" + str( i ),
2228 args=[ ] )
2229 threads.append( t )
2230 t.start()
2231
2232 for t in threads:
2233 t.join()
2234 clusters.append( t.result )
2235
2236 elapsed = time.time() - startTime
2237 cliTime = time.time() - cliStart
2238 print "Elapsed time: " + str( elapsed )
2239 print "CLI time: " + str( cliTime )
2240
2241 mnSwitches = main.Mininet1.getSwitches()
2242 mnLinks = main.Mininet1.getLinks()
2243 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07002244 for controller in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07002245 controllerStr = str( controller + 1 )
2246 if devices[ controller ] and ports[ controller ] and\
2247 "Error" not in devices[ controller ] and\
2248 "Error" not in ports[ controller ]:
2249
2250 currentDevicesResult = main.Mininet1.compareSwitches(
2251 mnSwitches,
2252 json.loads( devices[ controller ] ),
2253 json.loads( ports[ controller ] ) )
2254 else:
2255 currentDevicesResult = main.FALSE
2256 utilities.assert_equals( expect=main.TRUE,
2257 actual=currentDevicesResult,
2258 onpass="ONOS" + controllerStr +
2259 " Switches view is correct",
2260 onfail="ONOS" + controllerStr +
2261 " Switches view is incorrect" )
2262
2263 if links[ controller ] and "Error" not in links[ controller ]:
2264 currentLinksResult = main.Mininet1.compareLinks(
2265 mnSwitches, mnLinks,
2266 json.loads( links[ controller ] ) )
2267 else:
2268 currentLinksResult = main.FALSE
2269 utilities.assert_equals( expect=main.TRUE,
2270 actual=currentLinksResult,
2271 onpass="ONOS" + controllerStr +
2272 " links view is correct",
2273 onfail="ONOS" + controllerStr +
2274 " links view is incorrect" )
2275
2276 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2277 currentHostsResult = main.Mininet1.compareHosts(
2278 mnHosts,
2279 hosts[ controller ] )
2280 else:
2281 currentHostsResult = main.FALSE
2282 utilities.assert_equals( expect=main.TRUE,
2283 actual=currentHostsResult,
2284 onpass="ONOS" + controllerStr +
2285 " hosts exist in Mininet",
2286 onfail="ONOS" + controllerStr +
2287 " hosts don't match Mininet" )
2288 # CHECKING HOST ATTACHMENT POINTS
2289 hostAttachment = True
2290 noHosts = False
2291 # FIXME: topo-HA/obelisk specific mappings:
2292 # key is mac and value is dpid
2293 mappings = {}
2294 for i in range( 1, 29 ): # hosts 1 through 28
2295 # set up correct variables:
2296 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2297 if i == 1:
2298 deviceId = "1000".zfill(16)
2299 elif i == 2:
2300 deviceId = "2000".zfill(16)
2301 elif i == 3:
2302 deviceId = "3000".zfill(16)
2303 elif i == 4:
2304 deviceId = "3004".zfill(16)
2305 elif i == 5:
2306 deviceId = "5000".zfill(16)
2307 elif i == 6:
2308 deviceId = "6000".zfill(16)
2309 elif i == 7:
2310 deviceId = "6007".zfill(16)
2311 elif i >= 8 and i <= 17:
2312 dpid = '3' + str( i ).zfill( 3 )
2313 deviceId = dpid.zfill(16)
2314 elif i >= 18 and i <= 27:
2315 dpid = '6' + str( i ).zfill( 3 )
2316 deviceId = dpid.zfill(16)
2317 elif i == 28:
2318 deviceId = "2800".zfill(16)
2319 mappings[ macId ] = deviceId
2320 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2321 if hosts[ controller ] == []:
2322 main.log.warn( "There are no hosts discovered" )
2323 noHosts = True
2324 else:
2325 for host in hosts[ controller ]:
2326 mac = None
2327 location = None
2328 device = None
2329 port = None
2330 try:
2331 mac = host.get( 'mac' )
2332 assert mac, "mac field could not be found for this host object"
2333
2334 location = host.get( 'location' )
2335 assert location, "location field could not be found for this host object"
2336
2337 # Trim the protocol identifier off deviceId
2338 device = str( location.get( 'elementId' ) ).split(':')[1]
2339 assert device, "elementId field could not be found for this host location object"
2340
2341 port = location.get( 'port' )
2342 assert port, "port field could not be found for this host location object"
2343
2344 # Now check if this matches where they should be
2345 if mac and device and port:
2346 if str( port ) != "1":
2347 main.log.error( "The attachment port is incorrect for " +
2348 "host " + str( mac ) +
2349 ". Expected: 1 Actual: " + str( port) )
2350 hostAttachment = False
2351 if device != mappings[ str( mac ) ]:
2352 main.log.error( "The attachment device is incorrect for " +
2353 "host " + str( mac ) +
2354 ". Expected: " + mappings[ str( mac ) ] +
2355 " Actual: " + device )
2356 hostAttachment = False
2357 else:
2358 hostAttachment = False
2359 except AssertionError:
2360 main.log.exception( "Json object not as expected" )
2361 main.log.error( repr( host ) )
2362 hostAttachment = False
2363 else:
2364 main.log.error( "No hosts json output or \"Error\"" +
2365 " in output. hosts = " +
2366 repr( hosts[ controller ] ) )
2367 if noHosts is False:
2368 # TODO: Find a way to know if there should be hosts in a
2369 # given point of the test
2370 hostAttachment = True
2371
2372 # END CHECKING HOST ATTACHMENT POINTS
2373 devicesResults = devicesResults and currentDevicesResult
2374 linksResults = linksResults and currentLinksResult
2375 hostsResults = hostsResults and currentHostsResult
2376 hostAttachmentResults = hostAttachmentResults and\
2377 hostAttachment
2378 topoResult = ( devicesResults and linksResults
2379 and hostsResults and ipResult and
2380 hostAttachmentResults )
2381
2382 # Compare json objects for hosts and dataplane clusters
2383
2384 # hosts
2385 main.step( "Hosts view is consistent across all ONOS nodes" )
2386 consistentHostsResult = main.TRUE
2387 for controller in range( len( hosts ) ):
2388 controllerStr = str( controller + 1 )
2389 if "Error" not in hosts[ controller ]:
2390 if hosts[ controller ] == hosts[ 0 ]:
2391 continue
2392 else: # hosts not consistent
2393 main.log.error( "hosts from ONOS" + controllerStr +
2394 " is inconsistent with ONOS1" )
2395 main.log.warn( repr( hosts[ controller ] ) )
2396 consistentHostsResult = main.FALSE
2397
2398 else:
2399 main.log.error( "Error in getting ONOS hosts from ONOS" +
2400 controllerStr )
2401 consistentHostsResult = main.FALSE
2402 main.log.warn( "ONOS" + controllerStr +
2403 " hosts response: " +
2404 repr( hosts[ controller ] ) )
2405 utilities.assert_equals(
2406 expect=main.TRUE,
2407 actual=consistentHostsResult,
2408 onpass="Hosts view is consistent across all ONOS nodes",
2409 onfail="ONOS nodes have different views of hosts" )
2410
2411 main.step( "Hosts information is correct" )
2412 hostsResults = hostsResults and ipResult
2413 utilities.assert_equals(
2414 expect=main.TRUE,
2415 actual=hostsResults,
2416 onpass="Host information is correct",
2417 onfail="Host information is incorrect" )
2418
2419 main.step( "Host attachment points to the network" )
2420 utilities.assert_equals(
2421 expect=True,
2422 actual=hostAttachmentResults,
2423 onpass="Hosts are correctly attached to the network",
2424 onfail="ONOS did not correctly attach hosts to the network" )
2425
2426 # Strongly connected clusters of devices
2427 main.step( "Clusters view is consistent across all ONOS nodes" )
2428 consistentClustersResult = main.TRUE
2429 for controller in range( len( clusters ) ):
2430 controllerStr = str( controller + 1 )
2431 if "Error" not in clusters[ controller ]:
2432 if clusters[ controller ] == clusters[ 0 ]:
2433 continue
2434 else: # clusters not consistent
2435 main.log.error( "clusters from ONOS" +
2436 controllerStr +
2437 " is inconsistent with ONOS1" )
2438 consistentClustersResult = main.FALSE
2439
2440 else:
2441 main.log.error( "Error in getting dataplane clusters " +
2442 "from ONOS" + controllerStr )
2443 consistentClustersResult = main.FALSE
2444 main.log.warn( "ONOS" + controllerStr +
2445 " clusters response: " +
2446 repr( clusters[ controller ] ) )
2447 utilities.assert_equals(
2448 expect=main.TRUE,
2449 actual=consistentClustersResult,
2450 onpass="Clusters view is consistent across all ONOS nodes",
2451 onfail="ONOS nodes have different views of clusters" )
2452
2453 main.step( "There is only one SCC" )
2454 # there should always only be one cluster
2455 try:
2456 numClusters = len( json.loads( clusters[ 0 ] ) )
2457 except ( ValueError, TypeError ):
2458 main.log.exception( "Error parsing clusters[0]: " +
2459 repr( clusters[0] ) )
2460 clusterResults = main.FALSE
2461 if numClusters == 1:
2462 clusterResults = main.TRUE
2463 utilities.assert_equals(
2464 expect=1,
2465 actual=numClusters,
2466 onpass="ONOS shows 1 SCC",
2467 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2468
2469 topoResult = ( devicesResults and linksResults
2470 and hostsResults and consistentHostsResult
2471 and consistentClustersResult and clusterResults
2472 and ipResult and hostAttachmentResults )
2473
2474 topoResult = topoResult and int( count <= 2 )
2475 note = "note it takes about " + str( int( cliTime ) ) + \
2476 " seconds for the test to make all the cli calls to fetch " +\
2477 "the topology from each ONOS instance"
2478 main.log.info(
2479 "Very crass estimate for topology discovery/convergence( " +
2480 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2481 str( count ) + " tries" )
2482
2483 main.step( "Device information is correct" )
2484 utilities.assert_equals(
2485 expect=main.TRUE,
2486 actual=devicesResults,
2487 onpass="Device information is correct",
2488 onfail="Device information is incorrect" )
2489
2490 main.step( "Links are correct" )
2491 utilities.assert_equals(
2492 expect=main.TRUE,
2493 actual=linksResults,
2494 onpass="Link are correct",
2495 onfail="Links are incorrect" )
2496
2497 # FIXME: move this to an ONOS state case
2498 main.step( "Checking ONOS nodes" )
2499 nodesOutput = []
2500 nodeResults = main.TRUE
2501 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002502 for i in range( main.numCtrls ):
2503 t = main.Thread( target=main.CLIs[i].nodes,
Jon Hall5cf14d52015-07-16 12:15:19 -07002504 name="nodes-" + str( i ),
2505 args=[ ] )
2506 threads.append( t )
2507 t.start()
2508
2509 for t in threads:
2510 t.join()
2511 nodesOutput.append( t.result )
Jon Halle1a3b752015-07-22 13:02:46 -07002512 ips = [ node.ip_address for node in main.nodes ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002513 for i in nodesOutput:
2514 try:
2515 current = json.loads( i )
2516 for node in current:
2517 currentResult = main.FALSE
2518 if node['ip'] in ips: # node in nodes() output is in cell
2519 if node['state'] == 'ACTIVE':
2520 currentResult = main.TRUE
2521 else:
2522 main.log.error( "Error in ONOS node availability" )
2523 main.log.error(
2524 json.dumps( current,
2525 sort_keys=True,
2526 indent=4,
2527 separators=( ',', ': ' ) ) )
2528 break
2529 nodeResults = nodeResults and currentResult
2530 except ( ValueError, TypeError ):
2531 main.log.error( "Error parsing nodes output" )
2532 main.log.warn( repr( i ) )
2533 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2534 onpass="Nodes check successful",
2535 onfail="Nodes check NOT successful" )
2536
2537 def CASE9( self, main ):
2538 """
2539 Link s3-s28 down
2540 """
2541 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002542 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002543 assert main, "main not defined"
2544 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002545 assert main.CLIs, "main.CLIs not defined"
2546 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002547 # NOTE: You should probably run a topology check after this
2548
2549 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2550
2551 description = "Turn off a link to ensure that Link Discovery " +\
2552 "is working properly"
2553 main.case( description )
2554
2555 main.step( "Kill Link between s3 and s28" )
2556 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
2557 main.log.info( "Waiting " + str( linkSleep ) +
2558 " seconds for link down to be discovered" )
2559 time.sleep( linkSleep )
2560 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
2561 onpass="Link down successful",
2562 onfail="Failed to bring link down" )
2563 # TODO do some sort of check here
2564
2565 def CASE10( self, main ):
2566 """
2567 Link s3-s28 up
2568 """
2569 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002570 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002571 assert main, "main not defined"
2572 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002573 assert main.CLIs, "main.CLIs not defined"
2574 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002575 # NOTE: You should probably run a topology check after this
2576
2577 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2578
2579 description = "Restore a link to ensure that Link Discovery is " + \
2580 "working properly"
2581 main.case( description )
2582
2583 main.step( "Bring link between s3 and s28 back up" )
2584 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
2585 main.log.info( "Waiting " + str( linkSleep ) +
2586 " seconds for link up to be discovered" )
2587 time.sleep( linkSleep )
2588 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
2589 onpass="Link up successful",
2590 onfail="Failed to bring link up" )
2591 # TODO do some sort of check here
2592
2593 def CASE11( self, main ):
2594 """
2595 Switch Down
2596 """
2597 # NOTE: You should probably run a topology check after this
2598 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002599 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002600 assert main, "main not defined"
2601 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002602 assert main.CLIs, "main.CLIs not defined"
2603 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002604
2605 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2606
2607 description = "Killing a switch to ensure it is discovered correctly"
2608 main.case( description )
2609 switch = main.params[ 'kill' ][ 'switch' ]
2610 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2611
2612 # TODO: Make this switch parameterizable
2613 main.step( "Kill " + switch )
2614 main.log.info( "Deleting " + switch )
2615 main.Mininet1.delSwitch( switch )
2616 main.log.info( "Waiting " + str( switchSleep ) +
2617 " seconds for switch down to be discovered" )
2618 time.sleep( switchSleep )
2619 device = main.ONOScli1.getDevice( dpid=switchDPID )
2620 # Peek at the deleted switch
2621 main.log.warn( str( device ) )
2622 result = main.FALSE
2623 if device and device[ 'available' ] is False:
2624 result = main.TRUE
2625 utilities.assert_equals( expect=main.TRUE, actual=result,
2626 onpass="Kill switch successful",
2627 onfail="Failed to kill switch?" )
2628
2629 def CASE12( self, main ):
2630 """
2631 Switch Up
2632 """
2633 # NOTE: You should probably run a topology check after this
2634 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002635 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002636 assert main, "main not defined"
2637 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002638 assert main.CLIs, "main.CLIs not defined"
2639 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002640 assert ONOS1Port, "ONOS1Port not defined"
2641 assert ONOS2Port, "ONOS2Port not defined"
2642 assert ONOS3Port, "ONOS3Port not defined"
2643 assert ONOS4Port, "ONOS4Port not defined"
2644 assert ONOS5Port, "ONOS5Port not defined"
2645 assert ONOS6Port, "ONOS6Port not defined"
2646 assert ONOS7Port, "ONOS7Port not defined"
2647
2648 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2649 switch = main.params[ 'kill' ][ 'switch' ]
2650 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2651 links = main.params[ 'kill' ][ 'links' ].split()
2652 description = "Adding a switch to ensure it is discovered correctly"
2653 main.case( description )
2654
2655 main.step( "Add back " + switch )
2656 main.Mininet1.addSwitch( switch, dpid=switchDPID )
2657 for peer in links:
2658 main.Mininet1.addLink( switch, peer )
2659 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -07002660 for i in range( main.numCtrls ):
2661 ipList.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -07002662 main.Mininet1.assignSwController( sw=switch, ip=ipList )
2663 main.log.info( "Waiting " + str( switchSleep ) +
2664 " seconds for switch up to be discovered" )
2665 time.sleep( switchSleep )
2666 device = main.ONOScli1.getDevice( dpid=switchDPID )
2667 # Peek at the deleted switch
2668 main.log.warn( str( device ) )
2669 result = main.FALSE
2670 if device and device[ 'available' ]:
2671 result = main.TRUE
2672 utilities.assert_equals( expect=main.TRUE, actual=result,
2673 onpass="add switch successful",
2674 onfail="Failed to add switch?" )
2675
2676 def CASE13( self, main ):
2677 """
2678 Clean up
2679 """
2680 import os
2681 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002682 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002683 assert main, "main not defined"
2684 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002685 assert main.CLIs, "main.CLIs not defined"
2686 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002687
2688 # printing colors to terminal
2689 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2690 'blue': '\033[94m', 'green': '\033[92m',
2691 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
2692 main.case( "Test Cleanup" )
2693 main.step( "Killing tcpdumps" )
2694 main.Mininet2.stopTcpdump()
2695
2696 testname = main.TEST
2697 if main.params[ 'BACKUP' ] == "True":
2698 main.step( "Copying MN pcap and ONOS log files to test station" )
2699 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
2700 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
2701 # NOTE: MN Pcap file is being saved to ~/packet_captures
2702 # scp this file as MN and TestON aren't necessarily the same vm
2703 # FIXME: scp
2704 # mn files
2705 # TODO: Load these from params
2706 # NOTE: must end in /
2707 logFolder = "/opt/onos/log/"
2708 logFiles = [ "karaf.log", "karaf.log.1" ]
2709 # NOTE: must end in /
2710 dstDir = "~/packet_captures/"
2711 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002712 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07002713 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2714 ":" + logFolder + f + " " +
2715 teststationUser + "@" +
2716 teststationIP + ":" +
2717 dstDir + str( testname ) +
2718 "-" + node.name + "-" + f )
2719 main.ONOSbench.handle.expect( "\$" )
2720
2721 # std*.log's
2722 # NOTE: must end in /
2723 logFolder = "/opt/onos/var/"
2724 logFiles = [ "stderr.log", "stdout.log" ]
2725 # NOTE: must end in /
2726 dstDir = "~/packet_captures/"
2727 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002728 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07002729 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2730 ":" + logFolder + f + " " +
2731 teststationUser + "@" +
2732 teststationIP + ":" +
2733 dstDir + str( testname ) +
2734 "-" + node.name + "-" + f )
2735 main.ONOSbench.handle.expect( "\$" )
2736 # sleep so scp can finish
2737 time.sleep( 10 )
2738 main.step( "Packing and rotating pcap archives" )
2739 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
2740
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 Hall5cf14d52015-07-16 12:15:19 -07002749 print colors[ 'purple' ] + "Checking logs for errors on " + \
2750 node.name + ":" + colors[ 'end' ]
2751 print main.ONOSbench.checkLogs( node.ip_address, restart=True )
2752
2753 try:
2754 timerLog = open( main.logdir + "/Timers.csv", 'w')
2755 main.log.error( ", ".join( labels ) + "\n" + ", ".join( data ) )
2756 timerLog.write( ", ".join( labels ) + "\n" + ", ".join( data ) )
2757 timerLog.close()
2758 except NameError, e:
2759 main.log.exception(e)
2760
2761 def CASE14( self, main ):
2762 """
2763 start election app on all onos nodes
2764 """
Jon Halle1a3b752015-07-22 13:02:46 -07002765 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002766 assert main, "main not defined"
2767 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002768 assert main.CLIs, "main.CLIs not defined"
2769 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002770
2771 main.case("Start Leadership Election app")
2772 main.step( "Install leadership election app" )
2773 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
2774 utilities.assert_equals(
2775 expect=main.TRUE,
2776 actual=appResult,
2777 onpass="Election app installed",
2778 onfail="Something went wrong with installing Leadership election" )
2779
2780 main.step( "Run for election on each node" )
2781 leaderResult = main.TRUE
2782 leaders = []
Jon Halle1a3b752015-07-22 13:02:46 -07002783 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002784 cli.electionTestRun()
Jon Halle1a3b752015-07-22 13:02:46 -07002785 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002786 leader = cli.electionTestLeader()
2787 if leader is None or leader == main.FALSE:
2788 main.log.error( cli.name + ": Leader for the election app " +
2789 "should be an ONOS node, instead got '" +
2790 str( leader ) + "'" )
2791 leaderResult = main.FALSE
2792 leaders.append( leader )
2793 utilities.assert_equals(
2794 expect=main.TRUE,
2795 actual=leaderResult,
2796 onpass="Successfully ran for leadership",
2797 onfail="Failed to run for leadership" )
2798
2799 main.step( "Check that each node shows the same leader" )
2800 sameLeader = main.TRUE
2801 if len( set( leaders ) ) != 1:
2802 sameLeader = main.FALSE
2803 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2804 str( leaders ) )
2805 utilities.assert_equals(
2806 expect=main.TRUE,
2807 actual=sameLeader,
2808 onpass="Leadership is consistent for the election topic",
2809 onfail="Nodes have different leaders" )
2810
2811 def CASE15( self, main ):
2812 """
2813 Check that Leadership Election is still functional
acsmars9475b1c2015-08-28 18:02:08 -07002814 15.1 Run election on each node
2815 15.2 Check that each node has the same leaders and candidates
2816 15.3 Find current leader and withdraw
2817 15.4 Check that a new node was elected leader
2818 15.5 Check that that new leader was the candidate of old leader
2819 15.6 Run for election on old leader
2820 15.7 Check that oldLeader is a candidate, and leader if only 1 node
2821 15.8 Make sure that the old leader was added to the candidate list
2822
2823 old and new variable prefixes refer to data from before vs after
2824 withdrawl and later before withdrawl vs after re-election
Jon Hall5cf14d52015-07-16 12:15:19 -07002825 """
2826 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002827 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002828 assert main, "main not defined"
2829 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002830 assert main.CLIs, "main.CLIs not defined"
2831 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002832
Jon Hall5cf14d52015-07-16 12:15:19 -07002833 description = "Check that Leadership Election is still functional"
2834 main.case( description )
2835 # NOTE: Need to re-run since being a canidate is not persistant
acsmars9475b1c2015-08-28 18:02:08 -07002836 # TODO: add check for "Command not found:" in the driver, this
2837 # means the election test app isn't loaded
2838
2839 oldLeaders = [] # leaders by node before withdrawl from candidates
2840 newLeaders = [] # leaders by node after withdrawl from candidates
2841 oldAllCandidates = [] # list of lists of each nodes' candidates before
2842 newAllCandidates = [] # list of lists of each nodes' candidates after
2843 oldCandidates = [] # list of candidates from node 0 before withdrawl
2844 newCandidates = [] # list of candidates from node 0 after withdrawl
2845 oldLeader = '' # the old leader from oldLeaders, None if not same
2846 newLeader = '' # the new leaders fron newLoeaders, None if not same
2847 oldLeaderCLI = None # the CLI of the old leader used for re-electing
acsmars71adceb2015-08-31 15:09:26 -07002848 expectNoLeader = False # True when there is only one leader
2849 if main.numCtrls == 1:
2850 expectNoLeader = True
acsmars9475b1c2015-08-28 18:02:08 -07002851
Jon Hall5cf14d52015-07-16 12:15:19 -07002852 main.step( "Run for election on each node" )
acsmars9475b1c2015-08-28 18:02:08 -07002853 electionResult = main.TRUE
2854
2855 for cli in main.CLIs: # run test election on each node
2856 if cli.electionTestRun() == main.FALSE:
2857 electionResult = main.FALSE
2858
Jon Hall5cf14d52015-07-16 12:15:19 -07002859 utilities.assert_equals(
2860 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07002861 actual=electionResult,
2862 onpass="All nodes successfully ran for leadership",
2863 onfail="At least one node failed to run for leadership" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002864
acsmars3a72bde2015-09-02 14:16:22 -07002865 if electionResult == main.FALSE:
2866 main.log.error(
2867 "Skipping Test Case because Election Test App isn't loaded" )
2868 main.skipCase()
2869
acsmars9475b1c2015-08-28 18:02:08 -07002870 main.step( "Check that each node shows the same leader and candidates" )
2871 sameResult = main.TRUE
2872 failMessage = "Nodes have different leaders"
2873 for cli in main.CLIs:
2874 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2875 oldAllCandidates.append( node )
2876 oldLeaders.append( node[ 0 ] )
2877 oldCandidates = oldAllCandidates[ 0 ]
2878
2879 # Check that each node has the same leader. Defines oldLeader
2880 if len( set( oldLeaders ) ) != 1:
2881 sameResult = main.FALSE
acsmars71adceb2015-08-31 15:09:26 -07002882 main.log.error( "More than one leader present:" + str( oldLeaders ) )
acsmars9475b1c2015-08-28 18:02:08 -07002883 oldLeader = None
2884 else:
2885 oldLeader = oldLeaders[ 0 ]
2886
2887 # Check that each node's candidate list is the same
2888 for candidates in oldAllCandidates:
2889 if set( candidates ) != set( oldCandidates ):
2890 sameResult = main.FALSE
2891 failMessage += "and candidates"
2892
Jon Hall5cf14d52015-07-16 12:15:19 -07002893 utilities.assert_equals(
2894 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002895 actual=sameResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002896 onpass="Leadership is consistent for the election topic",
acsmars9475b1c2015-08-28 18:02:08 -07002897 onfail=failMessage )
Jon Hall5cf14d52015-07-16 12:15:19 -07002898
2899 main.step( "Find current leader and withdraw" )
acsmars9475b1c2015-08-28 18:02:08 -07002900 withdrawResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002901 # do some sanity checking on leader before using it
acsmars9475b1c2015-08-28 18:02:08 -07002902 if oldLeader is None:
2903 main.log.error( "Leadership isn't consistent." )
2904 withdrawResult = main.FALSE
2905 # Get the CLI of the oldLeader
Jon Halle1a3b752015-07-22 13:02:46 -07002906 for i in range( len( main.CLIs ) ):
acsmars9475b1c2015-08-28 18:02:08 -07002907 if oldLeader == main.nodes[ i ].ip_address:
2908 oldLeaderCLI = main.CLIs[ i ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002909 break
2910 else: # FOR/ELSE statement
2911 main.log.error( "Leader election, could not find current leader" )
2912 if oldLeader:
acsmars9475b1c2015-08-28 18:02:08 -07002913 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall5cf14d52015-07-16 12:15:19 -07002914 utilities.assert_equals(
2915 expect=main.TRUE,
2916 actual=withdrawResult,
2917 onpass="Node was withdrawn from election",
2918 onfail="Node was not withdrawn from election" )
2919
acsmars9475b1c2015-08-28 18:02:08 -07002920 main.step( "Check that a new node was elected leader" )
acsmars71adceb2015-08-31 15:09:26 -07002921
Jon Hall5cf14d52015-07-16 12:15:19 -07002922 # FIXME: use threads
acsmars9475b1c2015-08-28 18:02:08 -07002923 newLeaderResult = main.TRUE
2924 failMessage = "Nodes have different leaders"
2925
2926 # Get new leaders and candidates
Jon Halle1a3b752015-07-22 13:02:46 -07002927 for cli in main.CLIs:
acsmars9475b1c2015-08-28 18:02:08 -07002928 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
acsmars71adceb2015-08-31 15:09:26 -07002929 # elections might no have finished yet
2930 if node[ 0 ] == 'none' and not expectNoLeader:
acsmars9475b1c2015-08-28 18:02:08 -07002931 main.log.info( "Node has no leader, waiting 5 seconds to be " +
2932 "sure elections are complete." )
2933 time.sleep(5)
2934 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
acsmars71adceb2015-08-31 15:09:26 -07002935 # election still isn't done or there is a problem
2936 if node[ 0 ] == 'none':
2937 main.log.error( "No leader was elected on at least 1 node" )
2938 newLeaderResult = main.FALSE
acsmars9475b1c2015-08-28 18:02:08 -07002939 newAllCandidates.append( node )
2940 newLeaders.append( node[ 0 ] )
2941 newCandidates = newAllCandidates[ 0 ]
2942
2943 # Check that each node has the same leader. Defines newLeader
2944 if len( set( newLeaders ) ) != 1:
2945 newLeaderResult = main.FALSE
2946 main.log.error( "Nodes have different leaders: " +
2947 str( newLeaders ) )
2948 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07002949 else:
acsmars9475b1c2015-08-28 18:02:08 -07002950 newLeader = newLeaders[ 0 ]
2951
acsmars71adceb2015-08-31 15:09:26 -07002952 # Check that each node's candidate list is the same
2953 for candidates in newAllCandidates:
2954 if set( candidates ) != set( newCandidates ):
2955 newLeaderResult = main.FALSE
2956 main.error.log( "Discrepancy in candidate lists detected" )
2957
acsmars9475b1c2015-08-28 18:02:08 -07002958 # Check that the new leader is not the older leader, which was withdrawn
2959 if newLeader == oldLeader:
2960 newLeaderResult = main.FALSE
2961 main.log.error( "All nodes still see old leader: " + oldLeader +
2962 " as the current leader" )
2963
Jon Hall5cf14d52015-07-16 12:15:19 -07002964 utilities.assert_equals(
2965 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07002966 actual=newLeaderResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002967 onpass="Leadership election passed",
2968 onfail="Something went wrong with Leadership election" )
2969
acsmars9475b1c2015-08-28 18:02:08 -07002970 main.step( "Check that that new leader was the candidate of old leader")
2971 # candidates[ 2 ] should be come the top candidate after withdrawl
2972 correctCandidateResult = main.TRUE
acsmars71adceb2015-08-31 15:09:26 -07002973 if expectNoLeader:
2974 if newLeader == 'none':
2975 main.log.info( "No leader expected. None found. Pass" )
2976 correctCandidateResult = main.TRUE
2977 else:
2978 main.log.info( "Expected no leader, got: " + str( newLeader ) )
2979 correctCandidateResult = main.FALSE
2980 elif newLeader != oldCandidates[ 2 ]:
acsmars9475b1c2015-08-28 18:02:08 -07002981 correctCandidateResult = main.FALSE
2982 main.log.error( "Candidate " + newLeader + " was elected. " +
2983 oldCandidates[ 2 ] + " should have had priority." )
2984
2985 utilities.assert_equals(
2986 expect=main.TRUE,
2987 actual=correctCandidateResult,
2988 onpass="Correct Candidate Elected",
2989 onfail="Incorrect Candidate Elected" )
2990
Jon Hall5cf14d52015-07-16 12:15:19 -07002991 main.step( "Run for election on old leader( just so everyone " +
2992 "is in the hat )" )
acsmars9475b1c2015-08-28 18:02:08 -07002993 if oldLeaderCLI is not None:
2994 runResult = oldLeaderCLI.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07002995 else:
acsmars9475b1c2015-08-28 18:02:08 -07002996 main.log.error( "No old leader to re-elect" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002997 runResult = main.FALSE
2998 utilities.assert_equals(
2999 expect=main.TRUE,
3000 actual=runResult,
3001 onpass="App re-ran for election",
3002 onfail="App failed to run for election" )
acsmars9475b1c2015-08-28 18:02:08 -07003003 main.step(
3004 "Check that oldLeader is a candidate, and leader if only 1 node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003005 # verify leader didn't just change
acsmars9475b1c2015-08-28 18:02:08 -07003006 positionResult = main.TRUE
3007 # Get new leaders and candidates, wait if oldLeader is not a candidate yet
3008
3009 # Reset and reuse the new candidate and leaders lists
3010 newAllCandidates = []
3011 newCandidates = []
3012 newLeaders = []
3013 for cli in main.CLIs:
3014 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
3015 if oldLeader not in node: # election might no have finished yet
3016 main.log.info( "Old Leader not elected, waiting 5 seconds to " +
3017 "be sure elections are complete" )
3018 time.sleep(5)
3019 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
3020 if oldLeader not in node: # election still isn't done, errors
3021 main.log.error(
3022 "Old leader was not elected on at least one node" )
3023 positionResult = main.FALSE
3024 newAllCandidates.append( node )
3025 newLeaders.append( node[ 0 ] )
3026 newCandidates = newAllCandidates[ 0 ]
3027
3028 # Check that each node has the same leader. Defines newLeader
3029 if len( set( newLeaders ) ) != 1:
3030 positionResult = main.FALSE
3031 main.log.error( "Nodes have different leaders: " +
3032 str( newLeaders ) )
3033 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07003034 else:
acsmars9475b1c2015-08-28 18:02:08 -07003035 newLeader = newLeaders[ 0 ]
3036
acsmars71adceb2015-08-31 15:09:26 -07003037 # Check that each node's candidate list is the same
3038 for candidates in newAllCandidates:
3039 if set( candidates ) != set( newCandidates ):
3040 newLeaderResult = main.FALSE
3041 main.error.log( "Discrepancy in candidate lists detected" )
3042
acsmars9475b1c2015-08-28 18:02:08 -07003043 # Check that the re-elected node is last on the candidate List
3044 if oldLeader != newCandidates[ -1 ]:
3045 main.log.error( "Old Leader (" + oldLeader + ") not in the proper position " +
3046 str( newCandidates ) )
3047 positionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07003048
3049 utilities.assert_equals(
3050 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07003051 actual=positionResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07003052 onpass="Old leader successfully re-ran for election",
3053 onfail="Something went wrong with Leadership election after " +
3054 "the old leader re-ran for election" )
3055
3056 def CASE16( self, main ):
3057 """
3058 Install Distributed Primitives app
3059 """
3060 import time
Jon Halle1a3b752015-07-22 13:02:46 -07003061 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003062 assert main, "main not defined"
3063 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003064 assert main.CLIs, "main.CLIs not defined"
3065 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003066
3067 # Variables for the distributed primitives tests
3068 global pCounterName
3069 global iCounterName
3070 global pCounterValue
3071 global iCounterValue
3072 global onosSet
3073 global onosSetName
3074 pCounterName = "TestON-Partitions"
3075 iCounterName = "TestON-inMemory"
3076 pCounterValue = 0
3077 iCounterValue = 0
3078 onosSet = set([])
3079 onosSetName = "TestON-set"
3080
3081 description = "Install Primitives app"
3082 main.case( description )
3083 main.step( "Install Primitives app" )
3084 appName = "org.onosproject.distributedprimitives"
Jon Halle1a3b752015-07-22 13:02:46 -07003085 appResults = main.CLIs[0].activateApp( appName )
Jon Hall5cf14d52015-07-16 12:15:19 -07003086 utilities.assert_equals( expect=main.TRUE,
3087 actual=appResults,
3088 onpass="Primitives app activated",
3089 onfail="Primitives app not activated" )
3090 time.sleep( 5 ) # To allow all nodes to activate
3091
3092 def CASE17( self, main ):
3093 """
3094 Check for basic functionality with distributed primitives
3095 """
Jon Hall5cf14d52015-07-16 12:15:19 -07003096 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07003097 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003098 assert main, "main not defined"
3099 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003100 assert main.CLIs, "main.CLIs not defined"
3101 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003102 assert pCounterName, "pCounterName not defined"
3103 assert iCounterName, "iCounterName not defined"
3104 assert onosSetName, "onosSetName not defined"
3105 # NOTE: assert fails if value is 0/None/Empty/False
3106 try:
3107 pCounterValue
3108 except NameError:
3109 main.log.error( "pCounterValue not defined, setting to 0" )
3110 pCounterValue = 0
3111 try:
3112 iCounterValue
3113 except NameError:
3114 main.log.error( "iCounterValue not defined, setting to 0" )
3115 iCounterValue = 0
3116 try:
3117 onosSet
3118 except NameError:
3119 main.log.error( "onosSet not defined, setting to empty Set" )
3120 onosSet = set([])
3121 # Variables for the distributed primitives tests. These are local only
3122 addValue = "a"
3123 addAllValue = "a b c d e f"
3124 retainValue = "c d e f"
3125
3126 description = "Check for basic functionality with distributed " +\
3127 "primitives"
3128 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07003129 main.caseExplanation = "Test the methods of the distributed " +\
3130 "primitives (counters and sets) throught the cli"
Jon Hall5cf14d52015-07-16 12:15:19 -07003131 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07003132 # Partitioned counters
3133 main.step( "Increment then get a default counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003134 pCounters = []
3135 threads = []
3136 addedPValues = []
Jon Halle1a3b752015-07-22 13:02:46 -07003137 for i in range( main.numCtrls ):
3138 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3139 name="counterAddAndGet-" + str( i ),
Jon Hall5cf14d52015-07-16 12:15:19 -07003140 args=[ pCounterName ] )
3141 pCounterValue += 1
3142 addedPValues.append( pCounterValue )
3143 threads.append( t )
3144 t.start()
3145
3146 for t in threads:
3147 t.join()
3148 pCounters.append( t.result )
3149 # Check that counter incremented numController times
3150 pCounterResults = True
3151 for i in addedPValues:
3152 tmpResult = i in pCounters
3153 pCounterResults = pCounterResults and tmpResult
3154 if not tmpResult:
3155 main.log.error( str( i ) + " is not in partitioned "
3156 "counter incremented results" )
3157 utilities.assert_equals( expect=True,
3158 actual=pCounterResults,
3159 onpass="Default counter incremented",
3160 onfail="Error incrementing default" +
3161 " counter" )
3162
Jon Halle1a3b752015-07-22 13:02:46 -07003163 main.step( "Get then Increment a default counter on each node" )
3164 pCounters = []
3165 threads = []
3166 addedPValues = []
3167 for i in range( main.numCtrls ):
3168 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3169 name="counterGetAndAdd-" + str( i ),
3170 args=[ pCounterName ] )
3171 addedPValues.append( pCounterValue )
3172 pCounterValue += 1
3173 threads.append( t )
3174 t.start()
3175
3176 for t in threads:
3177 t.join()
3178 pCounters.append( t.result )
3179 # Check that counter incremented numController times
3180 pCounterResults = True
3181 for i in addedPValues:
3182 tmpResult = i in pCounters
3183 pCounterResults = pCounterResults and tmpResult
3184 if not tmpResult:
3185 main.log.error( str( i ) + " is not in partitioned "
3186 "counter incremented results" )
3187 utilities.assert_equals( expect=True,
3188 actual=pCounterResults,
3189 onpass="Default counter incremented",
3190 onfail="Error incrementing default" +
3191 " counter" )
3192
3193 main.step( "Counters we added have the correct values" )
3194 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3195 utilities.assert_equals( expect=main.TRUE,
3196 actual=incrementCheck,
3197 onpass="Added counters are correct",
3198 onfail="Added counters are incorrect" )
3199
3200 main.step( "Add -8 to then get a default counter on each node" )
3201 pCounters = []
3202 threads = []
3203 addedPValues = []
3204 for i in range( main.numCtrls ):
3205 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3206 name="counterIncrement-" + str( i ),
3207 args=[ pCounterName ],
3208 kwargs={ "delta": -8 } )
3209 pCounterValue += -8
3210 addedPValues.append( pCounterValue )
3211 threads.append( t )
3212 t.start()
3213
3214 for t in threads:
3215 t.join()
3216 pCounters.append( t.result )
3217 # Check that counter incremented numController times
3218 pCounterResults = True
3219 for i in addedPValues:
3220 tmpResult = i in pCounters
3221 pCounterResults = pCounterResults and tmpResult
3222 if not tmpResult:
3223 main.log.error( str( i ) + " is not in partitioned "
3224 "counter incremented results" )
3225 utilities.assert_equals( expect=True,
3226 actual=pCounterResults,
3227 onpass="Default counter incremented",
3228 onfail="Error incrementing default" +
3229 " counter" )
3230
3231 main.step( "Add 5 to then get a default counter on each node" )
3232 pCounters = []
3233 threads = []
3234 addedPValues = []
3235 for i in range( main.numCtrls ):
3236 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3237 name="counterIncrement-" + str( i ),
3238 args=[ pCounterName ],
3239 kwargs={ "delta": 5 } )
3240 pCounterValue += 5
3241 addedPValues.append( pCounterValue )
3242 threads.append( t )
3243 t.start()
3244
3245 for t in threads:
3246 t.join()
3247 pCounters.append( t.result )
3248 # Check that counter incremented numController times
3249 pCounterResults = True
3250 for i in addedPValues:
3251 tmpResult = i in pCounters
3252 pCounterResults = pCounterResults and tmpResult
3253 if not tmpResult:
3254 main.log.error( str( i ) + " is not in partitioned "
3255 "counter incremented results" )
3256 utilities.assert_equals( expect=True,
3257 actual=pCounterResults,
3258 onpass="Default counter incremented",
3259 onfail="Error incrementing default" +
3260 " counter" )
3261
3262 main.step( "Get then add 5 to a default counter on each node" )
3263 pCounters = []
3264 threads = []
3265 addedPValues = []
3266 for i in range( main.numCtrls ):
3267 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3268 name="counterIncrement-" + str( i ),
3269 args=[ pCounterName ],
3270 kwargs={ "delta": 5 } )
3271 addedPValues.append( pCounterValue )
3272 pCounterValue += 5
3273 threads.append( t )
3274 t.start()
3275
3276 for t in threads:
3277 t.join()
3278 pCounters.append( t.result )
3279 # Check that counter incremented numController times
3280 pCounterResults = True
3281 for i in addedPValues:
3282 tmpResult = i in pCounters
3283 pCounterResults = pCounterResults and tmpResult
3284 if not tmpResult:
3285 main.log.error( str( i ) + " is not in partitioned "
3286 "counter incremented results" )
3287 utilities.assert_equals( expect=True,
3288 actual=pCounterResults,
3289 onpass="Default counter incremented",
3290 onfail="Error incrementing default" +
3291 " counter" )
3292
3293 main.step( "Counters we added have the correct values" )
3294 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3295 utilities.assert_equals( expect=main.TRUE,
3296 actual=incrementCheck,
3297 onpass="Added counters are correct",
3298 onfail="Added counters are incorrect" )
3299
3300 # In-Memory counters
3301 main.step( "Increment and get an in-memory counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003302 iCounters = []
3303 addedIValues = []
3304 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003305 for i in range( main.numCtrls ):
3306 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003307 name="icounterIncrement-" + str( i ),
3308 args=[ iCounterName ],
3309 kwargs={ "inMemory": True } )
3310 iCounterValue += 1
3311 addedIValues.append( iCounterValue )
3312 threads.append( t )
3313 t.start()
3314
3315 for t in threads:
3316 t.join()
3317 iCounters.append( t.result )
3318 # Check that counter incremented numController times
3319 iCounterResults = True
3320 for i in addedIValues:
3321 tmpResult = i in iCounters
3322 iCounterResults = iCounterResults and tmpResult
3323 if not tmpResult:
3324 main.log.error( str( i ) + " is not in the in-memory "
3325 "counter incremented results" )
3326 utilities.assert_equals( expect=True,
3327 actual=iCounterResults,
Jon Halle1a3b752015-07-22 13:02:46 -07003328 onpass="In-memory counter incremented",
3329 onfail="Error incrementing in-memory" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003330 " counter" )
3331
Jon Halle1a3b752015-07-22 13:02:46 -07003332 main.step( "Get then Increment a in-memory counter on each node" )
3333 iCounters = []
3334 threads = []
3335 addedIValues = []
3336 for i in range( main.numCtrls ):
3337 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3338 name="counterGetAndAdd-" + str( i ),
3339 args=[ iCounterName ],
3340 kwargs={ "inMemory": True } )
3341 addedIValues.append( iCounterValue )
3342 iCounterValue += 1
3343 threads.append( t )
3344 t.start()
3345
3346 for t in threads:
3347 t.join()
3348 iCounters.append( t.result )
3349 # Check that counter incremented numController times
3350 iCounterResults = True
3351 for i in addedIValues:
3352 tmpResult = i in iCounters
3353 iCounterResults = iCounterResults and tmpResult
3354 if not tmpResult:
3355 main.log.error( str( i ) + " is not in in-memory "
3356 "counter incremented results" )
3357 utilities.assert_equals( expect=True,
3358 actual=iCounterResults,
3359 onpass="In-memory counter incremented",
3360 onfail="Error incrementing in-memory" +
3361 " counter" )
3362
3363 main.step( "Counters we added have the correct values" )
3364 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3365 utilities.assert_equals( expect=main.TRUE,
3366 actual=incrementCheck,
3367 onpass="Added counters are correct",
3368 onfail="Added counters are incorrect" )
3369
3370 main.step( "Add -8 to then get a in-memory counter on each node" )
3371 iCounters = []
3372 threads = []
3373 addedIValues = []
3374 for i in range( main.numCtrls ):
3375 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3376 name="counterIncrement-" + str( i ),
3377 args=[ iCounterName ],
3378 kwargs={ "delta": -8, "inMemory": True } )
3379 iCounterValue += -8
3380 addedIValues.append( iCounterValue )
3381 threads.append( t )
3382 t.start()
3383
3384 for t in threads:
3385 t.join()
3386 iCounters.append( t.result )
3387 # Check that counter incremented numController times
3388 iCounterResults = True
3389 for i in addedIValues:
3390 tmpResult = i in iCounters
3391 iCounterResults = iCounterResults and tmpResult
3392 if not tmpResult:
3393 main.log.error( str( i ) + " is not in in-memory "
3394 "counter incremented results" )
3395 utilities.assert_equals( expect=True,
3396 actual=pCounterResults,
3397 onpass="In-memory counter incremented",
3398 onfail="Error incrementing in-memory" +
3399 " counter" )
3400
3401 main.step( "Add 5 to then get a in-memory counter on each node" )
3402 iCounters = []
3403 threads = []
3404 addedIValues = []
3405 for i in range( main.numCtrls ):
3406 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3407 name="counterIncrement-" + str( i ),
3408 args=[ iCounterName ],
3409 kwargs={ "delta": 5, "inMemory": True } )
3410 iCounterValue += 5
3411 addedIValues.append( iCounterValue )
3412 threads.append( t )
3413 t.start()
3414
3415 for t in threads:
3416 t.join()
3417 iCounters.append( t.result )
3418 # Check that counter incremented numController times
3419 iCounterResults = True
3420 for i in addedIValues:
3421 tmpResult = i in iCounters
3422 iCounterResults = iCounterResults and tmpResult
3423 if not tmpResult:
3424 main.log.error( str( i ) + " is not in in-memory "
3425 "counter incremented results" )
3426 utilities.assert_equals( expect=True,
3427 actual=pCounterResults,
3428 onpass="In-memory counter incremented",
3429 onfail="Error incrementing in-memory" +
3430 " counter" )
3431
3432 main.step( "Get then add 5 to a in-memory counter on each node" )
3433 iCounters = []
3434 threads = []
3435 addedIValues = []
3436 for i in range( main.numCtrls ):
3437 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3438 name="counterIncrement-" + str( i ),
3439 args=[ iCounterName ],
3440 kwargs={ "delta": 5, "inMemory": True } )
3441 addedIValues.append( iCounterValue )
3442 iCounterValue += 5
3443 threads.append( t )
3444 t.start()
3445
3446 for t in threads:
3447 t.join()
3448 iCounters.append( t.result )
3449 # Check that counter incremented numController times
3450 iCounterResults = True
3451 for i in addedIValues:
3452 tmpResult = i in iCounters
3453 iCounterResults = iCounterResults and tmpResult
3454 if not tmpResult:
3455 main.log.error( str( i ) + " is not in in-memory "
3456 "counter incremented results" )
3457 utilities.assert_equals( expect=True,
3458 actual=iCounterResults,
3459 onpass="In-memory counter incremented",
3460 onfail="Error incrementing in-memory" +
3461 " counter" )
3462
3463 main.step( "Counters we added have the correct values" )
3464 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3465 utilities.assert_equals( expect=main.TRUE,
3466 actual=incrementCheck,
3467 onpass="Added counters are correct",
3468 onfail="Added counters are incorrect" )
3469
Jon Hall5cf14d52015-07-16 12:15:19 -07003470 main.step( "Check counters are consistant across nodes" )
3471 onosCounters = []
3472 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003473 for i in range( main.numCtrls ):
3474 t = main.Thread( target=main.CLIs[i].counters,
Jon Hall5cf14d52015-07-16 12:15:19 -07003475 name="counters-" + str( i ) )
3476 threads.append( t )
3477 t.start()
3478 for t in threads:
3479 t.join()
3480 onosCounters.append( t.result )
3481 tmp = [ i == onosCounters[ 0 ] for i in onosCounters ]
3482 if all( tmp ):
3483 main.log.info( "Counters are consistent across all nodes" )
3484 consistentCounterResults = main.TRUE
3485 else:
3486 main.log.error( "Counters are not consistent across all nodes" )
3487 consistentCounterResults = main.FALSE
3488 utilities.assert_equals( expect=main.TRUE,
3489 actual=consistentCounterResults,
3490 onpass="ONOS counters are consistent " +
3491 "across nodes",
3492 onfail="ONOS Counters are inconsistent " +
3493 "across nodes" )
3494
3495 main.step( "Counters we added have the correct values" )
Jon Halle1a3b752015-07-22 13:02:46 -07003496 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3497 incrementCheck = incrementCheck and \
3498 main.Counters.counterCheck( iCounterName, iCounterValue )
Jon Hall5cf14d52015-07-16 12:15:19 -07003499 utilities.assert_equals( expect=main.TRUE,
Jon Halle1a3b752015-07-22 13:02:46 -07003500 actual=incrementCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -07003501 onpass="Added counters are correct",
3502 onfail="Added counters are incorrect" )
Jon Halle1a3b752015-07-22 13:02:46 -07003503
Jon Hall5cf14d52015-07-16 12:15:19 -07003504 # DISTRIBUTED SETS
3505 main.step( "Distributed Set get" )
3506 size = len( onosSet )
3507 getResponses = []
3508 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003509 for i in range( main.numCtrls ):
3510 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003511 name="setTestGet-" + str( i ),
3512 args=[ onosSetName ] )
3513 threads.append( t )
3514 t.start()
3515 for t in threads:
3516 t.join()
3517 getResponses.append( t.result )
3518
3519 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003520 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003521 if isinstance( getResponses[ i ], list):
3522 current = set( getResponses[ i ] )
3523 if len( current ) == len( getResponses[ i ] ):
3524 # no repeats
3525 if onosSet != current:
3526 main.log.error( "ONOS" + str( i + 1 ) +
3527 " has incorrect view" +
3528 " of set " + onosSetName + ":\n" +
3529 str( getResponses[ i ] ) )
3530 main.log.debug( "Expected: " + str( onosSet ) )
3531 main.log.debug( "Actual: " + str( current ) )
3532 getResults = main.FALSE
3533 else:
3534 # error, set is not a set
3535 main.log.error( "ONOS" + str( i + 1 ) +
3536 " has repeat elements in" +
3537 " set " + onosSetName + ":\n" +
3538 str( getResponses[ i ] ) )
3539 getResults = main.FALSE
3540 elif getResponses[ i ] == main.ERROR:
3541 getResults = main.FALSE
3542 utilities.assert_equals( expect=main.TRUE,
3543 actual=getResults,
3544 onpass="Set elements are correct",
3545 onfail="Set elements are incorrect" )
3546
3547 main.step( "Distributed Set size" )
3548 sizeResponses = []
3549 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003550 for i in range( main.numCtrls ):
3551 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003552 name="setTestSize-" + str( i ),
3553 args=[ onosSetName ] )
3554 threads.append( t )
3555 t.start()
3556 for t in threads:
3557 t.join()
3558 sizeResponses.append( t.result )
3559
3560 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003561 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003562 if size != sizeResponses[ i ]:
3563 sizeResults = main.FALSE
3564 main.log.error( "ONOS" + str( i + 1 ) +
3565 " expected a size of " + str( size ) +
3566 " for set " + onosSetName +
3567 " but got " + str( sizeResponses[ i ] ) )
3568 utilities.assert_equals( expect=main.TRUE,
3569 actual=sizeResults,
3570 onpass="Set sizes are correct",
3571 onfail="Set sizes are incorrect" )
3572
3573 main.step( "Distributed Set add()" )
3574 onosSet.add( addValue )
3575 addResponses = []
3576 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003577 for i in range( main.numCtrls ):
3578 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003579 name="setTestAdd-" + str( i ),
3580 args=[ onosSetName, addValue ] )
3581 threads.append( t )
3582 t.start()
3583 for t in threads:
3584 t.join()
3585 addResponses.append( t.result )
3586
3587 # main.TRUE = successfully changed the set
3588 # main.FALSE = action resulted in no change in set
3589 # main.ERROR - Some error in executing the function
3590 addResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003591 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003592 if addResponses[ i ] == main.TRUE:
3593 # All is well
3594 pass
3595 elif addResponses[ i ] == main.FALSE:
3596 # Already in set, probably fine
3597 pass
3598 elif addResponses[ i ] == main.ERROR:
3599 # Error in execution
3600 addResults = main.FALSE
3601 else:
3602 # unexpected result
3603 addResults = main.FALSE
3604 if addResults != main.TRUE:
3605 main.log.error( "Error executing set add" )
3606
3607 # Check if set is still correct
3608 size = len( onosSet )
3609 getResponses = []
3610 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003611 for i in range( main.numCtrls ):
3612 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003613 name="setTestGet-" + str( i ),
3614 args=[ onosSetName ] )
3615 threads.append( t )
3616 t.start()
3617 for t in threads:
3618 t.join()
3619 getResponses.append( t.result )
3620 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003621 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003622 if isinstance( getResponses[ i ], list):
3623 current = set( getResponses[ i ] )
3624 if len( current ) == len( getResponses[ i ] ):
3625 # no repeats
3626 if onosSet != current:
3627 main.log.error( "ONOS" + str( i + 1 ) +
3628 " has incorrect view" +
3629 " of set " + onosSetName + ":\n" +
3630 str( getResponses[ i ] ) )
3631 main.log.debug( "Expected: " + str( onosSet ) )
3632 main.log.debug( "Actual: " + str( current ) )
3633 getResults = main.FALSE
3634 else:
3635 # error, set is not a set
3636 main.log.error( "ONOS" + str( i + 1 ) +
3637 " has repeat elements in" +
3638 " set " + onosSetName + ":\n" +
3639 str( getResponses[ i ] ) )
3640 getResults = main.FALSE
3641 elif getResponses[ i ] == main.ERROR:
3642 getResults = main.FALSE
3643 sizeResponses = []
3644 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003645 for i in range( main.numCtrls ):
3646 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003647 name="setTestSize-" + str( i ),
3648 args=[ onosSetName ] )
3649 threads.append( t )
3650 t.start()
3651 for t in threads:
3652 t.join()
3653 sizeResponses.append( t.result )
3654 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003655 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003656 if size != sizeResponses[ i ]:
3657 sizeResults = main.FALSE
3658 main.log.error( "ONOS" + str( i + 1 ) +
3659 " expected a size of " + str( size ) +
3660 " for set " + onosSetName +
3661 " but got " + str( sizeResponses[ i ] ) )
3662 addResults = addResults and getResults and sizeResults
3663 utilities.assert_equals( expect=main.TRUE,
3664 actual=addResults,
3665 onpass="Set add correct",
3666 onfail="Set add was incorrect" )
3667
3668 main.step( "Distributed Set addAll()" )
3669 onosSet.update( addAllValue.split() )
3670 addResponses = []
3671 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003672 for i in range( main.numCtrls ):
3673 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003674 name="setTestAddAll-" + str( i ),
3675 args=[ onosSetName, addAllValue ] )
3676 threads.append( t )
3677 t.start()
3678 for t in threads:
3679 t.join()
3680 addResponses.append( t.result )
3681
3682 # main.TRUE = successfully changed the set
3683 # main.FALSE = action resulted in no change in set
3684 # main.ERROR - Some error in executing the function
3685 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003686 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003687 if addResponses[ i ] == main.TRUE:
3688 # All is well
3689 pass
3690 elif addResponses[ i ] == main.FALSE:
3691 # Already in set, probably fine
3692 pass
3693 elif addResponses[ i ] == main.ERROR:
3694 # Error in execution
3695 addAllResults = main.FALSE
3696 else:
3697 # unexpected result
3698 addAllResults = main.FALSE
3699 if addAllResults != main.TRUE:
3700 main.log.error( "Error executing set addAll" )
3701
3702 # Check if set is still correct
3703 size = len( onosSet )
3704 getResponses = []
3705 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003706 for i in range( main.numCtrls ):
3707 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003708 name="setTestGet-" + str( i ),
3709 args=[ onosSetName ] )
3710 threads.append( t )
3711 t.start()
3712 for t in threads:
3713 t.join()
3714 getResponses.append( t.result )
3715 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003716 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003717 if isinstance( getResponses[ i ], list):
3718 current = set( getResponses[ i ] )
3719 if len( current ) == len( getResponses[ i ] ):
3720 # no repeats
3721 if onosSet != current:
3722 main.log.error( "ONOS" + str( i + 1 ) +
3723 " has incorrect view" +
3724 " of set " + onosSetName + ":\n" +
3725 str( getResponses[ i ] ) )
3726 main.log.debug( "Expected: " + str( onosSet ) )
3727 main.log.debug( "Actual: " + str( current ) )
3728 getResults = main.FALSE
3729 else:
3730 # error, set is not a set
3731 main.log.error( "ONOS" + str( i + 1 ) +
3732 " has repeat elements in" +
3733 " set " + onosSetName + ":\n" +
3734 str( getResponses[ i ] ) )
3735 getResults = main.FALSE
3736 elif getResponses[ i ] == main.ERROR:
3737 getResults = main.FALSE
3738 sizeResponses = []
3739 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003740 for i in range( main.numCtrls ):
3741 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003742 name="setTestSize-" + str( i ),
3743 args=[ onosSetName ] )
3744 threads.append( t )
3745 t.start()
3746 for t in threads:
3747 t.join()
3748 sizeResponses.append( t.result )
3749 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003750 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003751 if size != sizeResponses[ i ]:
3752 sizeResults = main.FALSE
3753 main.log.error( "ONOS" + str( i + 1 ) +
3754 " expected a size of " + str( size ) +
3755 " for set " + onosSetName +
3756 " but got " + str( sizeResponses[ i ] ) )
3757 addAllResults = addAllResults and getResults and sizeResults
3758 utilities.assert_equals( expect=main.TRUE,
3759 actual=addAllResults,
3760 onpass="Set addAll correct",
3761 onfail="Set addAll was incorrect" )
3762
3763 main.step( "Distributed Set contains()" )
3764 containsResponses = []
3765 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003766 for i in range( main.numCtrls ):
3767 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003768 name="setContains-" + str( i ),
3769 args=[ onosSetName ],
3770 kwargs={ "values": addValue } )
3771 threads.append( t )
3772 t.start()
3773 for t in threads:
3774 t.join()
3775 # NOTE: This is the tuple
3776 containsResponses.append( t.result )
3777
3778 containsResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003779 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003780 if containsResponses[ i ] == main.ERROR:
3781 containsResults = main.FALSE
3782 else:
3783 containsResults = containsResults and\
3784 containsResponses[ i ][ 1 ]
3785 utilities.assert_equals( expect=main.TRUE,
3786 actual=containsResults,
3787 onpass="Set contains is functional",
3788 onfail="Set contains failed" )
3789
3790 main.step( "Distributed Set containsAll()" )
3791 containsAllResponses = []
3792 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003793 for i in range( main.numCtrls ):
3794 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003795 name="setContainsAll-" + str( i ),
3796 args=[ onosSetName ],
3797 kwargs={ "values": addAllValue } )
3798 threads.append( t )
3799 t.start()
3800 for t in threads:
3801 t.join()
3802 # NOTE: This is the tuple
3803 containsAllResponses.append( t.result )
3804
3805 containsAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003806 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003807 if containsResponses[ i ] == main.ERROR:
3808 containsResults = main.FALSE
3809 else:
3810 containsResults = containsResults and\
3811 containsResponses[ i ][ 1 ]
3812 utilities.assert_equals( expect=main.TRUE,
3813 actual=containsAllResults,
3814 onpass="Set containsAll is functional",
3815 onfail="Set containsAll failed" )
3816
3817 main.step( "Distributed Set remove()" )
3818 onosSet.remove( addValue )
3819 removeResponses = []
3820 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003821 for i in range( main.numCtrls ):
3822 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003823 name="setTestRemove-" + str( i ),
3824 args=[ onosSetName, addValue ] )
3825 threads.append( t )
3826 t.start()
3827 for t in threads:
3828 t.join()
3829 removeResponses.append( t.result )
3830
3831 # main.TRUE = successfully changed the set
3832 # main.FALSE = action resulted in no change in set
3833 # main.ERROR - Some error in executing the function
3834 removeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003835 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003836 if removeResponses[ i ] == main.TRUE:
3837 # All is well
3838 pass
3839 elif removeResponses[ i ] == main.FALSE:
3840 # not in set, probably fine
3841 pass
3842 elif removeResponses[ i ] == main.ERROR:
3843 # Error in execution
3844 removeResults = main.FALSE
3845 else:
3846 # unexpected result
3847 removeResults = main.FALSE
3848 if removeResults != main.TRUE:
3849 main.log.error( "Error executing set remove" )
3850
3851 # Check if set is still correct
3852 size = len( onosSet )
3853 getResponses = []
3854 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003855 for i in range( main.numCtrls ):
3856 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003857 name="setTestGet-" + str( i ),
3858 args=[ onosSetName ] )
3859 threads.append( t )
3860 t.start()
3861 for t in threads:
3862 t.join()
3863 getResponses.append( t.result )
3864 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003865 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003866 if isinstance( getResponses[ i ], list):
3867 current = set( getResponses[ i ] )
3868 if len( current ) == len( getResponses[ i ] ):
3869 # no repeats
3870 if onosSet != current:
3871 main.log.error( "ONOS" + str( i + 1 ) +
3872 " has incorrect view" +
3873 " of set " + onosSetName + ":\n" +
3874 str( getResponses[ i ] ) )
3875 main.log.debug( "Expected: " + str( onosSet ) )
3876 main.log.debug( "Actual: " + str( current ) )
3877 getResults = main.FALSE
3878 else:
3879 # error, set is not a set
3880 main.log.error( "ONOS" + str( i + 1 ) +
3881 " has repeat elements in" +
3882 " set " + onosSetName + ":\n" +
3883 str( getResponses[ i ] ) )
3884 getResults = main.FALSE
3885 elif getResponses[ i ] == main.ERROR:
3886 getResults = main.FALSE
3887 sizeResponses = []
3888 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003889 for i in range( main.numCtrls ):
3890 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003891 name="setTestSize-" + str( i ),
3892 args=[ onosSetName ] )
3893 threads.append( t )
3894 t.start()
3895 for t in threads:
3896 t.join()
3897 sizeResponses.append( t.result )
3898 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003899 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003900 if size != sizeResponses[ i ]:
3901 sizeResults = main.FALSE
3902 main.log.error( "ONOS" + str( i + 1 ) +
3903 " expected a size of " + str( size ) +
3904 " for set " + onosSetName +
3905 " but got " + str( sizeResponses[ i ] ) )
3906 removeResults = removeResults and getResults and sizeResults
3907 utilities.assert_equals( expect=main.TRUE,
3908 actual=removeResults,
3909 onpass="Set remove correct",
3910 onfail="Set remove was incorrect" )
3911
3912 main.step( "Distributed Set removeAll()" )
3913 onosSet.difference_update( addAllValue.split() )
3914 removeAllResponses = []
3915 threads = []
3916 try:
Jon Halle1a3b752015-07-22 13:02:46 -07003917 for i in range( main.numCtrls ):
3918 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003919 name="setTestRemoveAll-" + str( i ),
3920 args=[ onosSetName, addAllValue ] )
3921 threads.append( t )
3922 t.start()
3923 for t in threads:
3924 t.join()
3925 removeAllResponses.append( t.result )
3926 except Exception, e:
3927 main.log.exception(e)
3928
3929 # main.TRUE = successfully changed the set
3930 # main.FALSE = action resulted in no change in set
3931 # main.ERROR - Some error in executing the function
3932 removeAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003933 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003934 if removeAllResponses[ i ] == main.TRUE:
3935 # All is well
3936 pass
3937 elif removeAllResponses[ i ] == main.FALSE:
3938 # not in set, probably fine
3939 pass
3940 elif removeAllResponses[ i ] == main.ERROR:
3941 # Error in execution
3942 removeAllResults = main.FALSE
3943 else:
3944 # unexpected result
3945 removeAllResults = main.FALSE
3946 if removeAllResults != main.TRUE:
3947 main.log.error( "Error executing set removeAll" )
3948
3949 # Check if set is still correct
3950 size = len( onosSet )
3951 getResponses = []
3952 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003953 for i in range( main.numCtrls ):
3954 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003955 name="setTestGet-" + str( i ),
3956 args=[ onosSetName ] )
3957 threads.append( t )
3958 t.start()
3959 for t in threads:
3960 t.join()
3961 getResponses.append( t.result )
3962 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003963 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003964 if isinstance( getResponses[ i ], list):
3965 current = set( getResponses[ i ] )
3966 if len( current ) == len( getResponses[ i ] ):
3967 # no repeats
3968 if onosSet != current:
3969 main.log.error( "ONOS" + str( i + 1 ) +
3970 " has incorrect view" +
3971 " of set " + onosSetName + ":\n" +
3972 str( getResponses[ i ] ) )
3973 main.log.debug( "Expected: " + str( onosSet ) )
3974 main.log.debug( "Actual: " + str( current ) )
3975 getResults = main.FALSE
3976 else:
3977 # error, set is not a set
3978 main.log.error( "ONOS" + str( i + 1 ) +
3979 " has repeat elements in" +
3980 " set " + onosSetName + ":\n" +
3981 str( getResponses[ i ] ) )
3982 getResults = main.FALSE
3983 elif getResponses[ i ] == main.ERROR:
3984 getResults = main.FALSE
3985 sizeResponses = []
3986 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003987 for i in range( main.numCtrls ):
3988 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003989 name="setTestSize-" + str( i ),
3990 args=[ onosSetName ] )
3991 threads.append( t )
3992 t.start()
3993 for t in threads:
3994 t.join()
3995 sizeResponses.append( t.result )
3996 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003997 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003998 if size != sizeResponses[ i ]:
3999 sizeResults = main.FALSE
4000 main.log.error( "ONOS" + str( i + 1 ) +
4001 " expected a size of " + str( size ) +
4002 " for set " + onosSetName +
4003 " but got " + str( sizeResponses[ i ] ) )
4004 removeAllResults = removeAllResults and getResults and sizeResults
4005 utilities.assert_equals( expect=main.TRUE,
4006 actual=removeAllResults,
4007 onpass="Set removeAll correct",
4008 onfail="Set removeAll was incorrect" )
4009
4010 main.step( "Distributed Set addAll()" )
4011 onosSet.update( addAllValue.split() )
4012 addResponses = []
4013 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004014 for i in range( main.numCtrls ):
4015 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004016 name="setTestAddAll-" + str( i ),
4017 args=[ onosSetName, addAllValue ] )
4018 threads.append( t )
4019 t.start()
4020 for t in threads:
4021 t.join()
4022 addResponses.append( t.result )
4023
4024 # main.TRUE = successfully changed the set
4025 # main.FALSE = action resulted in no change in set
4026 # main.ERROR - Some error in executing the function
4027 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004028 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004029 if addResponses[ i ] == main.TRUE:
4030 # All is well
4031 pass
4032 elif addResponses[ i ] == main.FALSE:
4033 # Already in set, probably fine
4034 pass
4035 elif addResponses[ i ] == main.ERROR:
4036 # Error in execution
4037 addAllResults = main.FALSE
4038 else:
4039 # unexpected result
4040 addAllResults = main.FALSE
4041 if addAllResults != main.TRUE:
4042 main.log.error( "Error executing set addAll" )
4043
4044 # Check if set is still correct
4045 size = len( onosSet )
4046 getResponses = []
4047 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004048 for i in range( main.numCtrls ):
4049 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004050 name="setTestGet-" + str( i ),
4051 args=[ onosSetName ] )
4052 threads.append( t )
4053 t.start()
4054 for t in threads:
4055 t.join()
4056 getResponses.append( t.result )
4057 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004058 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004059 if isinstance( getResponses[ i ], list):
4060 current = set( getResponses[ i ] )
4061 if len( current ) == len( getResponses[ i ] ):
4062 # no repeats
4063 if onosSet != current:
4064 main.log.error( "ONOS" + str( i + 1 ) +
4065 " has incorrect view" +
4066 " of set " + onosSetName + ":\n" +
4067 str( getResponses[ i ] ) )
4068 main.log.debug( "Expected: " + str( onosSet ) )
4069 main.log.debug( "Actual: " + str( current ) )
4070 getResults = main.FALSE
4071 else:
4072 # error, set is not a set
4073 main.log.error( "ONOS" + str( i + 1 ) +
4074 " has repeat elements in" +
4075 " set " + onosSetName + ":\n" +
4076 str( getResponses[ i ] ) )
4077 getResults = main.FALSE
4078 elif getResponses[ i ] == main.ERROR:
4079 getResults = main.FALSE
4080 sizeResponses = []
4081 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004082 for i in range( main.numCtrls ):
4083 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004084 name="setTestSize-" + str( i ),
4085 args=[ onosSetName ] )
4086 threads.append( t )
4087 t.start()
4088 for t in threads:
4089 t.join()
4090 sizeResponses.append( t.result )
4091 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004092 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004093 if size != sizeResponses[ i ]:
4094 sizeResults = main.FALSE
4095 main.log.error( "ONOS" + str( i + 1 ) +
4096 " expected a size of " + str( size ) +
4097 " for set " + onosSetName +
4098 " but got " + str( sizeResponses[ i ] ) )
4099 addAllResults = addAllResults and getResults and sizeResults
4100 utilities.assert_equals( expect=main.TRUE,
4101 actual=addAllResults,
4102 onpass="Set addAll correct",
4103 onfail="Set addAll was incorrect" )
4104
4105 main.step( "Distributed Set clear()" )
4106 onosSet.clear()
4107 clearResponses = []
4108 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004109 for i in range( main.numCtrls ):
4110 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004111 name="setTestClear-" + str( i ),
4112 args=[ onosSetName, " "], # Values doesn't matter
4113 kwargs={ "clear": True } )
4114 threads.append( t )
4115 t.start()
4116 for t in threads:
4117 t.join()
4118 clearResponses.append( t.result )
4119
4120 # main.TRUE = successfully changed the set
4121 # main.FALSE = action resulted in no change in set
4122 # main.ERROR - Some error in executing the function
4123 clearResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004124 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004125 if clearResponses[ i ] == main.TRUE:
4126 # All is well
4127 pass
4128 elif clearResponses[ i ] == main.FALSE:
4129 # Nothing set, probably fine
4130 pass
4131 elif clearResponses[ i ] == main.ERROR:
4132 # Error in execution
4133 clearResults = main.FALSE
4134 else:
4135 # unexpected result
4136 clearResults = main.FALSE
4137 if clearResults != main.TRUE:
4138 main.log.error( "Error executing set clear" )
4139
4140 # Check if set is still correct
4141 size = len( onosSet )
4142 getResponses = []
4143 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004144 for i in range( main.numCtrls ):
4145 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004146 name="setTestGet-" + str( i ),
4147 args=[ onosSetName ] )
4148 threads.append( t )
4149 t.start()
4150 for t in threads:
4151 t.join()
4152 getResponses.append( t.result )
4153 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004154 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004155 if isinstance( getResponses[ i ], list):
4156 current = set( getResponses[ i ] )
4157 if len( current ) == len( getResponses[ i ] ):
4158 # no repeats
4159 if onosSet != current:
4160 main.log.error( "ONOS" + str( i + 1 ) +
4161 " has incorrect view" +
4162 " of set " + onosSetName + ":\n" +
4163 str( getResponses[ i ] ) )
4164 main.log.debug( "Expected: " + str( onosSet ) )
4165 main.log.debug( "Actual: " + str( current ) )
4166 getResults = main.FALSE
4167 else:
4168 # error, set is not a set
4169 main.log.error( "ONOS" + str( i + 1 ) +
4170 " has repeat elements in" +
4171 " set " + onosSetName + ":\n" +
4172 str( getResponses[ i ] ) )
4173 getResults = main.FALSE
4174 elif getResponses[ i ] == main.ERROR:
4175 getResults = main.FALSE
4176 sizeResponses = []
4177 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004178 for i in range( main.numCtrls ):
4179 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004180 name="setTestSize-" + str( i ),
4181 args=[ onosSetName ] )
4182 threads.append( t )
4183 t.start()
4184 for t in threads:
4185 t.join()
4186 sizeResponses.append( t.result )
4187 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004188 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004189 if size != sizeResponses[ i ]:
4190 sizeResults = main.FALSE
4191 main.log.error( "ONOS" + str( i + 1 ) +
4192 " expected a size of " + str( size ) +
4193 " for set " + onosSetName +
4194 " but got " + str( sizeResponses[ i ] ) )
4195 clearResults = clearResults and getResults and sizeResults
4196 utilities.assert_equals( expect=main.TRUE,
4197 actual=clearResults,
4198 onpass="Set clear correct",
4199 onfail="Set clear was incorrect" )
4200
4201 main.step( "Distributed Set addAll()" )
4202 onosSet.update( addAllValue.split() )
4203 addResponses = []
4204 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004205 for i in range( main.numCtrls ):
4206 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004207 name="setTestAddAll-" + str( i ),
4208 args=[ onosSetName, addAllValue ] )
4209 threads.append( t )
4210 t.start()
4211 for t in threads:
4212 t.join()
4213 addResponses.append( t.result )
4214
4215 # main.TRUE = successfully changed the set
4216 # main.FALSE = action resulted in no change in set
4217 # main.ERROR - Some error in executing the function
4218 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004219 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004220 if addResponses[ i ] == main.TRUE:
4221 # All is well
4222 pass
4223 elif addResponses[ i ] == main.FALSE:
4224 # Already in set, probably fine
4225 pass
4226 elif addResponses[ i ] == main.ERROR:
4227 # Error in execution
4228 addAllResults = main.FALSE
4229 else:
4230 # unexpected result
4231 addAllResults = main.FALSE
4232 if addAllResults != main.TRUE:
4233 main.log.error( "Error executing set addAll" )
4234
4235 # Check if set is still correct
4236 size = len( onosSet )
4237 getResponses = []
4238 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004239 for i in range( main.numCtrls ):
4240 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004241 name="setTestGet-" + str( i ),
4242 args=[ onosSetName ] )
4243 threads.append( t )
4244 t.start()
4245 for t in threads:
4246 t.join()
4247 getResponses.append( t.result )
4248 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004249 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004250 if isinstance( getResponses[ i ], list):
4251 current = set( getResponses[ i ] )
4252 if len( current ) == len( getResponses[ i ] ):
4253 # no repeats
4254 if onosSet != current:
4255 main.log.error( "ONOS" + str( i + 1 ) +
4256 " has incorrect view" +
4257 " of set " + onosSetName + ":\n" +
4258 str( getResponses[ i ] ) )
4259 main.log.debug( "Expected: " + str( onosSet ) )
4260 main.log.debug( "Actual: " + str( current ) )
4261 getResults = main.FALSE
4262 else:
4263 # error, set is not a set
4264 main.log.error( "ONOS" + str( i + 1 ) +
4265 " has repeat elements in" +
4266 " set " + onosSetName + ":\n" +
4267 str( getResponses[ i ] ) )
4268 getResults = main.FALSE
4269 elif getResponses[ i ] == main.ERROR:
4270 getResults = main.FALSE
4271 sizeResponses = []
4272 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004273 for i in range( main.numCtrls ):
4274 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004275 name="setTestSize-" + str( i ),
4276 args=[ onosSetName ] )
4277 threads.append( t )
4278 t.start()
4279 for t in threads:
4280 t.join()
4281 sizeResponses.append( t.result )
4282 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004283 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004284 if size != sizeResponses[ i ]:
4285 sizeResults = main.FALSE
4286 main.log.error( "ONOS" + str( i + 1 ) +
4287 " expected a size of " + str( size ) +
4288 " for set " + onosSetName +
4289 " but got " + str( sizeResponses[ i ] ) )
4290 addAllResults = addAllResults and getResults and sizeResults
4291 utilities.assert_equals( expect=main.TRUE,
4292 actual=addAllResults,
4293 onpass="Set addAll correct",
4294 onfail="Set addAll was incorrect" )
4295
4296 main.step( "Distributed Set retain()" )
4297 onosSet.intersection_update( retainValue.split() )
4298 retainResponses = []
4299 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004300 for i in range( main.numCtrls ):
4301 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004302 name="setTestRetain-" + str( i ),
4303 args=[ onosSetName, retainValue ],
4304 kwargs={ "retain": True } )
4305 threads.append( t )
4306 t.start()
4307 for t in threads:
4308 t.join()
4309 retainResponses.append( t.result )
4310
4311 # main.TRUE = successfully changed the set
4312 # main.FALSE = action resulted in no change in set
4313 # main.ERROR - Some error in executing the function
4314 retainResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004315 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004316 if retainResponses[ i ] == main.TRUE:
4317 # All is well
4318 pass
4319 elif retainResponses[ i ] == main.FALSE:
4320 # Already in set, probably fine
4321 pass
4322 elif retainResponses[ i ] == main.ERROR:
4323 # Error in execution
4324 retainResults = main.FALSE
4325 else:
4326 # unexpected result
4327 retainResults = main.FALSE
4328 if retainResults != main.TRUE:
4329 main.log.error( "Error executing set retain" )
4330
4331 # Check if set is still correct
4332 size = len( onosSet )
4333 getResponses = []
4334 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004335 for i in range( main.numCtrls ):
4336 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004337 name="setTestGet-" + str( i ),
4338 args=[ onosSetName ] )
4339 threads.append( t )
4340 t.start()
4341 for t in threads:
4342 t.join()
4343 getResponses.append( t.result )
4344 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004345 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004346 if isinstance( getResponses[ i ], list):
4347 current = set( getResponses[ i ] )
4348 if len( current ) == len( getResponses[ i ] ):
4349 # no repeats
4350 if onosSet != current:
4351 main.log.error( "ONOS" + str( i + 1 ) +
4352 " has incorrect view" +
4353 " of set " + onosSetName + ":\n" +
4354 str( getResponses[ i ] ) )
4355 main.log.debug( "Expected: " + str( onosSet ) )
4356 main.log.debug( "Actual: " + str( current ) )
4357 getResults = main.FALSE
4358 else:
4359 # error, set is not a set
4360 main.log.error( "ONOS" + str( i + 1 ) +
4361 " has repeat elements in" +
4362 " set " + onosSetName + ":\n" +
4363 str( getResponses[ i ] ) )
4364 getResults = main.FALSE
4365 elif getResponses[ i ] == main.ERROR:
4366 getResults = main.FALSE
4367 sizeResponses = []
4368 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004369 for i in range( main.numCtrls ):
4370 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004371 name="setTestSize-" + str( i ),
4372 args=[ onosSetName ] )
4373 threads.append( t )
4374 t.start()
4375 for t in threads:
4376 t.join()
4377 sizeResponses.append( t.result )
4378 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004379 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004380 if size != sizeResponses[ i ]:
4381 sizeResults = main.FALSE
4382 main.log.error( "ONOS" + str( i + 1 ) +
4383 " expected a size of " +
4384 str( size ) + " for set " + onosSetName +
4385 " but got " + str( sizeResponses[ i ] ) )
4386 retainResults = retainResults and getResults and sizeResults
4387 utilities.assert_equals( expect=main.TRUE,
4388 actual=retainResults,
4389 onpass="Set retain correct",
4390 onfail="Set retain was incorrect" )
4391
Jon Hall2a5002c2015-08-21 16:49:11 -07004392 # Transactional maps
4393 main.step( "Partitioned Transactional maps put" )
4394 tMapValue = "Testing"
4395 numKeys = 100
4396 putResult = True
4397 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue )
4398 if len( putResponses ) == 100:
4399 for i in putResponses:
4400 if putResponses[ i ][ 'value' ] != tMapValue:
4401 putResult = False
4402 else:
4403 putResult = False
4404 if not putResult:
4405 main.log.debug( "Put response values: " + str( putResponses ) )
4406 utilities.assert_equals( expect=True,
4407 actual=putResult,
4408 onpass="Partitioned Transactional Map put successful",
4409 onfail="Partitioned Transactional Map put values are incorrect" )
4410
4411 main.step( "Partitioned Transactional maps get" )
4412 getCheck = True
4413 for n in range( 1, numKeys + 1 ):
4414 getResponses = []
4415 threads = []
4416 valueCheck = True
4417 for i in range( main.numCtrls ):
4418 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4419 name="TMap-get-" + str( i ),
4420 args=[ "Key" + str ( n ) ] )
4421 threads.append( t )
4422 t.start()
4423 for t in threads:
4424 t.join()
4425 getResponses.append( t.result )
4426 for node in getResponses:
4427 if node != tMapValue:
4428 valueCheck = False
4429 if not valueCheck:
4430 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4431 main.log.warn( getResponses )
4432 getCheck = getCheck and valueCheck
4433 utilities.assert_equals( expect=True,
4434 actual=getCheck,
4435 onpass="Partitioned Transactional Map get values were correct",
4436 onfail="Partitioned Transactional Map values incorrect" )
4437
4438 main.step( "In-memory Transactional maps put" )
4439 tMapValue = "Testing"
4440 numKeys = 100
4441 putResult = True
4442 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue, inMemory=True )
4443 if len( putResponses ) == 100:
4444 for i in putResponses:
4445 if putResponses[ i ][ 'value' ] != tMapValue:
4446 putResult = False
4447 else:
4448 putResult = False
4449 if not putResult:
4450 main.log.debug( "Put response values: " + str( putResponses ) )
4451 utilities.assert_equals( expect=True,
4452 actual=putResult,
4453 onpass="In-Memory Transactional Map put successful",
4454 onfail="In-Memory Transactional Map put values are incorrect" )
4455
4456 main.step( "In-Memory Transactional maps get" )
4457 getCheck = True
4458 for n in range( 1, numKeys + 1 ):
4459 getResponses = []
4460 threads = []
4461 valueCheck = True
4462 for i in range( main.numCtrls ):
4463 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4464 name="TMap-get-" + str( i ),
4465 args=[ "Key" + str ( n ) ],
4466 kwargs={ "inMemory": True } )
4467 threads.append( t )
4468 t.start()
4469 for t in threads:
4470 t.join()
4471 getResponses.append( t.result )
4472 for node in getResponses:
4473 if node != tMapValue:
4474 valueCheck = False
4475 if not valueCheck:
4476 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4477 main.log.warn( getResponses )
4478 getCheck = getCheck and valueCheck
4479 utilities.assert_equals( expect=True,
4480 actual=getCheck,
4481 onpass="In-Memory Transactional Map get values were correct",
4482 onfail="In-Memory Transactional Map values incorrect" )