blob: 1abca54de251d41f7490495fd0ebfabf8d860684 [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
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001720 main.step( "Checking ONOS Logs for errors" )
1721 for node in main.nodes:
1722 main.log.debug( "Checking logs for errors on " + node.name + ":" )
1723 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
1724
Jon Hall5cf14d52015-07-16 12:15:19 -07001725 main.step( "Killing ONOS nodes" )
1726 killResults = main.TRUE
1727 killTime = time.time()
Jon Halle1a3b752015-07-22 13:02:46 -07001728 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001729 killed = main.ONOSbench.onosKill( node.ip_address )
1730 killResults = killResults and killed
1731 utilities.assert_equals( expect=main.TRUE, actual=killResults,
1732 onpass="ONOS nodes killed",
1733 onfail="ONOS kill unsuccessful" )
1734
1735 main.step( "Checking if ONOS is up yet" )
1736 for i in range( 2 ):
1737 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001738 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001739 started = main.ONOSbench.isup( node.ip_address )
1740 if not started:
1741 main.log.error( node.name + " didn't start!" )
1742 onosIsupResult = onosIsupResult and started
1743 if onosIsupResult == main.TRUE:
1744 break
1745 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1746 onpass="ONOS restarted",
1747 onfail="ONOS restart NOT successful" )
1748
1749 main.log.step( "Starting ONOS CLI sessions" )
1750 cliResults = main.TRUE
1751 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001752 for i in range( main.numCtrls ):
1753 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -07001754 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -07001755 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -07001756 threads.append( t )
1757 t.start()
1758
1759 for t in threads:
1760 t.join()
1761 cliResults = cliResults and t.result
1762 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1763 onpass="ONOS cli started",
1764 onfail="ONOS clis did not restart" )
1765
1766 # Grab the time of restart so we chan check how long the gossip
1767 # protocol has had time to work
1768 main.restartTime = time.time() - killTime
1769 main.log.debug( "Restart time: " + str( main.restartTime ) )
1770 labels.append( "Restart" )
1771 data.append( str( main.restartTime ) )
1772
1773 # FIXME: revisit test plan for election with madan
1774 # Rerun for election on restarted nodes
1775 runResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001776 for cli in main.CLIs:
1777 run = main.CLIs[0].electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07001778 if run != main.TRUE:
1779 main.log.error( "Error running for election on " + cli.name )
1780 runResults = runResults and run
1781 utilities.assert_equals( expect=main.TRUE, actual=runResults,
1782 onpass="Reran for election",
1783 onfail="Failed to rerun for election" )
1784
1785 # TODO: Make this configurable
1786 time.sleep( 60 )
Jon Halle1a3b752015-07-22 13:02:46 -07001787 main.log.debug( main.CLIs[0].nodes( jsonFormat=False ) )
1788 main.log.debug( main.CLIs[0].leaders( jsonFormat=False ) )
1789 main.log.debug( main.CLIs[0].partitions( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001790
1791 def CASE7( self, main ):
1792 """
1793 Check state after ONOS failure
1794 """
1795 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001796 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001797 assert main, "main not defined"
1798 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001799 assert main.CLIs, "main.CLIs not defined"
1800 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001801 main.case( "Running ONOS Constant State Tests" )
1802
1803 main.step( "Check that each switch has a master" )
1804 # Assert that each device has a master
1805 rolesNotNull = main.TRUE
1806 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001807 for i in range( main.numCtrls ):
1808 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001809 name="rolesNotNull-" + str( i ),
1810 args=[ ] )
1811 threads.append( t )
1812 t.start()
1813
1814 for t in threads:
1815 t.join()
1816 rolesNotNull = rolesNotNull and t.result
1817 utilities.assert_equals(
1818 expect=main.TRUE,
1819 actual=rolesNotNull,
1820 onpass="Each device has a master",
1821 onfail="Some devices don't have a master assigned" )
1822
1823 main.step( "Read device roles from ONOS" )
1824 ONOSMastership = []
1825 mastershipCheck = main.FALSE
1826 consistentMastership = True
1827 rolesResults = True
1828 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001829 for i in range( main.numCtrls ):
1830 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001831 name="roles-" + str( i ),
1832 args=[] )
1833 threads.append( t )
1834 t.start()
1835
1836 for t in threads:
1837 t.join()
1838 ONOSMastership.append( t.result )
1839
Jon Halle1a3b752015-07-22 13:02:46 -07001840 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001841 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1842 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1843 " roles" )
1844 main.log.warn(
1845 "ONOS" + str( i + 1 ) + " mastership response: " +
1846 repr( ONOSMastership[i] ) )
1847 rolesResults = False
1848 utilities.assert_equals(
1849 expect=True,
1850 actual=rolesResults,
1851 onpass="No error in reading roles output",
1852 onfail="Error in reading roles from ONOS" )
1853
1854 main.step( "Check for consistency in roles from each controller" )
1855 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1856 main.log.info(
1857 "Switch roles are consistent across all ONOS nodes" )
1858 else:
1859 consistentMastership = False
1860 utilities.assert_equals(
1861 expect=True,
1862 actual=consistentMastership,
1863 onpass="Switch roles are consistent across all ONOS nodes",
1864 onfail="ONOS nodes have different views of switch roles" )
1865
1866 if rolesResults and not consistentMastership:
Jon Halle1a3b752015-07-22 13:02:46 -07001867 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001868 main.log.warn(
1869 "ONOS" + str( i + 1 ) + " roles: ",
1870 json.dumps(
1871 json.loads( ONOSMastership[ i ] ),
1872 sort_keys=True,
1873 indent=4,
1874 separators=( ',', ': ' ) ) )
1875 elif rolesResults and not consistentMastership:
1876 mastershipCheck = main.TRUE
1877
1878 '''
1879 description2 = "Compare switch roles from before failure"
1880 main.step( description2 )
1881 try:
1882 currentJson = json.loads( ONOSMastership[0] )
1883 oldJson = json.loads( mastershipState )
1884 except ( ValueError, TypeError ):
1885 main.log.exception( "Something is wrong with parsing " +
1886 "ONOSMastership[0] or mastershipState" )
1887 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1888 main.log.error( "mastershipState" + repr( mastershipState ) )
1889 main.cleanup()
1890 main.exit()
1891 mastershipCheck = main.TRUE
1892 for i in range( 1, 29 ):
1893 switchDPID = str(
1894 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
1895 current = [ switch[ 'master' ] for switch in currentJson
1896 if switchDPID in switch[ 'id' ] ]
1897 old = [ switch[ 'master' ] for switch in oldJson
1898 if switchDPID in switch[ 'id' ] ]
1899 if current == old:
1900 mastershipCheck = mastershipCheck and main.TRUE
1901 else:
1902 main.log.warn( "Mastership of switch %s changed" % switchDPID )
1903 mastershipCheck = main.FALSE
1904 utilities.assert_equals(
1905 expect=main.TRUE,
1906 actual=mastershipCheck,
1907 onpass="Mastership of Switches was not changed",
1908 onfail="Mastership of some switches changed" )
1909 '''
1910 # NOTE: we expect mastership to change on controller failure
1911
1912 main.step( "Get the intents and compare across all nodes" )
1913 ONOSIntents = []
1914 intentCheck = main.FALSE
1915 consistentIntents = True
1916 intentsResults = True
1917 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001918 for i in range( main.numCtrls ):
1919 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001920 name="intents-" + str( i ),
1921 args=[],
1922 kwargs={ 'jsonFormat': True } )
1923 threads.append( t )
1924 t.start()
1925
1926 for t in threads:
1927 t.join()
1928 ONOSIntents.append( t.result )
1929
Jon Halle1a3b752015-07-22 13:02:46 -07001930 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001931 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1932 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1933 " intents" )
1934 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1935 repr( ONOSIntents[ i ] ) )
1936 intentsResults = False
1937 utilities.assert_equals(
1938 expect=True,
1939 actual=intentsResults,
1940 onpass="No error in reading intents output",
1941 onfail="Error in reading intents from ONOS" )
1942
1943 main.step( "Check for consistency in Intents from each controller" )
1944 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1945 main.log.info( "Intents are consistent across all ONOS " +
1946 "nodes" )
1947 else:
1948 consistentIntents = False
1949
1950 # Try to make it easy to figure out what is happening
1951 #
1952 # Intent ONOS1 ONOS2 ...
1953 # 0x01 INSTALLED INSTALLING
1954 # ... ... ...
1955 # ... ... ...
1956 title = " ID"
Jon Halle1a3b752015-07-22 13:02:46 -07001957 for n in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001958 title += " " * 10 + "ONOS" + str( n + 1 )
1959 main.log.warn( title )
1960 # get all intent keys in the cluster
1961 keys = []
1962 for nodeStr in ONOSIntents:
1963 node = json.loads( nodeStr )
1964 for intent in node:
1965 keys.append( intent.get( 'id' ) )
1966 keys = set( keys )
1967 for key in keys:
1968 row = "%-13s" % key
1969 for nodeStr in ONOSIntents:
1970 node = json.loads( nodeStr )
1971 for intent in node:
1972 if intent.get( 'id' ) == key:
1973 row += "%-15s" % intent.get( 'state' )
1974 main.log.warn( row )
1975 # End table view
1976
1977 utilities.assert_equals(
1978 expect=True,
1979 actual=consistentIntents,
1980 onpass="Intents are consistent across all ONOS nodes",
1981 onfail="ONOS nodes have different views of intents" )
1982 intentStates = []
1983 for node in ONOSIntents: # Iter through ONOS nodes
1984 nodeStates = []
1985 # Iter through intents of a node
1986 try:
1987 for intent in json.loads( node ):
1988 nodeStates.append( intent[ 'state' ] )
1989 except ( ValueError, TypeError ):
1990 main.log.exception( "Error in parsing intents" )
1991 main.log.error( repr( node ) )
1992 intentStates.append( nodeStates )
1993 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1994 main.log.info( dict( out ) )
1995
1996 if intentsResults and not consistentIntents:
Jon Halle1a3b752015-07-22 13:02:46 -07001997 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001998 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1999 main.log.warn( json.dumps(
2000 json.loads( ONOSIntents[ i ] ),
2001 sort_keys=True,
2002 indent=4,
2003 separators=( ',', ': ' ) ) )
2004 elif intentsResults and consistentIntents:
2005 intentCheck = main.TRUE
2006
2007 # NOTE: Store has no durability, so intents are lost across system
2008 # restarts
2009 """
2010 main.step( "Compare current intents with intents before the failure" )
2011 # NOTE: this requires case 5 to pass for intentState to be set.
2012 # maybe we should stop the test if that fails?
2013 sameIntents = main.FALSE
2014 if intentState and intentState == ONOSIntents[ 0 ]:
2015 sameIntents = main.TRUE
2016 main.log.info( "Intents are consistent with before failure" )
2017 # TODO: possibly the states have changed? we may need to figure out
2018 # what the acceptable states are
2019 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
2020 sameIntents = main.TRUE
2021 try:
2022 before = json.loads( intentState )
2023 after = json.loads( ONOSIntents[ 0 ] )
2024 for intent in before:
2025 if intent not in after:
2026 sameIntents = main.FALSE
2027 main.log.debug( "Intent is not currently in ONOS " +
2028 "(at least in the same form):" )
2029 main.log.debug( json.dumps( intent ) )
2030 except ( ValueError, TypeError ):
2031 main.log.exception( "Exception printing intents" )
2032 main.log.debug( repr( ONOSIntents[0] ) )
2033 main.log.debug( repr( intentState ) )
2034 if sameIntents == main.FALSE:
2035 try:
2036 main.log.debug( "ONOS intents before: " )
2037 main.log.debug( json.dumps( json.loads( intentState ),
2038 sort_keys=True, indent=4,
2039 separators=( ',', ': ' ) ) )
2040 main.log.debug( "Current ONOS intents: " )
2041 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
2042 sort_keys=True, indent=4,
2043 separators=( ',', ': ' ) ) )
2044 except ( ValueError, TypeError ):
2045 main.log.exception( "Exception printing intents" )
2046 main.log.debug( repr( ONOSIntents[0] ) )
2047 main.log.debug( repr( intentState ) )
2048 utilities.assert_equals(
2049 expect=main.TRUE,
2050 actual=sameIntents,
2051 onpass="Intents are consistent with before failure",
2052 onfail="The Intents changed during failure" )
2053 intentCheck = intentCheck and sameIntents
2054 """
2055 main.step( "Get the OF Table entries and compare to before " +
2056 "component failure" )
2057 FlowTables = main.TRUE
2058 flows2 = []
2059 for i in range( 28 ):
2060 main.log.info( "Checking flow table on s" + str( i + 1 ) )
Jon Hall9043c902015-07-30 14:23:44 -07002061 tmpFlows = main.Mininet1.getFlowTable( 1.3, "s" + str( i + 1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002062 flows2.append( tmpFlows )
Jon Hall9043c902015-07-30 14:23:44 -07002063 tempResult = main.Mininet1.flowComp(
Jon Hall5cf14d52015-07-16 12:15:19 -07002064 flow1=flows[ i ],
2065 flow2=tmpFlows )
2066 FlowTables = FlowTables and tempResult
2067 if FlowTables == main.FALSE:
2068 main.log.info( "Differences in flow table for switch: s" +
2069 str( i + 1 ) )
2070 utilities.assert_equals(
2071 expect=main.TRUE,
2072 actual=FlowTables,
2073 onpass="No changes were found in the flow tables",
2074 onfail="Changes were found in the flow tables" )
2075
2076 main.Mininet2.pingLongKill()
2077 '''
2078 # main.step( "Check the continuous pings to ensure that no packets " +
2079 # "were dropped during component failure" )
2080 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
2081 main.params[ 'TESTONIP' ] )
2082 LossInPings = main.FALSE
2083 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
2084 for i in range( 8, 18 ):
2085 main.log.info(
2086 "Checking for a loss in pings along flow from s" +
2087 str( i ) )
2088 LossInPings = main.Mininet2.checkForLoss(
2089 "/tmp/ping.h" +
2090 str( i ) ) or LossInPings
2091 if LossInPings == main.TRUE:
2092 main.log.info( "Loss in ping detected" )
2093 elif LossInPings == main.ERROR:
2094 main.log.info( "There are multiple mininet process running" )
2095 elif LossInPings == main.FALSE:
2096 main.log.info( "No Loss in the pings" )
2097 main.log.info( "No loss of dataplane connectivity" )
2098 # utilities.assert_equals(
2099 # expect=main.FALSE,
2100 # actual=LossInPings,
2101 # onpass="No Loss of connectivity",
2102 # onfail="Loss of dataplane connectivity detected" )
2103
2104 # NOTE: Since intents are not persisted with IntnentStore,
2105 # we expect loss in dataplane connectivity
2106 LossInPings = main.FALSE
2107 '''
2108
2109 main.step( "Leadership Election is still functional" )
2110 # Test of LeadershipElection
2111 leaderList = []
2112 leaderResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002113 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002114 leaderN = cli.electionTestLeader()
2115 leaderList.append( leaderN )
2116 if leaderN == main.FALSE:
2117 # error in response
2118 main.log.error( "Something is wrong with " +
2119 "electionTestLeader function, check the" +
2120 " error logs" )
2121 leaderResult = main.FALSE
2122 elif leaderN is None:
2123 main.log.error( cli.name +
2124 " shows no leader for the election-app." )
2125 leaderResult = main.FALSE
2126 if len( set( leaderList ) ) != 1:
2127 leaderResult = main.FALSE
2128 main.log.error(
2129 "Inconsistent view of leader for the election test app" )
2130 # TODO: print the list
2131 utilities.assert_equals(
2132 expect=main.TRUE,
2133 actual=leaderResult,
2134 onpass="Leadership election passed",
2135 onfail="Something went wrong with Leadership election" )
2136
2137 def CASE8( self, main ):
2138 """
2139 Compare topo
2140 """
2141 import json
2142 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002143 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002144 assert main, "main not defined"
2145 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002146 assert main.CLIs, "main.CLIs not defined"
2147 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002148
2149 main.case( "Compare ONOS Topology view to Mininet topology" )
Jon Hall783bbf92015-07-23 14:33:19 -07002150 main.caseExplanation = "Compare topology objects between Mininet" +\
Jon Hall5cf14d52015-07-16 12:15:19 -07002151 " and ONOS"
2152
2153 main.step( "Comparing ONOS topology to MN" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002154 topoResult = main.FALSE
2155 elapsed = 0
2156 count = 0
2157 main.step( "Collecting topology information from ONOS" )
2158 startTime = time.time()
2159 # Give time for Gossip to work
2160 while topoResult == main.FALSE and elapsed < 60:
Jon Hallba609822015-09-18 12:00:21 -07002161 devicesResults = main.TRUE
2162 linksResults = main.TRUE
2163 hostsResults = main.TRUE
2164 hostAttachmentResults = True
Jon Hall5cf14d52015-07-16 12:15:19 -07002165 count += 1
2166 cliStart = time.time()
2167 devices = []
2168 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002169 for i in range( main.numCtrls ):
2170 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07002171 name="devices-" + str( i ),
2172 args=[ ] )
2173 threads.append( t )
2174 t.start()
2175
2176 for t in threads:
2177 t.join()
2178 devices.append( t.result )
2179 hosts = []
2180 ipResult = main.TRUE
2181 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002182 for i in range( main.numCtrls ):
2183 t = main.Thread( target=main.CLIs[i].hosts,
Jon Hall5cf14d52015-07-16 12:15:19 -07002184 name="hosts-" + str( i ),
2185 args=[ ] )
2186 threads.append( t )
2187 t.start()
2188
2189 for t in threads:
2190 t.join()
2191 try:
2192 hosts.append( json.loads( t.result ) )
2193 except ( ValueError, TypeError ):
2194 main.log.exception( "Error parsing hosts results" )
2195 main.log.error( repr( t.result ) )
2196 for controller in range( 0, len( hosts ) ):
2197 controllerStr = str( controller + 1 )
2198 for host in hosts[ controller ]:
2199 if host is None or host.get( 'ipAddresses', [] ) == []:
2200 main.log.error(
2201 "DEBUG:Error with host ipAddresses on controller" +
2202 controllerStr + ": " + str( host ) )
2203 ipResult = main.FALSE
2204 ports = []
2205 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002206 for i in range( main.numCtrls ):
2207 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07002208 name="ports-" + str( i ),
2209 args=[ ] )
2210 threads.append( t )
2211 t.start()
2212
2213 for t in threads:
2214 t.join()
2215 ports.append( t.result )
2216 links = []
2217 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002218 for i in range( main.numCtrls ):
2219 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07002220 name="links-" + str( i ),
2221 args=[ ] )
2222 threads.append( t )
2223 t.start()
2224
2225 for t in threads:
2226 t.join()
2227 links.append( t.result )
2228 clusters = []
2229 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002230 for i in range( main.numCtrls ):
2231 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07002232 name="clusters-" + str( i ),
2233 args=[ ] )
2234 threads.append( t )
2235 t.start()
2236
2237 for t in threads:
2238 t.join()
2239 clusters.append( t.result )
2240
2241 elapsed = time.time() - startTime
2242 cliTime = time.time() - cliStart
2243 print "Elapsed time: " + str( elapsed )
2244 print "CLI time: " + str( cliTime )
2245
2246 mnSwitches = main.Mininet1.getSwitches()
2247 mnLinks = main.Mininet1.getLinks()
2248 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07002249 for controller in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07002250 controllerStr = str( controller + 1 )
2251 if devices[ controller ] and ports[ controller ] and\
2252 "Error" not in devices[ controller ] and\
2253 "Error" not in ports[ controller ]:
2254
2255 currentDevicesResult = main.Mininet1.compareSwitches(
2256 mnSwitches,
2257 json.loads( devices[ controller ] ),
2258 json.loads( ports[ controller ] ) )
2259 else:
2260 currentDevicesResult = main.FALSE
2261 utilities.assert_equals( expect=main.TRUE,
2262 actual=currentDevicesResult,
2263 onpass="ONOS" + controllerStr +
2264 " Switches view is correct",
2265 onfail="ONOS" + controllerStr +
2266 " Switches view is incorrect" )
2267
2268 if links[ controller ] and "Error" not in links[ controller ]:
2269 currentLinksResult = main.Mininet1.compareLinks(
2270 mnSwitches, mnLinks,
2271 json.loads( links[ controller ] ) )
2272 else:
2273 currentLinksResult = main.FALSE
2274 utilities.assert_equals( expect=main.TRUE,
2275 actual=currentLinksResult,
2276 onpass="ONOS" + controllerStr +
2277 " links view is correct",
2278 onfail="ONOS" + controllerStr +
2279 " links view is incorrect" )
2280
2281 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2282 currentHostsResult = main.Mininet1.compareHosts(
2283 mnHosts,
2284 hosts[ controller ] )
2285 else:
2286 currentHostsResult = main.FALSE
2287 utilities.assert_equals( expect=main.TRUE,
2288 actual=currentHostsResult,
2289 onpass="ONOS" + controllerStr +
2290 " hosts exist in Mininet",
2291 onfail="ONOS" + controllerStr +
2292 " hosts don't match Mininet" )
2293 # CHECKING HOST ATTACHMENT POINTS
2294 hostAttachment = True
2295 noHosts = False
2296 # FIXME: topo-HA/obelisk specific mappings:
2297 # key is mac and value is dpid
2298 mappings = {}
2299 for i in range( 1, 29 ): # hosts 1 through 28
2300 # set up correct variables:
2301 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2302 if i == 1:
2303 deviceId = "1000".zfill(16)
2304 elif i == 2:
2305 deviceId = "2000".zfill(16)
2306 elif i == 3:
2307 deviceId = "3000".zfill(16)
2308 elif i == 4:
2309 deviceId = "3004".zfill(16)
2310 elif i == 5:
2311 deviceId = "5000".zfill(16)
2312 elif i == 6:
2313 deviceId = "6000".zfill(16)
2314 elif i == 7:
2315 deviceId = "6007".zfill(16)
2316 elif i >= 8 and i <= 17:
2317 dpid = '3' + str( i ).zfill( 3 )
2318 deviceId = dpid.zfill(16)
2319 elif i >= 18 and i <= 27:
2320 dpid = '6' + str( i ).zfill( 3 )
2321 deviceId = dpid.zfill(16)
2322 elif i == 28:
2323 deviceId = "2800".zfill(16)
2324 mappings[ macId ] = deviceId
2325 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2326 if hosts[ controller ] == []:
2327 main.log.warn( "There are no hosts discovered" )
2328 noHosts = True
2329 else:
2330 for host in hosts[ controller ]:
2331 mac = None
2332 location = None
2333 device = None
2334 port = None
2335 try:
2336 mac = host.get( 'mac' )
2337 assert mac, "mac field could not be found for this host object"
2338
2339 location = host.get( 'location' )
2340 assert location, "location field could not be found for this host object"
2341
2342 # Trim the protocol identifier off deviceId
2343 device = str( location.get( 'elementId' ) ).split(':')[1]
2344 assert device, "elementId field could not be found for this host location object"
2345
2346 port = location.get( 'port' )
2347 assert port, "port field could not be found for this host location object"
2348
2349 # Now check if this matches where they should be
2350 if mac and device and port:
2351 if str( port ) != "1":
2352 main.log.error( "The attachment port is incorrect for " +
2353 "host " + str( mac ) +
2354 ". Expected: 1 Actual: " + str( port) )
2355 hostAttachment = False
2356 if device != mappings[ str( mac ) ]:
2357 main.log.error( "The attachment device is incorrect for " +
2358 "host " + str( mac ) +
2359 ". Expected: " + mappings[ str( mac ) ] +
2360 " Actual: " + device )
2361 hostAttachment = False
2362 else:
2363 hostAttachment = False
2364 except AssertionError:
2365 main.log.exception( "Json object not as expected" )
2366 main.log.error( repr( host ) )
2367 hostAttachment = False
2368 else:
2369 main.log.error( "No hosts json output or \"Error\"" +
2370 " in output. hosts = " +
2371 repr( hosts[ controller ] ) )
2372 if noHosts is False:
2373 # TODO: Find a way to know if there should be hosts in a
2374 # given point of the test
2375 hostAttachment = True
2376
2377 # END CHECKING HOST ATTACHMENT POINTS
2378 devicesResults = devicesResults and currentDevicesResult
2379 linksResults = linksResults and currentLinksResult
2380 hostsResults = hostsResults and currentHostsResult
2381 hostAttachmentResults = hostAttachmentResults and\
2382 hostAttachment
2383 topoResult = ( devicesResults and linksResults
2384 and hostsResults and ipResult and
2385 hostAttachmentResults )
2386
2387 # Compare json objects for hosts and dataplane clusters
2388
2389 # hosts
2390 main.step( "Hosts view is consistent across all ONOS nodes" )
2391 consistentHostsResult = main.TRUE
2392 for controller in range( len( hosts ) ):
2393 controllerStr = str( controller + 1 )
2394 if "Error" not in hosts[ controller ]:
2395 if hosts[ controller ] == hosts[ 0 ]:
2396 continue
2397 else: # hosts not consistent
2398 main.log.error( "hosts from ONOS" + controllerStr +
2399 " is inconsistent with ONOS1" )
2400 main.log.warn( repr( hosts[ controller ] ) )
2401 consistentHostsResult = main.FALSE
2402
2403 else:
2404 main.log.error( "Error in getting ONOS hosts from ONOS" +
2405 controllerStr )
2406 consistentHostsResult = main.FALSE
2407 main.log.warn( "ONOS" + controllerStr +
2408 " hosts response: " +
2409 repr( hosts[ controller ] ) )
2410 utilities.assert_equals(
2411 expect=main.TRUE,
2412 actual=consistentHostsResult,
2413 onpass="Hosts view is consistent across all ONOS nodes",
2414 onfail="ONOS nodes have different views of hosts" )
2415
2416 main.step( "Hosts information is correct" )
2417 hostsResults = hostsResults and ipResult
2418 utilities.assert_equals(
2419 expect=main.TRUE,
2420 actual=hostsResults,
2421 onpass="Host information is correct",
2422 onfail="Host information is incorrect" )
2423
2424 main.step( "Host attachment points to the network" )
2425 utilities.assert_equals(
2426 expect=True,
2427 actual=hostAttachmentResults,
2428 onpass="Hosts are correctly attached to the network",
2429 onfail="ONOS did not correctly attach hosts to the network" )
2430
2431 # Strongly connected clusters of devices
2432 main.step( "Clusters view is consistent across all ONOS nodes" )
2433 consistentClustersResult = main.TRUE
2434 for controller in range( len( clusters ) ):
2435 controllerStr = str( controller + 1 )
2436 if "Error" not in clusters[ controller ]:
2437 if clusters[ controller ] == clusters[ 0 ]:
2438 continue
2439 else: # clusters not consistent
2440 main.log.error( "clusters from ONOS" +
2441 controllerStr +
2442 " is inconsistent with ONOS1" )
2443 consistentClustersResult = main.FALSE
2444
2445 else:
2446 main.log.error( "Error in getting dataplane clusters " +
2447 "from ONOS" + controllerStr )
2448 consistentClustersResult = main.FALSE
2449 main.log.warn( "ONOS" + controllerStr +
2450 " clusters response: " +
2451 repr( clusters[ controller ] ) )
2452 utilities.assert_equals(
2453 expect=main.TRUE,
2454 actual=consistentClustersResult,
2455 onpass="Clusters view is consistent across all ONOS nodes",
2456 onfail="ONOS nodes have different views of clusters" )
2457
2458 main.step( "There is only one SCC" )
2459 # there should always only be one cluster
2460 try:
2461 numClusters = len( json.loads( clusters[ 0 ] ) )
2462 except ( ValueError, TypeError ):
2463 main.log.exception( "Error parsing clusters[0]: " +
2464 repr( clusters[0] ) )
2465 clusterResults = main.FALSE
2466 if numClusters == 1:
2467 clusterResults = main.TRUE
2468 utilities.assert_equals(
2469 expect=1,
2470 actual=numClusters,
2471 onpass="ONOS shows 1 SCC",
2472 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2473
2474 topoResult = ( devicesResults and linksResults
2475 and hostsResults and consistentHostsResult
2476 and consistentClustersResult and clusterResults
2477 and ipResult and hostAttachmentResults )
2478
2479 topoResult = topoResult and int( count <= 2 )
2480 note = "note it takes about " + str( int( cliTime ) ) + \
2481 " seconds for the test to make all the cli calls to fetch " +\
2482 "the topology from each ONOS instance"
2483 main.log.info(
2484 "Very crass estimate for topology discovery/convergence( " +
2485 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2486 str( count ) + " tries" )
2487
2488 main.step( "Device information is correct" )
2489 utilities.assert_equals(
2490 expect=main.TRUE,
2491 actual=devicesResults,
2492 onpass="Device information is correct",
2493 onfail="Device information is incorrect" )
2494
2495 main.step( "Links are correct" )
2496 utilities.assert_equals(
2497 expect=main.TRUE,
2498 actual=linksResults,
2499 onpass="Link are correct",
2500 onfail="Links are incorrect" )
2501
2502 # FIXME: move this to an ONOS state case
2503 main.step( "Checking ONOS nodes" )
2504 nodesOutput = []
2505 nodeResults = main.TRUE
2506 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002507 for i in range( main.numCtrls ):
2508 t = main.Thread( target=main.CLIs[i].nodes,
Jon Hall5cf14d52015-07-16 12:15:19 -07002509 name="nodes-" + str( i ),
2510 args=[ ] )
2511 threads.append( t )
2512 t.start()
2513
2514 for t in threads:
2515 t.join()
2516 nodesOutput.append( t.result )
Jon Halle1a3b752015-07-22 13:02:46 -07002517 ips = [ node.ip_address for node in main.nodes ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002518 for i in nodesOutput:
2519 try:
2520 current = json.loads( i )
2521 for node in current:
2522 currentResult = main.FALSE
2523 if node['ip'] in ips: # node in nodes() output is in cell
2524 if node['state'] == 'ACTIVE':
2525 currentResult = main.TRUE
2526 else:
2527 main.log.error( "Error in ONOS node availability" )
2528 main.log.error(
2529 json.dumps( current,
2530 sort_keys=True,
2531 indent=4,
2532 separators=( ',', ': ' ) ) )
2533 break
2534 nodeResults = nodeResults and currentResult
2535 except ( ValueError, TypeError ):
2536 main.log.error( "Error parsing nodes output" )
2537 main.log.warn( repr( i ) )
2538 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2539 onpass="Nodes check successful",
2540 onfail="Nodes check NOT successful" )
2541
2542 def CASE9( self, main ):
2543 """
2544 Link s3-s28 down
2545 """
2546 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002547 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002548 assert main, "main not defined"
2549 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002550 assert main.CLIs, "main.CLIs not defined"
2551 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002552 # NOTE: You should probably run a topology check after this
2553
2554 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2555
2556 description = "Turn off a link to ensure that Link Discovery " +\
2557 "is working properly"
2558 main.case( description )
2559
2560 main.step( "Kill Link between s3 and s28" )
2561 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
2562 main.log.info( "Waiting " + str( linkSleep ) +
2563 " seconds for link down to be discovered" )
2564 time.sleep( linkSleep )
2565 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
2566 onpass="Link down successful",
2567 onfail="Failed to bring link down" )
2568 # TODO do some sort of check here
2569
2570 def CASE10( self, main ):
2571 """
2572 Link s3-s28 up
2573 """
2574 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002575 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002576 assert main, "main not defined"
2577 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002578 assert main.CLIs, "main.CLIs not defined"
2579 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002580 # NOTE: You should probably run a topology check after this
2581
2582 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2583
2584 description = "Restore a link to ensure that Link Discovery is " + \
2585 "working properly"
2586 main.case( description )
2587
2588 main.step( "Bring link between s3 and s28 back up" )
2589 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
2590 main.log.info( "Waiting " + str( linkSleep ) +
2591 " seconds for link up to be discovered" )
2592 time.sleep( linkSleep )
2593 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
2594 onpass="Link up successful",
2595 onfail="Failed to bring link up" )
2596 # TODO do some sort of check here
2597
2598 def CASE11( self, main ):
2599 """
2600 Switch Down
2601 """
2602 # NOTE: You should probably run a topology check after this
2603 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002604 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002605 assert main, "main not defined"
2606 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002607 assert main.CLIs, "main.CLIs not defined"
2608 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002609
2610 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2611
2612 description = "Killing a switch to ensure it is discovered correctly"
2613 main.case( description )
2614 switch = main.params[ 'kill' ][ 'switch' ]
2615 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2616
2617 # TODO: Make this switch parameterizable
2618 main.step( "Kill " + switch )
2619 main.log.info( "Deleting " + switch )
2620 main.Mininet1.delSwitch( switch )
2621 main.log.info( "Waiting " + str( switchSleep ) +
2622 " seconds for switch down to be discovered" )
2623 time.sleep( switchSleep )
2624 device = main.ONOScli1.getDevice( dpid=switchDPID )
2625 # Peek at the deleted switch
2626 main.log.warn( str( device ) )
2627 result = main.FALSE
2628 if device and device[ 'available' ] is False:
2629 result = main.TRUE
2630 utilities.assert_equals( expect=main.TRUE, actual=result,
2631 onpass="Kill switch successful",
2632 onfail="Failed to kill switch?" )
2633
2634 def CASE12( self, main ):
2635 """
2636 Switch Up
2637 """
2638 # NOTE: You should probably run a topology check after this
2639 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002640 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002641 assert main, "main not defined"
2642 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002643 assert main.CLIs, "main.CLIs not defined"
2644 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002645 assert ONOS1Port, "ONOS1Port not defined"
2646 assert ONOS2Port, "ONOS2Port not defined"
2647 assert ONOS3Port, "ONOS3Port not defined"
2648 assert ONOS4Port, "ONOS4Port not defined"
2649 assert ONOS5Port, "ONOS5Port not defined"
2650 assert ONOS6Port, "ONOS6Port not defined"
2651 assert ONOS7Port, "ONOS7Port not defined"
2652
2653 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2654 switch = main.params[ 'kill' ][ 'switch' ]
2655 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2656 links = main.params[ 'kill' ][ 'links' ].split()
2657 description = "Adding a switch to ensure it is discovered correctly"
2658 main.case( description )
2659
2660 main.step( "Add back " + switch )
2661 main.Mininet1.addSwitch( switch, dpid=switchDPID )
2662 for peer in links:
2663 main.Mininet1.addLink( switch, peer )
2664 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -07002665 for i in range( main.numCtrls ):
2666 ipList.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -07002667 main.Mininet1.assignSwController( sw=switch, ip=ipList )
2668 main.log.info( "Waiting " + str( switchSleep ) +
2669 " seconds for switch up to be discovered" )
2670 time.sleep( switchSleep )
2671 device = main.ONOScli1.getDevice( dpid=switchDPID )
2672 # Peek at the deleted switch
2673 main.log.warn( str( device ) )
2674 result = main.FALSE
2675 if device and device[ 'available' ]:
2676 result = main.TRUE
2677 utilities.assert_equals( expect=main.TRUE, actual=result,
2678 onpass="add switch successful",
2679 onfail="Failed to add switch?" )
2680
2681 def CASE13( self, main ):
2682 """
2683 Clean up
2684 """
2685 import os
2686 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002687 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002688 assert main, "main not defined"
2689 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002690 assert main.CLIs, "main.CLIs not defined"
2691 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002692
2693 # printing colors to terminal
2694 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2695 'blue': '\033[94m', 'green': '\033[92m',
2696 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
2697 main.case( "Test Cleanup" )
2698 main.step( "Killing tcpdumps" )
2699 main.Mininet2.stopTcpdump()
2700
2701 testname = main.TEST
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002702 main.log.error( main.params[ 'BACKUP' ][ 'ENABLED' ] )
2703 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall5cf14d52015-07-16 12:15:19 -07002704 main.step( "Copying MN pcap and ONOS log files to test station" )
2705 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
2706 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
2707 # NOTE: MN Pcap file is being saved to ~/packet_captures
2708 # scp this file as MN and TestON aren't necessarily the same vm
2709 # FIXME: scp
2710 # mn files
2711 # TODO: Load these from params
2712 # NOTE: must end in /
2713 logFolder = "/opt/onos/log/"
2714 logFiles = [ "karaf.log", "karaf.log.1" ]
2715 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002716 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002717 for node in main.nodes:
Jon Hallba609822015-09-18 12:00:21 -07002718 # scp sdn@<ip>:<file path> <test's log path>/<node name>-<orig filename>
Jon Hall5cf14d52015-07-16 12:15:19 -07002719 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2720 ":" + logFolder + f + " " +
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002721 main.logdir + "/" +
2722 node.name + "-" + f )
2723 main.ONOSbench.handle.expect( "\$ " )
2724 print main.ONOSbench.handle.before
Jon Hall5cf14d52015-07-16 12:15:19 -07002725
2726 # std*.log's
2727 # NOTE: must end in /
2728 logFolder = "/opt/onos/var/"
2729 logFiles = [ "stderr.log", "stdout.log" ]
2730 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002731 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002732 for node in main.nodes:
Jon Hallba609822015-09-18 12:00:21 -07002733 # scp sdn@<ip>:<file path> <test's log path>/<node name>-<orig filename>
Jon Hall5cf14d52015-07-16 12:15:19 -07002734 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2735 ":" + logFolder + f + " " +
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002736 main.logdir + "/" +
2737 node.name + "-" + f )
2738 main.ONOSbench.handle.expect( "\$ " )
2739 print main.ONOSbench.handle.before
Jon Hall5cf14d52015-07-16 12:15:19 -07002740 # sleep so scp can finish
2741 time.sleep( 10 )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002742 # main.step( "Packing and rotating pcap archives" )
2743 # os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
2744 else:
2745 main.log.debug( "skipping saving log files" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002746
2747 main.step( "Stopping Mininet" )
2748 mnResult = main.Mininet1.stopNet()
2749 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2750 onpass="Mininet stopped",
2751 onfail="MN cleanup NOT successful" )
2752
2753 main.step( "Checking ONOS Logs for errors" )
Jon Halle1a3b752015-07-22 13:02:46 -07002754 for node in main.nodes:
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002755 main.log.debug( "Checking logs for errors on " + node.name + ":" )
2756 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002757
2758 try:
2759 timerLog = open( main.logdir + "/Timers.csv", 'w')
2760 main.log.error( ", ".join( labels ) + "\n" + ", ".join( data ) )
2761 timerLog.write( ", ".join( labels ) + "\n" + ", ".join( data ) )
2762 timerLog.close()
2763 except NameError, e:
2764 main.log.exception(e)
2765
2766 def CASE14( self, main ):
2767 """
2768 start election app on all onos nodes
2769 """
Jon Halle1a3b752015-07-22 13:02:46 -07002770 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002771 assert main, "main not defined"
2772 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002773 assert main.CLIs, "main.CLIs not defined"
2774 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002775
2776 main.case("Start Leadership Election app")
2777 main.step( "Install leadership election app" )
2778 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
2779 utilities.assert_equals(
2780 expect=main.TRUE,
2781 actual=appResult,
2782 onpass="Election app installed",
2783 onfail="Something went wrong with installing Leadership election" )
2784
2785 main.step( "Run for election on each node" )
2786 leaderResult = main.TRUE
2787 leaders = []
Jon Halle1a3b752015-07-22 13:02:46 -07002788 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002789 cli.electionTestRun()
Jon Halle1a3b752015-07-22 13:02:46 -07002790 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002791 leader = cli.electionTestLeader()
2792 if leader is None or leader == main.FALSE:
2793 main.log.error( cli.name + ": Leader for the election app " +
2794 "should be an ONOS node, instead got '" +
2795 str( leader ) + "'" )
2796 leaderResult = main.FALSE
2797 leaders.append( leader )
2798 utilities.assert_equals(
2799 expect=main.TRUE,
2800 actual=leaderResult,
2801 onpass="Successfully ran for leadership",
2802 onfail="Failed to run for leadership" )
2803
2804 main.step( "Check that each node shows the same leader" )
2805 sameLeader = main.TRUE
2806 if len( set( leaders ) ) != 1:
2807 sameLeader = main.FALSE
2808 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2809 str( leaders ) )
2810 utilities.assert_equals(
2811 expect=main.TRUE,
2812 actual=sameLeader,
2813 onpass="Leadership is consistent for the election topic",
2814 onfail="Nodes have different leaders" )
2815
2816 def CASE15( self, main ):
2817 """
2818 Check that Leadership Election is still functional
acsmars9475b1c2015-08-28 18:02:08 -07002819 15.1 Run election on each node
2820 15.2 Check that each node has the same leaders and candidates
2821 15.3 Find current leader and withdraw
2822 15.4 Check that a new node was elected leader
2823 15.5 Check that that new leader was the candidate of old leader
2824 15.6 Run for election on old leader
2825 15.7 Check that oldLeader is a candidate, and leader if only 1 node
2826 15.8 Make sure that the old leader was added to the candidate list
2827
2828 old and new variable prefixes refer to data from before vs after
2829 withdrawl and later before withdrawl vs after re-election
Jon Hall5cf14d52015-07-16 12:15:19 -07002830 """
2831 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002832 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002833 assert main, "main not defined"
2834 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002835 assert main.CLIs, "main.CLIs not defined"
2836 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002837
Jon Hall5cf14d52015-07-16 12:15:19 -07002838 description = "Check that Leadership Election is still functional"
2839 main.case( description )
2840 # NOTE: Need to re-run since being a canidate is not persistant
acsmars9475b1c2015-08-28 18:02:08 -07002841 # TODO: add check for "Command not found:" in the driver, this
2842 # means the election test app isn't loaded
2843
2844 oldLeaders = [] # leaders by node before withdrawl from candidates
2845 newLeaders = [] # leaders by node after withdrawl from candidates
2846 oldAllCandidates = [] # list of lists of each nodes' candidates before
2847 newAllCandidates = [] # list of lists of each nodes' candidates after
2848 oldCandidates = [] # list of candidates from node 0 before withdrawl
2849 newCandidates = [] # list of candidates from node 0 after withdrawl
2850 oldLeader = '' # the old leader from oldLeaders, None if not same
2851 newLeader = '' # the new leaders fron newLoeaders, None if not same
2852 oldLeaderCLI = None # the CLI of the old leader used for re-electing
acsmars71adceb2015-08-31 15:09:26 -07002853 expectNoLeader = False # True when there is only one leader
2854 if main.numCtrls == 1:
2855 expectNoLeader = True
acsmars9475b1c2015-08-28 18:02:08 -07002856
Jon Hall5cf14d52015-07-16 12:15:19 -07002857 main.step( "Run for election on each node" )
acsmars9475b1c2015-08-28 18:02:08 -07002858 electionResult = main.TRUE
2859
2860 for cli in main.CLIs: # run test election on each node
2861 if cli.electionTestRun() == main.FALSE:
2862 electionResult = main.FALSE
2863
Jon Hall5cf14d52015-07-16 12:15:19 -07002864 utilities.assert_equals(
2865 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07002866 actual=electionResult,
2867 onpass="All nodes successfully ran for leadership",
2868 onfail="At least one node failed to run for leadership" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002869
acsmars3a72bde2015-09-02 14:16:22 -07002870 if electionResult == main.FALSE:
2871 main.log.error(
2872 "Skipping Test Case because Election Test App isn't loaded" )
2873 main.skipCase()
2874
acsmars9475b1c2015-08-28 18:02:08 -07002875 main.step( "Check that each node shows the same leader and candidates" )
2876 sameResult = main.TRUE
2877 failMessage = "Nodes have different leaders"
2878 for cli in main.CLIs:
2879 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2880 oldAllCandidates.append( node )
2881 oldLeaders.append( node[ 0 ] )
2882 oldCandidates = oldAllCandidates[ 0 ]
2883
2884 # Check that each node has the same leader. Defines oldLeader
2885 if len( set( oldLeaders ) ) != 1:
2886 sameResult = main.FALSE
acsmars71adceb2015-08-31 15:09:26 -07002887 main.log.error( "More than one leader present:" + str( oldLeaders ) )
acsmars9475b1c2015-08-28 18:02:08 -07002888 oldLeader = None
2889 else:
2890 oldLeader = oldLeaders[ 0 ]
2891
2892 # Check that each node's candidate list is the same
2893 for candidates in oldAllCandidates:
2894 if set( candidates ) != set( oldCandidates ):
2895 sameResult = main.FALSE
2896 failMessage += "and candidates"
2897
Jon Hall5cf14d52015-07-16 12:15:19 -07002898 utilities.assert_equals(
2899 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002900 actual=sameResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002901 onpass="Leadership is consistent for the election topic",
acsmars9475b1c2015-08-28 18:02:08 -07002902 onfail=failMessage )
Jon Hall5cf14d52015-07-16 12:15:19 -07002903
2904 main.step( "Find current leader and withdraw" )
acsmars9475b1c2015-08-28 18:02:08 -07002905 withdrawResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002906 # do some sanity checking on leader before using it
acsmars9475b1c2015-08-28 18:02:08 -07002907 if oldLeader is None:
2908 main.log.error( "Leadership isn't consistent." )
2909 withdrawResult = main.FALSE
2910 # Get the CLI of the oldLeader
Jon Halle1a3b752015-07-22 13:02:46 -07002911 for i in range( len( main.CLIs ) ):
acsmars9475b1c2015-08-28 18:02:08 -07002912 if oldLeader == main.nodes[ i ].ip_address:
2913 oldLeaderCLI = main.CLIs[ i ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002914 break
2915 else: # FOR/ELSE statement
2916 main.log.error( "Leader election, could not find current leader" )
2917 if oldLeader:
acsmars9475b1c2015-08-28 18:02:08 -07002918 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall5cf14d52015-07-16 12:15:19 -07002919 utilities.assert_equals(
2920 expect=main.TRUE,
2921 actual=withdrawResult,
2922 onpass="Node was withdrawn from election",
2923 onfail="Node was not withdrawn from election" )
2924
acsmars9475b1c2015-08-28 18:02:08 -07002925 main.step( "Check that a new node was elected leader" )
acsmars71adceb2015-08-31 15:09:26 -07002926
Jon Hall5cf14d52015-07-16 12:15:19 -07002927 # FIXME: use threads
acsmars9475b1c2015-08-28 18:02:08 -07002928 newLeaderResult = main.TRUE
2929 failMessage = "Nodes have different leaders"
2930
2931 # Get new leaders and candidates
Jon Halle1a3b752015-07-22 13:02:46 -07002932 for cli in main.CLIs:
acsmars9475b1c2015-08-28 18:02:08 -07002933 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
acsmars71adceb2015-08-31 15:09:26 -07002934 # elections might no have finished yet
2935 if node[ 0 ] == 'none' and not expectNoLeader:
acsmars9475b1c2015-08-28 18:02:08 -07002936 main.log.info( "Node has no leader, waiting 5 seconds to be " +
2937 "sure elections are complete." )
2938 time.sleep(5)
2939 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
acsmars71adceb2015-08-31 15:09:26 -07002940 # election still isn't done or there is a problem
2941 if node[ 0 ] == 'none':
2942 main.log.error( "No leader was elected on at least 1 node" )
2943 newLeaderResult = main.FALSE
acsmars9475b1c2015-08-28 18:02:08 -07002944 newAllCandidates.append( node )
2945 newLeaders.append( node[ 0 ] )
2946 newCandidates = newAllCandidates[ 0 ]
2947
2948 # Check that each node has the same leader. Defines newLeader
2949 if len( set( newLeaders ) ) != 1:
2950 newLeaderResult = main.FALSE
2951 main.log.error( "Nodes have different leaders: " +
2952 str( newLeaders ) )
2953 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07002954 else:
acsmars9475b1c2015-08-28 18:02:08 -07002955 newLeader = newLeaders[ 0 ]
2956
acsmars71adceb2015-08-31 15:09:26 -07002957 # Check that each node's candidate list is the same
2958 for candidates in newAllCandidates:
2959 if set( candidates ) != set( newCandidates ):
2960 newLeaderResult = main.FALSE
2961 main.error.log( "Discrepancy in candidate lists detected" )
2962
acsmars9475b1c2015-08-28 18:02:08 -07002963 # Check that the new leader is not the older leader, which was withdrawn
2964 if newLeader == oldLeader:
2965 newLeaderResult = main.FALSE
2966 main.log.error( "All nodes still see old leader: " + oldLeader +
2967 " as the current leader" )
2968
Jon Hall5cf14d52015-07-16 12:15:19 -07002969 utilities.assert_equals(
2970 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07002971 actual=newLeaderResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002972 onpass="Leadership election passed",
2973 onfail="Something went wrong with Leadership election" )
2974
acsmars9475b1c2015-08-28 18:02:08 -07002975 main.step( "Check that that new leader was the candidate of old leader")
2976 # candidates[ 2 ] should be come the top candidate after withdrawl
2977 correctCandidateResult = main.TRUE
acsmars71adceb2015-08-31 15:09:26 -07002978 if expectNoLeader:
2979 if newLeader == 'none':
2980 main.log.info( "No leader expected. None found. Pass" )
2981 correctCandidateResult = main.TRUE
2982 else:
2983 main.log.info( "Expected no leader, got: " + str( newLeader ) )
2984 correctCandidateResult = main.FALSE
2985 elif newLeader != oldCandidates[ 2 ]:
acsmars9475b1c2015-08-28 18:02:08 -07002986 correctCandidateResult = main.FALSE
2987 main.log.error( "Candidate " + newLeader + " was elected. " +
2988 oldCandidates[ 2 ] + " should have had priority." )
2989
2990 utilities.assert_equals(
2991 expect=main.TRUE,
2992 actual=correctCandidateResult,
2993 onpass="Correct Candidate Elected",
2994 onfail="Incorrect Candidate Elected" )
2995
Jon Hall5cf14d52015-07-16 12:15:19 -07002996 main.step( "Run for election on old leader( just so everyone " +
2997 "is in the hat )" )
acsmars9475b1c2015-08-28 18:02:08 -07002998 if oldLeaderCLI is not None:
2999 runResult = oldLeaderCLI.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07003000 else:
acsmars9475b1c2015-08-28 18:02:08 -07003001 main.log.error( "No old leader to re-elect" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003002 runResult = main.FALSE
3003 utilities.assert_equals(
3004 expect=main.TRUE,
3005 actual=runResult,
3006 onpass="App re-ran for election",
3007 onfail="App failed to run for election" )
acsmars9475b1c2015-08-28 18:02:08 -07003008 main.step(
3009 "Check that oldLeader is a candidate, and leader if only 1 node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003010 # verify leader didn't just change
acsmars9475b1c2015-08-28 18:02:08 -07003011 positionResult = main.TRUE
3012 # Get new leaders and candidates, wait if oldLeader is not a candidate yet
3013
3014 # Reset and reuse the new candidate and leaders lists
3015 newAllCandidates = []
3016 newCandidates = []
3017 newLeaders = []
3018 for cli in main.CLIs:
3019 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
3020 if oldLeader not in node: # election might no have finished yet
3021 main.log.info( "Old Leader not elected, waiting 5 seconds to " +
3022 "be sure elections are complete" )
3023 time.sleep(5)
3024 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
3025 if oldLeader not in node: # election still isn't done, errors
3026 main.log.error(
3027 "Old leader was not elected on at least one node" )
3028 positionResult = main.FALSE
3029 newAllCandidates.append( node )
3030 newLeaders.append( node[ 0 ] )
3031 newCandidates = newAllCandidates[ 0 ]
3032
3033 # Check that each node has the same leader. Defines newLeader
3034 if len( set( newLeaders ) ) != 1:
3035 positionResult = main.FALSE
3036 main.log.error( "Nodes have different leaders: " +
3037 str( newLeaders ) )
3038 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07003039 else:
acsmars9475b1c2015-08-28 18:02:08 -07003040 newLeader = newLeaders[ 0 ]
3041
acsmars71adceb2015-08-31 15:09:26 -07003042 # Check that each node's candidate list is the same
3043 for candidates in newAllCandidates:
3044 if set( candidates ) != set( newCandidates ):
3045 newLeaderResult = main.FALSE
3046 main.error.log( "Discrepancy in candidate lists detected" )
3047
acsmars9475b1c2015-08-28 18:02:08 -07003048 # Check that the re-elected node is last on the candidate List
3049 if oldLeader != newCandidates[ -1 ]:
3050 main.log.error( "Old Leader (" + oldLeader + ") not in the proper position " +
3051 str( newCandidates ) )
3052 positionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07003053
3054 utilities.assert_equals(
3055 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07003056 actual=positionResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07003057 onpass="Old leader successfully re-ran for election",
3058 onfail="Something went wrong with Leadership election after " +
3059 "the old leader re-ran for election" )
3060
3061 def CASE16( self, main ):
3062 """
3063 Install Distributed Primitives app
3064 """
3065 import time
Jon Halle1a3b752015-07-22 13:02:46 -07003066 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003067 assert main, "main not defined"
3068 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003069 assert main.CLIs, "main.CLIs not defined"
3070 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003071
3072 # Variables for the distributed primitives tests
3073 global pCounterName
3074 global iCounterName
3075 global pCounterValue
3076 global iCounterValue
3077 global onosSet
3078 global onosSetName
3079 pCounterName = "TestON-Partitions"
3080 iCounterName = "TestON-inMemory"
3081 pCounterValue = 0
3082 iCounterValue = 0
3083 onosSet = set([])
3084 onosSetName = "TestON-set"
3085
3086 description = "Install Primitives app"
3087 main.case( description )
3088 main.step( "Install Primitives app" )
3089 appName = "org.onosproject.distributedprimitives"
Jon Halle1a3b752015-07-22 13:02:46 -07003090 appResults = main.CLIs[0].activateApp( appName )
Jon Hall5cf14d52015-07-16 12:15:19 -07003091 utilities.assert_equals( expect=main.TRUE,
3092 actual=appResults,
3093 onpass="Primitives app activated",
3094 onfail="Primitives app not activated" )
3095 time.sleep( 5 ) # To allow all nodes to activate
3096
3097 def CASE17( self, main ):
3098 """
3099 Check for basic functionality with distributed primitives
3100 """
Jon Hall5cf14d52015-07-16 12:15:19 -07003101 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07003102 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003103 assert main, "main not defined"
3104 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003105 assert main.CLIs, "main.CLIs not defined"
3106 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003107 assert pCounterName, "pCounterName not defined"
3108 assert iCounterName, "iCounterName not defined"
3109 assert onosSetName, "onosSetName not defined"
3110 # NOTE: assert fails if value is 0/None/Empty/False
3111 try:
3112 pCounterValue
3113 except NameError:
3114 main.log.error( "pCounterValue not defined, setting to 0" )
3115 pCounterValue = 0
3116 try:
3117 iCounterValue
3118 except NameError:
3119 main.log.error( "iCounterValue not defined, setting to 0" )
3120 iCounterValue = 0
3121 try:
3122 onosSet
3123 except NameError:
3124 main.log.error( "onosSet not defined, setting to empty Set" )
3125 onosSet = set([])
3126 # Variables for the distributed primitives tests. These are local only
3127 addValue = "a"
3128 addAllValue = "a b c d e f"
3129 retainValue = "c d e f"
3130
3131 description = "Check for basic functionality with distributed " +\
3132 "primitives"
3133 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07003134 main.caseExplanation = "Test the methods of the distributed " +\
3135 "primitives (counters and sets) throught the cli"
Jon Hall5cf14d52015-07-16 12:15:19 -07003136 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07003137 # Partitioned counters
3138 main.step( "Increment then get a default counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003139 pCounters = []
3140 threads = []
3141 addedPValues = []
Jon Halle1a3b752015-07-22 13:02:46 -07003142 for i in range( main.numCtrls ):
3143 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3144 name="counterAddAndGet-" + str( i ),
Jon Hall5cf14d52015-07-16 12:15:19 -07003145 args=[ pCounterName ] )
3146 pCounterValue += 1
3147 addedPValues.append( pCounterValue )
3148 threads.append( t )
3149 t.start()
3150
3151 for t in threads:
3152 t.join()
3153 pCounters.append( t.result )
3154 # Check that counter incremented numController times
3155 pCounterResults = True
3156 for i in addedPValues:
3157 tmpResult = i in pCounters
3158 pCounterResults = pCounterResults and tmpResult
3159 if not tmpResult:
3160 main.log.error( str( i ) + " is not in partitioned "
3161 "counter incremented results" )
3162 utilities.assert_equals( expect=True,
3163 actual=pCounterResults,
3164 onpass="Default counter incremented",
3165 onfail="Error incrementing default" +
3166 " counter" )
3167
Jon Halle1a3b752015-07-22 13:02:46 -07003168 main.step( "Get then Increment a default counter on each node" )
3169 pCounters = []
3170 threads = []
3171 addedPValues = []
3172 for i in range( main.numCtrls ):
3173 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3174 name="counterGetAndAdd-" + str( i ),
3175 args=[ pCounterName ] )
3176 addedPValues.append( pCounterValue )
3177 pCounterValue += 1
3178 threads.append( t )
3179 t.start()
3180
3181 for t in threads:
3182 t.join()
3183 pCounters.append( t.result )
3184 # Check that counter incremented numController times
3185 pCounterResults = True
3186 for i in addedPValues:
3187 tmpResult = i in pCounters
3188 pCounterResults = pCounterResults and tmpResult
3189 if not tmpResult:
3190 main.log.error( str( i ) + " is not in partitioned "
3191 "counter incremented results" )
3192 utilities.assert_equals( expect=True,
3193 actual=pCounterResults,
3194 onpass="Default counter incremented",
3195 onfail="Error incrementing default" +
3196 " counter" )
3197
3198 main.step( "Counters we added have the correct values" )
3199 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3200 utilities.assert_equals( expect=main.TRUE,
3201 actual=incrementCheck,
3202 onpass="Added counters are correct",
3203 onfail="Added counters are incorrect" )
3204
3205 main.step( "Add -8 to then get a default counter on each node" )
3206 pCounters = []
3207 threads = []
3208 addedPValues = []
3209 for i in range( main.numCtrls ):
3210 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3211 name="counterIncrement-" + str( i ),
3212 args=[ pCounterName ],
3213 kwargs={ "delta": -8 } )
3214 pCounterValue += -8
3215 addedPValues.append( pCounterValue )
3216 threads.append( t )
3217 t.start()
3218
3219 for t in threads:
3220 t.join()
3221 pCounters.append( t.result )
3222 # Check that counter incremented numController times
3223 pCounterResults = True
3224 for i in addedPValues:
3225 tmpResult = i in pCounters
3226 pCounterResults = pCounterResults and tmpResult
3227 if not tmpResult:
3228 main.log.error( str( i ) + " is not in partitioned "
3229 "counter incremented results" )
3230 utilities.assert_equals( expect=True,
3231 actual=pCounterResults,
3232 onpass="Default counter incremented",
3233 onfail="Error incrementing default" +
3234 " counter" )
3235
3236 main.step( "Add 5 to then get a default counter on each node" )
3237 pCounters = []
3238 threads = []
3239 addedPValues = []
3240 for i in range( main.numCtrls ):
3241 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3242 name="counterIncrement-" + str( i ),
3243 args=[ pCounterName ],
3244 kwargs={ "delta": 5 } )
3245 pCounterValue += 5
3246 addedPValues.append( pCounterValue )
3247 threads.append( t )
3248 t.start()
3249
3250 for t in threads:
3251 t.join()
3252 pCounters.append( t.result )
3253 # Check that counter incremented numController times
3254 pCounterResults = True
3255 for i in addedPValues:
3256 tmpResult = i in pCounters
3257 pCounterResults = pCounterResults and tmpResult
3258 if not tmpResult:
3259 main.log.error( str( i ) + " is not in partitioned "
3260 "counter incremented results" )
3261 utilities.assert_equals( expect=True,
3262 actual=pCounterResults,
3263 onpass="Default counter incremented",
3264 onfail="Error incrementing default" +
3265 " counter" )
3266
3267 main.step( "Get then add 5 to a default counter on each node" )
3268 pCounters = []
3269 threads = []
3270 addedPValues = []
3271 for i in range( main.numCtrls ):
3272 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3273 name="counterIncrement-" + str( i ),
3274 args=[ pCounterName ],
3275 kwargs={ "delta": 5 } )
3276 addedPValues.append( pCounterValue )
3277 pCounterValue += 5
3278 threads.append( t )
3279 t.start()
3280
3281 for t in threads:
3282 t.join()
3283 pCounters.append( t.result )
3284 # Check that counter incremented numController times
3285 pCounterResults = True
3286 for i in addedPValues:
3287 tmpResult = i in pCounters
3288 pCounterResults = pCounterResults and tmpResult
3289 if not tmpResult:
3290 main.log.error( str( i ) + " is not in partitioned "
3291 "counter incremented results" )
3292 utilities.assert_equals( expect=True,
3293 actual=pCounterResults,
3294 onpass="Default counter incremented",
3295 onfail="Error incrementing default" +
3296 " counter" )
3297
3298 main.step( "Counters we added have the correct values" )
3299 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3300 utilities.assert_equals( expect=main.TRUE,
3301 actual=incrementCheck,
3302 onpass="Added counters are correct",
3303 onfail="Added counters are incorrect" )
3304
3305 # In-Memory counters
3306 main.step( "Increment and get an in-memory counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003307 iCounters = []
3308 addedIValues = []
3309 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003310 for i in range( main.numCtrls ):
3311 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003312 name="icounterIncrement-" + str( i ),
3313 args=[ iCounterName ],
3314 kwargs={ "inMemory": True } )
3315 iCounterValue += 1
3316 addedIValues.append( iCounterValue )
3317 threads.append( t )
3318 t.start()
3319
3320 for t in threads:
3321 t.join()
3322 iCounters.append( t.result )
3323 # Check that counter incremented numController times
3324 iCounterResults = True
3325 for i in addedIValues:
3326 tmpResult = i in iCounters
3327 iCounterResults = iCounterResults and tmpResult
3328 if not tmpResult:
3329 main.log.error( str( i ) + " is not in the in-memory "
3330 "counter incremented results" )
3331 utilities.assert_equals( expect=True,
3332 actual=iCounterResults,
Jon Halle1a3b752015-07-22 13:02:46 -07003333 onpass="In-memory counter incremented",
3334 onfail="Error incrementing in-memory" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003335 " counter" )
3336
Jon Halle1a3b752015-07-22 13:02:46 -07003337 main.step( "Get then Increment a in-memory counter on each node" )
3338 iCounters = []
3339 threads = []
3340 addedIValues = []
3341 for i in range( main.numCtrls ):
3342 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3343 name="counterGetAndAdd-" + str( i ),
3344 args=[ iCounterName ],
3345 kwargs={ "inMemory": True } )
3346 addedIValues.append( iCounterValue )
3347 iCounterValue += 1
3348 threads.append( t )
3349 t.start()
3350
3351 for t in threads:
3352 t.join()
3353 iCounters.append( t.result )
3354 # Check that counter incremented numController times
3355 iCounterResults = True
3356 for i in addedIValues:
3357 tmpResult = i in iCounters
3358 iCounterResults = iCounterResults and tmpResult
3359 if not tmpResult:
3360 main.log.error( str( i ) + " is not in in-memory "
3361 "counter incremented results" )
3362 utilities.assert_equals( expect=True,
3363 actual=iCounterResults,
3364 onpass="In-memory counter incremented",
3365 onfail="Error incrementing in-memory" +
3366 " counter" )
3367
3368 main.step( "Counters we added have the correct values" )
3369 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3370 utilities.assert_equals( expect=main.TRUE,
3371 actual=incrementCheck,
3372 onpass="Added counters are correct",
3373 onfail="Added counters are incorrect" )
3374
3375 main.step( "Add -8 to then get a in-memory counter on each node" )
3376 iCounters = []
3377 threads = []
3378 addedIValues = []
3379 for i in range( main.numCtrls ):
3380 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3381 name="counterIncrement-" + str( i ),
3382 args=[ iCounterName ],
3383 kwargs={ "delta": -8, "inMemory": True } )
3384 iCounterValue += -8
3385 addedIValues.append( iCounterValue )
3386 threads.append( t )
3387 t.start()
3388
3389 for t in threads:
3390 t.join()
3391 iCounters.append( t.result )
3392 # Check that counter incremented numController times
3393 iCounterResults = True
3394 for i in addedIValues:
3395 tmpResult = i in iCounters
3396 iCounterResults = iCounterResults and tmpResult
3397 if not tmpResult:
3398 main.log.error( str( i ) + " is not in in-memory "
3399 "counter incremented results" )
3400 utilities.assert_equals( expect=True,
3401 actual=pCounterResults,
3402 onpass="In-memory counter incremented",
3403 onfail="Error incrementing in-memory" +
3404 " counter" )
3405
3406 main.step( "Add 5 to then get a in-memory counter on each node" )
3407 iCounters = []
3408 threads = []
3409 addedIValues = []
3410 for i in range( main.numCtrls ):
3411 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3412 name="counterIncrement-" + str( i ),
3413 args=[ iCounterName ],
3414 kwargs={ "delta": 5, "inMemory": True } )
3415 iCounterValue += 5
3416 addedIValues.append( iCounterValue )
3417 threads.append( t )
3418 t.start()
3419
3420 for t in threads:
3421 t.join()
3422 iCounters.append( t.result )
3423 # Check that counter incremented numController times
3424 iCounterResults = True
3425 for i in addedIValues:
3426 tmpResult = i in iCounters
3427 iCounterResults = iCounterResults and tmpResult
3428 if not tmpResult:
3429 main.log.error( str( i ) + " is not in in-memory "
3430 "counter incremented results" )
3431 utilities.assert_equals( expect=True,
3432 actual=pCounterResults,
3433 onpass="In-memory counter incremented",
3434 onfail="Error incrementing in-memory" +
3435 " counter" )
3436
3437 main.step( "Get then add 5 to a in-memory counter on each node" )
3438 iCounters = []
3439 threads = []
3440 addedIValues = []
3441 for i in range( main.numCtrls ):
3442 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3443 name="counterIncrement-" + str( i ),
3444 args=[ iCounterName ],
3445 kwargs={ "delta": 5, "inMemory": True } )
3446 addedIValues.append( iCounterValue )
3447 iCounterValue += 5
3448 threads.append( t )
3449 t.start()
3450
3451 for t in threads:
3452 t.join()
3453 iCounters.append( t.result )
3454 # Check that counter incremented numController times
3455 iCounterResults = True
3456 for i in addedIValues:
3457 tmpResult = i in iCounters
3458 iCounterResults = iCounterResults and tmpResult
3459 if not tmpResult:
3460 main.log.error( str( i ) + " is not in in-memory "
3461 "counter incremented results" )
3462 utilities.assert_equals( expect=True,
3463 actual=iCounterResults,
3464 onpass="In-memory counter incremented",
3465 onfail="Error incrementing in-memory" +
3466 " counter" )
3467
3468 main.step( "Counters we added have the correct values" )
3469 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3470 utilities.assert_equals( expect=main.TRUE,
3471 actual=incrementCheck,
3472 onpass="Added counters are correct",
3473 onfail="Added counters are incorrect" )
3474
Jon Hall5cf14d52015-07-16 12:15:19 -07003475 main.step( "Check counters are consistant across nodes" )
3476 onosCounters = []
3477 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003478 for i in range( main.numCtrls ):
3479 t = main.Thread( target=main.CLIs[i].counters,
Jon Hall5cf14d52015-07-16 12:15:19 -07003480 name="counters-" + str( i ) )
3481 threads.append( t )
3482 t.start()
3483 for t in threads:
3484 t.join()
3485 onosCounters.append( t.result )
3486 tmp = [ i == onosCounters[ 0 ] for i in onosCounters ]
3487 if all( tmp ):
3488 main.log.info( "Counters are consistent across all nodes" )
3489 consistentCounterResults = main.TRUE
3490 else:
3491 main.log.error( "Counters are not consistent across all nodes" )
3492 consistentCounterResults = main.FALSE
3493 utilities.assert_equals( expect=main.TRUE,
3494 actual=consistentCounterResults,
3495 onpass="ONOS counters are consistent " +
3496 "across nodes",
3497 onfail="ONOS Counters are inconsistent " +
3498 "across nodes" )
3499
3500 main.step( "Counters we added have the correct values" )
Jon Halle1a3b752015-07-22 13:02:46 -07003501 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3502 incrementCheck = incrementCheck and \
3503 main.Counters.counterCheck( iCounterName, iCounterValue )
Jon Hall5cf14d52015-07-16 12:15:19 -07003504 utilities.assert_equals( expect=main.TRUE,
Jon Halle1a3b752015-07-22 13:02:46 -07003505 actual=incrementCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -07003506 onpass="Added counters are correct",
3507 onfail="Added counters are incorrect" )
Jon Halle1a3b752015-07-22 13:02:46 -07003508
Jon Hall5cf14d52015-07-16 12:15:19 -07003509 # DISTRIBUTED SETS
3510 main.step( "Distributed Set get" )
3511 size = len( onosSet )
3512 getResponses = []
3513 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003514 for i in range( main.numCtrls ):
3515 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003516 name="setTestGet-" + str( i ),
3517 args=[ onosSetName ] )
3518 threads.append( t )
3519 t.start()
3520 for t in threads:
3521 t.join()
3522 getResponses.append( t.result )
3523
3524 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003525 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003526 if isinstance( getResponses[ i ], list):
3527 current = set( getResponses[ i ] )
3528 if len( current ) == len( getResponses[ i ] ):
3529 # no repeats
3530 if onosSet != current:
3531 main.log.error( "ONOS" + str( i + 1 ) +
3532 " has incorrect view" +
3533 " of set " + onosSetName + ":\n" +
3534 str( getResponses[ i ] ) )
3535 main.log.debug( "Expected: " + str( onosSet ) )
3536 main.log.debug( "Actual: " + str( current ) )
3537 getResults = main.FALSE
3538 else:
3539 # error, set is not a set
3540 main.log.error( "ONOS" + str( i + 1 ) +
3541 " has repeat elements in" +
3542 " set " + onosSetName + ":\n" +
3543 str( getResponses[ i ] ) )
3544 getResults = main.FALSE
3545 elif getResponses[ i ] == main.ERROR:
3546 getResults = main.FALSE
3547 utilities.assert_equals( expect=main.TRUE,
3548 actual=getResults,
3549 onpass="Set elements are correct",
3550 onfail="Set elements are incorrect" )
3551
3552 main.step( "Distributed Set size" )
3553 sizeResponses = []
3554 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003555 for i in range( main.numCtrls ):
3556 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003557 name="setTestSize-" + str( i ),
3558 args=[ onosSetName ] )
3559 threads.append( t )
3560 t.start()
3561 for t in threads:
3562 t.join()
3563 sizeResponses.append( t.result )
3564
3565 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003566 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003567 if size != sizeResponses[ i ]:
3568 sizeResults = main.FALSE
3569 main.log.error( "ONOS" + str( i + 1 ) +
3570 " expected a size of " + str( size ) +
3571 " for set " + onosSetName +
3572 " but got " + str( sizeResponses[ i ] ) )
3573 utilities.assert_equals( expect=main.TRUE,
3574 actual=sizeResults,
3575 onpass="Set sizes are correct",
3576 onfail="Set sizes are incorrect" )
3577
3578 main.step( "Distributed Set add()" )
3579 onosSet.add( addValue )
3580 addResponses = []
3581 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003582 for i in range( main.numCtrls ):
3583 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003584 name="setTestAdd-" + str( i ),
3585 args=[ onosSetName, addValue ] )
3586 threads.append( t )
3587 t.start()
3588 for t in threads:
3589 t.join()
3590 addResponses.append( t.result )
3591
3592 # main.TRUE = successfully changed the set
3593 # main.FALSE = action resulted in no change in set
3594 # main.ERROR - Some error in executing the function
3595 addResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003596 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003597 if addResponses[ i ] == main.TRUE:
3598 # All is well
3599 pass
3600 elif addResponses[ i ] == main.FALSE:
3601 # Already in set, probably fine
3602 pass
3603 elif addResponses[ i ] == main.ERROR:
3604 # Error in execution
3605 addResults = main.FALSE
3606 else:
3607 # unexpected result
3608 addResults = main.FALSE
3609 if addResults != main.TRUE:
3610 main.log.error( "Error executing set add" )
3611
3612 # Check if set is still correct
3613 size = len( onosSet )
3614 getResponses = []
3615 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003616 for i in range( main.numCtrls ):
3617 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003618 name="setTestGet-" + str( i ),
3619 args=[ onosSetName ] )
3620 threads.append( t )
3621 t.start()
3622 for t in threads:
3623 t.join()
3624 getResponses.append( t.result )
3625 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003626 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003627 if isinstance( getResponses[ i ], list):
3628 current = set( getResponses[ i ] )
3629 if len( current ) == len( getResponses[ i ] ):
3630 # no repeats
3631 if onosSet != current:
3632 main.log.error( "ONOS" + str( i + 1 ) +
3633 " has incorrect view" +
3634 " of set " + onosSetName + ":\n" +
3635 str( getResponses[ i ] ) )
3636 main.log.debug( "Expected: " + str( onosSet ) )
3637 main.log.debug( "Actual: " + str( current ) )
3638 getResults = main.FALSE
3639 else:
3640 # error, set is not a set
3641 main.log.error( "ONOS" + str( i + 1 ) +
3642 " has repeat elements in" +
3643 " set " + onosSetName + ":\n" +
3644 str( getResponses[ i ] ) )
3645 getResults = main.FALSE
3646 elif getResponses[ i ] == main.ERROR:
3647 getResults = main.FALSE
3648 sizeResponses = []
3649 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003650 for i in range( main.numCtrls ):
3651 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003652 name="setTestSize-" + str( i ),
3653 args=[ onosSetName ] )
3654 threads.append( t )
3655 t.start()
3656 for t in threads:
3657 t.join()
3658 sizeResponses.append( t.result )
3659 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003660 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003661 if size != sizeResponses[ i ]:
3662 sizeResults = main.FALSE
3663 main.log.error( "ONOS" + str( i + 1 ) +
3664 " expected a size of " + str( size ) +
3665 " for set " + onosSetName +
3666 " but got " + str( sizeResponses[ i ] ) )
3667 addResults = addResults and getResults and sizeResults
3668 utilities.assert_equals( expect=main.TRUE,
3669 actual=addResults,
3670 onpass="Set add correct",
3671 onfail="Set add was incorrect" )
3672
3673 main.step( "Distributed Set addAll()" )
3674 onosSet.update( addAllValue.split() )
3675 addResponses = []
3676 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003677 for i in range( main.numCtrls ):
3678 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003679 name="setTestAddAll-" + str( i ),
3680 args=[ onosSetName, addAllValue ] )
3681 threads.append( t )
3682 t.start()
3683 for t in threads:
3684 t.join()
3685 addResponses.append( t.result )
3686
3687 # main.TRUE = successfully changed the set
3688 # main.FALSE = action resulted in no change in set
3689 # main.ERROR - Some error in executing the function
3690 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003691 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003692 if addResponses[ i ] == main.TRUE:
3693 # All is well
3694 pass
3695 elif addResponses[ i ] == main.FALSE:
3696 # Already in set, probably fine
3697 pass
3698 elif addResponses[ i ] == main.ERROR:
3699 # Error in execution
3700 addAllResults = main.FALSE
3701 else:
3702 # unexpected result
3703 addAllResults = main.FALSE
3704 if addAllResults != main.TRUE:
3705 main.log.error( "Error executing set addAll" )
3706
3707 # Check if set is still correct
3708 size = len( onosSet )
3709 getResponses = []
3710 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003711 for i in range( main.numCtrls ):
3712 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003713 name="setTestGet-" + str( i ),
3714 args=[ onosSetName ] )
3715 threads.append( t )
3716 t.start()
3717 for t in threads:
3718 t.join()
3719 getResponses.append( t.result )
3720 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003721 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003722 if isinstance( getResponses[ i ], list):
3723 current = set( getResponses[ i ] )
3724 if len( current ) == len( getResponses[ i ] ):
3725 # no repeats
3726 if onosSet != current:
3727 main.log.error( "ONOS" + str( i + 1 ) +
3728 " has incorrect view" +
3729 " of set " + onosSetName + ":\n" +
3730 str( getResponses[ i ] ) )
3731 main.log.debug( "Expected: " + str( onosSet ) )
3732 main.log.debug( "Actual: " + str( current ) )
3733 getResults = main.FALSE
3734 else:
3735 # error, set is not a set
3736 main.log.error( "ONOS" + str( i + 1 ) +
3737 " has repeat elements in" +
3738 " set " + onosSetName + ":\n" +
3739 str( getResponses[ i ] ) )
3740 getResults = main.FALSE
3741 elif getResponses[ i ] == main.ERROR:
3742 getResults = main.FALSE
3743 sizeResponses = []
3744 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003745 for i in range( main.numCtrls ):
3746 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003747 name="setTestSize-" + str( i ),
3748 args=[ onosSetName ] )
3749 threads.append( t )
3750 t.start()
3751 for t in threads:
3752 t.join()
3753 sizeResponses.append( t.result )
3754 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003755 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003756 if size != sizeResponses[ i ]:
3757 sizeResults = main.FALSE
3758 main.log.error( "ONOS" + str( i + 1 ) +
3759 " expected a size of " + str( size ) +
3760 " for set " + onosSetName +
3761 " but got " + str( sizeResponses[ i ] ) )
3762 addAllResults = addAllResults and getResults and sizeResults
3763 utilities.assert_equals( expect=main.TRUE,
3764 actual=addAllResults,
3765 onpass="Set addAll correct",
3766 onfail="Set addAll was incorrect" )
3767
3768 main.step( "Distributed Set contains()" )
3769 containsResponses = []
3770 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003771 for i in range( main.numCtrls ):
3772 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003773 name="setContains-" + str( i ),
3774 args=[ onosSetName ],
3775 kwargs={ "values": addValue } )
3776 threads.append( t )
3777 t.start()
3778 for t in threads:
3779 t.join()
3780 # NOTE: This is the tuple
3781 containsResponses.append( t.result )
3782
3783 containsResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003784 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003785 if containsResponses[ i ] == main.ERROR:
3786 containsResults = main.FALSE
3787 else:
3788 containsResults = containsResults and\
3789 containsResponses[ i ][ 1 ]
3790 utilities.assert_equals( expect=main.TRUE,
3791 actual=containsResults,
3792 onpass="Set contains is functional",
3793 onfail="Set contains failed" )
3794
3795 main.step( "Distributed Set containsAll()" )
3796 containsAllResponses = []
3797 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003798 for i in range( main.numCtrls ):
3799 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003800 name="setContainsAll-" + str( i ),
3801 args=[ onosSetName ],
3802 kwargs={ "values": addAllValue } )
3803 threads.append( t )
3804 t.start()
3805 for t in threads:
3806 t.join()
3807 # NOTE: This is the tuple
3808 containsAllResponses.append( t.result )
3809
3810 containsAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003811 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003812 if containsResponses[ i ] == main.ERROR:
3813 containsResults = main.FALSE
3814 else:
3815 containsResults = containsResults and\
3816 containsResponses[ i ][ 1 ]
3817 utilities.assert_equals( expect=main.TRUE,
3818 actual=containsAllResults,
3819 onpass="Set containsAll is functional",
3820 onfail="Set containsAll failed" )
3821
3822 main.step( "Distributed Set remove()" )
3823 onosSet.remove( addValue )
3824 removeResponses = []
3825 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003826 for i in range( main.numCtrls ):
3827 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003828 name="setTestRemove-" + str( i ),
3829 args=[ onosSetName, addValue ] )
3830 threads.append( t )
3831 t.start()
3832 for t in threads:
3833 t.join()
3834 removeResponses.append( t.result )
3835
3836 # main.TRUE = successfully changed the set
3837 # main.FALSE = action resulted in no change in set
3838 # main.ERROR - Some error in executing the function
3839 removeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003840 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003841 if removeResponses[ i ] == main.TRUE:
3842 # All is well
3843 pass
3844 elif removeResponses[ i ] == main.FALSE:
3845 # not in set, probably fine
3846 pass
3847 elif removeResponses[ i ] == main.ERROR:
3848 # Error in execution
3849 removeResults = main.FALSE
3850 else:
3851 # unexpected result
3852 removeResults = main.FALSE
3853 if removeResults != main.TRUE:
3854 main.log.error( "Error executing set remove" )
3855
3856 # Check if set is still correct
3857 size = len( onosSet )
3858 getResponses = []
3859 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003860 for i in range( main.numCtrls ):
3861 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003862 name="setTestGet-" + str( i ),
3863 args=[ onosSetName ] )
3864 threads.append( t )
3865 t.start()
3866 for t in threads:
3867 t.join()
3868 getResponses.append( t.result )
3869 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003870 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003871 if isinstance( getResponses[ i ], list):
3872 current = set( getResponses[ i ] )
3873 if len( current ) == len( getResponses[ i ] ):
3874 # no repeats
3875 if onosSet != current:
3876 main.log.error( "ONOS" + str( i + 1 ) +
3877 " has incorrect view" +
3878 " of set " + onosSetName + ":\n" +
3879 str( getResponses[ i ] ) )
3880 main.log.debug( "Expected: " + str( onosSet ) )
3881 main.log.debug( "Actual: " + str( current ) )
3882 getResults = main.FALSE
3883 else:
3884 # error, set is not a set
3885 main.log.error( "ONOS" + str( i + 1 ) +
3886 " has repeat elements in" +
3887 " set " + onosSetName + ":\n" +
3888 str( getResponses[ i ] ) )
3889 getResults = main.FALSE
3890 elif getResponses[ i ] == main.ERROR:
3891 getResults = main.FALSE
3892 sizeResponses = []
3893 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003894 for i in range( main.numCtrls ):
3895 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003896 name="setTestSize-" + str( i ),
3897 args=[ onosSetName ] )
3898 threads.append( t )
3899 t.start()
3900 for t in threads:
3901 t.join()
3902 sizeResponses.append( t.result )
3903 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003904 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003905 if size != sizeResponses[ i ]:
3906 sizeResults = main.FALSE
3907 main.log.error( "ONOS" + str( i + 1 ) +
3908 " expected a size of " + str( size ) +
3909 " for set " + onosSetName +
3910 " but got " + str( sizeResponses[ i ] ) )
3911 removeResults = removeResults and getResults and sizeResults
3912 utilities.assert_equals( expect=main.TRUE,
3913 actual=removeResults,
3914 onpass="Set remove correct",
3915 onfail="Set remove was incorrect" )
3916
3917 main.step( "Distributed Set removeAll()" )
3918 onosSet.difference_update( addAllValue.split() )
3919 removeAllResponses = []
3920 threads = []
3921 try:
Jon Halle1a3b752015-07-22 13:02:46 -07003922 for i in range( main.numCtrls ):
3923 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003924 name="setTestRemoveAll-" + str( i ),
3925 args=[ onosSetName, addAllValue ] )
3926 threads.append( t )
3927 t.start()
3928 for t in threads:
3929 t.join()
3930 removeAllResponses.append( t.result )
3931 except Exception, e:
3932 main.log.exception(e)
3933
3934 # main.TRUE = successfully changed the set
3935 # main.FALSE = action resulted in no change in set
3936 # main.ERROR - Some error in executing the function
3937 removeAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003938 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003939 if removeAllResponses[ i ] == main.TRUE:
3940 # All is well
3941 pass
3942 elif removeAllResponses[ i ] == main.FALSE:
3943 # not in set, probably fine
3944 pass
3945 elif removeAllResponses[ i ] == main.ERROR:
3946 # Error in execution
3947 removeAllResults = main.FALSE
3948 else:
3949 # unexpected result
3950 removeAllResults = main.FALSE
3951 if removeAllResults != main.TRUE:
3952 main.log.error( "Error executing set removeAll" )
3953
3954 # Check if set is still correct
3955 size = len( onosSet )
3956 getResponses = []
3957 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003958 for i in range( main.numCtrls ):
3959 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003960 name="setTestGet-" + str( i ),
3961 args=[ onosSetName ] )
3962 threads.append( t )
3963 t.start()
3964 for t in threads:
3965 t.join()
3966 getResponses.append( t.result )
3967 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003968 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003969 if isinstance( getResponses[ i ], list):
3970 current = set( getResponses[ i ] )
3971 if len( current ) == len( getResponses[ i ] ):
3972 # no repeats
3973 if onosSet != current:
3974 main.log.error( "ONOS" + str( i + 1 ) +
3975 " has incorrect view" +
3976 " of set " + onosSetName + ":\n" +
3977 str( getResponses[ i ] ) )
3978 main.log.debug( "Expected: " + str( onosSet ) )
3979 main.log.debug( "Actual: " + str( current ) )
3980 getResults = main.FALSE
3981 else:
3982 # error, set is not a set
3983 main.log.error( "ONOS" + str( i + 1 ) +
3984 " has repeat elements in" +
3985 " set " + onosSetName + ":\n" +
3986 str( getResponses[ i ] ) )
3987 getResults = main.FALSE
3988 elif getResponses[ i ] == main.ERROR:
3989 getResults = main.FALSE
3990 sizeResponses = []
3991 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003992 for i in range( main.numCtrls ):
3993 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003994 name="setTestSize-" + str( i ),
3995 args=[ onosSetName ] )
3996 threads.append( t )
3997 t.start()
3998 for t in threads:
3999 t.join()
4000 sizeResponses.append( t.result )
4001 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004002 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004003 if size != sizeResponses[ i ]:
4004 sizeResults = main.FALSE
4005 main.log.error( "ONOS" + str( i + 1 ) +
4006 " expected a size of " + str( size ) +
4007 " for set " + onosSetName +
4008 " but got " + str( sizeResponses[ i ] ) )
4009 removeAllResults = removeAllResults and getResults and sizeResults
4010 utilities.assert_equals( expect=main.TRUE,
4011 actual=removeAllResults,
4012 onpass="Set removeAll correct",
4013 onfail="Set removeAll was incorrect" )
4014
4015 main.step( "Distributed Set addAll()" )
4016 onosSet.update( addAllValue.split() )
4017 addResponses = []
4018 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004019 for i in range( main.numCtrls ):
4020 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004021 name="setTestAddAll-" + str( i ),
4022 args=[ onosSetName, addAllValue ] )
4023 threads.append( t )
4024 t.start()
4025 for t in threads:
4026 t.join()
4027 addResponses.append( t.result )
4028
4029 # main.TRUE = successfully changed the set
4030 # main.FALSE = action resulted in no change in set
4031 # main.ERROR - Some error in executing the function
4032 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004033 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004034 if addResponses[ i ] == main.TRUE:
4035 # All is well
4036 pass
4037 elif addResponses[ i ] == main.FALSE:
4038 # Already in set, probably fine
4039 pass
4040 elif addResponses[ i ] == main.ERROR:
4041 # Error in execution
4042 addAllResults = main.FALSE
4043 else:
4044 # unexpected result
4045 addAllResults = main.FALSE
4046 if addAllResults != main.TRUE:
4047 main.log.error( "Error executing set addAll" )
4048
4049 # Check if set is still correct
4050 size = len( onosSet )
4051 getResponses = []
4052 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004053 for i in range( main.numCtrls ):
4054 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004055 name="setTestGet-" + str( i ),
4056 args=[ onosSetName ] )
4057 threads.append( t )
4058 t.start()
4059 for t in threads:
4060 t.join()
4061 getResponses.append( t.result )
4062 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004063 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004064 if isinstance( getResponses[ i ], list):
4065 current = set( getResponses[ i ] )
4066 if len( current ) == len( getResponses[ i ] ):
4067 # no repeats
4068 if onosSet != current:
4069 main.log.error( "ONOS" + str( i + 1 ) +
4070 " has incorrect view" +
4071 " of set " + onosSetName + ":\n" +
4072 str( getResponses[ i ] ) )
4073 main.log.debug( "Expected: " + str( onosSet ) )
4074 main.log.debug( "Actual: " + str( current ) )
4075 getResults = main.FALSE
4076 else:
4077 # error, set is not a set
4078 main.log.error( "ONOS" + str( i + 1 ) +
4079 " has repeat elements in" +
4080 " set " + onosSetName + ":\n" +
4081 str( getResponses[ i ] ) )
4082 getResults = main.FALSE
4083 elif getResponses[ i ] == main.ERROR:
4084 getResults = main.FALSE
4085 sizeResponses = []
4086 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004087 for i in range( main.numCtrls ):
4088 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004089 name="setTestSize-" + str( i ),
4090 args=[ onosSetName ] )
4091 threads.append( t )
4092 t.start()
4093 for t in threads:
4094 t.join()
4095 sizeResponses.append( t.result )
4096 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004097 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004098 if size != sizeResponses[ i ]:
4099 sizeResults = main.FALSE
4100 main.log.error( "ONOS" + str( i + 1 ) +
4101 " expected a size of " + str( size ) +
4102 " for set " + onosSetName +
4103 " but got " + str( sizeResponses[ i ] ) )
4104 addAllResults = addAllResults and getResults and sizeResults
4105 utilities.assert_equals( expect=main.TRUE,
4106 actual=addAllResults,
4107 onpass="Set addAll correct",
4108 onfail="Set addAll was incorrect" )
4109
4110 main.step( "Distributed Set clear()" )
4111 onosSet.clear()
4112 clearResponses = []
4113 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004114 for i in range( main.numCtrls ):
4115 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004116 name="setTestClear-" + str( i ),
4117 args=[ onosSetName, " "], # Values doesn't matter
4118 kwargs={ "clear": True } )
4119 threads.append( t )
4120 t.start()
4121 for t in threads:
4122 t.join()
4123 clearResponses.append( t.result )
4124
4125 # main.TRUE = successfully changed the set
4126 # main.FALSE = action resulted in no change in set
4127 # main.ERROR - Some error in executing the function
4128 clearResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004129 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004130 if clearResponses[ i ] == main.TRUE:
4131 # All is well
4132 pass
4133 elif clearResponses[ i ] == main.FALSE:
4134 # Nothing set, probably fine
4135 pass
4136 elif clearResponses[ i ] == main.ERROR:
4137 # Error in execution
4138 clearResults = main.FALSE
4139 else:
4140 # unexpected result
4141 clearResults = main.FALSE
4142 if clearResults != main.TRUE:
4143 main.log.error( "Error executing set clear" )
4144
4145 # Check if set is still correct
4146 size = len( onosSet )
4147 getResponses = []
4148 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004149 for i in range( main.numCtrls ):
4150 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004151 name="setTestGet-" + str( i ),
4152 args=[ onosSetName ] )
4153 threads.append( t )
4154 t.start()
4155 for t in threads:
4156 t.join()
4157 getResponses.append( t.result )
4158 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004159 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004160 if isinstance( getResponses[ i ], list):
4161 current = set( getResponses[ i ] )
4162 if len( current ) == len( getResponses[ i ] ):
4163 # no repeats
4164 if onosSet != current:
4165 main.log.error( "ONOS" + str( i + 1 ) +
4166 " has incorrect view" +
4167 " of set " + onosSetName + ":\n" +
4168 str( getResponses[ i ] ) )
4169 main.log.debug( "Expected: " + str( onosSet ) )
4170 main.log.debug( "Actual: " + str( current ) )
4171 getResults = main.FALSE
4172 else:
4173 # error, set is not a set
4174 main.log.error( "ONOS" + str( i + 1 ) +
4175 " has repeat elements in" +
4176 " set " + onosSetName + ":\n" +
4177 str( getResponses[ i ] ) )
4178 getResults = main.FALSE
4179 elif getResponses[ i ] == main.ERROR:
4180 getResults = main.FALSE
4181 sizeResponses = []
4182 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004183 for i in range( main.numCtrls ):
4184 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004185 name="setTestSize-" + str( i ),
4186 args=[ onosSetName ] )
4187 threads.append( t )
4188 t.start()
4189 for t in threads:
4190 t.join()
4191 sizeResponses.append( t.result )
4192 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004193 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004194 if size != sizeResponses[ i ]:
4195 sizeResults = main.FALSE
4196 main.log.error( "ONOS" + str( i + 1 ) +
4197 " expected a size of " + str( size ) +
4198 " for set " + onosSetName +
4199 " but got " + str( sizeResponses[ i ] ) )
4200 clearResults = clearResults and getResults and sizeResults
4201 utilities.assert_equals( expect=main.TRUE,
4202 actual=clearResults,
4203 onpass="Set clear correct",
4204 onfail="Set clear was incorrect" )
4205
4206 main.step( "Distributed Set addAll()" )
4207 onosSet.update( addAllValue.split() )
4208 addResponses = []
4209 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004210 for i in range( main.numCtrls ):
4211 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004212 name="setTestAddAll-" + str( i ),
4213 args=[ onosSetName, addAllValue ] )
4214 threads.append( t )
4215 t.start()
4216 for t in threads:
4217 t.join()
4218 addResponses.append( t.result )
4219
4220 # main.TRUE = successfully changed the set
4221 # main.FALSE = action resulted in no change in set
4222 # main.ERROR - Some error in executing the function
4223 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004224 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004225 if addResponses[ i ] == main.TRUE:
4226 # All is well
4227 pass
4228 elif addResponses[ i ] == main.FALSE:
4229 # Already in set, probably fine
4230 pass
4231 elif addResponses[ i ] == main.ERROR:
4232 # Error in execution
4233 addAllResults = main.FALSE
4234 else:
4235 # unexpected result
4236 addAllResults = main.FALSE
4237 if addAllResults != main.TRUE:
4238 main.log.error( "Error executing set addAll" )
4239
4240 # Check if set is still correct
4241 size = len( onosSet )
4242 getResponses = []
4243 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004244 for i in range( main.numCtrls ):
4245 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004246 name="setTestGet-" + str( i ),
4247 args=[ onosSetName ] )
4248 threads.append( t )
4249 t.start()
4250 for t in threads:
4251 t.join()
4252 getResponses.append( t.result )
4253 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004254 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004255 if isinstance( getResponses[ i ], list):
4256 current = set( getResponses[ i ] )
4257 if len( current ) == len( getResponses[ i ] ):
4258 # no repeats
4259 if onosSet != current:
4260 main.log.error( "ONOS" + str( i + 1 ) +
4261 " has incorrect view" +
4262 " of set " + onosSetName + ":\n" +
4263 str( getResponses[ i ] ) )
4264 main.log.debug( "Expected: " + str( onosSet ) )
4265 main.log.debug( "Actual: " + str( current ) )
4266 getResults = main.FALSE
4267 else:
4268 # error, set is not a set
4269 main.log.error( "ONOS" + str( i + 1 ) +
4270 " has repeat elements in" +
4271 " set " + onosSetName + ":\n" +
4272 str( getResponses[ i ] ) )
4273 getResults = main.FALSE
4274 elif getResponses[ i ] == main.ERROR:
4275 getResults = main.FALSE
4276 sizeResponses = []
4277 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004278 for i in range( main.numCtrls ):
4279 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004280 name="setTestSize-" + str( i ),
4281 args=[ onosSetName ] )
4282 threads.append( t )
4283 t.start()
4284 for t in threads:
4285 t.join()
4286 sizeResponses.append( t.result )
4287 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004288 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004289 if size != sizeResponses[ i ]:
4290 sizeResults = main.FALSE
4291 main.log.error( "ONOS" + str( i + 1 ) +
4292 " expected a size of " + str( size ) +
4293 " for set " + onosSetName +
4294 " but got " + str( sizeResponses[ i ] ) )
4295 addAllResults = addAllResults and getResults and sizeResults
4296 utilities.assert_equals( expect=main.TRUE,
4297 actual=addAllResults,
4298 onpass="Set addAll correct",
4299 onfail="Set addAll was incorrect" )
4300
4301 main.step( "Distributed Set retain()" )
4302 onosSet.intersection_update( retainValue.split() )
4303 retainResponses = []
4304 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004305 for i in range( main.numCtrls ):
4306 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004307 name="setTestRetain-" + str( i ),
4308 args=[ onosSetName, retainValue ],
4309 kwargs={ "retain": True } )
4310 threads.append( t )
4311 t.start()
4312 for t in threads:
4313 t.join()
4314 retainResponses.append( t.result )
4315
4316 # main.TRUE = successfully changed the set
4317 # main.FALSE = action resulted in no change in set
4318 # main.ERROR - Some error in executing the function
4319 retainResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004320 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004321 if retainResponses[ i ] == main.TRUE:
4322 # All is well
4323 pass
4324 elif retainResponses[ i ] == main.FALSE:
4325 # Already in set, probably fine
4326 pass
4327 elif retainResponses[ i ] == main.ERROR:
4328 # Error in execution
4329 retainResults = main.FALSE
4330 else:
4331 # unexpected result
4332 retainResults = main.FALSE
4333 if retainResults != main.TRUE:
4334 main.log.error( "Error executing set retain" )
4335
4336 # Check if set is still correct
4337 size = len( onosSet )
4338 getResponses = []
4339 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004340 for i in range( main.numCtrls ):
4341 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004342 name="setTestGet-" + str( i ),
4343 args=[ onosSetName ] )
4344 threads.append( t )
4345 t.start()
4346 for t in threads:
4347 t.join()
4348 getResponses.append( t.result )
4349 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004350 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004351 if isinstance( getResponses[ i ], list):
4352 current = set( getResponses[ i ] )
4353 if len( current ) == len( getResponses[ i ] ):
4354 # no repeats
4355 if onosSet != current:
4356 main.log.error( "ONOS" + str( i + 1 ) +
4357 " has incorrect view" +
4358 " of set " + onosSetName + ":\n" +
4359 str( getResponses[ i ] ) )
4360 main.log.debug( "Expected: " + str( onosSet ) )
4361 main.log.debug( "Actual: " + str( current ) )
4362 getResults = main.FALSE
4363 else:
4364 # error, set is not a set
4365 main.log.error( "ONOS" + str( i + 1 ) +
4366 " has repeat elements in" +
4367 " set " + onosSetName + ":\n" +
4368 str( getResponses[ i ] ) )
4369 getResults = main.FALSE
4370 elif getResponses[ i ] == main.ERROR:
4371 getResults = main.FALSE
4372 sizeResponses = []
4373 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004374 for i in range( main.numCtrls ):
4375 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004376 name="setTestSize-" + str( i ),
4377 args=[ onosSetName ] )
4378 threads.append( t )
4379 t.start()
4380 for t in threads:
4381 t.join()
4382 sizeResponses.append( t.result )
4383 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004384 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004385 if size != sizeResponses[ i ]:
4386 sizeResults = main.FALSE
4387 main.log.error( "ONOS" + str( i + 1 ) +
4388 " expected a size of " +
4389 str( size ) + " for set " + onosSetName +
4390 " but got " + str( sizeResponses[ i ] ) )
4391 retainResults = retainResults and getResults and sizeResults
4392 utilities.assert_equals( expect=main.TRUE,
4393 actual=retainResults,
4394 onpass="Set retain correct",
4395 onfail="Set retain was incorrect" )
4396
Jon Hall2a5002c2015-08-21 16:49:11 -07004397 # Transactional maps
4398 main.step( "Partitioned Transactional maps put" )
4399 tMapValue = "Testing"
4400 numKeys = 100
4401 putResult = True
4402 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue )
4403 if len( putResponses ) == 100:
4404 for i in putResponses:
4405 if putResponses[ i ][ 'value' ] != tMapValue:
4406 putResult = False
4407 else:
4408 putResult = False
4409 if not putResult:
4410 main.log.debug( "Put response values: " + str( putResponses ) )
4411 utilities.assert_equals( expect=True,
4412 actual=putResult,
4413 onpass="Partitioned Transactional Map put successful",
4414 onfail="Partitioned Transactional Map put values are incorrect" )
4415
4416 main.step( "Partitioned Transactional maps get" )
4417 getCheck = True
4418 for n in range( 1, numKeys + 1 ):
4419 getResponses = []
4420 threads = []
4421 valueCheck = True
4422 for i in range( main.numCtrls ):
4423 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4424 name="TMap-get-" + str( i ),
4425 args=[ "Key" + str ( n ) ] )
4426 threads.append( t )
4427 t.start()
4428 for t in threads:
4429 t.join()
4430 getResponses.append( t.result )
4431 for node in getResponses:
4432 if node != tMapValue:
4433 valueCheck = False
4434 if not valueCheck:
4435 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4436 main.log.warn( getResponses )
4437 getCheck = getCheck and valueCheck
4438 utilities.assert_equals( expect=True,
4439 actual=getCheck,
4440 onpass="Partitioned Transactional Map get values were correct",
4441 onfail="Partitioned Transactional Map values incorrect" )
4442
4443 main.step( "In-memory Transactional maps put" )
4444 tMapValue = "Testing"
4445 numKeys = 100
4446 putResult = True
4447 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue, inMemory=True )
4448 if len( putResponses ) == 100:
4449 for i in putResponses:
4450 if putResponses[ i ][ 'value' ] != tMapValue:
4451 putResult = False
4452 else:
4453 putResult = False
4454 if not putResult:
4455 main.log.debug( "Put response values: " + str( putResponses ) )
4456 utilities.assert_equals( expect=True,
4457 actual=putResult,
4458 onpass="In-Memory Transactional Map put successful",
4459 onfail="In-Memory Transactional Map put values are incorrect" )
4460
4461 main.step( "In-Memory Transactional maps get" )
4462 getCheck = True
4463 for n in range( 1, numKeys + 1 ):
4464 getResponses = []
4465 threads = []
4466 valueCheck = True
4467 for i in range( main.numCtrls ):
4468 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4469 name="TMap-get-" + str( i ),
4470 args=[ "Key" + str ( n ) ],
4471 kwargs={ "inMemory": True } )
4472 threads.append( t )
4473 t.start()
4474 for t in threads:
4475 t.join()
4476 getResponses.append( t.result )
4477 for node in getResponses:
4478 if node != tMapValue:
4479 valueCheck = False
4480 if not valueCheck:
4481 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4482 main.log.warn( getResponses )
4483 getCheck = getCheck and valueCheck
4484 utilities.assert_equals( expect=True,
4485 actual=getCheck,
4486 onpass="In-Memory Transactional Map get values were correct",
4487 onfail="In-Memory Transactional Map values incorrect" )