blob: 79d575b3e4dca4dcfe7cd6040ffade58dacd545c [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
Jon Hall96091e62015-09-21 17:34:17 -0700513 passMsg = "Reactive Pingall test passed"
514 time1 = time.time()
515 pingResult = main.Mininet1.pingall()
516 time2 = time.time()
517 if not pingResult:
518 main.log.warn("First pingall failed. Trying again...")
Jon Hall5cf14d52015-07-16 12:15:19 -0700519 pingResult = main.Mininet1.pingall()
Jon Hall96091e62015-09-21 17:34:17 -0700520 passMsg += " on the second try"
521 utilities.assert_equals(
522 expect=main.TRUE,
523 actual=pingResult,
524 onpass= passMsg,
525 onfail="Reactive Pingall failed, " +
526 "one or more ping pairs failed" )
527 main.log.info( "Time for pingall: %2f seconds" %
528 ( time2 - time1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -0700529 # timeout for fwd flows
530 time.sleep( 11 )
531 # uninstall onos-app-fwd
532 main.step( "Uninstall reactive forwarding app" )
Jon Halle1a3b752015-07-22 13:02:46 -0700533 uninstallResult = main.CLIs[0].deactivateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700534 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
535 onpass="Uninstall fwd successful",
536 onfail="Uninstall fwd failed" )
537
538 main.step( "Check app ids" )
539 threads = []
540 appCheck2 = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700541 for i in range( main.numCtrls ):
542 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700543 name="appToIDCheck-" + str( i ),
544 args=[] )
545 threads.append( t )
546 t.start()
547
548 for t in threads:
549 t.join()
550 appCheck2 = appCheck2 and t.result
551 if appCheck2 != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700552 main.log.warn( main.CLIs[0].apps() )
553 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700554 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
555 onpass="App Ids seem to be correct",
556 onfail="Something is wrong with app Ids" )
557
558 main.step( "Add host intents via cli" )
559 intentIds = []
560 # TODO: move the host numbers to params
561 # Maybe look at all the paths we ping?
562 intentAddResult = True
563 hostResult = main.TRUE
564 for i in range( 8, 18 ):
565 main.log.info( "Adding host intent between h" + str( i ) +
566 " and h" + str( i + 10 ) )
567 host1 = "00:00:00:00:00:" + \
568 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
569 host2 = "00:00:00:00:00:" + \
570 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
571 # NOTE: getHost can return None
572 host1Dict = main.ONOScli1.getHost( host1 )
573 host2Dict = main.ONOScli1.getHost( host2 )
574 host1Id = None
575 host2Id = None
576 if host1Dict and host2Dict:
577 host1Id = host1Dict.get( 'id', None )
578 host2Id = host2Dict.get( 'id', None )
579 if host1Id and host2Id:
Jon Halle1a3b752015-07-22 13:02:46 -0700580 nodeNum = ( i % main.numCtrls )
581 tmpId = main.CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
Jon Hall5cf14d52015-07-16 12:15:19 -0700582 if tmpId:
583 main.log.info( "Added intent with id: " + tmpId )
584 intentIds.append( tmpId )
585 else:
586 main.log.error( "addHostIntent returned: " +
587 repr( tmpId ) )
588 else:
589 main.log.error( "Error, getHost() failed for h" + str( i ) +
590 " and/or h" + str( i + 10 ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700591 hosts = main.CLIs[ 0 ].hosts()
Jon Hall5cf14d52015-07-16 12:15:19 -0700592 main.log.warn( "Hosts output: " )
593 try:
594 main.log.warn( json.dumps( json.loads( hosts ),
595 sort_keys=True,
596 indent=4,
597 separators=( ',', ': ' ) ) )
598 except ( ValueError, TypeError ):
599 main.log.warn( repr( hosts ) )
600 hostResult = main.FALSE
601 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
602 onpass="Found a host id for each host",
603 onfail="Error looking up host ids" )
604
605 intentStart = time.time()
606 onosIds = main.ONOScli1.getAllIntentsId()
607 main.log.info( "Submitted intents: " + str( intentIds ) )
608 main.log.info( "Intents in ONOS: " + str( onosIds ) )
609 for intent in intentIds:
610 if intent in onosIds:
611 pass # intent submitted is in onos
612 else:
613 intentAddResult = False
614 if intentAddResult:
615 intentStop = time.time()
616 else:
617 intentStop = None
618 # Print the intent states
619 intents = main.ONOScli1.intents()
620 intentStates = []
621 installedCheck = True
622 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
623 count = 0
624 try:
625 for intent in json.loads( intents ):
626 state = intent.get( 'state', None )
627 if "INSTALLED" not in state:
628 installedCheck = False
629 intentId = intent.get( 'id', None )
630 intentStates.append( ( intentId, state ) )
631 except ( ValueError, TypeError ):
632 main.log.exception( "Error parsing intents" )
633 # add submitted intents not in the store
634 tmplist = [ i for i, s in intentStates ]
635 missingIntents = False
636 for i in intentIds:
637 if i not in tmplist:
638 intentStates.append( ( i, " - " ) )
639 missingIntents = True
640 intentStates.sort()
641 for i, s in intentStates:
642 count += 1
643 main.log.info( "%-6s%-15s%-15s" %
644 ( str( count ), str( i ), str( s ) ) )
645 leaders = main.ONOScli1.leaders()
646 try:
647 missing = False
648 if leaders:
649 parsedLeaders = json.loads( leaders )
650 main.log.warn( json.dumps( parsedLeaders,
651 sort_keys=True,
652 indent=4,
653 separators=( ',', ': ' ) ) )
654 # check for all intent partitions
655 topics = []
656 for i in range( 14 ):
657 topics.append( "intent-partition-" + str( i ) )
658 main.log.debug( topics )
659 ONOStopics = [ j['topic'] for j in parsedLeaders ]
660 for topic in topics:
661 if topic not in ONOStopics:
662 main.log.error( "Error: " + topic +
663 " not in leaders" )
664 missing = True
665 else:
666 main.log.error( "leaders() returned None" )
667 except ( ValueError, TypeError ):
668 main.log.exception( "Error parsing leaders" )
669 main.log.error( repr( leaders ) )
670 # Check all nodes
671 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -0700672 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700673 response = node.leaders( jsonFormat=False)
674 main.log.warn( str( node.name ) + " leaders output: \n" +
675 str( response ) )
676
677 partitions = main.ONOScli1.partitions()
678 try:
679 if partitions :
680 parsedPartitions = json.loads( partitions )
681 main.log.warn( json.dumps( parsedPartitions,
682 sort_keys=True,
683 indent=4,
684 separators=( ',', ': ' ) ) )
685 # TODO check for a leader in all paritions
686 # TODO check for consistency among nodes
687 else:
688 main.log.error( "partitions() returned None" )
689 except ( ValueError, TypeError ):
690 main.log.exception( "Error parsing partitions" )
691 main.log.error( repr( partitions ) )
692 pendingMap = main.ONOScli1.pendingMap()
693 try:
694 if pendingMap :
695 parsedPending = json.loads( pendingMap )
696 main.log.warn( json.dumps( parsedPending,
697 sort_keys=True,
698 indent=4,
699 separators=( ',', ': ' ) ) )
700 # TODO check something here?
701 else:
702 main.log.error( "pendingMap() returned None" )
703 except ( ValueError, TypeError ):
704 main.log.exception( "Error parsing pending map" )
705 main.log.error( repr( pendingMap ) )
706
707 intentAddResult = bool( intentAddResult and not missingIntents and
708 installedCheck )
709 if not intentAddResult:
710 main.log.error( "Error in pushing host intents to ONOS" )
711
712 main.step( "Intent Anti-Entropy dispersion" )
713 for i in range(100):
714 correct = True
715 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700716 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700717 onosIds = []
718 ids = cli.getAllIntentsId()
719 onosIds.append( ids )
720 main.log.debug( "Intents in " + cli.name + ": " +
721 str( sorted( onosIds ) ) )
722 if sorted( ids ) != sorted( intentIds ):
723 main.log.warn( "Set of intent IDs doesn't match" )
724 correct = False
725 break
726 else:
727 intents = json.loads( cli.intents() )
728 for intent in intents:
729 if intent[ 'state' ] != "INSTALLED":
730 main.log.warn( "Intent " + intent[ 'id' ] +
731 " is " + intent[ 'state' ] )
732 correct = False
733 break
734 if correct:
735 break
736 else:
737 time.sleep(1)
738 if not intentStop:
739 intentStop = time.time()
740 global gossipTime
741 gossipTime = intentStop - intentStart
742 main.log.info( "It took about " + str( gossipTime ) +
743 " seconds for all intents to appear in each node" )
744 append = False
745 title = "Gossip Intents"
746 count = 1
747 while append is False:
748 curTitle = title + str( count )
749 if curTitle not in labels:
750 labels.append( curTitle )
751 data.append( str( gossipTime ) )
752 append = True
753 else:
754 count += 1
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700755 gossipPeriod = int( main.params['timers']['gossip'] )
756 maxGossipTime = gossipPeriod * len( main.nodes )
Jon Hall5cf14d52015-07-16 12:15:19 -0700757 utilities.assert_greater_equals(
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700758 expect=maxGossipTime, actual=gossipTime,
Jon Hall5cf14d52015-07-16 12:15:19 -0700759 onpass="ECM anti-entropy for intents worked within " +
760 "expected time",
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700761 onfail="Intent ECM anti-entropy took too long. " +
762 "Expected time:{}, Actual time:{}".format( maxGossipTime,
763 gossipTime ) )
764 if gossipTime <= maxGossipTime:
Jon Hall5cf14d52015-07-16 12:15:19 -0700765 intentAddResult = True
766
767 if not intentAddResult or "key" in pendingMap:
768 import time
769 installedCheck = True
770 main.log.info( "Sleeping 60 seconds to see if intents are found" )
771 time.sleep( 60 )
772 onosIds = main.ONOScli1.getAllIntentsId()
773 main.log.info( "Submitted intents: " + str( intentIds ) )
774 main.log.info( "Intents in ONOS: " + str( onosIds ) )
775 # Print the intent states
776 intents = main.ONOScli1.intents()
777 intentStates = []
778 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
779 count = 0
780 try:
781 for intent in json.loads( intents ):
782 # Iter through intents of a node
783 state = intent.get( 'state', None )
784 if "INSTALLED" not in state:
785 installedCheck = False
786 intentId = intent.get( 'id', None )
787 intentStates.append( ( intentId, state ) )
788 except ( ValueError, TypeError ):
789 main.log.exception( "Error parsing intents" )
790 # add submitted intents not in the store
791 tmplist = [ i for i, s in intentStates ]
792 for i in intentIds:
793 if i not in tmplist:
794 intentStates.append( ( i, " - " ) )
795 intentStates.sort()
796 for i, s in intentStates:
797 count += 1
798 main.log.info( "%-6s%-15s%-15s" %
799 ( str( count ), str( i ), str( s ) ) )
800 leaders = main.ONOScli1.leaders()
801 try:
802 missing = False
803 if leaders:
804 parsedLeaders = json.loads( leaders )
805 main.log.warn( json.dumps( parsedLeaders,
806 sort_keys=True,
807 indent=4,
808 separators=( ',', ': ' ) ) )
809 # check for all intent partitions
810 # check for election
811 topics = []
812 for i in range( 14 ):
813 topics.append( "intent-partition-" + str( i ) )
814 # FIXME: this should only be after we start the app
815 topics.append( "org.onosproject.election" )
816 main.log.debug( topics )
817 ONOStopics = [ j['topic'] for j in parsedLeaders ]
818 for topic in topics:
819 if topic not in ONOStopics:
820 main.log.error( "Error: " + topic +
821 " not in leaders" )
822 missing = True
823 else:
824 main.log.error( "leaders() returned None" )
825 except ( ValueError, TypeError ):
826 main.log.exception( "Error parsing leaders" )
827 main.log.error( repr( leaders ) )
828 # Check all nodes
829 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -0700830 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700831 response = node.leaders( jsonFormat=False)
832 main.log.warn( str( node.name ) + " leaders output: \n" +
833 str( response ) )
834
835 partitions = main.ONOScli1.partitions()
836 try:
837 if partitions :
838 parsedPartitions = json.loads( partitions )
839 main.log.warn( json.dumps( parsedPartitions,
840 sort_keys=True,
841 indent=4,
842 separators=( ',', ': ' ) ) )
843 # TODO check for a leader in all paritions
844 # TODO check for consistency among nodes
845 else:
846 main.log.error( "partitions() returned None" )
847 except ( ValueError, TypeError ):
848 main.log.exception( "Error parsing partitions" )
849 main.log.error( repr( partitions ) )
850 pendingMap = main.ONOScli1.pendingMap()
851 try:
852 if pendingMap :
853 parsedPending = json.loads( pendingMap )
854 main.log.warn( json.dumps( parsedPending,
855 sort_keys=True,
856 indent=4,
857 separators=( ',', ': ' ) ) )
858 # TODO check something here?
859 else:
860 main.log.error( "pendingMap() returned None" )
861 except ( ValueError, TypeError ):
862 main.log.exception( "Error parsing pending map" )
863 main.log.error( repr( pendingMap ) )
864
865 def CASE4( self, main ):
866 """
867 Ping across added host intents
868 """
869 import json
870 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700871 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700872 assert main, "main not defined"
873 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700874 assert main.CLIs, "main.CLIs not defined"
875 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700876 main.case( "Verify connectivity by sendind traffic across Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700877 main.caseExplanation = "Ping across added host intents to check " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700878 "functionality and check the state of " +\
879 "the intent"
880 main.step( "Ping across added host intents" )
881 PingResult = main.TRUE
882 for i in range( 8, 18 ):
883 ping = main.Mininet1.pingHost( src="h" + str( i ),
884 target="h" + str( i + 10 ) )
885 PingResult = PingResult and ping
886 if ping == main.FALSE:
887 main.log.warn( "Ping failed between h" + str( i ) +
888 " and h" + str( i + 10 ) )
889 elif ping == main.TRUE:
890 main.log.info( "Ping test passed!" )
891 # Don't set PingResult or you'd override failures
892 if PingResult == main.FALSE:
893 main.log.error(
894 "Intents have not been installed correctly, pings failed." )
895 # TODO: pretty print
896 main.log.warn( "ONOS1 intents: " )
897 try:
898 tmpIntents = main.ONOScli1.intents()
899 main.log.warn( json.dumps( json.loads( tmpIntents ),
900 sort_keys=True,
901 indent=4,
902 separators=( ',', ': ' ) ) )
903 except ( ValueError, TypeError ):
904 main.log.warn( repr( tmpIntents ) )
905 utilities.assert_equals(
906 expect=main.TRUE,
907 actual=PingResult,
908 onpass="Intents have been installed correctly and pings work",
909 onfail="Intents have not been installed correctly, pings failed." )
910
911 main.step( "Check Intent state" )
912 installedCheck = False
913 loopCount = 0
914 while not installedCheck and loopCount < 40:
915 installedCheck = True
916 # Print the intent states
917 intents = main.ONOScli1.intents()
918 intentStates = []
919 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700920 count = 0
Jon Hall5cf14d52015-07-16 12:15:19 -0700921 # Iter through intents of a node
922 try:
923 for intent in json.loads( intents ):
924 state = intent.get( 'state', None )
925 if "INSTALLED" not in state:
926 installedCheck = False
927 intentId = intent.get( 'id', None )
928 intentStates.append( ( intentId, state ) )
929 except ( ValueError, TypeError ):
930 main.log.exception( "Error parsing intents." )
931 # Print states
932 intentStates.sort()
933 for i, s in intentStates:
934 count += 1
935 main.log.info( "%-6s%-15s%-15s" %
936 ( str( count ), str( i ), str( s ) ) )
937 if not installedCheck:
938 time.sleep( 1 )
939 loopCount += 1
940 utilities.assert_equals( expect=True, actual=installedCheck,
941 onpass="Intents are all INSTALLED",
942 onfail="Intents are not all in " +
943 "INSTALLED state" )
944
945 main.step( "Check leadership of topics" )
946 leaders = main.ONOScli1.leaders()
947 topicCheck = main.TRUE
948 try:
949 if leaders:
950 parsedLeaders = json.loads( leaders )
951 main.log.warn( json.dumps( parsedLeaders,
952 sort_keys=True,
953 indent=4,
954 separators=( ',', ': ' ) ) )
955 # check for all intent partitions
956 # check for election
957 # TODO: Look at Devices as topics now that it uses this system
958 topics = []
959 for i in range( 14 ):
960 topics.append( "intent-partition-" + str( i ) )
961 # FIXME: this should only be after we start the app
962 # FIXME: topics.append( "org.onosproject.election" )
963 # Print leaders output
964 main.log.debug( topics )
965 ONOStopics = [ j['topic'] for j in parsedLeaders ]
966 for topic in topics:
967 if topic not in ONOStopics:
968 main.log.error( "Error: " + topic +
969 " not in leaders" )
970 topicCheck = main.FALSE
971 else:
972 main.log.error( "leaders() returned None" )
973 topicCheck = main.FALSE
974 except ( ValueError, TypeError ):
975 topicCheck = main.FALSE
976 main.log.exception( "Error parsing leaders" )
977 main.log.error( repr( leaders ) )
978 # TODO: Check for a leader of these topics
979 # Check all nodes
980 if topicCheck:
Jon Halle1a3b752015-07-22 13:02:46 -0700981 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700982 response = node.leaders( jsonFormat=False)
983 main.log.warn( str( node.name ) + " leaders output: \n" +
984 str( response ) )
985
986 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
987 onpass="intent Partitions is in leaders",
988 onfail="Some topics were lost " )
989 # Print partitions
990 partitions = main.ONOScli1.partitions()
991 try:
992 if partitions :
993 parsedPartitions = json.loads( partitions )
994 main.log.warn( json.dumps( parsedPartitions,
995 sort_keys=True,
996 indent=4,
997 separators=( ',', ': ' ) ) )
998 # TODO check for a leader in all paritions
999 # TODO check for consistency among nodes
1000 else:
1001 main.log.error( "partitions() returned None" )
1002 except ( ValueError, TypeError ):
1003 main.log.exception( "Error parsing partitions" )
1004 main.log.error( repr( partitions ) )
1005 # Print Pending Map
1006 pendingMap = main.ONOScli1.pendingMap()
1007 try:
1008 if pendingMap :
1009 parsedPending = json.loads( pendingMap )
1010 main.log.warn( json.dumps( parsedPending,
1011 sort_keys=True,
1012 indent=4,
1013 separators=( ',', ': ' ) ) )
1014 # TODO check something here?
1015 else:
1016 main.log.error( "pendingMap() returned None" )
1017 except ( ValueError, TypeError ):
1018 main.log.exception( "Error parsing pending map" )
1019 main.log.error( repr( pendingMap ) )
1020
1021 if not installedCheck:
1022 main.log.info( "Waiting 60 seconds to see if the state of " +
1023 "intents change" )
1024 time.sleep( 60 )
1025 # Print the intent states
1026 intents = main.ONOScli1.intents()
1027 intentStates = []
1028 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
1029 count = 0
1030 # Iter through intents of a node
1031 try:
1032 for intent in json.loads( intents ):
1033 state = intent.get( 'state', None )
1034 if "INSTALLED" not in state:
1035 installedCheck = False
1036 intentId = intent.get( 'id', None )
1037 intentStates.append( ( intentId, state ) )
1038 except ( ValueError, TypeError ):
1039 main.log.exception( "Error parsing intents." )
1040 intentStates.sort()
1041 for i, s in intentStates:
1042 count += 1
1043 main.log.info( "%-6s%-15s%-15s" %
1044 ( str( count ), str( i ), str( s ) ) )
1045 leaders = main.ONOScli1.leaders()
1046 try:
1047 missing = False
1048 if leaders:
1049 parsedLeaders = json.loads( leaders )
1050 main.log.warn( json.dumps( parsedLeaders,
1051 sort_keys=True,
1052 indent=4,
1053 separators=( ',', ': ' ) ) )
1054 # check for all intent partitions
1055 # check for election
1056 topics = []
1057 for i in range( 14 ):
1058 topics.append( "intent-partition-" + str( i ) )
1059 # FIXME: this should only be after we start the app
1060 topics.append( "org.onosproject.election" )
1061 main.log.debug( topics )
1062 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1063 for topic in topics:
1064 if topic not in ONOStopics:
1065 main.log.error( "Error: " + topic +
1066 " not in leaders" )
1067 missing = True
1068 else:
1069 main.log.error( "leaders() returned None" )
1070 except ( ValueError, TypeError ):
1071 main.log.exception( "Error parsing leaders" )
1072 main.log.error( repr( leaders ) )
1073 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -07001074 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07001075 response = node.leaders( jsonFormat=False)
1076 main.log.warn( str( node.name ) + " leaders output: \n" +
1077 str( response ) )
1078
1079 partitions = main.ONOScli1.partitions()
1080 try:
1081 if partitions :
1082 parsedPartitions = json.loads( partitions )
1083 main.log.warn( json.dumps( parsedPartitions,
1084 sort_keys=True,
1085 indent=4,
1086 separators=( ',', ': ' ) ) )
1087 # TODO check for a leader in all paritions
1088 # TODO check for consistency among nodes
1089 else:
1090 main.log.error( "partitions() returned None" )
1091 except ( ValueError, TypeError ):
1092 main.log.exception( "Error parsing partitions" )
1093 main.log.error( repr( partitions ) )
1094 pendingMap = main.ONOScli1.pendingMap()
1095 try:
1096 if pendingMap :
1097 parsedPending = json.loads( pendingMap )
1098 main.log.warn( json.dumps( parsedPending,
1099 sort_keys=True,
1100 indent=4,
1101 separators=( ',', ': ' ) ) )
1102 # TODO check something here?
1103 else:
1104 main.log.error( "pendingMap() returned None" )
1105 except ( ValueError, TypeError ):
1106 main.log.exception( "Error parsing pending map" )
1107 main.log.error( repr( pendingMap ) )
1108 # Print flowrules
Jon Halle1a3b752015-07-22 13:02:46 -07001109 main.log.debug( main.CLIs[0].flows( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001110 main.step( "Wait a minute then ping again" )
1111 # the wait is above
1112 PingResult = main.TRUE
1113 for i in range( 8, 18 ):
1114 ping = main.Mininet1.pingHost( src="h" + str( i ),
1115 target="h" + str( i + 10 ) )
1116 PingResult = PingResult and ping
1117 if ping == main.FALSE:
1118 main.log.warn( "Ping failed between h" + str( i ) +
1119 " and h" + str( i + 10 ) )
1120 elif ping == main.TRUE:
1121 main.log.info( "Ping test passed!" )
1122 # Don't set PingResult or you'd override failures
1123 if PingResult == main.FALSE:
1124 main.log.error(
1125 "Intents have not been installed correctly, pings failed." )
1126 # TODO: pretty print
1127 main.log.warn( "ONOS1 intents: " )
1128 try:
1129 tmpIntents = main.ONOScli1.intents()
1130 main.log.warn( json.dumps( json.loads( tmpIntents ),
1131 sort_keys=True,
1132 indent=4,
1133 separators=( ',', ': ' ) ) )
1134 except ( ValueError, TypeError ):
1135 main.log.warn( repr( tmpIntents ) )
1136 utilities.assert_equals(
1137 expect=main.TRUE,
1138 actual=PingResult,
1139 onpass="Intents have been installed correctly and pings work",
1140 onfail="Intents have not been installed correctly, pings failed." )
1141
1142 def CASE5( self, main ):
1143 """
1144 Reading state of ONOS
1145 """
1146 import json
1147 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001148 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001149 assert main, "main not defined"
1150 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001151 assert main.CLIs, "main.CLIs not defined"
1152 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001153
1154 main.case( "Setting up and gathering data for current state" )
1155 # The general idea for this test case is to pull the state of
1156 # ( intents,flows, topology,... ) from each ONOS node
1157 # We can then compare them with each other and also with past states
1158
1159 main.step( "Check that each switch has a master" )
1160 global mastershipState
1161 mastershipState = '[]'
1162
1163 # Assert that each device has a master
1164 rolesNotNull = main.TRUE
1165 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001166 for i in range( main.numCtrls ):
1167 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001168 name="rolesNotNull-" + str( i ),
1169 args=[] )
1170 threads.append( t )
1171 t.start()
1172
1173 for t in threads:
1174 t.join()
1175 rolesNotNull = rolesNotNull and t.result
1176 utilities.assert_equals(
1177 expect=main.TRUE,
1178 actual=rolesNotNull,
1179 onpass="Each device has a master",
1180 onfail="Some devices don't have a master assigned" )
1181
1182 main.step( "Get the Mastership of each switch from each controller" )
1183 ONOSMastership = []
1184 mastershipCheck = main.FALSE
1185 consistentMastership = True
1186 rolesResults = True
1187 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001188 for i in range( main.numCtrls ):
1189 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001190 name="roles-" + str( i ),
1191 args=[] )
1192 threads.append( t )
1193 t.start()
1194
1195 for t in threads:
1196 t.join()
1197 ONOSMastership.append( t.result )
1198
Jon Halle1a3b752015-07-22 13:02:46 -07001199 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001200 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1201 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1202 " roles" )
1203 main.log.warn(
1204 "ONOS" + str( i + 1 ) + " mastership response: " +
1205 repr( ONOSMastership[i] ) )
1206 rolesResults = False
1207 utilities.assert_equals(
1208 expect=True,
1209 actual=rolesResults,
1210 onpass="No error in reading roles output",
1211 onfail="Error in reading roles from ONOS" )
1212
1213 main.step( "Check for consistency in roles from each controller" )
1214 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1215 main.log.info(
1216 "Switch roles are consistent across all ONOS nodes" )
1217 else:
1218 consistentMastership = False
1219 utilities.assert_equals(
1220 expect=True,
1221 actual=consistentMastership,
1222 onpass="Switch roles are consistent across all ONOS nodes",
1223 onfail="ONOS nodes have different views of switch roles" )
1224
1225 if rolesResults and not consistentMastership:
Jon Halle1a3b752015-07-22 13:02:46 -07001226 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001227 try:
1228 main.log.warn(
1229 "ONOS" + str( i + 1 ) + " roles: ",
1230 json.dumps(
1231 json.loads( ONOSMastership[ i ] ),
1232 sort_keys=True,
1233 indent=4,
1234 separators=( ',', ': ' ) ) )
1235 except ( ValueError, TypeError ):
1236 main.log.warn( repr( ONOSMastership[ i ] ) )
1237 elif rolesResults and consistentMastership:
1238 mastershipCheck = main.TRUE
1239 mastershipState = ONOSMastership[ 0 ]
1240
1241 main.step( "Get the intents from each controller" )
1242 global intentState
1243 intentState = []
1244 ONOSIntents = []
1245 intentCheck = main.FALSE
1246 consistentIntents = True
1247 intentsResults = True
1248 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001249 for i in range( main.numCtrls ):
1250 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001251 name="intents-" + str( i ),
1252 args=[],
1253 kwargs={ 'jsonFormat': True } )
1254 threads.append( t )
1255 t.start()
1256
1257 for t in threads:
1258 t.join()
1259 ONOSIntents.append( t.result )
1260
Jon Halle1a3b752015-07-22 13:02:46 -07001261 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001262 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1263 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1264 " intents" )
1265 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1266 repr( ONOSIntents[ i ] ) )
1267 intentsResults = False
1268 utilities.assert_equals(
1269 expect=True,
1270 actual=intentsResults,
1271 onpass="No error in reading intents output",
1272 onfail="Error in reading intents from ONOS" )
1273
1274 main.step( "Check for consistency in Intents from each controller" )
1275 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1276 main.log.info( "Intents are consistent across all ONOS " +
1277 "nodes" )
1278 else:
1279 consistentIntents = False
1280 main.log.error( "Intents not consistent" )
1281 utilities.assert_equals(
1282 expect=True,
1283 actual=consistentIntents,
1284 onpass="Intents are consistent across all ONOS nodes",
1285 onfail="ONOS nodes have different views of intents" )
1286
1287 if intentsResults:
1288 # Try to make it easy to figure out what is happening
1289 #
1290 # Intent ONOS1 ONOS2 ...
1291 # 0x01 INSTALLED INSTALLING
1292 # ... ... ...
1293 # ... ... ...
1294 title = " Id"
Jon Halle1a3b752015-07-22 13:02:46 -07001295 for n in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001296 title += " " * 10 + "ONOS" + str( n + 1 )
1297 main.log.warn( title )
1298 # get all intent keys in the cluster
1299 keys = []
1300 for nodeStr in ONOSIntents:
1301 node = json.loads( nodeStr )
1302 for intent in node:
1303 keys.append( intent.get( 'id' ) )
1304 keys = set( keys )
1305 for key in keys:
1306 row = "%-13s" % key
1307 for nodeStr in ONOSIntents:
1308 node = json.loads( nodeStr )
1309 for intent in node:
1310 if intent.get( 'id', "Error" ) == key:
1311 row += "%-15s" % intent.get( 'state' )
1312 main.log.warn( row )
1313 # End table view
1314
1315 if intentsResults and not consistentIntents:
1316 # print the json objects
1317 n = len(ONOSIntents)
1318 main.log.debug( "ONOS" + str( n ) + " intents: " )
1319 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1320 sort_keys=True,
1321 indent=4,
1322 separators=( ',', ': ' ) ) )
Jon Halle1a3b752015-07-22 13:02:46 -07001323 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001324 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
1325 main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
1326 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1327 sort_keys=True,
1328 indent=4,
1329 separators=( ',', ': ' ) ) )
1330 else:
Jon Halle1a3b752015-07-22 13:02:46 -07001331 main.log.debug( main.nodes[ i ].name + " intents match ONOS" +
Jon Hall5cf14d52015-07-16 12:15:19 -07001332 str( n ) + " intents" )
1333 elif intentsResults and consistentIntents:
1334 intentCheck = main.TRUE
1335 intentState = ONOSIntents[ 0 ]
1336
1337 main.step( "Get the flows from each controller" )
1338 global flowState
1339 flowState = []
1340 ONOSFlows = []
1341 ONOSFlowsJson = []
1342 flowCheck = main.FALSE
1343 consistentFlows = True
1344 flowsResults = True
1345 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001346 for i in range( main.numCtrls ):
1347 t = main.Thread( target=main.CLIs[i].flows,
Jon Hall5cf14d52015-07-16 12:15:19 -07001348 name="flows-" + str( i ),
1349 args=[],
1350 kwargs={ 'jsonFormat': True } )
1351 threads.append( t )
1352 t.start()
1353
1354 # NOTE: Flows command can take some time to run
1355 time.sleep(30)
1356 for t in threads:
1357 t.join()
1358 result = t.result
1359 ONOSFlows.append( result )
1360
Jon Halle1a3b752015-07-22 13:02:46 -07001361 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001362 num = str( i + 1 )
1363 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1364 main.log.error( "Error in getting ONOS" + num + " flows" )
1365 main.log.warn( "ONOS" + num + " flows response: " +
1366 repr( ONOSFlows[ i ] ) )
1367 flowsResults = False
1368 ONOSFlowsJson.append( None )
1369 else:
1370 try:
1371 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1372 except ( ValueError, TypeError ):
1373 # FIXME: change this to log.error?
1374 main.log.exception( "Error in parsing ONOS" + num +
1375 " response as json." )
1376 main.log.error( repr( ONOSFlows[ i ] ) )
1377 ONOSFlowsJson.append( None )
1378 flowsResults = False
1379 utilities.assert_equals(
1380 expect=True,
1381 actual=flowsResults,
1382 onpass="No error in reading flows output",
1383 onfail="Error in reading flows from ONOS" )
1384
1385 main.step( "Check for consistency in Flows from each controller" )
1386 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1387 if all( tmp ):
1388 main.log.info( "Flow count is consistent across all ONOS nodes" )
1389 else:
1390 consistentFlows = False
1391 utilities.assert_equals(
1392 expect=True,
1393 actual=consistentFlows,
1394 onpass="The flow count is consistent across all ONOS nodes",
1395 onfail="ONOS nodes have different flow counts" )
1396
1397 if flowsResults and not consistentFlows:
Jon Halle1a3b752015-07-22 13:02:46 -07001398 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001399 try:
1400 main.log.warn(
1401 "ONOS" + str( i + 1 ) + " flows: " +
1402 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1403 indent=4, separators=( ',', ': ' ) ) )
1404 except ( ValueError, TypeError ):
1405 main.log.warn(
1406 "ONOS" + str( i + 1 ) + " flows: " +
1407 repr( ONOSFlows[ i ] ) )
1408 elif flowsResults and consistentFlows:
1409 flowCheck = main.TRUE
1410 flowState = ONOSFlows[ 0 ]
1411
1412 main.step( "Get the OF Table entries" )
1413 global flows
1414 flows = []
1415 for i in range( 1, 29 ):
Jon Hallca7ac292015-11-11 09:28:12 -08001416 flows.append( main.Mininet1.getFlowTable( "s" + str( i ), version="1.3" ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001417 if flowCheck == main.FALSE:
1418 for table in flows:
1419 main.log.warn( table )
1420 # TODO: Compare switch flow tables with ONOS flow tables
1421
1422 main.step( "Start continuous pings" )
1423 main.Mininet2.pingLong(
1424 src=main.params[ 'PING' ][ 'source1' ],
1425 target=main.params[ 'PING' ][ 'target1' ],
1426 pingTime=500 )
1427 main.Mininet2.pingLong(
1428 src=main.params[ 'PING' ][ 'source2' ],
1429 target=main.params[ 'PING' ][ 'target2' ],
1430 pingTime=500 )
1431 main.Mininet2.pingLong(
1432 src=main.params[ 'PING' ][ 'source3' ],
1433 target=main.params[ 'PING' ][ 'target3' ],
1434 pingTime=500 )
1435 main.Mininet2.pingLong(
1436 src=main.params[ 'PING' ][ 'source4' ],
1437 target=main.params[ 'PING' ][ 'target4' ],
1438 pingTime=500 )
1439 main.Mininet2.pingLong(
1440 src=main.params[ 'PING' ][ 'source5' ],
1441 target=main.params[ 'PING' ][ 'target5' ],
1442 pingTime=500 )
1443 main.Mininet2.pingLong(
1444 src=main.params[ 'PING' ][ 'source6' ],
1445 target=main.params[ 'PING' ][ 'target6' ],
1446 pingTime=500 )
1447 main.Mininet2.pingLong(
1448 src=main.params[ 'PING' ][ 'source7' ],
1449 target=main.params[ 'PING' ][ 'target7' ],
1450 pingTime=500 )
1451 main.Mininet2.pingLong(
1452 src=main.params[ 'PING' ][ 'source8' ],
1453 target=main.params[ 'PING' ][ 'target8' ],
1454 pingTime=500 )
1455 main.Mininet2.pingLong(
1456 src=main.params[ 'PING' ][ 'source9' ],
1457 target=main.params[ 'PING' ][ 'target9' ],
1458 pingTime=500 )
1459 main.Mininet2.pingLong(
1460 src=main.params[ 'PING' ][ 'source10' ],
1461 target=main.params[ 'PING' ][ 'target10' ],
1462 pingTime=500 )
1463
1464 main.step( "Collecting topology information from ONOS" )
1465 devices = []
1466 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001467 for i in range( main.numCtrls ):
1468 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07001469 name="devices-" + str( i ),
1470 args=[ ] )
1471 threads.append( t )
1472 t.start()
1473
1474 for t in threads:
1475 t.join()
1476 devices.append( t.result )
1477 hosts = []
1478 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001479 for i in range( main.numCtrls ):
1480 t = main.Thread( target=main.CLIs[i].hosts,
Jon Hall5cf14d52015-07-16 12:15:19 -07001481 name="hosts-" + str( i ),
1482 args=[ ] )
1483 threads.append( t )
1484 t.start()
1485
1486 for t in threads:
1487 t.join()
1488 try:
1489 hosts.append( json.loads( t.result ) )
1490 except ( ValueError, TypeError ):
1491 # FIXME: better handling of this, print which node
1492 # Maybe use thread name?
1493 main.log.exception( "Error parsing json output of hosts" )
1494 # FIXME: should this be an empty json object instead?
1495 hosts.append( None )
1496
1497 ports = []
1498 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001499 for i in range( main.numCtrls ):
1500 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07001501 name="ports-" + str( i ),
1502 args=[ ] )
1503 threads.append( t )
1504 t.start()
1505
1506 for t in threads:
1507 t.join()
1508 ports.append( t.result )
1509 links = []
1510 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001511 for i in range( main.numCtrls ):
1512 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07001513 name="links-" + str( i ),
1514 args=[ ] )
1515 threads.append( t )
1516 t.start()
1517
1518 for t in threads:
1519 t.join()
1520 links.append( t.result )
1521 clusters = []
1522 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001523 for i in range( main.numCtrls ):
1524 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07001525 name="clusters-" + str( i ),
1526 args=[ ] )
1527 threads.append( t )
1528 t.start()
1529
1530 for t in threads:
1531 t.join()
1532 clusters.append( t.result )
1533 # Compare json objects for hosts and dataplane clusters
1534
1535 # hosts
1536 main.step( "Host view is consistent across ONOS nodes" )
1537 consistentHostsResult = main.TRUE
1538 for controller in range( len( hosts ) ):
1539 controllerStr = str( controller + 1 )
1540 if "Error" not in hosts[ controller ]:
1541 if hosts[ controller ] == hosts[ 0 ]:
1542 continue
1543 else: # hosts not consistent
1544 main.log.error( "hosts from ONOS" +
1545 controllerStr +
1546 " is inconsistent with ONOS1" )
1547 main.log.warn( repr( hosts[ controller ] ) )
1548 consistentHostsResult = main.FALSE
1549
1550 else:
1551 main.log.error( "Error in getting ONOS hosts from ONOS" +
1552 controllerStr )
1553 consistentHostsResult = main.FALSE
1554 main.log.warn( "ONOS" + controllerStr +
1555 " hosts response: " +
1556 repr( hosts[ controller ] ) )
1557 utilities.assert_equals(
1558 expect=main.TRUE,
1559 actual=consistentHostsResult,
1560 onpass="Hosts view is consistent across all ONOS nodes",
1561 onfail="ONOS nodes have different views of hosts" )
1562
1563 main.step( "Each host has an IP address" )
1564 ipResult = main.TRUE
1565 for controller in range( 0, len( hosts ) ):
1566 controllerStr = str( controller + 1 )
1567 for host in hosts[ controller ]:
1568 if not host.get( 'ipAddresses', [ ] ):
1569 main.log.error( "DEBUG:Error with host ips on controller" +
1570 controllerStr + ": " + str( host ) )
1571 ipResult = main.FALSE
1572 utilities.assert_equals(
1573 expect=main.TRUE,
1574 actual=ipResult,
1575 onpass="The ips of the hosts aren't empty",
1576 onfail="The ip of at least one host is missing" )
1577
1578 # Strongly connected clusters of devices
1579 main.step( "Cluster view is consistent across ONOS nodes" )
1580 consistentClustersResult = main.TRUE
1581 for controller in range( len( clusters ) ):
1582 controllerStr = str( controller + 1 )
1583 if "Error" not in clusters[ controller ]:
1584 if clusters[ controller ] == clusters[ 0 ]:
1585 continue
1586 else: # clusters not consistent
1587 main.log.error( "clusters from ONOS" + controllerStr +
1588 " is inconsistent with ONOS1" )
1589 consistentClustersResult = main.FALSE
1590
1591 else:
1592 main.log.error( "Error in getting dataplane clusters " +
1593 "from ONOS" + controllerStr )
1594 consistentClustersResult = main.FALSE
1595 main.log.warn( "ONOS" + controllerStr +
1596 " clusters response: " +
1597 repr( clusters[ controller ] ) )
1598 utilities.assert_equals(
1599 expect=main.TRUE,
1600 actual=consistentClustersResult,
1601 onpass="Clusters view is consistent across all ONOS nodes",
1602 onfail="ONOS nodes have different views of clusters" )
1603 # there should always only be one cluster
1604 main.step( "Cluster view correct across ONOS nodes" )
1605 try:
1606 numClusters = len( json.loads( clusters[ 0 ] ) )
1607 except ( ValueError, TypeError ):
1608 main.log.exception( "Error parsing clusters[0]: " +
1609 repr( clusters[ 0 ] ) )
1610 clusterResults = main.FALSE
1611 if numClusters == 1:
1612 clusterResults = main.TRUE
1613 utilities.assert_equals(
1614 expect=1,
1615 actual=numClusters,
1616 onpass="ONOS shows 1 SCC",
1617 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1618
1619 main.step( "Comparing ONOS topology to MN" )
1620 devicesResults = main.TRUE
1621 linksResults = main.TRUE
1622 hostsResults = main.TRUE
1623 mnSwitches = main.Mininet1.getSwitches()
1624 mnLinks = main.Mininet1.getLinks()
1625 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07001626 for controller in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001627 controllerStr = str( controller + 1 )
1628 if devices[ controller ] and ports[ controller ] and\
1629 "Error" not in devices[ controller ] and\
1630 "Error" not in ports[ controller ]:
Jon Halle1a3b752015-07-22 13:02:46 -07001631 currentDevicesResult = main.Mininet1.compareSwitches(
1632 mnSwitches,
1633 json.loads( devices[ controller ] ),
1634 json.loads( ports[ controller ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001635 else:
1636 currentDevicesResult = main.FALSE
1637 utilities.assert_equals( expect=main.TRUE,
1638 actual=currentDevicesResult,
1639 onpass="ONOS" + controllerStr +
1640 " Switches view is correct",
1641 onfail="ONOS" + controllerStr +
1642 " Switches view is incorrect" )
1643 if links[ controller ] and "Error" not in links[ controller ]:
1644 currentLinksResult = main.Mininet1.compareLinks(
1645 mnSwitches, mnLinks,
1646 json.loads( links[ controller ] ) )
1647 else:
1648 currentLinksResult = main.FALSE
1649 utilities.assert_equals( expect=main.TRUE,
1650 actual=currentLinksResult,
1651 onpass="ONOS" + controllerStr +
1652 " links view is correct",
1653 onfail="ONOS" + controllerStr +
1654 " links view is incorrect" )
1655
1656 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1657 currentHostsResult = main.Mininet1.compareHosts(
1658 mnHosts,
1659 hosts[ controller ] )
1660 else:
1661 currentHostsResult = main.FALSE
1662 utilities.assert_equals( expect=main.TRUE,
1663 actual=currentHostsResult,
1664 onpass="ONOS" + controllerStr +
1665 " hosts exist in Mininet",
1666 onfail="ONOS" + controllerStr +
1667 " hosts don't match Mininet" )
1668
1669 devicesResults = devicesResults and currentDevicesResult
1670 linksResults = linksResults and currentLinksResult
1671 hostsResults = hostsResults and currentHostsResult
1672
1673 main.step( "Device information is correct" )
1674 utilities.assert_equals(
1675 expect=main.TRUE,
1676 actual=devicesResults,
1677 onpass="Device information is correct",
1678 onfail="Device information is incorrect" )
1679
1680 main.step( "Links are correct" )
1681 utilities.assert_equals(
1682 expect=main.TRUE,
1683 actual=linksResults,
1684 onpass="Link are correct",
1685 onfail="Links are incorrect" )
1686
1687 main.step( "Hosts are correct" )
1688 utilities.assert_equals(
1689 expect=main.TRUE,
1690 actual=hostsResults,
1691 onpass="Hosts are correct",
1692 onfail="Hosts are incorrect" )
1693
1694 def CASE6( self, main ):
1695 """
1696 The Failure case.
1697 """
1698 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001699 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001700 assert main, "main not defined"
1701 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001702 assert main.CLIs, "main.CLIs not defined"
1703 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001704 try:
1705 labels
1706 except NameError:
1707 main.log.error( "labels not defined, setting to []" )
1708 global labels
1709 labels = []
1710 try:
1711 data
1712 except NameError:
1713 main.log.error( "data not defined, setting to []" )
1714 global data
1715 data = []
1716 # Reset non-persistent variables
1717 try:
1718 iCounterValue = 0
1719 except NameError:
1720 main.log.error( "iCounterValue not defined, setting to 0" )
1721 iCounterValue = 0
1722
1723 main.case( "Restart entire ONOS cluster" )
1724
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001725 main.step( "Checking ONOS Logs for errors" )
1726 for node in main.nodes:
1727 main.log.debug( "Checking logs for errors on " + node.name + ":" )
1728 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
1729
Jon Hall5cf14d52015-07-16 12:15:19 -07001730 main.step( "Killing ONOS nodes" )
1731 killResults = main.TRUE
1732 killTime = time.time()
Jon Halle1a3b752015-07-22 13:02:46 -07001733 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001734 killed = main.ONOSbench.onosKill( node.ip_address )
1735 killResults = killResults and killed
1736 utilities.assert_equals( expect=main.TRUE, actual=killResults,
1737 onpass="ONOS nodes killed",
1738 onfail="ONOS kill unsuccessful" )
1739
1740 main.step( "Checking if ONOS is up yet" )
1741 for i in range( 2 ):
1742 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001743 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001744 started = main.ONOSbench.isup( node.ip_address )
1745 if not started:
1746 main.log.error( node.name + " didn't start!" )
1747 onosIsupResult = onosIsupResult and started
1748 if onosIsupResult == main.TRUE:
1749 break
1750 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1751 onpass="ONOS restarted",
1752 onfail="ONOS restart NOT successful" )
1753
1754 main.log.step( "Starting ONOS CLI sessions" )
1755 cliResults = main.TRUE
1756 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001757 for i in range( main.numCtrls ):
1758 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -07001759 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -07001760 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -07001761 threads.append( t )
1762 t.start()
1763
1764 for t in threads:
1765 t.join()
1766 cliResults = cliResults and t.result
1767 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1768 onpass="ONOS cli started",
1769 onfail="ONOS clis did not restart" )
1770
1771 # Grab the time of restart so we chan check how long the gossip
1772 # protocol has had time to work
1773 main.restartTime = time.time() - killTime
1774 main.log.debug( "Restart time: " + str( main.restartTime ) )
1775 labels.append( "Restart" )
1776 data.append( str( main.restartTime ) )
1777
1778 # FIXME: revisit test plan for election with madan
1779 # Rerun for election on restarted nodes
1780 runResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001781 for cli in main.CLIs:
1782 run = main.CLIs[0].electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07001783 if run != main.TRUE:
1784 main.log.error( "Error running for election on " + cli.name )
1785 runResults = runResults and run
1786 utilities.assert_equals( expect=main.TRUE, actual=runResults,
1787 onpass="Reran for election",
1788 onfail="Failed to rerun for election" )
1789
1790 # TODO: Make this configurable
1791 time.sleep( 60 )
Jon Halle1a3b752015-07-22 13:02:46 -07001792 main.log.debug( main.CLIs[0].nodes( jsonFormat=False ) )
1793 main.log.debug( main.CLIs[0].leaders( jsonFormat=False ) )
1794 main.log.debug( main.CLIs[0].partitions( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001795
1796 def CASE7( self, main ):
1797 """
1798 Check state after ONOS failure
1799 """
1800 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001801 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001802 assert main, "main not defined"
1803 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001804 assert main.CLIs, "main.CLIs not defined"
1805 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001806 main.case( "Running ONOS Constant State Tests" )
1807
1808 main.step( "Check that each switch has a master" )
1809 # Assert that each device has a master
1810 rolesNotNull = main.TRUE
1811 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001812 for i in range( main.numCtrls ):
1813 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001814 name="rolesNotNull-" + str( i ),
1815 args=[ ] )
1816 threads.append( t )
1817 t.start()
1818
1819 for t in threads:
1820 t.join()
1821 rolesNotNull = rolesNotNull and t.result
1822 utilities.assert_equals(
1823 expect=main.TRUE,
1824 actual=rolesNotNull,
1825 onpass="Each device has a master",
1826 onfail="Some devices don't have a master assigned" )
1827
1828 main.step( "Read device roles from ONOS" )
1829 ONOSMastership = []
1830 mastershipCheck = main.FALSE
1831 consistentMastership = True
1832 rolesResults = True
1833 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001834 for i in range( main.numCtrls ):
1835 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001836 name="roles-" + str( i ),
1837 args=[] )
1838 threads.append( t )
1839 t.start()
1840
1841 for t in threads:
1842 t.join()
1843 ONOSMastership.append( t.result )
1844
Jon Halle1a3b752015-07-22 13:02:46 -07001845 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001846 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1847 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1848 " roles" )
1849 main.log.warn(
1850 "ONOS" + str( i + 1 ) + " mastership response: " +
1851 repr( ONOSMastership[i] ) )
1852 rolesResults = False
1853 utilities.assert_equals(
1854 expect=True,
1855 actual=rolesResults,
1856 onpass="No error in reading roles output",
1857 onfail="Error in reading roles from ONOS" )
1858
1859 main.step( "Check for consistency in roles from each controller" )
1860 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1861 main.log.info(
1862 "Switch roles are consistent across all ONOS nodes" )
1863 else:
1864 consistentMastership = False
1865 utilities.assert_equals(
1866 expect=True,
1867 actual=consistentMastership,
1868 onpass="Switch roles are consistent across all ONOS nodes",
1869 onfail="ONOS nodes have different views of switch roles" )
1870
1871 if rolesResults and not consistentMastership:
Jon Halle1a3b752015-07-22 13:02:46 -07001872 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001873 main.log.warn(
1874 "ONOS" + str( i + 1 ) + " roles: ",
1875 json.dumps(
1876 json.loads( ONOSMastership[ i ] ),
1877 sort_keys=True,
1878 indent=4,
1879 separators=( ',', ': ' ) ) )
1880 elif rolesResults and not consistentMastership:
1881 mastershipCheck = main.TRUE
1882
1883 '''
1884 description2 = "Compare switch roles from before failure"
1885 main.step( description2 )
1886 try:
1887 currentJson = json.loads( ONOSMastership[0] )
1888 oldJson = json.loads( mastershipState )
1889 except ( ValueError, TypeError ):
1890 main.log.exception( "Something is wrong with parsing " +
1891 "ONOSMastership[0] or mastershipState" )
1892 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1893 main.log.error( "mastershipState" + repr( mastershipState ) )
1894 main.cleanup()
1895 main.exit()
1896 mastershipCheck = main.TRUE
1897 for i in range( 1, 29 ):
1898 switchDPID = str(
1899 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
1900 current = [ switch[ 'master' ] for switch in currentJson
1901 if switchDPID in switch[ 'id' ] ]
1902 old = [ switch[ 'master' ] for switch in oldJson
1903 if switchDPID in switch[ 'id' ] ]
1904 if current == old:
1905 mastershipCheck = mastershipCheck and main.TRUE
1906 else:
1907 main.log.warn( "Mastership of switch %s changed" % switchDPID )
1908 mastershipCheck = main.FALSE
1909 utilities.assert_equals(
1910 expect=main.TRUE,
1911 actual=mastershipCheck,
1912 onpass="Mastership of Switches was not changed",
1913 onfail="Mastership of some switches changed" )
1914 '''
1915 # NOTE: we expect mastership to change on controller failure
1916
1917 main.step( "Get the intents and compare across all nodes" )
1918 ONOSIntents = []
1919 intentCheck = main.FALSE
1920 consistentIntents = True
1921 intentsResults = True
1922 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001923 for i in range( main.numCtrls ):
1924 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001925 name="intents-" + str( i ),
1926 args=[],
1927 kwargs={ 'jsonFormat': True } )
1928 threads.append( t )
1929 t.start()
1930
1931 for t in threads:
1932 t.join()
1933 ONOSIntents.append( t.result )
1934
Jon Halle1a3b752015-07-22 13:02:46 -07001935 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001936 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1937 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1938 " intents" )
1939 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1940 repr( ONOSIntents[ i ] ) )
1941 intentsResults = False
1942 utilities.assert_equals(
1943 expect=True,
1944 actual=intentsResults,
1945 onpass="No error in reading intents output",
1946 onfail="Error in reading intents from ONOS" )
1947
1948 main.step( "Check for consistency in Intents from each controller" )
1949 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1950 main.log.info( "Intents are consistent across all ONOS " +
1951 "nodes" )
1952 else:
1953 consistentIntents = False
1954
1955 # Try to make it easy to figure out what is happening
1956 #
1957 # Intent ONOS1 ONOS2 ...
1958 # 0x01 INSTALLED INSTALLING
1959 # ... ... ...
1960 # ... ... ...
1961 title = " ID"
Jon Halle1a3b752015-07-22 13:02:46 -07001962 for n in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001963 title += " " * 10 + "ONOS" + str( n + 1 )
1964 main.log.warn( title )
1965 # get all intent keys in the cluster
1966 keys = []
1967 for nodeStr in ONOSIntents:
1968 node = json.loads( nodeStr )
1969 for intent in node:
1970 keys.append( intent.get( 'id' ) )
1971 keys = set( keys )
1972 for key in keys:
1973 row = "%-13s" % key
1974 for nodeStr in ONOSIntents:
1975 node = json.loads( nodeStr )
1976 for intent in node:
1977 if intent.get( 'id' ) == key:
1978 row += "%-15s" % intent.get( 'state' )
1979 main.log.warn( row )
1980 # End table view
1981
1982 utilities.assert_equals(
1983 expect=True,
1984 actual=consistentIntents,
1985 onpass="Intents are consistent across all ONOS nodes",
1986 onfail="ONOS nodes have different views of intents" )
1987 intentStates = []
1988 for node in ONOSIntents: # Iter through ONOS nodes
1989 nodeStates = []
1990 # Iter through intents of a node
1991 try:
1992 for intent in json.loads( node ):
1993 nodeStates.append( intent[ 'state' ] )
1994 except ( ValueError, TypeError ):
1995 main.log.exception( "Error in parsing intents" )
1996 main.log.error( repr( node ) )
1997 intentStates.append( nodeStates )
1998 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1999 main.log.info( dict( out ) )
2000
2001 if intentsResults and not consistentIntents:
Jon Halle1a3b752015-07-22 13:02:46 -07002002 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07002003 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
2004 main.log.warn( json.dumps(
2005 json.loads( ONOSIntents[ i ] ),
2006 sort_keys=True,
2007 indent=4,
2008 separators=( ',', ': ' ) ) )
2009 elif intentsResults and consistentIntents:
2010 intentCheck = main.TRUE
2011
2012 # NOTE: Store has no durability, so intents are lost across system
2013 # restarts
2014 """
2015 main.step( "Compare current intents with intents before the failure" )
2016 # NOTE: this requires case 5 to pass for intentState to be set.
2017 # maybe we should stop the test if that fails?
2018 sameIntents = main.FALSE
2019 if intentState and intentState == ONOSIntents[ 0 ]:
2020 sameIntents = main.TRUE
2021 main.log.info( "Intents are consistent with before failure" )
2022 # TODO: possibly the states have changed? we may need to figure out
2023 # what the acceptable states are
2024 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
2025 sameIntents = main.TRUE
2026 try:
2027 before = json.loads( intentState )
2028 after = json.loads( ONOSIntents[ 0 ] )
2029 for intent in before:
2030 if intent not in after:
2031 sameIntents = main.FALSE
2032 main.log.debug( "Intent is not currently in ONOS " +
2033 "(at least in the same form):" )
2034 main.log.debug( json.dumps( intent ) )
2035 except ( ValueError, TypeError ):
2036 main.log.exception( "Exception printing intents" )
2037 main.log.debug( repr( ONOSIntents[0] ) )
2038 main.log.debug( repr( intentState ) )
2039 if sameIntents == main.FALSE:
2040 try:
2041 main.log.debug( "ONOS intents before: " )
2042 main.log.debug( json.dumps( json.loads( intentState ),
2043 sort_keys=True, indent=4,
2044 separators=( ',', ': ' ) ) )
2045 main.log.debug( "Current ONOS intents: " )
2046 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
2047 sort_keys=True, indent=4,
2048 separators=( ',', ': ' ) ) )
2049 except ( ValueError, TypeError ):
2050 main.log.exception( "Exception printing intents" )
2051 main.log.debug( repr( ONOSIntents[0] ) )
2052 main.log.debug( repr( intentState ) )
2053 utilities.assert_equals(
2054 expect=main.TRUE,
2055 actual=sameIntents,
2056 onpass="Intents are consistent with before failure",
2057 onfail="The Intents changed during failure" )
2058 intentCheck = intentCheck and sameIntents
2059 """
2060 main.step( "Get the OF Table entries and compare to before " +
2061 "component failure" )
2062 FlowTables = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002063 for i in range( 28 ):
2064 main.log.info( "Checking flow table on s" + str( i + 1 ) )
GlennRC68467eb2015-11-16 18:01:01 -08002065 tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
2066 FlowTables = FlowTables and main.Mininet1.flowTableComp( flows[i], tmpFlows )
Jon Hall5cf14d52015-07-16 12:15:19 -07002067 if FlowTables == main.FALSE:
GlennRC68467eb2015-11-16 18:01:01 -08002068 main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
2069
Jon Hall5cf14d52015-07-16 12:15:19 -07002070 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 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall5cf14d52015-07-16 12:15:19 -07002703 main.step( "Copying MN pcap and ONOS log files to test station" )
2704 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
2705 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
Jon Hall96091e62015-09-21 17:34:17 -07002706 # NOTE: MN Pcap file is being saved to logdir.
2707 # We scp this file as MN and TestON aren't necessarily the same vm
2708
2709 # FIXME: To be replaced with a Jenkin's post script
Jon Hall5cf14d52015-07-16 12:15:19 -07002710 # TODO: Load these from params
2711 # NOTE: must end in /
2712 logFolder = "/opt/onos/log/"
2713 logFiles = [ "karaf.log", "karaf.log.1" ]
2714 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002715 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002716 for node in main.nodes:
Jon Hall96091e62015-09-21 17:34:17 -07002717 dstName = main.logdir + "/" + node.name + "-" + f
2718 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2719 logFolder + f, dstName )
Jon Hall5cf14d52015-07-16 12:15:19 -07002720 # std*.log's
2721 # NOTE: must end in /
2722 logFolder = "/opt/onos/var/"
2723 logFiles = [ "stderr.log", "stdout.log" ]
2724 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002725 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002726 for node in main.nodes:
Jon Hall96091e62015-09-21 17:34:17 -07002727 dstName = main.logdir + "/" + node.name + "-" + f
2728 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2729 logFolder + f, dstName )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002730 else:
2731 main.log.debug( "skipping saving log files" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002732
2733 main.step( "Stopping Mininet" )
2734 mnResult = main.Mininet1.stopNet()
2735 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2736 onpass="Mininet stopped",
2737 onfail="MN cleanup NOT successful" )
2738
2739 main.step( "Checking ONOS Logs for errors" )
Jon Halle1a3b752015-07-22 13:02:46 -07002740 for node in main.nodes:
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002741 main.log.debug( "Checking logs for errors on " + node.name + ":" )
2742 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002743
2744 try:
2745 timerLog = open( main.logdir + "/Timers.csv", 'w')
2746 main.log.error( ", ".join( labels ) + "\n" + ", ".join( data ) )
2747 timerLog.write( ", ".join( labels ) + "\n" + ", ".join( data ) )
2748 timerLog.close()
2749 except NameError, e:
2750 main.log.exception(e)
2751
2752 def CASE14( self, main ):
2753 """
2754 start election app on all onos nodes
2755 """
Jon Halle1a3b752015-07-22 13:02:46 -07002756 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002757 assert main, "main not defined"
2758 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002759 assert main.CLIs, "main.CLIs not defined"
2760 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002761
2762 main.case("Start Leadership Election app")
2763 main.step( "Install leadership election app" )
2764 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
2765 utilities.assert_equals(
2766 expect=main.TRUE,
2767 actual=appResult,
2768 onpass="Election app installed",
2769 onfail="Something went wrong with installing Leadership election" )
2770
2771 main.step( "Run for election on each node" )
2772 leaderResult = main.TRUE
2773 leaders = []
Jon Halle1a3b752015-07-22 13:02:46 -07002774 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002775 cli.electionTestRun()
Jon Halle1a3b752015-07-22 13:02:46 -07002776 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002777 leader = cli.electionTestLeader()
2778 if leader is None or leader == main.FALSE:
2779 main.log.error( cli.name + ": Leader for the election app " +
2780 "should be an ONOS node, instead got '" +
2781 str( leader ) + "'" )
2782 leaderResult = main.FALSE
2783 leaders.append( leader )
2784 utilities.assert_equals(
2785 expect=main.TRUE,
2786 actual=leaderResult,
2787 onpass="Successfully ran for leadership",
2788 onfail="Failed to run for leadership" )
2789
2790 main.step( "Check that each node shows the same leader" )
2791 sameLeader = main.TRUE
2792 if len( set( leaders ) ) != 1:
2793 sameLeader = main.FALSE
2794 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2795 str( leaders ) )
2796 utilities.assert_equals(
2797 expect=main.TRUE,
2798 actual=sameLeader,
2799 onpass="Leadership is consistent for the election topic",
2800 onfail="Nodes have different leaders" )
2801
2802 def CASE15( self, main ):
2803 """
2804 Check that Leadership Election is still functional
acsmars9475b1c2015-08-28 18:02:08 -07002805 15.1 Run election on each node
2806 15.2 Check that each node has the same leaders and candidates
2807 15.3 Find current leader and withdraw
2808 15.4 Check that a new node was elected leader
2809 15.5 Check that that new leader was the candidate of old leader
2810 15.6 Run for election on old leader
2811 15.7 Check that oldLeader is a candidate, and leader if only 1 node
2812 15.8 Make sure that the old leader was added to the candidate list
2813
2814 old and new variable prefixes refer to data from before vs after
2815 withdrawl and later before withdrawl vs after re-election
Jon Hall5cf14d52015-07-16 12:15:19 -07002816 """
2817 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002818 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002819 assert main, "main not defined"
2820 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002821 assert main.CLIs, "main.CLIs not defined"
2822 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002823
Jon Hall5cf14d52015-07-16 12:15:19 -07002824 description = "Check that Leadership Election is still functional"
2825 main.case( description )
2826 # NOTE: Need to re-run since being a canidate is not persistant
acsmars9475b1c2015-08-28 18:02:08 -07002827 # TODO: add check for "Command not found:" in the driver, this
2828 # means the election test app isn't loaded
2829
2830 oldLeaders = [] # leaders by node before withdrawl from candidates
2831 newLeaders = [] # leaders by node after withdrawl from candidates
2832 oldAllCandidates = [] # list of lists of each nodes' candidates before
2833 newAllCandidates = [] # list of lists of each nodes' candidates after
2834 oldCandidates = [] # list of candidates from node 0 before withdrawl
2835 newCandidates = [] # list of candidates from node 0 after withdrawl
2836 oldLeader = '' # the old leader from oldLeaders, None if not same
2837 newLeader = '' # the new leaders fron newLoeaders, None if not same
2838 oldLeaderCLI = None # the CLI of the old leader used for re-electing
acsmars71adceb2015-08-31 15:09:26 -07002839 expectNoLeader = False # True when there is only one leader
2840 if main.numCtrls == 1:
2841 expectNoLeader = True
acsmars9475b1c2015-08-28 18:02:08 -07002842
Jon Hall5cf14d52015-07-16 12:15:19 -07002843 main.step( "Run for election on each node" )
acsmars9475b1c2015-08-28 18:02:08 -07002844 electionResult = main.TRUE
2845
2846 for cli in main.CLIs: # run test election on each node
2847 if cli.electionTestRun() == main.FALSE:
2848 electionResult = main.FALSE
2849
Jon Hall5cf14d52015-07-16 12:15:19 -07002850 utilities.assert_equals(
2851 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07002852 actual=electionResult,
2853 onpass="All nodes successfully ran for leadership",
2854 onfail="At least one node failed to run for leadership" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002855
acsmars3a72bde2015-09-02 14:16:22 -07002856 if electionResult == main.FALSE:
2857 main.log.error(
2858 "Skipping Test Case because Election Test App isn't loaded" )
2859 main.skipCase()
2860
acsmars9475b1c2015-08-28 18:02:08 -07002861 main.step( "Check that each node shows the same leader and candidates" )
2862 sameResult = main.TRUE
2863 failMessage = "Nodes have different leaders"
2864 for cli in main.CLIs:
2865 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2866 oldAllCandidates.append( node )
2867 oldLeaders.append( node[ 0 ] )
2868 oldCandidates = oldAllCandidates[ 0 ]
2869
2870 # Check that each node has the same leader. Defines oldLeader
2871 if len( set( oldLeaders ) ) != 1:
2872 sameResult = main.FALSE
acsmars71adceb2015-08-31 15:09:26 -07002873 main.log.error( "More than one leader present:" + str( oldLeaders ) )
acsmars9475b1c2015-08-28 18:02:08 -07002874 oldLeader = None
2875 else:
2876 oldLeader = oldLeaders[ 0 ]
2877
2878 # Check that each node's candidate list is the same
acsmars29233db2015-11-04 11:15:00 -08002879 candidateDiscrepancy = False # Boolean of candidate mismatches
acsmars9475b1c2015-08-28 18:02:08 -07002880 for candidates in oldAllCandidates:
2881 if set( candidates ) != set( oldCandidates ):
2882 sameResult = main.FALSE
acsmars29233db2015-11-04 11:15:00 -08002883 candidateDiscrepancy = True
2884
2885 if candidateDiscrepancy:
2886 failMessage += " and candidates"
acsmars9475b1c2015-08-28 18:02:08 -07002887
Jon Hall5cf14d52015-07-16 12:15:19 -07002888 utilities.assert_equals(
2889 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002890 actual=sameResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002891 onpass="Leadership is consistent for the election topic",
acsmars9475b1c2015-08-28 18:02:08 -07002892 onfail=failMessage )
Jon Hall5cf14d52015-07-16 12:15:19 -07002893
2894 main.step( "Find current leader and withdraw" )
acsmars9475b1c2015-08-28 18:02:08 -07002895 withdrawResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002896 # do some sanity checking on leader before using it
acsmars9475b1c2015-08-28 18:02:08 -07002897 if oldLeader is None:
2898 main.log.error( "Leadership isn't consistent." )
2899 withdrawResult = main.FALSE
2900 # Get the CLI of the oldLeader
Jon Halle1a3b752015-07-22 13:02:46 -07002901 for i in range( len( main.CLIs ) ):
acsmars9475b1c2015-08-28 18:02:08 -07002902 if oldLeader == main.nodes[ i ].ip_address:
2903 oldLeaderCLI = main.CLIs[ i ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002904 break
2905 else: # FOR/ELSE statement
2906 main.log.error( "Leader election, could not find current leader" )
2907 if oldLeader:
acsmars9475b1c2015-08-28 18:02:08 -07002908 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall5cf14d52015-07-16 12:15:19 -07002909 utilities.assert_equals(
2910 expect=main.TRUE,
2911 actual=withdrawResult,
2912 onpass="Node was withdrawn from election",
2913 onfail="Node was not withdrawn from election" )
2914
acsmars9475b1c2015-08-28 18:02:08 -07002915 main.step( "Check that a new node was elected leader" )
acsmars71adceb2015-08-31 15:09:26 -07002916
Jon Hall5cf14d52015-07-16 12:15:19 -07002917 # FIXME: use threads
acsmars9475b1c2015-08-28 18:02:08 -07002918 newLeaderResult = main.TRUE
2919 failMessage = "Nodes have different leaders"
2920
2921 # Get new leaders and candidates
Jon Halle1a3b752015-07-22 13:02:46 -07002922 for cli in main.CLIs:
acsmars9475b1c2015-08-28 18:02:08 -07002923 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
acsmars71adceb2015-08-31 15:09:26 -07002924 # elections might no have finished yet
2925 if node[ 0 ] == 'none' and not expectNoLeader:
acsmars9475b1c2015-08-28 18:02:08 -07002926 main.log.info( "Node has no leader, waiting 5 seconds to be " +
2927 "sure elections are complete." )
2928 time.sleep(5)
2929 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
acsmars71adceb2015-08-31 15:09:26 -07002930 # election still isn't done or there is a problem
2931 if node[ 0 ] == 'none':
2932 main.log.error( "No leader was elected on at least 1 node" )
2933 newLeaderResult = main.FALSE
acsmars9475b1c2015-08-28 18:02:08 -07002934 newAllCandidates.append( node )
2935 newLeaders.append( node[ 0 ] )
2936 newCandidates = newAllCandidates[ 0 ]
2937
2938 # Check that each node has the same leader. Defines newLeader
2939 if len( set( newLeaders ) ) != 1:
2940 newLeaderResult = main.FALSE
2941 main.log.error( "Nodes have different leaders: " +
2942 str( newLeaders ) )
2943 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07002944 else:
acsmars9475b1c2015-08-28 18:02:08 -07002945 newLeader = newLeaders[ 0 ]
2946
acsmars71adceb2015-08-31 15:09:26 -07002947 # Check that each node's candidate list is the same
2948 for candidates in newAllCandidates:
2949 if set( candidates ) != set( newCandidates ):
2950 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07002951 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07002952
acsmars9475b1c2015-08-28 18:02:08 -07002953 # Check that the new leader is not the older leader, which was withdrawn
2954 if newLeader == oldLeader:
2955 newLeaderResult = main.FALSE
2956 main.log.error( "All nodes still see old leader: " + oldLeader +
2957 " as the current leader" )
2958
Jon Hall5cf14d52015-07-16 12:15:19 -07002959 utilities.assert_equals(
2960 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07002961 actual=newLeaderResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002962 onpass="Leadership election passed",
2963 onfail="Something went wrong with Leadership election" )
2964
acsmars9475b1c2015-08-28 18:02:08 -07002965 main.step( "Check that that new leader was the candidate of old leader")
2966 # candidates[ 2 ] should be come the top candidate after withdrawl
2967 correctCandidateResult = main.TRUE
acsmars71adceb2015-08-31 15:09:26 -07002968 if expectNoLeader:
2969 if newLeader == 'none':
2970 main.log.info( "No leader expected. None found. Pass" )
2971 correctCandidateResult = main.TRUE
2972 else:
2973 main.log.info( "Expected no leader, got: " + str( newLeader ) )
2974 correctCandidateResult = main.FALSE
2975 elif newLeader != oldCandidates[ 2 ]:
acsmars9475b1c2015-08-28 18:02:08 -07002976 correctCandidateResult = main.FALSE
2977 main.log.error( "Candidate " + newLeader + " was elected. " +
2978 oldCandidates[ 2 ] + " should have had priority." )
2979
2980 utilities.assert_equals(
2981 expect=main.TRUE,
2982 actual=correctCandidateResult,
2983 onpass="Correct Candidate Elected",
2984 onfail="Incorrect Candidate Elected" )
2985
Jon Hall5cf14d52015-07-16 12:15:19 -07002986 main.step( "Run for election on old leader( just so everyone " +
2987 "is in the hat )" )
acsmars9475b1c2015-08-28 18:02:08 -07002988 if oldLeaderCLI is not None:
2989 runResult = oldLeaderCLI.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07002990 else:
acsmars9475b1c2015-08-28 18:02:08 -07002991 main.log.error( "No old leader to re-elect" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002992 runResult = main.FALSE
2993 utilities.assert_equals(
2994 expect=main.TRUE,
2995 actual=runResult,
2996 onpass="App re-ran for election",
2997 onfail="App failed to run for election" )
acsmars9475b1c2015-08-28 18:02:08 -07002998 main.step(
2999 "Check that oldLeader is a candidate, and leader if only 1 node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003000 # verify leader didn't just change
acsmars9475b1c2015-08-28 18:02:08 -07003001 positionResult = main.TRUE
3002 # Get new leaders and candidates, wait if oldLeader is not a candidate yet
3003
3004 # Reset and reuse the new candidate and leaders lists
3005 newAllCandidates = []
3006 newCandidates = []
3007 newLeaders = []
3008 for cli in main.CLIs:
3009 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
3010 if oldLeader not in node: # election might no have finished yet
3011 main.log.info( "Old Leader not elected, waiting 5 seconds to " +
3012 "be sure elections are complete" )
3013 time.sleep(5)
3014 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
3015 if oldLeader not in node: # election still isn't done, errors
3016 main.log.error(
3017 "Old leader was not elected on at least one node" )
3018 positionResult = main.FALSE
3019 newAllCandidates.append( node )
3020 newLeaders.append( node[ 0 ] )
3021 newCandidates = newAllCandidates[ 0 ]
3022
3023 # Check that each node has the same leader. Defines newLeader
3024 if len( set( newLeaders ) ) != 1:
3025 positionResult = main.FALSE
3026 main.log.error( "Nodes have different leaders: " +
3027 str( newLeaders ) )
3028 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07003029 else:
acsmars9475b1c2015-08-28 18:02:08 -07003030 newLeader = newLeaders[ 0 ]
3031
acsmars71adceb2015-08-31 15:09:26 -07003032 # Check that each node's candidate list is the same
3033 for candidates in newAllCandidates:
3034 if set( candidates ) != set( newCandidates ):
3035 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07003036 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07003037
acsmars9475b1c2015-08-28 18:02:08 -07003038 # Check that the re-elected node is last on the candidate List
3039 if oldLeader != newCandidates[ -1 ]:
3040 main.log.error( "Old Leader (" + oldLeader + ") not in the proper position " +
3041 str( newCandidates ) )
3042 positionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07003043
3044 utilities.assert_equals(
3045 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07003046 actual=positionResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07003047 onpass="Old leader successfully re-ran for election",
3048 onfail="Something went wrong with Leadership election after " +
3049 "the old leader re-ran for election" )
3050
3051 def CASE16( self, main ):
3052 """
3053 Install Distributed Primitives app
3054 """
3055 import time
Jon Halle1a3b752015-07-22 13:02:46 -07003056 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003057 assert main, "main not defined"
3058 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003059 assert main.CLIs, "main.CLIs not defined"
3060 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003061
3062 # Variables for the distributed primitives tests
3063 global pCounterName
3064 global iCounterName
3065 global pCounterValue
3066 global iCounterValue
3067 global onosSet
3068 global onosSetName
3069 pCounterName = "TestON-Partitions"
3070 iCounterName = "TestON-inMemory"
3071 pCounterValue = 0
3072 iCounterValue = 0
3073 onosSet = set([])
3074 onosSetName = "TestON-set"
3075
3076 description = "Install Primitives app"
3077 main.case( description )
3078 main.step( "Install Primitives app" )
3079 appName = "org.onosproject.distributedprimitives"
Jon Halle1a3b752015-07-22 13:02:46 -07003080 appResults = main.CLIs[0].activateApp( appName )
Jon Hall5cf14d52015-07-16 12:15:19 -07003081 utilities.assert_equals( expect=main.TRUE,
3082 actual=appResults,
3083 onpass="Primitives app activated",
3084 onfail="Primitives app not activated" )
3085 time.sleep( 5 ) # To allow all nodes to activate
3086
3087 def CASE17( self, main ):
3088 """
3089 Check for basic functionality with distributed primitives
3090 """
Jon Hall5cf14d52015-07-16 12:15:19 -07003091 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07003092 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003093 assert main, "main not defined"
3094 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003095 assert main.CLIs, "main.CLIs not defined"
3096 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003097 assert pCounterName, "pCounterName not defined"
3098 assert iCounterName, "iCounterName not defined"
3099 assert onosSetName, "onosSetName not defined"
3100 # NOTE: assert fails if value is 0/None/Empty/False
3101 try:
3102 pCounterValue
3103 except NameError:
3104 main.log.error( "pCounterValue not defined, setting to 0" )
3105 pCounterValue = 0
3106 try:
3107 iCounterValue
3108 except NameError:
3109 main.log.error( "iCounterValue not defined, setting to 0" )
3110 iCounterValue = 0
3111 try:
3112 onosSet
3113 except NameError:
3114 main.log.error( "onosSet not defined, setting to empty Set" )
3115 onosSet = set([])
3116 # Variables for the distributed primitives tests. These are local only
3117 addValue = "a"
3118 addAllValue = "a b c d e f"
3119 retainValue = "c d e f"
3120
3121 description = "Check for basic functionality with distributed " +\
3122 "primitives"
3123 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07003124 main.caseExplanation = "Test the methods of the distributed " +\
3125 "primitives (counters and sets) throught the cli"
Jon Hall5cf14d52015-07-16 12:15:19 -07003126 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07003127 # Partitioned counters
3128 main.step( "Increment then get a default counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003129 pCounters = []
3130 threads = []
3131 addedPValues = []
Jon Halle1a3b752015-07-22 13:02:46 -07003132 for i in range( main.numCtrls ):
3133 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3134 name="counterAddAndGet-" + str( i ),
Jon Hall5cf14d52015-07-16 12:15:19 -07003135 args=[ pCounterName ] )
3136 pCounterValue += 1
3137 addedPValues.append( pCounterValue )
3138 threads.append( t )
3139 t.start()
3140
3141 for t in threads:
3142 t.join()
3143 pCounters.append( t.result )
3144 # Check that counter incremented numController times
3145 pCounterResults = True
3146 for i in addedPValues:
3147 tmpResult = i in pCounters
3148 pCounterResults = pCounterResults and tmpResult
3149 if not tmpResult:
3150 main.log.error( str( i ) + " is not in partitioned "
3151 "counter incremented results" )
3152 utilities.assert_equals( expect=True,
3153 actual=pCounterResults,
3154 onpass="Default counter incremented",
3155 onfail="Error incrementing default" +
3156 " counter" )
3157
Jon Halle1a3b752015-07-22 13:02:46 -07003158 main.step( "Get then Increment a default counter on each node" )
3159 pCounters = []
3160 threads = []
3161 addedPValues = []
3162 for i in range( main.numCtrls ):
3163 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3164 name="counterGetAndAdd-" + str( i ),
3165 args=[ pCounterName ] )
3166 addedPValues.append( pCounterValue )
3167 pCounterValue += 1
3168 threads.append( t )
3169 t.start()
3170
3171 for t in threads:
3172 t.join()
3173 pCounters.append( t.result )
3174 # Check that counter incremented numController times
3175 pCounterResults = True
3176 for i in addedPValues:
3177 tmpResult = i in pCounters
3178 pCounterResults = pCounterResults and tmpResult
3179 if not tmpResult:
3180 main.log.error( str( i ) + " is not in partitioned "
3181 "counter incremented results" )
3182 utilities.assert_equals( expect=True,
3183 actual=pCounterResults,
3184 onpass="Default counter incremented",
3185 onfail="Error incrementing default" +
3186 " counter" )
3187
3188 main.step( "Counters we added have the correct values" )
3189 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3190 utilities.assert_equals( expect=main.TRUE,
3191 actual=incrementCheck,
3192 onpass="Added counters are correct",
3193 onfail="Added counters are incorrect" )
3194
3195 main.step( "Add -8 to then get a default counter on each node" )
3196 pCounters = []
3197 threads = []
3198 addedPValues = []
3199 for i in range( main.numCtrls ):
3200 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3201 name="counterIncrement-" + str( i ),
3202 args=[ pCounterName ],
3203 kwargs={ "delta": -8 } )
3204 pCounterValue += -8
3205 addedPValues.append( pCounterValue )
3206 threads.append( t )
3207 t.start()
3208
3209 for t in threads:
3210 t.join()
3211 pCounters.append( t.result )
3212 # Check that counter incremented numController times
3213 pCounterResults = True
3214 for i in addedPValues:
3215 tmpResult = i in pCounters
3216 pCounterResults = pCounterResults and tmpResult
3217 if not tmpResult:
3218 main.log.error( str( i ) + " is not in partitioned "
3219 "counter incremented results" )
3220 utilities.assert_equals( expect=True,
3221 actual=pCounterResults,
3222 onpass="Default counter incremented",
3223 onfail="Error incrementing default" +
3224 " counter" )
3225
3226 main.step( "Add 5 to then get a default counter on each node" )
3227 pCounters = []
3228 threads = []
3229 addedPValues = []
3230 for i in range( main.numCtrls ):
3231 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3232 name="counterIncrement-" + str( i ),
3233 args=[ pCounterName ],
3234 kwargs={ "delta": 5 } )
3235 pCounterValue += 5
3236 addedPValues.append( pCounterValue )
3237 threads.append( t )
3238 t.start()
3239
3240 for t in threads:
3241 t.join()
3242 pCounters.append( t.result )
3243 # Check that counter incremented numController times
3244 pCounterResults = True
3245 for i in addedPValues:
3246 tmpResult = i in pCounters
3247 pCounterResults = pCounterResults and tmpResult
3248 if not tmpResult:
3249 main.log.error( str( i ) + " is not in partitioned "
3250 "counter incremented results" )
3251 utilities.assert_equals( expect=True,
3252 actual=pCounterResults,
3253 onpass="Default counter incremented",
3254 onfail="Error incrementing default" +
3255 " counter" )
3256
3257 main.step( "Get then add 5 to a default counter on each node" )
3258 pCounters = []
3259 threads = []
3260 addedPValues = []
3261 for i in range( main.numCtrls ):
3262 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3263 name="counterIncrement-" + str( i ),
3264 args=[ pCounterName ],
3265 kwargs={ "delta": 5 } )
3266 addedPValues.append( pCounterValue )
3267 pCounterValue += 5
3268 threads.append( t )
3269 t.start()
3270
3271 for t in threads:
3272 t.join()
3273 pCounters.append( t.result )
3274 # Check that counter incremented numController times
3275 pCounterResults = True
3276 for i in addedPValues:
3277 tmpResult = i in pCounters
3278 pCounterResults = pCounterResults and tmpResult
3279 if not tmpResult:
3280 main.log.error( str( i ) + " is not in partitioned "
3281 "counter incremented results" )
3282 utilities.assert_equals( expect=True,
3283 actual=pCounterResults,
3284 onpass="Default counter incremented",
3285 onfail="Error incrementing default" +
3286 " counter" )
3287
3288 main.step( "Counters we added have the correct values" )
3289 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3290 utilities.assert_equals( expect=main.TRUE,
3291 actual=incrementCheck,
3292 onpass="Added counters are correct",
3293 onfail="Added counters are incorrect" )
3294
3295 # In-Memory counters
3296 main.step( "Increment and get an in-memory counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003297 iCounters = []
3298 addedIValues = []
3299 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003300 for i in range( main.numCtrls ):
3301 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003302 name="icounterIncrement-" + str( i ),
3303 args=[ iCounterName ],
3304 kwargs={ "inMemory": True } )
3305 iCounterValue += 1
3306 addedIValues.append( iCounterValue )
3307 threads.append( t )
3308 t.start()
3309
3310 for t in threads:
3311 t.join()
3312 iCounters.append( t.result )
3313 # Check that counter incremented numController times
3314 iCounterResults = True
3315 for i in addedIValues:
3316 tmpResult = i in iCounters
3317 iCounterResults = iCounterResults and tmpResult
3318 if not tmpResult:
3319 main.log.error( str( i ) + " is not in the in-memory "
3320 "counter incremented results" )
3321 utilities.assert_equals( expect=True,
3322 actual=iCounterResults,
Jon Halle1a3b752015-07-22 13:02:46 -07003323 onpass="In-memory counter incremented",
3324 onfail="Error incrementing in-memory" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003325 " counter" )
3326
Jon Halle1a3b752015-07-22 13:02:46 -07003327 main.step( "Get then Increment a in-memory counter on each node" )
3328 iCounters = []
3329 threads = []
3330 addedIValues = []
3331 for i in range( main.numCtrls ):
3332 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3333 name="counterGetAndAdd-" + str( i ),
3334 args=[ iCounterName ],
3335 kwargs={ "inMemory": True } )
3336 addedIValues.append( iCounterValue )
3337 iCounterValue += 1
3338 threads.append( t )
3339 t.start()
3340
3341 for t in threads:
3342 t.join()
3343 iCounters.append( t.result )
3344 # Check that counter incremented numController times
3345 iCounterResults = True
3346 for i in addedIValues:
3347 tmpResult = i in iCounters
3348 iCounterResults = iCounterResults and tmpResult
3349 if not tmpResult:
3350 main.log.error( str( i ) + " is not in in-memory "
3351 "counter incremented results" )
3352 utilities.assert_equals( expect=True,
3353 actual=iCounterResults,
3354 onpass="In-memory counter incremented",
3355 onfail="Error incrementing in-memory" +
3356 " counter" )
3357
3358 main.step( "Counters we added have the correct values" )
3359 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3360 utilities.assert_equals( expect=main.TRUE,
3361 actual=incrementCheck,
3362 onpass="Added counters are correct",
3363 onfail="Added counters are incorrect" )
3364
3365 main.step( "Add -8 to then get a in-memory counter on each node" )
3366 iCounters = []
3367 threads = []
3368 addedIValues = []
3369 for i in range( main.numCtrls ):
3370 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3371 name="counterIncrement-" + str( i ),
3372 args=[ iCounterName ],
3373 kwargs={ "delta": -8, "inMemory": True } )
3374 iCounterValue += -8
3375 addedIValues.append( iCounterValue )
3376 threads.append( t )
3377 t.start()
3378
3379 for t in threads:
3380 t.join()
3381 iCounters.append( t.result )
3382 # Check that counter incremented numController times
3383 iCounterResults = True
3384 for i in addedIValues:
3385 tmpResult = i in iCounters
3386 iCounterResults = iCounterResults and tmpResult
3387 if not tmpResult:
3388 main.log.error( str( i ) + " is not in in-memory "
3389 "counter incremented results" )
3390 utilities.assert_equals( expect=True,
3391 actual=pCounterResults,
3392 onpass="In-memory counter incremented",
3393 onfail="Error incrementing in-memory" +
3394 " counter" )
3395
3396 main.step( "Add 5 to then get a in-memory counter on each node" )
3397 iCounters = []
3398 threads = []
3399 addedIValues = []
3400 for i in range( main.numCtrls ):
3401 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3402 name="counterIncrement-" + str( i ),
3403 args=[ iCounterName ],
3404 kwargs={ "delta": 5, "inMemory": True } )
3405 iCounterValue += 5
3406 addedIValues.append( iCounterValue )
3407 threads.append( t )
3408 t.start()
3409
3410 for t in threads:
3411 t.join()
3412 iCounters.append( t.result )
3413 # Check that counter incremented numController times
3414 iCounterResults = True
3415 for i in addedIValues:
3416 tmpResult = i in iCounters
3417 iCounterResults = iCounterResults and tmpResult
3418 if not tmpResult:
3419 main.log.error( str( i ) + " is not in in-memory "
3420 "counter incremented results" )
3421 utilities.assert_equals( expect=True,
3422 actual=pCounterResults,
3423 onpass="In-memory counter incremented",
3424 onfail="Error incrementing in-memory" +
3425 " counter" )
3426
3427 main.step( "Get then add 5 to a in-memory counter on each node" )
3428 iCounters = []
3429 threads = []
3430 addedIValues = []
3431 for i in range( main.numCtrls ):
3432 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3433 name="counterIncrement-" + str( i ),
3434 args=[ iCounterName ],
3435 kwargs={ "delta": 5, "inMemory": True } )
3436 addedIValues.append( iCounterValue )
3437 iCounterValue += 5
3438 threads.append( t )
3439 t.start()
3440
3441 for t in threads:
3442 t.join()
3443 iCounters.append( t.result )
3444 # Check that counter incremented numController times
3445 iCounterResults = True
3446 for i in addedIValues:
3447 tmpResult = i in iCounters
3448 iCounterResults = iCounterResults and tmpResult
3449 if not tmpResult:
3450 main.log.error( str( i ) + " is not in in-memory "
3451 "counter incremented results" )
3452 utilities.assert_equals( expect=True,
3453 actual=iCounterResults,
3454 onpass="In-memory counter incremented",
3455 onfail="Error incrementing in-memory" +
3456 " counter" )
3457
3458 main.step( "Counters we added have the correct values" )
3459 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3460 utilities.assert_equals( expect=main.TRUE,
3461 actual=incrementCheck,
3462 onpass="Added counters are correct",
3463 onfail="Added counters are incorrect" )
3464
Jon Hall5cf14d52015-07-16 12:15:19 -07003465 main.step( "Check counters are consistant across nodes" )
Jon Hall57b50432015-10-22 10:20:10 -07003466 onosCounters, consistentCounterResults = main.Counters.consistentCheck()
Jon Hall5cf14d52015-07-16 12:15:19 -07003467 utilities.assert_equals( expect=main.TRUE,
3468 actual=consistentCounterResults,
3469 onpass="ONOS counters are consistent " +
3470 "across nodes",
3471 onfail="ONOS Counters are inconsistent " +
3472 "across nodes" )
3473
3474 main.step( "Counters we added have the correct values" )
Jon Halle1a3b752015-07-22 13:02:46 -07003475 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3476 incrementCheck = incrementCheck and \
3477 main.Counters.counterCheck( iCounterName, iCounterValue )
Jon Hall5cf14d52015-07-16 12:15:19 -07003478 utilities.assert_equals( expect=main.TRUE,
Jon Halle1a3b752015-07-22 13:02:46 -07003479 actual=incrementCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -07003480 onpass="Added counters are correct",
3481 onfail="Added counters are incorrect" )
3482 # DISTRIBUTED SETS
3483 main.step( "Distributed Set get" )
3484 size = len( onosSet )
3485 getResponses = []
3486 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003487 for i in range( main.numCtrls ):
3488 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003489 name="setTestGet-" + str( i ),
3490 args=[ onosSetName ] )
3491 threads.append( t )
3492 t.start()
3493 for t in threads:
3494 t.join()
3495 getResponses.append( t.result )
3496
3497 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003498 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003499 if isinstance( getResponses[ i ], list):
3500 current = set( getResponses[ i ] )
3501 if len( current ) == len( getResponses[ i ] ):
3502 # no repeats
3503 if onosSet != current:
3504 main.log.error( "ONOS" + str( i + 1 ) +
3505 " has incorrect view" +
3506 " of set " + onosSetName + ":\n" +
3507 str( getResponses[ i ] ) )
3508 main.log.debug( "Expected: " + str( onosSet ) )
3509 main.log.debug( "Actual: " + str( current ) )
3510 getResults = main.FALSE
3511 else:
3512 # error, set is not a set
3513 main.log.error( "ONOS" + str( i + 1 ) +
3514 " has repeat elements in" +
3515 " set " + onosSetName + ":\n" +
3516 str( getResponses[ i ] ) )
3517 getResults = main.FALSE
3518 elif getResponses[ i ] == main.ERROR:
3519 getResults = main.FALSE
3520 utilities.assert_equals( expect=main.TRUE,
3521 actual=getResults,
3522 onpass="Set elements are correct",
3523 onfail="Set elements are incorrect" )
3524
3525 main.step( "Distributed Set size" )
3526 sizeResponses = []
3527 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003528 for i in range( main.numCtrls ):
3529 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003530 name="setTestSize-" + str( i ),
3531 args=[ onosSetName ] )
3532 threads.append( t )
3533 t.start()
3534 for t in threads:
3535 t.join()
3536 sizeResponses.append( t.result )
3537
3538 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003539 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003540 if size != sizeResponses[ i ]:
3541 sizeResults = main.FALSE
3542 main.log.error( "ONOS" + str( i + 1 ) +
3543 " expected a size of " + str( size ) +
3544 " for set " + onosSetName +
3545 " but got " + str( sizeResponses[ i ] ) )
3546 utilities.assert_equals( expect=main.TRUE,
3547 actual=sizeResults,
3548 onpass="Set sizes are correct",
3549 onfail="Set sizes are incorrect" )
3550
3551 main.step( "Distributed Set add()" )
3552 onosSet.add( addValue )
3553 addResponses = []
3554 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003555 for i in range( main.numCtrls ):
3556 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003557 name="setTestAdd-" + str( i ),
3558 args=[ onosSetName, addValue ] )
3559 threads.append( t )
3560 t.start()
3561 for t in threads:
3562 t.join()
3563 addResponses.append( t.result )
3564
3565 # main.TRUE = successfully changed the set
3566 # main.FALSE = action resulted in no change in set
3567 # main.ERROR - Some error in executing the function
3568 addResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003569 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003570 if addResponses[ i ] == main.TRUE:
3571 # All is well
3572 pass
3573 elif addResponses[ i ] == main.FALSE:
3574 # Already in set, probably fine
3575 pass
3576 elif addResponses[ i ] == main.ERROR:
3577 # Error in execution
3578 addResults = main.FALSE
3579 else:
3580 # unexpected result
3581 addResults = main.FALSE
3582 if addResults != main.TRUE:
3583 main.log.error( "Error executing set add" )
3584
3585 # Check if set is still correct
3586 size = len( onosSet )
3587 getResponses = []
3588 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003589 for i in range( main.numCtrls ):
3590 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003591 name="setTestGet-" + str( i ),
3592 args=[ onosSetName ] )
3593 threads.append( t )
3594 t.start()
3595 for t in threads:
3596 t.join()
3597 getResponses.append( t.result )
3598 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003599 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003600 if isinstance( getResponses[ i ], list):
3601 current = set( getResponses[ i ] )
3602 if len( current ) == len( getResponses[ i ] ):
3603 # no repeats
3604 if onosSet != current:
3605 main.log.error( "ONOS" + str( i + 1 ) +
3606 " has incorrect view" +
3607 " of set " + onosSetName + ":\n" +
3608 str( getResponses[ i ] ) )
3609 main.log.debug( "Expected: " + str( onosSet ) )
3610 main.log.debug( "Actual: " + str( current ) )
3611 getResults = main.FALSE
3612 else:
3613 # error, set is not a set
3614 main.log.error( "ONOS" + str( i + 1 ) +
3615 " has repeat elements in" +
3616 " set " + onosSetName + ":\n" +
3617 str( getResponses[ i ] ) )
3618 getResults = main.FALSE
3619 elif getResponses[ i ] == main.ERROR:
3620 getResults = main.FALSE
3621 sizeResponses = []
3622 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003623 for i in range( main.numCtrls ):
3624 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003625 name="setTestSize-" + str( i ),
3626 args=[ onosSetName ] )
3627 threads.append( t )
3628 t.start()
3629 for t in threads:
3630 t.join()
3631 sizeResponses.append( t.result )
3632 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003633 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003634 if size != sizeResponses[ i ]:
3635 sizeResults = main.FALSE
3636 main.log.error( "ONOS" + str( i + 1 ) +
3637 " expected a size of " + str( size ) +
3638 " for set " + onosSetName +
3639 " but got " + str( sizeResponses[ i ] ) )
3640 addResults = addResults and getResults and sizeResults
3641 utilities.assert_equals( expect=main.TRUE,
3642 actual=addResults,
3643 onpass="Set add correct",
3644 onfail="Set add was incorrect" )
3645
3646 main.step( "Distributed Set addAll()" )
3647 onosSet.update( addAllValue.split() )
3648 addResponses = []
3649 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003650 for i in range( main.numCtrls ):
3651 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003652 name="setTestAddAll-" + str( i ),
3653 args=[ onosSetName, addAllValue ] )
3654 threads.append( t )
3655 t.start()
3656 for t in threads:
3657 t.join()
3658 addResponses.append( t.result )
3659
3660 # main.TRUE = successfully changed the set
3661 # main.FALSE = action resulted in no change in set
3662 # main.ERROR - Some error in executing the function
3663 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003664 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003665 if addResponses[ i ] == main.TRUE:
3666 # All is well
3667 pass
3668 elif addResponses[ i ] == main.FALSE:
3669 # Already in set, probably fine
3670 pass
3671 elif addResponses[ i ] == main.ERROR:
3672 # Error in execution
3673 addAllResults = main.FALSE
3674 else:
3675 # unexpected result
3676 addAllResults = main.FALSE
3677 if addAllResults != main.TRUE:
3678 main.log.error( "Error executing set addAll" )
3679
3680 # Check if set is still correct
3681 size = len( onosSet )
3682 getResponses = []
3683 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003684 for i in range( main.numCtrls ):
3685 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003686 name="setTestGet-" + str( i ),
3687 args=[ onosSetName ] )
3688 threads.append( t )
3689 t.start()
3690 for t in threads:
3691 t.join()
3692 getResponses.append( t.result )
3693 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003694 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003695 if isinstance( getResponses[ i ], list):
3696 current = set( getResponses[ i ] )
3697 if len( current ) == len( getResponses[ i ] ):
3698 # no repeats
3699 if onosSet != current:
3700 main.log.error( "ONOS" + str( i + 1 ) +
3701 " has incorrect view" +
3702 " of set " + onosSetName + ":\n" +
3703 str( getResponses[ i ] ) )
3704 main.log.debug( "Expected: " + str( onosSet ) )
3705 main.log.debug( "Actual: " + str( current ) )
3706 getResults = main.FALSE
3707 else:
3708 # error, set is not a set
3709 main.log.error( "ONOS" + str( i + 1 ) +
3710 " has repeat elements in" +
3711 " set " + onosSetName + ":\n" +
3712 str( getResponses[ i ] ) )
3713 getResults = main.FALSE
3714 elif getResponses[ i ] == main.ERROR:
3715 getResults = main.FALSE
3716 sizeResponses = []
3717 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003718 for i in range( main.numCtrls ):
3719 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003720 name="setTestSize-" + str( i ),
3721 args=[ onosSetName ] )
3722 threads.append( t )
3723 t.start()
3724 for t in threads:
3725 t.join()
3726 sizeResponses.append( t.result )
3727 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003728 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003729 if size != sizeResponses[ i ]:
3730 sizeResults = main.FALSE
3731 main.log.error( "ONOS" + str( i + 1 ) +
3732 " expected a size of " + str( size ) +
3733 " for set " + onosSetName +
3734 " but got " + str( sizeResponses[ i ] ) )
3735 addAllResults = addAllResults and getResults and sizeResults
3736 utilities.assert_equals( expect=main.TRUE,
3737 actual=addAllResults,
3738 onpass="Set addAll correct",
3739 onfail="Set addAll was incorrect" )
3740
3741 main.step( "Distributed Set contains()" )
3742 containsResponses = []
3743 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003744 for i in range( main.numCtrls ):
3745 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003746 name="setContains-" + str( i ),
3747 args=[ onosSetName ],
3748 kwargs={ "values": addValue } )
3749 threads.append( t )
3750 t.start()
3751 for t in threads:
3752 t.join()
3753 # NOTE: This is the tuple
3754 containsResponses.append( t.result )
3755
3756 containsResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003757 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003758 if containsResponses[ i ] == main.ERROR:
3759 containsResults = main.FALSE
3760 else:
3761 containsResults = containsResults and\
3762 containsResponses[ i ][ 1 ]
3763 utilities.assert_equals( expect=main.TRUE,
3764 actual=containsResults,
3765 onpass="Set contains is functional",
3766 onfail="Set contains failed" )
3767
3768 main.step( "Distributed Set containsAll()" )
3769 containsAllResponses = []
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="setContainsAll-" + str( i ),
3774 args=[ onosSetName ],
3775 kwargs={ "values": addAllValue } )
3776 threads.append( t )
3777 t.start()
3778 for t in threads:
3779 t.join()
3780 # NOTE: This is the tuple
3781 containsAllResponses.append( t.result )
3782
3783 containsAllResults = 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=containsAllResults,
3792 onpass="Set containsAll is functional",
3793 onfail="Set containsAll failed" )
3794
3795 main.step( "Distributed Set remove()" )
3796 onosSet.remove( addValue )
3797 removeResponses = []
3798 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003799 for i in range( main.numCtrls ):
3800 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003801 name="setTestRemove-" + str( i ),
3802 args=[ onosSetName, addValue ] )
3803 threads.append( t )
3804 t.start()
3805 for t in threads:
3806 t.join()
3807 removeResponses.append( t.result )
3808
3809 # main.TRUE = successfully changed the set
3810 # main.FALSE = action resulted in no change in set
3811 # main.ERROR - Some error in executing the function
3812 removeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003813 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003814 if removeResponses[ i ] == main.TRUE:
3815 # All is well
3816 pass
3817 elif removeResponses[ i ] == main.FALSE:
3818 # not in set, probably fine
3819 pass
3820 elif removeResponses[ i ] == main.ERROR:
3821 # Error in execution
3822 removeResults = main.FALSE
3823 else:
3824 # unexpected result
3825 removeResults = main.FALSE
3826 if removeResults != main.TRUE:
3827 main.log.error( "Error executing set remove" )
3828
3829 # Check if set is still correct
3830 size = len( onosSet )
3831 getResponses = []
3832 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003833 for i in range( main.numCtrls ):
3834 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003835 name="setTestGet-" + str( i ),
3836 args=[ onosSetName ] )
3837 threads.append( t )
3838 t.start()
3839 for t in threads:
3840 t.join()
3841 getResponses.append( t.result )
3842 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003843 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003844 if isinstance( getResponses[ i ], list):
3845 current = set( getResponses[ i ] )
3846 if len( current ) == len( getResponses[ i ] ):
3847 # no repeats
3848 if onosSet != current:
3849 main.log.error( "ONOS" + str( i + 1 ) +
3850 " has incorrect view" +
3851 " of set " + onosSetName + ":\n" +
3852 str( getResponses[ i ] ) )
3853 main.log.debug( "Expected: " + str( onosSet ) )
3854 main.log.debug( "Actual: " + str( current ) )
3855 getResults = main.FALSE
3856 else:
3857 # error, set is not a set
3858 main.log.error( "ONOS" + str( i + 1 ) +
3859 " has repeat elements in" +
3860 " set " + onosSetName + ":\n" +
3861 str( getResponses[ i ] ) )
3862 getResults = main.FALSE
3863 elif getResponses[ i ] == main.ERROR:
3864 getResults = main.FALSE
3865 sizeResponses = []
3866 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003867 for i in range( main.numCtrls ):
3868 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003869 name="setTestSize-" + str( i ),
3870 args=[ onosSetName ] )
3871 threads.append( t )
3872 t.start()
3873 for t in threads:
3874 t.join()
3875 sizeResponses.append( t.result )
3876 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003877 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003878 if size != sizeResponses[ i ]:
3879 sizeResults = main.FALSE
3880 main.log.error( "ONOS" + str( i + 1 ) +
3881 " expected a size of " + str( size ) +
3882 " for set " + onosSetName +
3883 " but got " + str( sizeResponses[ i ] ) )
3884 removeResults = removeResults and getResults and sizeResults
3885 utilities.assert_equals( expect=main.TRUE,
3886 actual=removeResults,
3887 onpass="Set remove correct",
3888 onfail="Set remove was incorrect" )
3889
3890 main.step( "Distributed Set removeAll()" )
3891 onosSet.difference_update( addAllValue.split() )
3892 removeAllResponses = []
3893 threads = []
3894 try:
Jon Halle1a3b752015-07-22 13:02:46 -07003895 for i in range( main.numCtrls ):
3896 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003897 name="setTestRemoveAll-" + str( i ),
3898 args=[ onosSetName, addAllValue ] )
3899 threads.append( t )
3900 t.start()
3901 for t in threads:
3902 t.join()
3903 removeAllResponses.append( t.result )
3904 except Exception, e:
3905 main.log.exception(e)
3906
3907 # main.TRUE = successfully changed the set
3908 # main.FALSE = action resulted in no change in set
3909 # main.ERROR - Some error in executing the function
3910 removeAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003911 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003912 if removeAllResponses[ i ] == main.TRUE:
3913 # All is well
3914 pass
3915 elif removeAllResponses[ i ] == main.FALSE:
3916 # not in set, probably fine
3917 pass
3918 elif removeAllResponses[ i ] == main.ERROR:
3919 # Error in execution
3920 removeAllResults = main.FALSE
3921 else:
3922 # unexpected result
3923 removeAllResults = main.FALSE
3924 if removeAllResults != main.TRUE:
3925 main.log.error( "Error executing set removeAll" )
3926
3927 # Check if set is still correct
3928 size = len( onosSet )
3929 getResponses = []
3930 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003931 for i in range( main.numCtrls ):
3932 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003933 name="setTestGet-" + str( i ),
3934 args=[ onosSetName ] )
3935 threads.append( t )
3936 t.start()
3937 for t in threads:
3938 t.join()
3939 getResponses.append( t.result )
3940 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003941 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003942 if isinstance( getResponses[ i ], list):
3943 current = set( getResponses[ i ] )
3944 if len( current ) == len( getResponses[ i ] ):
3945 # no repeats
3946 if onosSet != current:
3947 main.log.error( "ONOS" + str( i + 1 ) +
3948 " has incorrect view" +
3949 " of set " + onosSetName + ":\n" +
3950 str( getResponses[ i ] ) )
3951 main.log.debug( "Expected: " + str( onosSet ) )
3952 main.log.debug( "Actual: " + str( current ) )
3953 getResults = main.FALSE
3954 else:
3955 # error, set is not a set
3956 main.log.error( "ONOS" + str( i + 1 ) +
3957 " has repeat elements in" +
3958 " set " + onosSetName + ":\n" +
3959 str( getResponses[ i ] ) )
3960 getResults = main.FALSE
3961 elif getResponses[ i ] == main.ERROR:
3962 getResults = main.FALSE
3963 sizeResponses = []
3964 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003965 for i in range( main.numCtrls ):
3966 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003967 name="setTestSize-" + str( i ),
3968 args=[ onosSetName ] )
3969 threads.append( t )
3970 t.start()
3971 for t in threads:
3972 t.join()
3973 sizeResponses.append( t.result )
3974 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003975 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003976 if size != sizeResponses[ i ]:
3977 sizeResults = main.FALSE
3978 main.log.error( "ONOS" + str( i + 1 ) +
3979 " expected a size of " + str( size ) +
3980 " for set " + onosSetName +
3981 " but got " + str( sizeResponses[ i ] ) )
3982 removeAllResults = removeAllResults and getResults and sizeResults
3983 utilities.assert_equals( expect=main.TRUE,
3984 actual=removeAllResults,
3985 onpass="Set removeAll correct",
3986 onfail="Set removeAll was incorrect" )
3987
3988 main.step( "Distributed Set addAll()" )
3989 onosSet.update( addAllValue.split() )
3990 addResponses = []
3991 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003992 for i in range( main.numCtrls ):
3993 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003994 name="setTestAddAll-" + str( i ),
3995 args=[ onosSetName, addAllValue ] )
3996 threads.append( t )
3997 t.start()
3998 for t in threads:
3999 t.join()
4000 addResponses.append( t.result )
4001
4002 # main.TRUE = successfully changed the set
4003 # main.FALSE = action resulted in no change in set
4004 # main.ERROR - Some error in executing the function
4005 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004006 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004007 if addResponses[ i ] == main.TRUE:
4008 # All is well
4009 pass
4010 elif addResponses[ i ] == main.FALSE:
4011 # Already in set, probably fine
4012 pass
4013 elif addResponses[ i ] == main.ERROR:
4014 # Error in execution
4015 addAllResults = main.FALSE
4016 else:
4017 # unexpected result
4018 addAllResults = main.FALSE
4019 if addAllResults != main.TRUE:
4020 main.log.error( "Error executing set addAll" )
4021
4022 # Check if set is still correct
4023 size = len( onosSet )
4024 getResponses = []
4025 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004026 for i in range( main.numCtrls ):
4027 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004028 name="setTestGet-" + str( i ),
4029 args=[ onosSetName ] )
4030 threads.append( t )
4031 t.start()
4032 for t in threads:
4033 t.join()
4034 getResponses.append( t.result )
4035 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004036 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004037 if isinstance( getResponses[ i ], list):
4038 current = set( getResponses[ i ] )
4039 if len( current ) == len( getResponses[ i ] ):
4040 # no repeats
4041 if onosSet != current:
4042 main.log.error( "ONOS" + str( i + 1 ) +
4043 " has incorrect view" +
4044 " of set " + onosSetName + ":\n" +
4045 str( getResponses[ i ] ) )
4046 main.log.debug( "Expected: " + str( onosSet ) )
4047 main.log.debug( "Actual: " + str( current ) )
4048 getResults = main.FALSE
4049 else:
4050 # error, set is not a set
4051 main.log.error( "ONOS" + str( i + 1 ) +
4052 " has repeat elements in" +
4053 " set " + onosSetName + ":\n" +
4054 str( getResponses[ i ] ) )
4055 getResults = main.FALSE
4056 elif getResponses[ i ] == main.ERROR:
4057 getResults = main.FALSE
4058 sizeResponses = []
4059 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004060 for i in range( main.numCtrls ):
4061 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004062 name="setTestSize-" + str( i ),
4063 args=[ onosSetName ] )
4064 threads.append( t )
4065 t.start()
4066 for t in threads:
4067 t.join()
4068 sizeResponses.append( t.result )
4069 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004070 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004071 if size != sizeResponses[ i ]:
4072 sizeResults = main.FALSE
4073 main.log.error( "ONOS" + str( i + 1 ) +
4074 " expected a size of " + str( size ) +
4075 " for set " + onosSetName +
4076 " but got " + str( sizeResponses[ i ] ) )
4077 addAllResults = addAllResults and getResults and sizeResults
4078 utilities.assert_equals( expect=main.TRUE,
4079 actual=addAllResults,
4080 onpass="Set addAll correct",
4081 onfail="Set addAll was incorrect" )
4082
4083 main.step( "Distributed Set clear()" )
4084 onosSet.clear()
4085 clearResponses = []
4086 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004087 for i in range( main.numCtrls ):
4088 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004089 name="setTestClear-" + str( i ),
4090 args=[ onosSetName, " "], # Values doesn't matter
4091 kwargs={ "clear": True } )
4092 threads.append( t )
4093 t.start()
4094 for t in threads:
4095 t.join()
4096 clearResponses.append( t.result )
4097
4098 # main.TRUE = successfully changed the set
4099 # main.FALSE = action resulted in no change in set
4100 # main.ERROR - Some error in executing the function
4101 clearResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004102 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004103 if clearResponses[ i ] == main.TRUE:
4104 # All is well
4105 pass
4106 elif clearResponses[ i ] == main.FALSE:
4107 # Nothing set, probably fine
4108 pass
4109 elif clearResponses[ i ] == main.ERROR:
4110 # Error in execution
4111 clearResults = main.FALSE
4112 else:
4113 # unexpected result
4114 clearResults = main.FALSE
4115 if clearResults != main.TRUE:
4116 main.log.error( "Error executing set clear" )
4117
4118 # Check if set is still correct
4119 size = len( onosSet )
4120 getResponses = []
4121 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004122 for i in range( main.numCtrls ):
4123 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004124 name="setTestGet-" + str( i ),
4125 args=[ onosSetName ] )
4126 threads.append( t )
4127 t.start()
4128 for t in threads:
4129 t.join()
4130 getResponses.append( t.result )
4131 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004132 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004133 if isinstance( getResponses[ i ], list):
4134 current = set( getResponses[ i ] )
4135 if len( current ) == len( getResponses[ i ] ):
4136 # no repeats
4137 if onosSet != current:
4138 main.log.error( "ONOS" + str( i + 1 ) +
4139 " has incorrect view" +
4140 " of set " + onosSetName + ":\n" +
4141 str( getResponses[ i ] ) )
4142 main.log.debug( "Expected: " + str( onosSet ) )
4143 main.log.debug( "Actual: " + str( current ) )
4144 getResults = main.FALSE
4145 else:
4146 # error, set is not a set
4147 main.log.error( "ONOS" + str( i + 1 ) +
4148 " has repeat elements in" +
4149 " set " + onosSetName + ":\n" +
4150 str( getResponses[ i ] ) )
4151 getResults = main.FALSE
4152 elif getResponses[ i ] == main.ERROR:
4153 getResults = main.FALSE
4154 sizeResponses = []
4155 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004156 for i in range( main.numCtrls ):
4157 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004158 name="setTestSize-" + str( i ),
4159 args=[ onosSetName ] )
4160 threads.append( t )
4161 t.start()
4162 for t in threads:
4163 t.join()
4164 sizeResponses.append( t.result )
4165 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004166 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004167 if size != sizeResponses[ i ]:
4168 sizeResults = main.FALSE
4169 main.log.error( "ONOS" + str( i + 1 ) +
4170 " expected a size of " + str( size ) +
4171 " for set " + onosSetName +
4172 " but got " + str( sizeResponses[ i ] ) )
4173 clearResults = clearResults and getResults and sizeResults
4174 utilities.assert_equals( expect=main.TRUE,
4175 actual=clearResults,
4176 onpass="Set clear correct",
4177 onfail="Set clear was incorrect" )
4178
4179 main.step( "Distributed Set addAll()" )
4180 onosSet.update( addAllValue.split() )
4181 addResponses = []
4182 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004183 for i in range( main.numCtrls ):
4184 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004185 name="setTestAddAll-" + str( i ),
4186 args=[ onosSetName, addAllValue ] )
4187 threads.append( t )
4188 t.start()
4189 for t in threads:
4190 t.join()
4191 addResponses.append( t.result )
4192
4193 # main.TRUE = successfully changed the set
4194 # main.FALSE = action resulted in no change in set
4195 # main.ERROR - Some error in executing the function
4196 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004197 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004198 if addResponses[ i ] == main.TRUE:
4199 # All is well
4200 pass
4201 elif addResponses[ i ] == main.FALSE:
4202 # Already in set, probably fine
4203 pass
4204 elif addResponses[ i ] == main.ERROR:
4205 # Error in execution
4206 addAllResults = main.FALSE
4207 else:
4208 # unexpected result
4209 addAllResults = main.FALSE
4210 if addAllResults != main.TRUE:
4211 main.log.error( "Error executing set addAll" )
4212
4213 # Check if set is still correct
4214 size = len( onosSet )
4215 getResponses = []
4216 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004217 for i in range( main.numCtrls ):
4218 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004219 name="setTestGet-" + str( i ),
4220 args=[ onosSetName ] )
4221 threads.append( t )
4222 t.start()
4223 for t in threads:
4224 t.join()
4225 getResponses.append( t.result )
4226 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004227 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004228 if isinstance( getResponses[ i ], list):
4229 current = set( getResponses[ i ] )
4230 if len( current ) == len( getResponses[ i ] ):
4231 # no repeats
4232 if onosSet != current:
4233 main.log.error( "ONOS" + str( i + 1 ) +
4234 " has incorrect view" +
4235 " of set " + onosSetName + ":\n" +
4236 str( getResponses[ i ] ) )
4237 main.log.debug( "Expected: " + str( onosSet ) )
4238 main.log.debug( "Actual: " + str( current ) )
4239 getResults = main.FALSE
4240 else:
4241 # error, set is not a set
4242 main.log.error( "ONOS" + str( i + 1 ) +
4243 " has repeat elements in" +
4244 " set " + onosSetName + ":\n" +
4245 str( getResponses[ i ] ) )
4246 getResults = main.FALSE
4247 elif getResponses[ i ] == main.ERROR:
4248 getResults = main.FALSE
4249 sizeResponses = []
4250 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004251 for i in range( main.numCtrls ):
4252 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004253 name="setTestSize-" + str( i ),
4254 args=[ onosSetName ] )
4255 threads.append( t )
4256 t.start()
4257 for t in threads:
4258 t.join()
4259 sizeResponses.append( t.result )
4260 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004261 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004262 if size != sizeResponses[ i ]:
4263 sizeResults = main.FALSE
4264 main.log.error( "ONOS" + str( i + 1 ) +
4265 " expected a size of " + str( size ) +
4266 " for set " + onosSetName +
4267 " but got " + str( sizeResponses[ i ] ) )
4268 addAllResults = addAllResults and getResults and sizeResults
4269 utilities.assert_equals( expect=main.TRUE,
4270 actual=addAllResults,
4271 onpass="Set addAll correct",
4272 onfail="Set addAll was incorrect" )
4273
4274 main.step( "Distributed Set retain()" )
4275 onosSet.intersection_update( retainValue.split() )
4276 retainResponses = []
4277 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004278 for i in range( main.numCtrls ):
4279 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004280 name="setTestRetain-" + str( i ),
4281 args=[ onosSetName, retainValue ],
4282 kwargs={ "retain": True } )
4283 threads.append( t )
4284 t.start()
4285 for t in threads:
4286 t.join()
4287 retainResponses.append( t.result )
4288
4289 # main.TRUE = successfully changed the set
4290 # main.FALSE = action resulted in no change in set
4291 # main.ERROR - Some error in executing the function
4292 retainResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004293 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004294 if retainResponses[ i ] == main.TRUE:
4295 # All is well
4296 pass
4297 elif retainResponses[ i ] == main.FALSE:
4298 # Already in set, probably fine
4299 pass
4300 elif retainResponses[ i ] == main.ERROR:
4301 # Error in execution
4302 retainResults = main.FALSE
4303 else:
4304 # unexpected result
4305 retainResults = main.FALSE
4306 if retainResults != main.TRUE:
4307 main.log.error( "Error executing set retain" )
4308
4309 # Check if set is still correct
4310 size = len( onosSet )
4311 getResponses = []
4312 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004313 for i in range( main.numCtrls ):
4314 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004315 name="setTestGet-" + str( i ),
4316 args=[ onosSetName ] )
4317 threads.append( t )
4318 t.start()
4319 for t in threads:
4320 t.join()
4321 getResponses.append( t.result )
4322 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004323 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004324 if isinstance( getResponses[ i ], list):
4325 current = set( getResponses[ i ] )
4326 if len( current ) == len( getResponses[ i ] ):
4327 # no repeats
4328 if onosSet != current:
4329 main.log.error( "ONOS" + str( i + 1 ) +
4330 " has incorrect view" +
4331 " of set " + onosSetName + ":\n" +
4332 str( getResponses[ i ] ) )
4333 main.log.debug( "Expected: " + str( onosSet ) )
4334 main.log.debug( "Actual: " + str( current ) )
4335 getResults = main.FALSE
4336 else:
4337 # error, set is not a set
4338 main.log.error( "ONOS" + str( i + 1 ) +
4339 " has repeat elements in" +
4340 " set " + onosSetName + ":\n" +
4341 str( getResponses[ i ] ) )
4342 getResults = main.FALSE
4343 elif getResponses[ i ] == main.ERROR:
4344 getResults = main.FALSE
4345 sizeResponses = []
4346 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004347 for i in range( main.numCtrls ):
4348 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004349 name="setTestSize-" + str( i ),
4350 args=[ onosSetName ] )
4351 threads.append( t )
4352 t.start()
4353 for t in threads:
4354 t.join()
4355 sizeResponses.append( t.result )
4356 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004357 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004358 if size != sizeResponses[ i ]:
4359 sizeResults = main.FALSE
4360 main.log.error( "ONOS" + str( i + 1 ) +
4361 " expected a size of " +
4362 str( size ) + " for set " + onosSetName +
4363 " but got " + str( sizeResponses[ i ] ) )
4364 retainResults = retainResults and getResults and sizeResults
4365 utilities.assert_equals( expect=main.TRUE,
4366 actual=retainResults,
4367 onpass="Set retain correct",
4368 onfail="Set retain was incorrect" )
4369
Jon Hall2a5002c2015-08-21 16:49:11 -07004370 # Transactional maps
4371 main.step( "Partitioned Transactional maps put" )
4372 tMapValue = "Testing"
4373 numKeys = 100
4374 putResult = True
4375 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue )
4376 if len( putResponses ) == 100:
4377 for i in putResponses:
4378 if putResponses[ i ][ 'value' ] != tMapValue:
4379 putResult = False
4380 else:
4381 putResult = False
4382 if not putResult:
4383 main.log.debug( "Put response values: " + str( putResponses ) )
4384 utilities.assert_equals( expect=True,
4385 actual=putResult,
4386 onpass="Partitioned Transactional Map put successful",
4387 onfail="Partitioned Transactional Map put values are incorrect" )
4388
4389 main.step( "Partitioned Transactional maps get" )
4390 getCheck = True
4391 for n in range( 1, numKeys + 1 ):
4392 getResponses = []
4393 threads = []
4394 valueCheck = True
4395 for i in range( main.numCtrls ):
4396 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4397 name="TMap-get-" + str( i ),
4398 args=[ "Key" + str ( n ) ] )
4399 threads.append( t )
4400 t.start()
4401 for t in threads:
4402 t.join()
4403 getResponses.append( t.result )
4404 for node in getResponses:
4405 if node != tMapValue:
4406 valueCheck = False
4407 if not valueCheck:
4408 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4409 main.log.warn( getResponses )
4410 getCheck = getCheck and valueCheck
4411 utilities.assert_equals( expect=True,
4412 actual=getCheck,
4413 onpass="Partitioned Transactional Map get values were correct",
4414 onfail="Partitioned Transactional Map values incorrect" )
4415
4416 main.step( "In-memory Transactional maps put" )
4417 tMapValue = "Testing"
4418 numKeys = 100
4419 putResult = True
4420 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue, inMemory=True )
4421 if len( putResponses ) == 100:
4422 for i in putResponses:
4423 if putResponses[ i ][ 'value' ] != tMapValue:
4424 putResult = False
4425 else:
4426 putResult = False
4427 if not putResult:
4428 main.log.debug( "Put response values: " + str( putResponses ) )
4429 utilities.assert_equals( expect=True,
4430 actual=putResult,
4431 onpass="In-Memory Transactional Map put successful",
4432 onfail="In-Memory Transactional Map put values are incorrect" )
4433
4434 main.step( "In-Memory Transactional maps get" )
4435 getCheck = True
4436 for n in range( 1, numKeys + 1 ):
4437 getResponses = []
4438 threads = []
4439 valueCheck = True
4440 for i in range( main.numCtrls ):
4441 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4442 name="TMap-get-" + str( i ),
4443 args=[ "Key" + str ( n ) ],
4444 kwargs={ "inMemory": True } )
4445 threads.append( t )
4446 t.start()
4447 for t in threads:
4448 t.join()
4449 getResponses.append( t.result )
4450 for node in getResponses:
4451 if node != tMapValue:
4452 valueCheck = False
4453 if not valueCheck:
4454 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4455 main.log.warn( getResponses )
4456 getCheck = getCheck and valueCheck
4457 utilities.assert_equals( expect=True,
4458 actual=getCheck,
4459 onpass="In-Memory Transactional Map get values were correct",
4460 onfail="In-Memory Transactional Map values incorrect" )