blob: 1169a7d134ce35771e75d54b70e96439fc5d6a66 [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 Hall9043c902015-07-30 14:23:44 -07001416 flows.append( main.Mininet1.getFlowTable( 1.3, "s" + str( i ) ) )
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
2063 flows2 = []
2064 for i in range( 28 ):
2065 main.log.info( "Checking flow table on s" + str( i + 1 ) )
Jon Hall9043c902015-07-30 14:23:44 -07002066 tmpFlows = main.Mininet1.getFlowTable( 1.3, "s" + str( i + 1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002067 flows2.append( tmpFlows )
Jon Hall9043c902015-07-30 14:23:44 -07002068 tempResult = main.Mininet1.flowComp(
Jon Hall5cf14d52015-07-16 12:15:19 -07002069 flow1=flows[ i ],
2070 flow2=tmpFlows )
2071 FlowTables = FlowTables and tempResult
2072 if FlowTables == main.FALSE:
2073 main.log.info( "Differences in flow table for switch: s" +
2074 str( i + 1 ) )
2075 utilities.assert_equals(
2076 expect=main.TRUE,
2077 actual=FlowTables,
2078 onpass="No changes were found in the flow tables",
2079 onfail="Changes were found in the flow tables" )
2080
2081 main.Mininet2.pingLongKill()
2082 '''
2083 # main.step( "Check the continuous pings to ensure that no packets " +
2084 # "were dropped during component failure" )
2085 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
2086 main.params[ 'TESTONIP' ] )
2087 LossInPings = main.FALSE
2088 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
2089 for i in range( 8, 18 ):
2090 main.log.info(
2091 "Checking for a loss in pings along flow from s" +
2092 str( i ) )
2093 LossInPings = main.Mininet2.checkForLoss(
2094 "/tmp/ping.h" +
2095 str( i ) ) or LossInPings
2096 if LossInPings == main.TRUE:
2097 main.log.info( "Loss in ping detected" )
2098 elif LossInPings == main.ERROR:
2099 main.log.info( "There are multiple mininet process running" )
2100 elif LossInPings == main.FALSE:
2101 main.log.info( "No Loss in the pings" )
2102 main.log.info( "No loss of dataplane connectivity" )
2103 # utilities.assert_equals(
2104 # expect=main.FALSE,
2105 # actual=LossInPings,
2106 # onpass="No Loss of connectivity",
2107 # onfail="Loss of dataplane connectivity detected" )
2108
2109 # NOTE: Since intents are not persisted with IntnentStore,
2110 # we expect loss in dataplane connectivity
2111 LossInPings = main.FALSE
2112 '''
2113
2114 main.step( "Leadership Election is still functional" )
2115 # Test of LeadershipElection
2116 leaderList = []
2117 leaderResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002118 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002119 leaderN = cli.electionTestLeader()
2120 leaderList.append( leaderN )
2121 if leaderN == main.FALSE:
2122 # error in response
2123 main.log.error( "Something is wrong with " +
2124 "electionTestLeader function, check the" +
2125 " error logs" )
2126 leaderResult = main.FALSE
2127 elif leaderN is None:
2128 main.log.error( cli.name +
2129 " shows no leader for the election-app." )
2130 leaderResult = main.FALSE
2131 if len( set( leaderList ) ) != 1:
2132 leaderResult = main.FALSE
2133 main.log.error(
2134 "Inconsistent view of leader for the election test app" )
2135 # TODO: print the list
2136 utilities.assert_equals(
2137 expect=main.TRUE,
2138 actual=leaderResult,
2139 onpass="Leadership election passed",
2140 onfail="Something went wrong with Leadership election" )
2141
2142 def CASE8( self, main ):
2143 """
2144 Compare topo
2145 """
2146 import json
2147 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002148 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002149 assert main, "main not defined"
2150 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002151 assert main.CLIs, "main.CLIs not defined"
2152 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002153
2154 main.case( "Compare ONOS Topology view to Mininet topology" )
Jon Hall783bbf92015-07-23 14:33:19 -07002155 main.caseExplanation = "Compare topology objects between Mininet" +\
Jon Hall5cf14d52015-07-16 12:15:19 -07002156 " and ONOS"
2157
2158 main.step( "Comparing ONOS topology to MN" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002159 topoResult = main.FALSE
2160 elapsed = 0
2161 count = 0
2162 main.step( "Collecting topology information from ONOS" )
2163 startTime = time.time()
2164 # Give time for Gossip to work
2165 while topoResult == main.FALSE and elapsed < 60:
Jon Hallba609822015-09-18 12:00:21 -07002166 devicesResults = main.TRUE
2167 linksResults = main.TRUE
2168 hostsResults = main.TRUE
2169 hostAttachmentResults = True
Jon Hall5cf14d52015-07-16 12:15:19 -07002170 count += 1
2171 cliStart = time.time()
2172 devices = []
2173 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002174 for i in range( main.numCtrls ):
2175 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07002176 name="devices-" + str( i ),
2177 args=[ ] )
2178 threads.append( t )
2179 t.start()
2180
2181 for t in threads:
2182 t.join()
2183 devices.append( t.result )
2184 hosts = []
2185 ipResult = main.TRUE
2186 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002187 for i in range( main.numCtrls ):
2188 t = main.Thread( target=main.CLIs[i].hosts,
Jon Hall5cf14d52015-07-16 12:15:19 -07002189 name="hosts-" + str( i ),
2190 args=[ ] )
2191 threads.append( t )
2192 t.start()
2193
2194 for t in threads:
2195 t.join()
2196 try:
2197 hosts.append( json.loads( t.result ) )
2198 except ( ValueError, TypeError ):
2199 main.log.exception( "Error parsing hosts results" )
2200 main.log.error( repr( t.result ) )
2201 for controller in range( 0, len( hosts ) ):
2202 controllerStr = str( controller + 1 )
2203 for host in hosts[ controller ]:
2204 if host is None or host.get( 'ipAddresses', [] ) == []:
2205 main.log.error(
2206 "DEBUG:Error with host ipAddresses on controller" +
2207 controllerStr + ": " + str( host ) )
2208 ipResult = main.FALSE
2209 ports = []
2210 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002211 for i in range( main.numCtrls ):
2212 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07002213 name="ports-" + str( i ),
2214 args=[ ] )
2215 threads.append( t )
2216 t.start()
2217
2218 for t in threads:
2219 t.join()
2220 ports.append( t.result )
2221 links = []
2222 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002223 for i in range( main.numCtrls ):
2224 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07002225 name="links-" + str( i ),
2226 args=[ ] )
2227 threads.append( t )
2228 t.start()
2229
2230 for t in threads:
2231 t.join()
2232 links.append( t.result )
2233 clusters = []
2234 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002235 for i in range( main.numCtrls ):
2236 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07002237 name="clusters-" + str( i ),
2238 args=[ ] )
2239 threads.append( t )
2240 t.start()
2241
2242 for t in threads:
2243 t.join()
2244 clusters.append( t.result )
2245
2246 elapsed = time.time() - startTime
2247 cliTime = time.time() - cliStart
2248 print "Elapsed time: " + str( elapsed )
2249 print "CLI time: " + str( cliTime )
2250
2251 mnSwitches = main.Mininet1.getSwitches()
2252 mnLinks = main.Mininet1.getLinks()
2253 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07002254 for controller in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07002255 controllerStr = str( controller + 1 )
2256 if devices[ controller ] and ports[ controller ] and\
2257 "Error" not in devices[ controller ] and\
2258 "Error" not in ports[ controller ]:
2259
2260 currentDevicesResult = main.Mininet1.compareSwitches(
2261 mnSwitches,
2262 json.loads( devices[ controller ] ),
2263 json.loads( ports[ controller ] ) )
2264 else:
2265 currentDevicesResult = main.FALSE
2266 utilities.assert_equals( expect=main.TRUE,
2267 actual=currentDevicesResult,
2268 onpass="ONOS" + controllerStr +
2269 " Switches view is correct",
2270 onfail="ONOS" + controllerStr +
2271 " Switches view is incorrect" )
2272
2273 if links[ controller ] and "Error" not in links[ controller ]:
2274 currentLinksResult = main.Mininet1.compareLinks(
2275 mnSwitches, mnLinks,
2276 json.loads( links[ controller ] ) )
2277 else:
2278 currentLinksResult = main.FALSE
2279 utilities.assert_equals( expect=main.TRUE,
2280 actual=currentLinksResult,
2281 onpass="ONOS" + controllerStr +
2282 " links view is correct",
2283 onfail="ONOS" + controllerStr +
2284 " links view is incorrect" )
2285
2286 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2287 currentHostsResult = main.Mininet1.compareHosts(
2288 mnHosts,
2289 hosts[ controller ] )
2290 else:
2291 currentHostsResult = main.FALSE
2292 utilities.assert_equals( expect=main.TRUE,
2293 actual=currentHostsResult,
2294 onpass="ONOS" + controllerStr +
2295 " hosts exist in Mininet",
2296 onfail="ONOS" + controllerStr +
2297 " hosts don't match Mininet" )
2298 # CHECKING HOST ATTACHMENT POINTS
2299 hostAttachment = True
2300 noHosts = False
2301 # FIXME: topo-HA/obelisk specific mappings:
2302 # key is mac and value is dpid
2303 mappings = {}
2304 for i in range( 1, 29 ): # hosts 1 through 28
2305 # set up correct variables:
2306 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2307 if i == 1:
2308 deviceId = "1000".zfill(16)
2309 elif i == 2:
2310 deviceId = "2000".zfill(16)
2311 elif i == 3:
2312 deviceId = "3000".zfill(16)
2313 elif i == 4:
2314 deviceId = "3004".zfill(16)
2315 elif i == 5:
2316 deviceId = "5000".zfill(16)
2317 elif i == 6:
2318 deviceId = "6000".zfill(16)
2319 elif i == 7:
2320 deviceId = "6007".zfill(16)
2321 elif i >= 8 and i <= 17:
2322 dpid = '3' + str( i ).zfill( 3 )
2323 deviceId = dpid.zfill(16)
2324 elif i >= 18 and i <= 27:
2325 dpid = '6' + str( i ).zfill( 3 )
2326 deviceId = dpid.zfill(16)
2327 elif i == 28:
2328 deviceId = "2800".zfill(16)
2329 mappings[ macId ] = deviceId
2330 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2331 if hosts[ controller ] == []:
2332 main.log.warn( "There are no hosts discovered" )
2333 noHosts = True
2334 else:
2335 for host in hosts[ controller ]:
2336 mac = None
2337 location = None
2338 device = None
2339 port = None
2340 try:
2341 mac = host.get( 'mac' )
2342 assert mac, "mac field could not be found for this host object"
2343
2344 location = host.get( 'location' )
2345 assert location, "location field could not be found for this host object"
2346
2347 # Trim the protocol identifier off deviceId
2348 device = str( location.get( 'elementId' ) ).split(':')[1]
2349 assert device, "elementId field could not be found for this host location object"
2350
2351 port = location.get( 'port' )
2352 assert port, "port field could not be found for this host location object"
2353
2354 # Now check if this matches where they should be
2355 if mac and device and port:
2356 if str( port ) != "1":
2357 main.log.error( "The attachment port is incorrect for " +
2358 "host " + str( mac ) +
2359 ". Expected: 1 Actual: " + str( port) )
2360 hostAttachment = False
2361 if device != mappings[ str( mac ) ]:
2362 main.log.error( "The attachment device is incorrect for " +
2363 "host " + str( mac ) +
2364 ". Expected: " + mappings[ str( mac ) ] +
2365 " Actual: " + device )
2366 hostAttachment = False
2367 else:
2368 hostAttachment = False
2369 except AssertionError:
2370 main.log.exception( "Json object not as expected" )
2371 main.log.error( repr( host ) )
2372 hostAttachment = False
2373 else:
2374 main.log.error( "No hosts json output or \"Error\"" +
2375 " in output. hosts = " +
2376 repr( hosts[ controller ] ) )
2377 if noHosts is False:
2378 # TODO: Find a way to know if there should be hosts in a
2379 # given point of the test
2380 hostAttachment = True
2381
2382 # END CHECKING HOST ATTACHMENT POINTS
2383 devicesResults = devicesResults and currentDevicesResult
2384 linksResults = linksResults and currentLinksResult
2385 hostsResults = hostsResults and currentHostsResult
2386 hostAttachmentResults = hostAttachmentResults and\
2387 hostAttachment
2388 topoResult = ( devicesResults and linksResults
2389 and hostsResults and ipResult and
2390 hostAttachmentResults )
2391
2392 # Compare json objects for hosts and dataplane clusters
2393
2394 # hosts
2395 main.step( "Hosts view is consistent across all ONOS nodes" )
2396 consistentHostsResult = main.TRUE
2397 for controller in range( len( hosts ) ):
2398 controllerStr = str( controller + 1 )
2399 if "Error" not in hosts[ controller ]:
2400 if hosts[ controller ] == hosts[ 0 ]:
2401 continue
2402 else: # hosts not consistent
2403 main.log.error( "hosts from ONOS" + controllerStr +
2404 " is inconsistent with ONOS1" )
2405 main.log.warn( repr( hosts[ controller ] ) )
2406 consistentHostsResult = main.FALSE
2407
2408 else:
2409 main.log.error( "Error in getting ONOS hosts from ONOS" +
2410 controllerStr )
2411 consistentHostsResult = main.FALSE
2412 main.log.warn( "ONOS" + controllerStr +
2413 " hosts response: " +
2414 repr( hosts[ controller ] ) )
2415 utilities.assert_equals(
2416 expect=main.TRUE,
2417 actual=consistentHostsResult,
2418 onpass="Hosts view is consistent across all ONOS nodes",
2419 onfail="ONOS nodes have different views of hosts" )
2420
2421 main.step( "Hosts information is correct" )
2422 hostsResults = hostsResults and ipResult
2423 utilities.assert_equals(
2424 expect=main.TRUE,
2425 actual=hostsResults,
2426 onpass="Host information is correct",
2427 onfail="Host information is incorrect" )
2428
2429 main.step( "Host attachment points to the network" )
2430 utilities.assert_equals(
2431 expect=True,
2432 actual=hostAttachmentResults,
2433 onpass="Hosts are correctly attached to the network",
2434 onfail="ONOS did not correctly attach hosts to the network" )
2435
2436 # Strongly connected clusters of devices
2437 main.step( "Clusters view is consistent across all ONOS nodes" )
2438 consistentClustersResult = main.TRUE
2439 for controller in range( len( clusters ) ):
2440 controllerStr = str( controller + 1 )
2441 if "Error" not in clusters[ controller ]:
2442 if clusters[ controller ] == clusters[ 0 ]:
2443 continue
2444 else: # clusters not consistent
2445 main.log.error( "clusters from ONOS" +
2446 controllerStr +
2447 " is inconsistent with ONOS1" )
2448 consistentClustersResult = main.FALSE
2449
2450 else:
2451 main.log.error( "Error in getting dataplane clusters " +
2452 "from ONOS" + controllerStr )
2453 consistentClustersResult = main.FALSE
2454 main.log.warn( "ONOS" + controllerStr +
2455 " clusters response: " +
2456 repr( clusters[ controller ] ) )
2457 utilities.assert_equals(
2458 expect=main.TRUE,
2459 actual=consistentClustersResult,
2460 onpass="Clusters view is consistent across all ONOS nodes",
2461 onfail="ONOS nodes have different views of clusters" )
2462
2463 main.step( "There is only one SCC" )
2464 # there should always only be one cluster
2465 try:
2466 numClusters = len( json.loads( clusters[ 0 ] ) )
2467 except ( ValueError, TypeError ):
2468 main.log.exception( "Error parsing clusters[0]: " +
2469 repr( clusters[0] ) )
2470 clusterResults = main.FALSE
2471 if numClusters == 1:
2472 clusterResults = main.TRUE
2473 utilities.assert_equals(
2474 expect=1,
2475 actual=numClusters,
2476 onpass="ONOS shows 1 SCC",
2477 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2478
2479 topoResult = ( devicesResults and linksResults
2480 and hostsResults and consistentHostsResult
2481 and consistentClustersResult and clusterResults
2482 and ipResult and hostAttachmentResults )
2483
2484 topoResult = topoResult and int( count <= 2 )
2485 note = "note it takes about " + str( int( cliTime ) ) + \
2486 " seconds for the test to make all the cli calls to fetch " +\
2487 "the topology from each ONOS instance"
2488 main.log.info(
2489 "Very crass estimate for topology discovery/convergence( " +
2490 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2491 str( count ) + " tries" )
2492
2493 main.step( "Device information is correct" )
2494 utilities.assert_equals(
2495 expect=main.TRUE,
2496 actual=devicesResults,
2497 onpass="Device information is correct",
2498 onfail="Device information is incorrect" )
2499
2500 main.step( "Links are correct" )
2501 utilities.assert_equals(
2502 expect=main.TRUE,
2503 actual=linksResults,
2504 onpass="Link are correct",
2505 onfail="Links are incorrect" )
2506
2507 # FIXME: move this to an ONOS state case
2508 main.step( "Checking ONOS nodes" )
2509 nodesOutput = []
2510 nodeResults = main.TRUE
2511 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002512 for i in range( main.numCtrls ):
2513 t = main.Thread( target=main.CLIs[i].nodes,
Jon Hall5cf14d52015-07-16 12:15:19 -07002514 name="nodes-" + str( i ),
2515 args=[ ] )
2516 threads.append( t )
2517 t.start()
2518
2519 for t in threads:
2520 t.join()
2521 nodesOutput.append( t.result )
Jon Halle1a3b752015-07-22 13:02:46 -07002522 ips = [ node.ip_address for node in main.nodes ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002523 for i in nodesOutput:
2524 try:
2525 current = json.loads( i )
2526 for node in current:
2527 currentResult = main.FALSE
2528 if node['ip'] in ips: # node in nodes() output is in cell
2529 if node['state'] == 'ACTIVE':
2530 currentResult = main.TRUE
2531 else:
2532 main.log.error( "Error in ONOS node availability" )
2533 main.log.error(
2534 json.dumps( current,
2535 sort_keys=True,
2536 indent=4,
2537 separators=( ',', ': ' ) ) )
2538 break
2539 nodeResults = nodeResults and currentResult
2540 except ( ValueError, TypeError ):
2541 main.log.error( "Error parsing nodes output" )
2542 main.log.warn( repr( i ) )
2543 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2544 onpass="Nodes check successful",
2545 onfail="Nodes check NOT successful" )
2546
2547 def CASE9( self, main ):
2548 """
2549 Link s3-s28 down
2550 """
2551 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002552 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002553 assert main, "main not defined"
2554 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002555 assert main.CLIs, "main.CLIs not defined"
2556 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002557 # NOTE: You should probably run a topology check after this
2558
2559 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2560
2561 description = "Turn off a link to ensure that Link Discovery " +\
2562 "is working properly"
2563 main.case( description )
2564
2565 main.step( "Kill Link between s3 and s28" )
2566 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
2567 main.log.info( "Waiting " + str( linkSleep ) +
2568 " seconds for link down to be discovered" )
2569 time.sleep( linkSleep )
2570 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
2571 onpass="Link down successful",
2572 onfail="Failed to bring link down" )
2573 # TODO do some sort of check here
2574
2575 def CASE10( self, main ):
2576 """
2577 Link s3-s28 up
2578 """
2579 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002580 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002581 assert main, "main not defined"
2582 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002583 assert main.CLIs, "main.CLIs not defined"
2584 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002585 # NOTE: You should probably run a topology check after this
2586
2587 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2588
2589 description = "Restore a link to ensure that Link Discovery is " + \
2590 "working properly"
2591 main.case( description )
2592
2593 main.step( "Bring link between s3 and s28 back up" )
2594 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
2595 main.log.info( "Waiting " + str( linkSleep ) +
2596 " seconds for link up to be discovered" )
2597 time.sleep( linkSleep )
2598 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
2599 onpass="Link up successful",
2600 onfail="Failed to bring link up" )
2601 # TODO do some sort of check here
2602
2603 def CASE11( self, main ):
2604 """
2605 Switch Down
2606 """
2607 # NOTE: You should probably run a topology check after this
2608 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002609 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002610 assert main, "main not defined"
2611 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002612 assert main.CLIs, "main.CLIs not defined"
2613 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002614
2615 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2616
2617 description = "Killing a switch to ensure it is discovered correctly"
2618 main.case( description )
2619 switch = main.params[ 'kill' ][ 'switch' ]
2620 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2621
2622 # TODO: Make this switch parameterizable
2623 main.step( "Kill " + switch )
2624 main.log.info( "Deleting " + switch )
2625 main.Mininet1.delSwitch( switch )
2626 main.log.info( "Waiting " + str( switchSleep ) +
2627 " seconds for switch down to be discovered" )
2628 time.sleep( switchSleep )
2629 device = main.ONOScli1.getDevice( dpid=switchDPID )
2630 # Peek at the deleted switch
2631 main.log.warn( str( device ) )
2632 result = main.FALSE
2633 if device and device[ 'available' ] is False:
2634 result = main.TRUE
2635 utilities.assert_equals( expect=main.TRUE, actual=result,
2636 onpass="Kill switch successful",
2637 onfail="Failed to kill switch?" )
2638
2639 def CASE12( self, main ):
2640 """
2641 Switch Up
2642 """
2643 # NOTE: You should probably run a topology check after this
2644 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002645 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002646 assert main, "main not defined"
2647 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002648 assert main.CLIs, "main.CLIs not defined"
2649 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002650 assert ONOS1Port, "ONOS1Port not defined"
2651 assert ONOS2Port, "ONOS2Port not defined"
2652 assert ONOS3Port, "ONOS3Port not defined"
2653 assert ONOS4Port, "ONOS4Port not defined"
2654 assert ONOS5Port, "ONOS5Port not defined"
2655 assert ONOS6Port, "ONOS6Port not defined"
2656 assert ONOS7Port, "ONOS7Port not defined"
2657
2658 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2659 switch = main.params[ 'kill' ][ 'switch' ]
2660 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2661 links = main.params[ 'kill' ][ 'links' ].split()
2662 description = "Adding a switch to ensure it is discovered correctly"
2663 main.case( description )
2664
2665 main.step( "Add back " + switch )
2666 main.Mininet1.addSwitch( switch, dpid=switchDPID )
2667 for peer in links:
2668 main.Mininet1.addLink( switch, peer )
2669 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -07002670 for i in range( main.numCtrls ):
2671 ipList.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -07002672 main.Mininet1.assignSwController( sw=switch, ip=ipList )
2673 main.log.info( "Waiting " + str( switchSleep ) +
2674 " seconds for switch up to be discovered" )
2675 time.sleep( switchSleep )
2676 device = main.ONOScli1.getDevice( dpid=switchDPID )
2677 # Peek at the deleted switch
2678 main.log.warn( str( device ) )
2679 result = main.FALSE
2680 if device and device[ 'available' ]:
2681 result = main.TRUE
2682 utilities.assert_equals( expect=main.TRUE, actual=result,
2683 onpass="add switch successful",
2684 onfail="Failed to add switch?" )
2685
2686 def CASE13( self, main ):
2687 """
2688 Clean up
2689 """
2690 import os
2691 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002692 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002693 assert main, "main not defined"
2694 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002695 assert main.CLIs, "main.CLIs not defined"
2696 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002697
2698 # printing colors to terminal
2699 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2700 'blue': '\033[94m', 'green': '\033[92m',
2701 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
2702 main.case( "Test Cleanup" )
2703 main.step( "Killing tcpdumps" )
2704 main.Mininet2.stopTcpdump()
2705
2706 testname = main.TEST
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002707 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall5cf14d52015-07-16 12:15:19 -07002708 main.step( "Copying MN pcap and ONOS log files to test station" )
2709 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
2710 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
Jon Hall96091e62015-09-21 17:34:17 -07002711 # NOTE: MN Pcap file is being saved to logdir.
2712 # We scp this file as MN and TestON aren't necessarily the same vm
2713
2714 # FIXME: To be replaced with a Jenkin's post script
Jon Hall5cf14d52015-07-16 12:15:19 -07002715 # TODO: Load these from params
2716 # NOTE: must end in /
2717 logFolder = "/opt/onos/log/"
2718 logFiles = [ "karaf.log", "karaf.log.1" ]
2719 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002720 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002721 for node in main.nodes:
Jon Hall96091e62015-09-21 17:34:17 -07002722 dstName = main.logdir + "/" + node.name + "-" + f
2723 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2724 logFolder + f, dstName )
Jon Hall5cf14d52015-07-16 12:15:19 -07002725 # std*.log's
2726 # NOTE: must end in /
2727 logFolder = "/opt/onos/var/"
2728 logFiles = [ "stderr.log", "stdout.log" ]
2729 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002730 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002731 for node in main.nodes:
Jon Hall96091e62015-09-21 17:34:17 -07002732 dstName = main.logdir + "/" + node.name + "-" + f
2733 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2734 logFolder + f, dstName )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002735 else:
2736 main.log.debug( "skipping saving log files" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002737
2738 main.step( "Stopping Mininet" )
2739 mnResult = main.Mininet1.stopNet()
2740 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2741 onpass="Mininet stopped",
2742 onfail="MN cleanup NOT successful" )
2743
2744 main.step( "Checking ONOS Logs for errors" )
Jon Halle1a3b752015-07-22 13:02:46 -07002745 for node in main.nodes:
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002746 main.log.debug( "Checking logs for errors on " + node.name + ":" )
2747 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002748
2749 try:
2750 timerLog = open( main.logdir + "/Timers.csv", 'w')
2751 main.log.error( ", ".join( labels ) + "\n" + ", ".join( data ) )
2752 timerLog.write( ", ".join( labels ) + "\n" + ", ".join( data ) )
2753 timerLog.close()
2754 except NameError, e:
2755 main.log.exception(e)
2756
2757 def CASE14( self, main ):
2758 """
2759 start election app on all onos nodes
2760 """
Jon Halle1a3b752015-07-22 13:02:46 -07002761 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002762 assert main, "main not defined"
2763 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002764 assert main.CLIs, "main.CLIs not defined"
2765 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002766
2767 main.case("Start Leadership Election app")
2768 main.step( "Install leadership election app" )
2769 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
2770 utilities.assert_equals(
2771 expect=main.TRUE,
2772 actual=appResult,
2773 onpass="Election app installed",
2774 onfail="Something went wrong with installing Leadership election" )
2775
2776 main.step( "Run for election on each node" )
2777 leaderResult = main.TRUE
2778 leaders = []
Jon Halle1a3b752015-07-22 13:02:46 -07002779 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002780 cli.electionTestRun()
Jon Halle1a3b752015-07-22 13:02:46 -07002781 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002782 leader = cli.electionTestLeader()
2783 if leader is None or leader == main.FALSE:
2784 main.log.error( cli.name + ": Leader for the election app " +
2785 "should be an ONOS node, instead got '" +
2786 str( leader ) + "'" )
2787 leaderResult = main.FALSE
2788 leaders.append( leader )
2789 utilities.assert_equals(
2790 expect=main.TRUE,
2791 actual=leaderResult,
2792 onpass="Successfully ran for leadership",
2793 onfail="Failed to run for leadership" )
2794
2795 main.step( "Check that each node shows the same leader" )
2796 sameLeader = main.TRUE
2797 if len( set( leaders ) ) != 1:
2798 sameLeader = main.FALSE
2799 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2800 str( leaders ) )
2801 utilities.assert_equals(
2802 expect=main.TRUE,
2803 actual=sameLeader,
2804 onpass="Leadership is consistent for the election topic",
2805 onfail="Nodes have different leaders" )
2806
2807 def CASE15( self, main ):
2808 """
2809 Check that Leadership Election is still functional
acsmars9475b1c2015-08-28 18:02:08 -07002810 15.1 Run election on each node
2811 15.2 Check that each node has the same leaders and candidates
2812 15.3 Find current leader and withdraw
2813 15.4 Check that a new node was elected leader
2814 15.5 Check that that new leader was the candidate of old leader
2815 15.6 Run for election on old leader
2816 15.7 Check that oldLeader is a candidate, and leader if only 1 node
2817 15.8 Make sure that the old leader was added to the candidate list
2818
2819 old and new variable prefixes refer to data from before vs after
2820 withdrawl and later before withdrawl vs after re-election
Jon Hall5cf14d52015-07-16 12:15:19 -07002821 """
2822 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002823 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002824 assert main, "main not defined"
2825 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002826 assert main.CLIs, "main.CLIs not defined"
2827 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002828
Jon Hall5cf14d52015-07-16 12:15:19 -07002829 description = "Check that Leadership Election is still functional"
2830 main.case( description )
2831 # NOTE: Need to re-run since being a canidate is not persistant
acsmars9475b1c2015-08-28 18:02:08 -07002832 # TODO: add check for "Command not found:" in the driver, this
2833 # means the election test app isn't loaded
2834
2835 oldLeaders = [] # leaders by node before withdrawl from candidates
2836 newLeaders = [] # leaders by node after withdrawl from candidates
2837 oldAllCandidates = [] # list of lists of each nodes' candidates before
2838 newAllCandidates = [] # list of lists of each nodes' candidates after
2839 oldCandidates = [] # list of candidates from node 0 before withdrawl
2840 newCandidates = [] # list of candidates from node 0 after withdrawl
2841 oldLeader = '' # the old leader from oldLeaders, None if not same
2842 newLeader = '' # the new leaders fron newLoeaders, None if not same
2843 oldLeaderCLI = None # the CLI of the old leader used for re-electing
acsmars71adceb2015-08-31 15:09:26 -07002844 expectNoLeader = False # True when there is only one leader
2845 if main.numCtrls == 1:
2846 expectNoLeader = True
acsmars9475b1c2015-08-28 18:02:08 -07002847
Jon Hall5cf14d52015-07-16 12:15:19 -07002848 main.step( "Run for election on each node" )
acsmars9475b1c2015-08-28 18:02:08 -07002849 electionResult = main.TRUE
2850
2851 for cli in main.CLIs: # run test election on each node
2852 if cli.electionTestRun() == main.FALSE:
2853 electionResult = main.FALSE
2854
Jon Hall5cf14d52015-07-16 12:15:19 -07002855 utilities.assert_equals(
2856 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07002857 actual=electionResult,
2858 onpass="All nodes successfully ran for leadership",
2859 onfail="At least one node failed to run for leadership" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002860
acsmars3a72bde2015-09-02 14:16:22 -07002861 if electionResult == main.FALSE:
2862 main.log.error(
2863 "Skipping Test Case because Election Test App isn't loaded" )
2864 main.skipCase()
2865
acsmars9475b1c2015-08-28 18:02:08 -07002866 main.step( "Check that each node shows the same leader and candidates" )
2867 sameResult = main.TRUE
2868 failMessage = "Nodes have different leaders"
2869 for cli in main.CLIs:
2870 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2871 oldAllCandidates.append( node )
2872 oldLeaders.append( node[ 0 ] )
2873 oldCandidates = oldAllCandidates[ 0 ]
2874
2875 # Check that each node has the same leader. Defines oldLeader
2876 if len( set( oldLeaders ) ) != 1:
2877 sameResult = main.FALSE
acsmars71adceb2015-08-31 15:09:26 -07002878 main.log.error( "More than one leader present:" + str( oldLeaders ) )
acsmars9475b1c2015-08-28 18:02:08 -07002879 oldLeader = None
2880 else:
2881 oldLeader = oldLeaders[ 0 ]
2882
2883 # Check that each node's candidate list is the same
2884 for candidates in oldAllCandidates:
2885 if set( candidates ) != set( oldCandidates ):
2886 sameResult = main.FALSE
2887 failMessage += "and candidates"
2888
Jon Hall5cf14d52015-07-16 12:15:19 -07002889 utilities.assert_equals(
2890 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002891 actual=sameResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002892 onpass="Leadership is consistent for the election topic",
acsmars9475b1c2015-08-28 18:02:08 -07002893 onfail=failMessage )
Jon Hall5cf14d52015-07-16 12:15:19 -07002894
2895 main.step( "Find current leader and withdraw" )
acsmars9475b1c2015-08-28 18:02:08 -07002896 withdrawResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002897 # do some sanity checking on leader before using it
acsmars9475b1c2015-08-28 18:02:08 -07002898 if oldLeader is None:
2899 main.log.error( "Leadership isn't consistent." )
2900 withdrawResult = main.FALSE
2901 # Get the CLI of the oldLeader
Jon Halle1a3b752015-07-22 13:02:46 -07002902 for i in range( len( main.CLIs ) ):
acsmars9475b1c2015-08-28 18:02:08 -07002903 if oldLeader == main.nodes[ i ].ip_address:
2904 oldLeaderCLI = main.CLIs[ i ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002905 break
2906 else: # FOR/ELSE statement
2907 main.log.error( "Leader election, could not find current leader" )
2908 if oldLeader:
acsmars9475b1c2015-08-28 18:02:08 -07002909 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall5cf14d52015-07-16 12:15:19 -07002910 utilities.assert_equals(
2911 expect=main.TRUE,
2912 actual=withdrawResult,
2913 onpass="Node was withdrawn from election",
2914 onfail="Node was not withdrawn from election" )
2915
acsmars9475b1c2015-08-28 18:02:08 -07002916 main.step( "Check that a new node was elected leader" )
acsmars71adceb2015-08-31 15:09:26 -07002917
Jon Hall5cf14d52015-07-16 12:15:19 -07002918 # FIXME: use threads
acsmars9475b1c2015-08-28 18:02:08 -07002919 newLeaderResult = main.TRUE
2920 failMessage = "Nodes have different leaders"
2921
2922 # Get new leaders and candidates
Jon Halle1a3b752015-07-22 13:02:46 -07002923 for cli in main.CLIs:
acsmars9475b1c2015-08-28 18:02:08 -07002924 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
acsmars71adceb2015-08-31 15:09:26 -07002925 # elections might no have finished yet
2926 if node[ 0 ] == 'none' and not expectNoLeader:
acsmars9475b1c2015-08-28 18:02:08 -07002927 main.log.info( "Node has no leader, waiting 5 seconds to be " +
2928 "sure elections are complete." )
2929 time.sleep(5)
2930 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
acsmars71adceb2015-08-31 15:09:26 -07002931 # election still isn't done or there is a problem
2932 if node[ 0 ] == 'none':
2933 main.log.error( "No leader was elected on at least 1 node" )
2934 newLeaderResult = main.FALSE
acsmars9475b1c2015-08-28 18:02:08 -07002935 newAllCandidates.append( node )
2936 newLeaders.append( node[ 0 ] )
2937 newCandidates = newAllCandidates[ 0 ]
2938
2939 # Check that each node has the same leader. Defines newLeader
2940 if len( set( newLeaders ) ) != 1:
2941 newLeaderResult = main.FALSE
2942 main.log.error( "Nodes have different leaders: " +
2943 str( newLeaders ) )
2944 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07002945 else:
acsmars9475b1c2015-08-28 18:02:08 -07002946 newLeader = newLeaders[ 0 ]
2947
acsmars71adceb2015-08-31 15:09:26 -07002948 # Check that each node's candidate list is the same
2949 for candidates in newAllCandidates:
2950 if set( candidates ) != set( newCandidates ):
2951 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07002952 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07002953
acsmars9475b1c2015-08-28 18:02:08 -07002954 # Check that the new leader is not the older leader, which was withdrawn
2955 if newLeader == oldLeader:
2956 newLeaderResult = main.FALSE
2957 main.log.error( "All nodes still see old leader: " + oldLeader +
2958 " as the current leader" )
2959
Jon Hall5cf14d52015-07-16 12:15:19 -07002960 utilities.assert_equals(
2961 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07002962 actual=newLeaderResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002963 onpass="Leadership election passed",
2964 onfail="Something went wrong with Leadership election" )
2965
acsmars9475b1c2015-08-28 18:02:08 -07002966 main.step( "Check that that new leader was the candidate of old leader")
2967 # candidates[ 2 ] should be come the top candidate after withdrawl
2968 correctCandidateResult = main.TRUE
acsmars71adceb2015-08-31 15:09:26 -07002969 if expectNoLeader:
2970 if newLeader == 'none':
2971 main.log.info( "No leader expected. None found. Pass" )
2972 correctCandidateResult = main.TRUE
2973 else:
2974 main.log.info( "Expected no leader, got: " + str( newLeader ) )
2975 correctCandidateResult = main.FALSE
2976 elif newLeader != oldCandidates[ 2 ]:
acsmars9475b1c2015-08-28 18:02:08 -07002977 correctCandidateResult = main.FALSE
2978 main.log.error( "Candidate " + newLeader + " was elected. " +
2979 oldCandidates[ 2 ] + " should have had priority." )
2980
2981 utilities.assert_equals(
2982 expect=main.TRUE,
2983 actual=correctCandidateResult,
2984 onpass="Correct Candidate Elected",
2985 onfail="Incorrect Candidate Elected" )
2986
Jon Hall5cf14d52015-07-16 12:15:19 -07002987 main.step( "Run for election on old leader( just so everyone " +
2988 "is in the hat )" )
acsmars9475b1c2015-08-28 18:02:08 -07002989 if oldLeaderCLI is not None:
2990 runResult = oldLeaderCLI.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07002991 else:
acsmars9475b1c2015-08-28 18:02:08 -07002992 main.log.error( "No old leader to re-elect" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002993 runResult = main.FALSE
2994 utilities.assert_equals(
2995 expect=main.TRUE,
2996 actual=runResult,
2997 onpass="App re-ran for election",
2998 onfail="App failed to run for election" )
acsmars9475b1c2015-08-28 18:02:08 -07002999 main.step(
3000 "Check that oldLeader is a candidate, and leader if only 1 node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003001 # verify leader didn't just change
acsmars9475b1c2015-08-28 18:02:08 -07003002 positionResult = main.TRUE
3003 # Get new leaders and candidates, wait if oldLeader is not a candidate yet
3004
3005 # Reset and reuse the new candidate and leaders lists
3006 newAllCandidates = []
3007 newCandidates = []
3008 newLeaders = []
3009 for cli in main.CLIs:
3010 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
3011 if oldLeader not in node: # election might no have finished yet
3012 main.log.info( "Old Leader not elected, waiting 5 seconds to " +
3013 "be sure elections are complete" )
3014 time.sleep(5)
3015 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
3016 if oldLeader not in node: # election still isn't done, errors
3017 main.log.error(
3018 "Old leader was not elected on at least one node" )
3019 positionResult = main.FALSE
3020 newAllCandidates.append( node )
3021 newLeaders.append( node[ 0 ] )
3022 newCandidates = newAllCandidates[ 0 ]
3023
3024 # Check that each node has the same leader. Defines newLeader
3025 if len( set( newLeaders ) ) != 1:
3026 positionResult = main.FALSE
3027 main.log.error( "Nodes have different leaders: " +
3028 str( newLeaders ) )
3029 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07003030 else:
acsmars9475b1c2015-08-28 18:02:08 -07003031 newLeader = newLeaders[ 0 ]
3032
acsmars71adceb2015-08-31 15:09:26 -07003033 # Check that each node's candidate list is the same
3034 for candidates in newAllCandidates:
3035 if set( candidates ) != set( newCandidates ):
3036 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07003037 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07003038
acsmars9475b1c2015-08-28 18:02:08 -07003039 # Check that the re-elected node is last on the candidate List
3040 if oldLeader != newCandidates[ -1 ]:
3041 main.log.error( "Old Leader (" + oldLeader + ") not in the proper position " +
3042 str( newCandidates ) )
3043 positionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07003044
3045 utilities.assert_equals(
3046 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07003047 actual=positionResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07003048 onpass="Old leader successfully re-ran for election",
3049 onfail="Something went wrong with Leadership election after " +
3050 "the old leader re-ran for election" )
3051
3052 def CASE16( self, main ):
3053 """
3054 Install Distributed Primitives app
3055 """
3056 import time
Jon Halle1a3b752015-07-22 13:02:46 -07003057 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003058 assert main, "main not defined"
3059 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003060 assert main.CLIs, "main.CLIs not defined"
3061 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003062
3063 # Variables for the distributed primitives tests
3064 global pCounterName
3065 global iCounterName
3066 global pCounterValue
3067 global iCounterValue
3068 global onosSet
3069 global onosSetName
3070 pCounterName = "TestON-Partitions"
3071 iCounterName = "TestON-inMemory"
3072 pCounterValue = 0
3073 iCounterValue = 0
3074 onosSet = set([])
3075 onosSetName = "TestON-set"
3076
3077 description = "Install Primitives app"
3078 main.case( description )
3079 main.step( "Install Primitives app" )
3080 appName = "org.onosproject.distributedprimitives"
Jon Halle1a3b752015-07-22 13:02:46 -07003081 appResults = main.CLIs[0].activateApp( appName )
Jon Hall5cf14d52015-07-16 12:15:19 -07003082 utilities.assert_equals( expect=main.TRUE,
3083 actual=appResults,
3084 onpass="Primitives app activated",
3085 onfail="Primitives app not activated" )
3086 time.sleep( 5 ) # To allow all nodes to activate
3087
3088 def CASE17( self, main ):
3089 """
3090 Check for basic functionality with distributed primitives
3091 """
Jon Hall5cf14d52015-07-16 12:15:19 -07003092 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07003093 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003094 assert main, "main not defined"
3095 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003096 assert main.CLIs, "main.CLIs not defined"
3097 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003098 assert pCounterName, "pCounterName not defined"
3099 assert iCounterName, "iCounterName not defined"
3100 assert onosSetName, "onosSetName not defined"
3101 # NOTE: assert fails if value is 0/None/Empty/False
3102 try:
3103 pCounterValue
3104 except NameError:
3105 main.log.error( "pCounterValue not defined, setting to 0" )
3106 pCounterValue = 0
3107 try:
3108 iCounterValue
3109 except NameError:
3110 main.log.error( "iCounterValue not defined, setting to 0" )
3111 iCounterValue = 0
3112 try:
3113 onosSet
3114 except NameError:
3115 main.log.error( "onosSet not defined, setting to empty Set" )
3116 onosSet = set([])
3117 # Variables for the distributed primitives tests. These are local only
3118 addValue = "a"
3119 addAllValue = "a b c d e f"
3120 retainValue = "c d e f"
3121
3122 description = "Check for basic functionality with distributed " +\
3123 "primitives"
3124 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07003125 main.caseExplanation = "Test the methods of the distributed " +\
3126 "primitives (counters and sets) throught the cli"
Jon Hall5cf14d52015-07-16 12:15:19 -07003127 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07003128 # Partitioned counters
3129 main.step( "Increment then get a default counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003130 pCounters = []
3131 threads = []
3132 addedPValues = []
Jon Halle1a3b752015-07-22 13:02:46 -07003133 for i in range( main.numCtrls ):
3134 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3135 name="counterAddAndGet-" + str( i ),
Jon Hall5cf14d52015-07-16 12:15:19 -07003136 args=[ pCounterName ] )
3137 pCounterValue += 1
3138 addedPValues.append( pCounterValue )
3139 threads.append( t )
3140 t.start()
3141
3142 for t in threads:
3143 t.join()
3144 pCounters.append( t.result )
3145 # Check that counter incremented numController times
3146 pCounterResults = True
3147 for i in addedPValues:
3148 tmpResult = i in pCounters
3149 pCounterResults = pCounterResults and tmpResult
3150 if not tmpResult:
3151 main.log.error( str( i ) + " is not in partitioned "
3152 "counter incremented results" )
3153 utilities.assert_equals( expect=True,
3154 actual=pCounterResults,
3155 onpass="Default counter incremented",
3156 onfail="Error incrementing default" +
3157 " counter" )
3158
Jon Halle1a3b752015-07-22 13:02:46 -07003159 main.step( "Get then Increment a default counter on each node" )
3160 pCounters = []
3161 threads = []
3162 addedPValues = []
3163 for i in range( main.numCtrls ):
3164 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3165 name="counterGetAndAdd-" + str( i ),
3166 args=[ pCounterName ] )
3167 addedPValues.append( pCounterValue )
3168 pCounterValue += 1
3169 threads.append( t )
3170 t.start()
3171
3172 for t in threads:
3173 t.join()
3174 pCounters.append( t.result )
3175 # Check that counter incremented numController times
3176 pCounterResults = True
3177 for i in addedPValues:
3178 tmpResult = i in pCounters
3179 pCounterResults = pCounterResults and tmpResult
3180 if not tmpResult:
3181 main.log.error( str( i ) + " is not in partitioned "
3182 "counter incremented results" )
3183 utilities.assert_equals( expect=True,
3184 actual=pCounterResults,
3185 onpass="Default counter incremented",
3186 onfail="Error incrementing default" +
3187 " counter" )
3188
3189 main.step( "Counters we added have the correct values" )
3190 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3191 utilities.assert_equals( expect=main.TRUE,
3192 actual=incrementCheck,
3193 onpass="Added counters are correct",
3194 onfail="Added counters are incorrect" )
3195
3196 main.step( "Add -8 to then get a default counter on each node" )
3197 pCounters = []
3198 threads = []
3199 addedPValues = []
3200 for i in range( main.numCtrls ):
3201 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3202 name="counterIncrement-" + str( i ),
3203 args=[ pCounterName ],
3204 kwargs={ "delta": -8 } )
3205 pCounterValue += -8
3206 addedPValues.append( pCounterValue )
3207 threads.append( t )
3208 t.start()
3209
3210 for t in threads:
3211 t.join()
3212 pCounters.append( t.result )
3213 # Check that counter incremented numController times
3214 pCounterResults = True
3215 for i in addedPValues:
3216 tmpResult = i in pCounters
3217 pCounterResults = pCounterResults and tmpResult
3218 if not tmpResult:
3219 main.log.error( str( i ) + " is not in partitioned "
3220 "counter incremented results" )
3221 utilities.assert_equals( expect=True,
3222 actual=pCounterResults,
3223 onpass="Default counter incremented",
3224 onfail="Error incrementing default" +
3225 " counter" )
3226
3227 main.step( "Add 5 to then get a default counter on each node" )
3228 pCounters = []
3229 threads = []
3230 addedPValues = []
3231 for i in range( main.numCtrls ):
3232 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3233 name="counterIncrement-" + str( i ),
3234 args=[ pCounterName ],
3235 kwargs={ "delta": 5 } )
3236 pCounterValue += 5
3237 addedPValues.append( pCounterValue )
3238 threads.append( t )
3239 t.start()
3240
3241 for t in threads:
3242 t.join()
3243 pCounters.append( t.result )
3244 # Check that counter incremented numController times
3245 pCounterResults = True
3246 for i in addedPValues:
3247 tmpResult = i in pCounters
3248 pCounterResults = pCounterResults and tmpResult
3249 if not tmpResult:
3250 main.log.error( str( i ) + " is not in partitioned "
3251 "counter incremented results" )
3252 utilities.assert_equals( expect=True,
3253 actual=pCounterResults,
3254 onpass="Default counter incremented",
3255 onfail="Error incrementing default" +
3256 " counter" )
3257
3258 main.step( "Get then add 5 to a default counter on each node" )
3259 pCounters = []
3260 threads = []
3261 addedPValues = []
3262 for i in range( main.numCtrls ):
3263 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3264 name="counterIncrement-" + str( i ),
3265 args=[ pCounterName ],
3266 kwargs={ "delta": 5 } )
3267 addedPValues.append( pCounterValue )
3268 pCounterValue += 5
3269 threads.append( t )
3270 t.start()
3271
3272 for t in threads:
3273 t.join()
3274 pCounters.append( t.result )
3275 # Check that counter incremented numController times
3276 pCounterResults = True
3277 for i in addedPValues:
3278 tmpResult = i in pCounters
3279 pCounterResults = pCounterResults and tmpResult
3280 if not tmpResult:
3281 main.log.error( str( i ) + " is not in partitioned "
3282 "counter incremented results" )
3283 utilities.assert_equals( expect=True,
3284 actual=pCounterResults,
3285 onpass="Default counter incremented",
3286 onfail="Error incrementing default" +
3287 " counter" )
3288
3289 main.step( "Counters we added have the correct values" )
3290 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3291 utilities.assert_equals( expect=main.TRUE,
3292 actual=incrementCheck,
3293 onpass="Added counters are correct",
3294 onfail="Added counters are incorrect" )
3295
3296 # In-Memory counters
3297 main.step( "Increment and get an in-memory counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003298 iCounters = []
3299 addedIValues = []
3300 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003301 for i in range( main.numCtrls ):
3302 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003303 name="icounterIncrement-" + str( i ),
3304 args=[ iCounterName ],
3305 kwargs={ "inMemory": True } )
3306 iCounterValue += 1
3307 addedIValues.append( iCounterValue )
3308 threads.append( t )
3309 t.start()
3310
3311 for t in threads:
3312 t.join()
3313 iCounters.append( t.result )
3314 # Check that counter incremented numController times
3315 iCounterResults = True
3316 for i in addedIValues:
3317 tmpResult = i in iCounters
3318 iCounterResults = iCounterResults and tmpResult
3319 if not tmpResult:
3320 main.log.error( str( i ) + " is not in the in-memory "
3321 "counter incremented results" )
3322 utilities.assert_equals( expect=True,
3323 actual=iCounterResults,
Jon Halle1a3b752015-07-22 13:02:46 -07003324 onpass="In-memory counter incremented",
3325 onfail="Error incrementing in-memory" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003326 " counter" )
3327
Jon Halle1a3b752015-07-22 13:02:46 -07003328 main.step( "Get then Increment a in-memory counter on each node" )
3329 iCounters = []
3330 threads = []
3331 addedIValues = []
3332 for i in range( main.numCtrls ):
3333 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3334 name="counterGetAndAdd-" + str( i ),
3335 args=[ iCounterName ],
3336 kwargs={ "inMemory": True } )
3337 addedIValues.append( iCounterValue )
3338 iCounterValue += 1
3339 threads.append( t )
3340 t.start()
3341
3342 for t in threads:
3343 t.join()
3344 iCounters.append( t.result )
3345 # Check that counter incremented numController times
3346 iCounterResults = True
3347 for i in addedIValues:
3348 tmpResult = i in iCounters
3349 iCounterResults = iCounterResults and tmpResult
3350 if not tmpResult:
3351 main.log.error( str( i ) + " is not in in-memory "
3352 "counter incremented results" )
3353 utilities.assert_equals( expect=True,
3354 actual=iCounterResults,
3355 onpass="In-memory counter incremented",
3356 onfail="Error incrementing in-memory" +
3357 " counter" )
3358
3359 main.step( "Counters we added have the correct values" )
3360 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3361 utilities.assert_equals( expect=main.TRUE,
3362 actual=incrementCheck,
3363 onpass="Added counters are correct",
3364 onfail="Added counters are incorrect" )
3365
3366 main.step( "Add -8 to then get a in-memory counter on each node" )
3367 iCounters = []
3368 threads = []
3369 addedIValues = []
3370 for i in range( main.numCtrls ):
3371 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3372 name="counterIncrement-" + str( i ),
3373 args=[ iCounterName ],
3374 kwargs={ "delta": -8, "inMemory": True } )
3375 iCounterValue += -8
3376 addedIValues.append( iCounterValue )
3377 threads.append( t )
3378 t.start()
3379
3380 for t in threads:
3381 t.join()
3382 iCounters.append( t.result )
3383 # Check that counter incremented numController times
3384 iCounterResults = True
3385 for i in addedIValues:
3386 tmpResult = i in iCounters
3387 iCounterResults = iCounterResults and tmpResult
3388 if not tmpResult:
3389 main.log.error( str( i ) + " is not in in-memory "
3390 "counter incremented results" )
3391 utilities.assert_equals( expect=True,
3392 actual=pCounterResults,
3393 onpass="In-memory counter incremented",
3394 onfail="Error incrementing in-memory" +
3395 " counter" )
3396
3397 main.step( "Add 5 to then get a in-memory counter on each node" )
3398 iCounters = []
3399 threads = []
3400 addedIValues = []
3401 for i in range( main.numCtrls ):
3402 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3403 name="counterIncrement-" + str( i ),
3404 args=[ iCounterName ],
3405 kwargs={ "delta": 5, "inMemory": True } )
3406 iCounterValue += 5
3407 addedIValues.append( iCounterValue )
3408 threads.append( t )
3409 t.start()
3410
3411 for t in threads:
3412 t.join()
3413 iCounters.append( t.result )
3414 # Check that counter incremented numController times
3415 iCounterResults = True
3416 for i in addedIValues:
3417 tmpResult = i in iCounters
3418 iCounterResults = iCounterResults and tmpResult
3419 if not tmpResult:
3420 main.log.error( str( i ) + " is not in in-memory "
3421 "counter incremented results" )
3422 utilities.assert_equals( expect=True,
3423 actual=pCounterResults,
3424 onpass="In-memory counter incremented",
3425 onfail="Error incrementing in-memory" +
3426 " counter" )
3427
3428 main.step( "Get then add 5 to a in-memory counter on each node" )
3429 iCounters = []
3430 threads = []
3431 addedIValues = []
3432 for i in range( main.numCtrls ):
3433 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3434 name="counterIncrement-" + str( i ),
3435 args=[ iCounterName ],
3436 kwargs={ "delta": 5, "inMemory": True } )
3437 addedIValues.append( iCounterValue )
3438 iCounterValue += 5
3439 threads.append( t )
3440 t.start()
3441
3442 for t in threads:
3443 t.join()
3444 iCounters.append( t.result )
3445 # Check that counter incremented numController times
3446 iCounterResults = True
3447 for i in addedIValues:
3448 tmpResult = i in iCounters
3449 iCounterResults = iCounterResults and tmpResult
3450 if not tmpResult:
3451 main.log.error( str( i ) + " is not in in-memory "
3452 "counter incremented results" )
3453 utilities.assert_equals( expect=True,
3454 actual=iCounterResults,
3455 onpass="In-memory counter incremented",
3456 onfail="Error incrementing in-memory" +
3457 " counter" )
3458
3459 main.step( "Counters we added have the correct values" )
3460 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3461 utilities.assert_equals( expect=main.TRUE,
3462 actual=incrementCheck,
3463 onpass="Added counters are correct",
3464 onfail="Added counters are incorrect" )
3465
Jon Hall5cf14d52015-07-16 12:15:19 -07003466 main.step( "Check counters are consistant across nodes" )
Jon Hall57b50432015-10-22 10:20:10 -07003467 onosCounters, consistentCounterResults = main.Counters.consistentCheck()
Jon Hall5cf14d52015-07-16 12:15:19 -07003468 utilities.assert_equals( expect=main.TRUE,
3469 actual=consistentCounterResults,
3470 onpass="ONOS counters are consistent " +
3471 "across nodes",
3472 onfail="ONOS Counters are inconsistent " +
3473 "across nodes" )
3474
3475 main.step( "Counters we added have the correct values" )
Jon Halle1a3b752015-07-22 13:02:46 -07003476 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3477 incrementCheck = incrementCheck and \
3478 main.Counters.counterCheck( iCounterName, iCounterValue )
Jon Hall5cf14d52015-07-16 12:15:19 -07003479 utilities.assert_equals( expect=main.TRUE,
Jon Halle1a3b752015-07-22 13:02:46 -07003480 actual=incrementCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -07003481 onpass="Added counters are correct",
3482 onfail="Added counters are incorrect" )
3483 # DISTRIBUTED SETS
3484 main.step( "Distributed Set get" )
3485 size = len( onosSet )
3486 getResponses = []
3487 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003488 for i in range( main.numCtrls ):
3489 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003490 name="setTestGet-" + str( i ),
3491 args=[ onosSetName ] )
3492 threads.append( t )
3493 t.start()
3494 for t in threads:
3495 t.join()
3496 getResponses.append( t.result )
3497
3498 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003499 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003500 if isinstance( getResponses[ i ], list):
3501 current = set( getResponses[ i ] )
3502 if len( current ) == len( getResponses[ i ] ):
3503 # no repeats
3504 if onosSet != current:
3505 main.log.error( "ONOS" + str( i + 1 ) +
3506 " has incorrect view" +
3507 " of set " + onosSetName + ":\n" +
3508 str( getResponses[ i ] ) )
3509 main.log.debug( "Expected: " + str( onosSet ) )
3510 main.log.debug( "Actual: " + str( current ) )
3511 getResults = main.FALSE
3512 else:
3513 # error, set is not a set
3514 main.log.error( "ONOS" + str( i + 1 ) +
3515 " has repeat elements in" +
3516 " set " + onosSetName + ":\n" +
3517 str( getResponses[ i ] ) )
3518 getResults = main.FALSE
3519 elif getResponses[ i ] == main.ERROR:
3520 getResults = main.FALSE
3521 utilities.assert_equals( expect=main.TRUE,
3522 actual=getResults,
3523 onpass="Set elements are correct",
3524 onfail="Set elements are incorrect" )
3525
3526 main.step( "Distributed Set size" )
3527 sizeResponses = []
3528 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003529 for i in range( main.numCtrls ):
3530 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003531 name="setTestSize-" + str( i ),
3532 args=[ onosSetName ] )
3533 threads.append( t )
3534 t.start()
3535 for t in threads:
3536 t.join()
3537 sizeResponses.append( t.result )
3538
3539 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003540 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003541 if size != sizeResponses[ i ]:
3542 sizeResults = main.FALSE
3543 main.log.error( "ONOS" + str( i + 1 ) +
3544 " expected a size of " + str( size ) +
3545 " for set " + onosSetName +
3546 " but got " + str( sizeResponses[ i ] ) )
3547 utilities.assert_equals( expect=main.TRUE,
3548 actual=sizeResults,
3549 onpass="Set sizes are correct",
3550 onfail="Set sizes are incorrect" )
3551
3552 main.step( "Distributed Set add()" )
3553 onosSet.add( addValue )
3554 addResponses = []
3555 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003556 for i in range( main.numCtrls ):
3557 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003558 name="setTestAdd-" + str( i ),
3559 args=[ onosSetName, addValue ] )
3560 threads.append( t )
3561 t.start()
3562 for t in threads:
3563 t.join()
3564 addResponses.append( t.result )
3565
3566 # main.TRUE = successfully changed the set
3567 # main.FALSE = action resulted in no change in set
3568 # main.ERROR - Some error in executing the function
3569 addResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003570 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003571 if addResponses[ i ] == main.TRUE:
3572 # All is well
3573 pass
3574 elif addResponses[ i ] == main.FALSE:
3575 # Already in set, probably fine
3576 pass
3577 elif addResponses[ i ] == main.ERROR:
3578 # Error in execution
3579 addResults = main.FALSE
3580 else:
3581 # unexpected result
3582 addResults = main.FALSE
3583 if addResults != main.TRUE:
3584 main.log.error( "Error executing set add" )
3585
3586 # Check if set is still correct
3587 size = len( onosSet )
3588 getResponses = []
3589 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003590 for i in range( main.numCtrls ):
3591 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003592 name="setTestGet-" + str( i ),
3593 args=[ onosSetName ] )
3594 threads.append( t )
3595 t.start()
3596 for t in threads:
3597 t.join()
3598 getResponses.append( t.result )
3599 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003600 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003601 if isinstance( getResponses[ i ], list):
3602 current = set( getResponses[ i ] )
3603 if len( current ) == len( getResponses[ i ] ):
3604 # no repeats
3605 if onosSet != current:
3606 main.log.error( "ONOS" + str( i + 1 ) +
3607 " has incorrect view" +
3608 " of set " + onosSetName + ":\n" +
3609 str( getResponses[ i ] ) )
3610 main.log.debug( "Expected: " + str( onosSet ) )
3611 main.log.debug( "Actual: " + str( current ) )
3612 getResults = main.FALSE
3613 else:
3614 # error, set is not a set
3615 main.log.error( "ONOS" + str( i + 1 ) +
3616 " has repeat elements in" +
3617 " set " + onosSetName + ":\n" +
3618 str( getResponses[ i ] ) )
3619 getResults = main.FALSE
3620 elif getResponses[ i ] == main.ERROR:
3621 getResults = main.FALSE
3622 sizeResponses = []
3623 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003624 for i in range( main.numCtrls ):
3625 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003626 name="setTestSize-" + str( i ),
3627 args=[ onosSetName ] )
3628 threads.append( t )
3629 t.start()
3630 for t in threads:
3631 t.join()
3632 sizeResponses.append( t.result )
3633 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003634 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003635 if size != sizeResponses[ i ]:
3636 sizeResults = main.FALSE
3637 main.log.error( "ONOS" + str( i + 1 ) +
3638 " expected a size of " + str( size ) +
3639 " for set " + onosSetName +
3640 " but got " + str( sizeResponses[ i ] ) )
3641 addResults = addResults and getResults and sizeResults
3642 utilities.assert_equals( expect=main.TRUE,
3643 actual=addResults,
3644 onpass="Set add correct",
3645 onfail="Set add was incorrect" )
3646
3647 main.step( "Distributed Set addAll()" )
3648 onosSet.update( addAllValue.split() )
3649 addResponses = []
3650 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003651 for i in range( main.numCtrls ):
3652 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003653 name="setTestAddAll-" + str( i ),
3654 args=[ onosSetName, addAllValue ] )
3655 threads.append( t )
3656 t.start()
3657 for t in threads:
3658 t.join()
3659 addResponses.append( t.result )
3660
3661 # main.TRUE = successfully changed the set
3662 # main.FALSE = action resulted in no change in set
3663 # main.ERROR - Some error in executing the function
3664 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003665 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003666 if addResponses[ i ] == main.TRUE:
3667 # All is well
3668 pass
3669 elif addResponses[ i ] == main.FALSE:
3670 # Already in set, probably fine
3671 pass
3672 elif addResponses[ i ] == main.ERROR:
3673 # Error in execution
3674 addAllResults = main.FALSE
3675 else:
3676 # unexpected result
3677 addAllResults = main.FALSE
3678 if addAllResults != main.TRUE:
3679 main.log.error( "Error executing set addAll" )
3680
3681 # Check if set is still correct
3682 size = len( onosSet )
3683 getResponses = []
3684 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003685 for i in range( main.numCtrls ):
3686 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003687 name="setTestGet-" + str( i ),
3688 args=[ onosSetName ] )
3689 threads.append( t )
3690 t.start()
3691 for t in threads:
3692 t.join()
3693 getResponses.append( t.result )
3694 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003695 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003696 if isinstance( getResponses[ i ], list):
3697 current = set( getResponses[ i ] )
3698 if len( current ) == len( getResponses[ i ] ):
3699 # no repeats
3700 if onosSet != current:
3701 main.log.error( "ONOS" + str( i + 1 ) +
3702 " has incorrect view" +
3703 " of set " + onosSetName + ":\n" +
3704 str( getResponses[ i ] ) )
3705 main.log.debug( "Expected: " + str( onosSet ) )
3706 main.log.debug( "Actual: " + str( current ) )
3707 getResults = main.FALSE
3708 else:
3709 # error, set is not a set
3710 main.log.error( "ONOS" + str( i + 1 ) +
3711 " has repeat elements in" +
3712 " set " + onosSetName + ":\n" +
3713 str( getResponses[ i ] ) )
3714 getResults = main.FALSE
3715 elif getResponses[ i ] == main.ERROR:
3716 getResults = main.FALSE
3717 sizeResponses = []
3718 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003719 for i in range( main.numCtrls ):
3720 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003721 name="setTestSize-" + str( i ),
3722 args=[ onosSetName ] )
3723 threads.append( t )
3724 t.start()
3725 for t in threads:
3726 t.join()
3727 sizeResponses.append( t.result )
3728 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003729 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003730 if size != sizeResponses[ i ]:
3731 sizeResults = main.FALSE
3732 main.log.error( "ONOS" + str( i + 1 ) +
3733 " expected a size of " + str( size ) +
3734 " for set " + onosSetName +
3735 " but got " + str( sizeResponses[ i ] ) )
3736 addAllResults = addAllResults and getResults and sizeResults
3737 utilities.assert_equals( expect=main.TRUE,
3738 actual=addAllResults,
3739 onpass="Set addAll correct",
3740 onfail="Set addAll was incorrect" )
3741
3742 main.step( "Distributed Set contains()" )
3743 containsResponses = []
3744 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003745 for i in range( main.numCtrls ):
3746 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003747 name="setContains-" + str( i ),
3748 args=[ onosSetName ],
3749 kwargs={ "values": addValue } )
3750 threads.append( t )
3751 t.start()
3752 for t in threads:
3753 t.join()
3754 # NOTE: This is the tuple
3755 containsResponses.append( t.result )
3756
3757 containsResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003758 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003759 if containsResponses[ i ] == main.ERROR:
3760 containsResults = main.FALSE
3761 else:
3762 containsResults = containsResults and\
3763 containsResponses[ i ][ 1 ]
3764 utilities.assert_equals( expect=main.TRUE,
3765 actual=containsResults,
3766 onpass="Set contains is functional",
3767 onfail="Set contains failed" )
3768
3769 main.step( "Distributed Set containsAll()" )
3770 containsAllResponses = []
3771 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003772 for i in range( main.numCtrls ):
3773 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003774 name="setContainsAll-" + str( i ),
3775 args=[ onosSetName ],
3776 kwargs={ "values": addAllValue } )
3777 threads.append( t )
3778 t.start()
3779 for t in threads:
3780 t.join()
3781 # NOTE: This is the tuple
3782 containsAllResponses.append( t.result )
3783
3784 containsAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003785 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003786 if containsResponses[ i ] == main.ERROR:
3787 containsResults = main.FALSE
3788 else:
3789 containsResults = containsResults and\
3790 containsResponses[ i ][ 1 ]
3791 utilities.assert_equals( expect=main.TRUE,
3792 actual=containsAllResults,
3793 onpass="Set containsAll is functional",
3794 onfail="Set containsAll failed" )
3795
3796 main.step( "Distributed Set remove()" )
3797 onosSet.remove( addValue )
3798 removeResponses = []
3799 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003800 for i in range( main.numCtrls ):
3801 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003802 name="setTestRemove-" + str( i ),
3803 args=[ onosSetName, addValue ] )
3804 threads.append( t )
3805 t.start()
3806 for t in threads:
3807 t.join()
3808 removeResponses.append( t.result )
3809
3810 # main.TRUE = successfully changed the set
3811 # main.FALSE = action resulted in no change in set
3812 # main.ERROR - Some error in executing the function
3813 removeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003814 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003815 if removeResponses[ i ] == main.TRUE:
3816 # All is well
3817 pass
3818 elif removeResponses[ i ] == main.FALSE:
3819 # not in set, probably fine
3820 pass
3821 elif removeResponses[ i ] == main.ERROR:
3822 # Error in execution
3823 removeResults = main.FALSE
3824 else:
3825 # unexpected result
3826 removeResults = main.FALSE
3827 if removeResults != main.TRUE:
3828 main.log.error( "Error executing set remove" )
3829
3830 # Check if set is still correct
3831 size = len( onosSet )
3832 getResponses = []
3833 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003834 for i in range( main.numCtrls ):
3835 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003836 name="setTestGet-" + str( i ),
3837 args=[ onosSetName ] )
3838 threads.append( t )
3839 t.start()
3840 for t in threads:
3841 t.join()
3842 getResponses.append( t.result )
3843 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003844 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003845 if isinstance( getResponses[ i ], list):
3846 current = set( getResponses[ i ] )
3847 if len( current ) == len( getResponses[ i ] ):
3848 # no repeats
3849 if onosSet != current:
3850 main.log.error( "ONOS" + str( i + 1 ) +
3851 " has incorrect view" +
3852 " of set " + onosSetName + ":\n" +
3853 str( getResponses[ i ] ) )
3854 main.log.debug( "Expected: " + str( onosSet ) )
3855 main.log.debug( "Actual: " + str( current ) )
3856 getResults = main.FALSE
3857 else:
3858 # error, set is not a set
3859 main.log.error( "ONOS" + str( i + 1 ) +
3860 " has repeat elements in" +
3861 " set " + onosSetName + ":\n" +
3862 str( getResponses[ i ] ) )
3863 getResults = main.FALSE
3864 elif getResponses[ i ] == main.ERROR:
3865 getResults = main.FALSE
3866 sizeResponses = []
3867 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003868 for i in range( main.numCtrls ):
3869 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003870 name="setTestSize-" + str( i ),
3871 args=[ onosSetName ] )
3872 threads.append( t )
3873 t.start()
3874 for t in threads:
3875 t.join()
3876 sizeResponses.append( t.result )
3877 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003878 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003879 if size != sizeResponses[ i ]:
3880 sizeResults = main.FALSE
3881 main.log.error( "ONOS" + str( i + 1 ) +
3882 " expected a size of " + str( size ) +
3883 " for set " + onosSetName +
3884 " but got " + str( sizeResponses[ i ] ) )
3885 removeResults = removeResults and getResults and sizeResults
3886 utilities.assert_equals( expect=main.TRUE,
3887 actual=removeResults,
3888 onpass="Set remove correct",
3889 onfail="Set remove was incorrect" )
3890
3891 main.step( "Distributed Set removeAll()" )
3892 onosSet.difference_update( addAllValue.split() )
3893 removeAllResponses = []
3894 threads = []
3895 try:
Jon Halle1a3b752015-07-22 13:02:46 -07003896 for i in range( main.numCtrls ):
3897 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003898 name="setTestRemoveAll-" + str( i ),
3899 args=[ onosSetName, addAllValue ] )
3900 threads.append( t )
3901 t.start()
3902 for t in threads:
3903 t.join()
3904 removeAllResponses.append( t.result )
3905 except Exception, e:
3906 main.log.exception(e)
3907
3908 # main.TRUE = successfully changed the set
3909 # main.FALSE = action resulted in no change in set
3910 # main.ERROR - Some error in executing the function
3911 removeAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003912 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003913 if removeAllResponses[ i ] == main.TRUE:
3914 # All is well
3915 pass
3916 elif removeAllResponses[ i ] == main.FALSE:
3917 # not in set, probably fine
3918 pass
3919 elif removeAllResponses[ i ] == main.ERROR:
3920 # Error in execution
3921 removeAllResults = main.FALSE
3922 else:
3923 # unexpected result
3924 removeAllResults = main.FALSE
3925 if removeAllResults != main.TRUE:
3926 main.log.error( "Error executing set removeAll" )
3927
3928 # Check if set is still correct
3929 size = len( onosSet )
3930 getResponses = []
3931 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003932 for i in range( main.numCtrls ):
3933 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003934 name="setTestGet-" + str( i ),
3935 args=[ onosSetName ] )
3936 threads.append( t )
3937 t.start()
3938 for t in threads:
3939 t.join()
3940 getResponses.append( t.result )
3941 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003942 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003943 if isinstance( getResponses[ i ], list):
3944 current = set( getResponses[ i ] )
3945 if len( current ) == len( getResponses[ i ] ):
3946 # no repeats
3947 if onosSet != current:
3948 main.log.error( "ONOS" + str( i + 1 ) +
3949 " has incorrect view" +
3950 " of set " + onosSetName + ":\n" +
3951 str( getResponses[ i ] ) )
3952 main.log.debug( "Expected: " + str( onosSet ) )
3953 main.log.debug( "Actual: " + str( current ) )
3954 getResults = main.FALSE
3955 else:
3956 # error, set is not a set
3957 main.log.error( "ONOS" + str( i + 1 ) +
3958 " has repeat elements in" +
3959 " set " + onosSetName + ":\n" +
3960 str( getResponses[ i ] ) )
3961 getResults = main.FALSE
3962 elif getResponses[ i ] == main.ERROR:
3963 getResults = main.FALSE
3964 sizeResponses = []
3965 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003966 for i in range( main.numCtrls ):
3967 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003968 name="setTestSize-" + str( i ),
3969 args=[ onosSetName ] )
3970 threads.append( t )
3971 t.start()
3972 for t in threads:
3973 t.join()
3974 sizeResponses.append( t.result )
3975 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003976 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003977 if size != sizeResponses[ i ]:
3978 sizeResults = main.FALSE
3979 main.log.error( "ONOS" + str( i + 1 ) +
3980 " expected a size of " + str( size ) +
3981 " for set " + onosSetName +
3982 " but got " + str( sizeResponses[ i ] ) )
3983 removeAllResults = removeAllResults and getResults and sizeResults
3984 utilities.assert_equals( expect=main.TRUE,
3985 actual=removeAllResults,
3986 onpass="Set removeAll correct",
3987 onfail="Set removeAll was incorrect" )
3988
3989 main.step( "Distributed Set addAll()" )
3990 onosSet.update( addAllValue.split() )
3991 addResponses = []
3992 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003993 for i in range( main.numCtrls ):
3994 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003995 name="setTestAddAll-" + str( i ),
3996 args=[ onosSetName, addAllValue ] )
3997 threads.append( t )
3998 t.start()
3999 for t in threads:
4000 t.join()
4001 addResponses.append( t.result )
4002
4003 # main.TRUE = successfully changed the set
4004 # main.FALSE = action resulted in no change in set
4005 # main.ERROR - Some error in executing the function
4006 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004007 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004008 if addResponses[ i ] == main.TRUE:
4009 # All is well
4010 pass
4011 elif addResponses[ i ] == main.FALSE:
4012 # Already in set, probably fine
4013 pass
4014 elif addResponses[ i ] == main.ERROR:
4015 # Error in execution
4016 addAllResults = main.FALSE
4017 else:
4018 # unexpected result
4019 addAllResults = main.FALSE
4020 if addAllResults != main.TRUE:
4021 main.log.error( "Error executing set addAll" )
4022
4023 # Check if set is still correct
4024 size = len( onosSet )
4025 getResponses = []
4026 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004027 for i in range( main.numCtrls ):
4028 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004029 name="setTestGet-" + str( i ),
4030 args=[ onosSetName ] )
4031 threads.append( t )
4032 t.start()
4033 for t in threads:
4034 t.join()
4035 getResponses.append( t.result )
4036 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004037 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004038 if isinstance( getResponses[ i ], list):
4039 current = set( getResponses[ i ] )
4040 if len( current ) == len( getResponses[ i ] ):
4041 # no repeats
4042 if onosSet != current:
4043 main.log.error( "ONOS" + str( i + 1 ) +
4044 " has incorrect view" +
4045 " of set " + onosSetName + ":\n" +
4046 str( getResponses[ i ] ) )
4047 main.log.debug( "Expected: " + str( onosSet ) )
4048 main.log.debug( "Actual: " + str( current ) )
4049 getResults = main.FALSE
4050 else:
4051 # error, set is not a set
4052 main.log.error( "ONOS" + str( i + 1 ) +
4053 " has repeat elements in" +
4054 " set " + onosSetName + ":\n" +
4055 str( getResponses[ i ] ) )
4056 getResults = main.FALSE
4057 elif getResponses[ i ] == main.ERROR:
4058 getResults = main.FALSE
4059 sizeResponses = []
4060 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004061 for i in range( main.numCtrls ):
4062 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004063 name="setTestSize-" + str( i ),
4064 args=[ onosSetName ] )
4065 threads.append( t )
4066 t.start()
4067 for t in threads:
4068 t.join()
4069 sizeResponses.append( t.result )
4070 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004071 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004072 if size != sizeResponses[ i ]:
4073 sizeResults = main.FALSE
4074 main.log.error( "ONOS" + str( i + 1 ) +
4075 " expected a size of " + str( size ) +
4076 " for set " + onosSetName +
4077 " but got " + str( sizeResponses[ i ] ) )
4078 addAllResults = addAllResults and getResults and sizeResults
4079 utilities.assert_equals( expect=main.TRUE,
4080 actual=addAllResults,
4081 onpass="Set addAll correct",
4082 onfail="Set addAll was incorrect" )
4083
4084 main.step( "Distributed Set clear()" )
4085 onosSet.clear()
4086 clearResponses = []
4087 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004088 for i in range( main.numCtrls ):
4089 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004090 name="setTestClear-" + str( i ),
4091 args=[ onosSetName, " "], # Values doesn't matter
4092 kwargs={ "clear": True } )
4093 threads.append( t )
4094 t.start()
4095 for t in threads:
4096 t.join()
4097 clearResponses.append( t.result )
4098
4099 # main.TRUE = successfully changed the set
4100 # main.FALSE = action resulted in no change in set
4101 # main.ERROR - Some error in executing the function
4102 clearResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004103 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004104 if clearResponses[ i ] == main.TRUE:
4105 # All is well
4106 pass
4107 elif clearResponses[ i ] == main.FALSE:
4108 # Nothing set, probably fine
4109 pass
4110 elif clearResponses[ i ] == main.ERROR:
4111 # Error in execution
4112 clearResults = main.FALSE
4113 else:
4114 # unexpected result
4115 clearResults = main.FALSE
4116 if clearResults != main.TRUE:
4117 main.log.error( "Error executing set clear" )
4118
4119 # Check if set is still correct
4120 size = len( onosSet )
4121 getResponses = []
4122 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004123 for i in range( main.numCtrls ):
4124 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004125 name="setTestGet-" + str( i ),
4126 args=[ onosSetName ] )
4127 threads.append( t )
4128 t.start()
4129 for t in threads:
4130 t.join()
4131 getResponses.append( t.result )
4132 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004133 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004134 if isinstance( getResponses[ i ], list):
4135 current = set( getResponses[ i ] )
4136 if len( current ) == len( getResponses[ i ] ):
4137 # no repeats
4138 if onosSet != current:
4139 main.log.error( "ONOS" + str( i + 1 ) +
4140 " has incorrect view" +
4141 " of set " + onosSetName + ":\n" +
4142 str( getResponses[ i ] ) )
4143 main.log.debug( "Expected: " + str( onosSet ) )
4144 main.log.debug( "Actual: " + str( current ) )
4145 getResults = main.FALSE
4146 else:
4147 # error, set is not a set
4148 main.log.error( "ONOS" + str( i + 1 ) +
4149 " has repeat elements in" +
4150 " set " + onosSetName + ":\n" +
4151 str( getResponses[ i ] ) )
4152 getResults = main.FALSE
4153 elif getResponses[ i ] == main.ERROR:
4154 getResults = main.FALSE
4155 sizeResponses = []
4156 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004157 for i in range( main.numCtrls ):
4158 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004159 name="setTestSize-" + str( i ),
4160 args=[ onosSetName ] )
4161 threads.append( t )
4162 t.start()
4163 for t in threads:
4164 t.join()
4165 sizeResponses.append( t.result )
4166 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004167 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004168 if size != sizeResponses[ i ]:
4169 sizeResults = main.FALSE
4170 main.log.error( "ONOS" + str( i + 1 ) +
4171 " expected a size of " + str( size ) +
4172 " for set " + onosSetName +
4173 " but got " + str( sizeResponses[ i ] ) )
4174 clearResults = clearResults and getResults and sizeResults
4175 utilities.assert_equals( expect=main.TRUE,
4176 actual=clearResults,
4177 onpass="Set clear correct",
4178 onfail="Set clear was incorrect" )
4179
4180 main.step( "Distributed Set addAll()" )
4181 onosSet.update( addAllValue.split() )
4182 addResponses = []
4183 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004184 for i in range( main.numCtrls ):
4185 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004186 name="setTestAddAll-" + str( i ),
4187 args=[ onosSetName, addAllValue ] )
4188 threads.append( t )
4189 t.start()
4190 for t in threads:
4191 t.join()
4192 addResponses.append( t.result )
4193
4194 # main.TRUE = successfully changed the set
4195 # main.FALSE = action resulted in no change in set
4196 # main.ERROR - Some error in executing the function
4197 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004198 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004199 if addResponses[ i ] == main.TRUE:
4200 # All is well
4201 pass
4202 elif addResponses[ i ] == main.FALSE:
4203 # Already in set, probably fine
4204 pass
4205 elif addResponses[ i ] == main.ERROR:
4206 # Error in execution
4207 addAllResults = main.FALSE
4208 else:
4209 # unexpected result
4210 addAllResults = main.FALSE
4211 if addAllResults != main.TRUE:
4212 main.log.error( "Error executing set addAll" )
4213
4214 # Check if set is still correct
4215 size = len( onosSet )
4216 getResponses = []
4217 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004218 for i in range( main.numCtrls ):
4219 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004220 name="setTestGet-" + str( i ),
4221 args=[ onosSetName ] )
4222 threads.append( t )
4223 t.start()
4224 for t in threads:
4225 t.join()
4226 getResponses.append( t.result )
4227 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004228 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004229 if isinstance( getResponses[ i ], list):
4230 current = set( getResponses[ i ] )
4231 if len( current ) == len( getResponses[ i ] ):
4232 # no repeats
4233 if onosSet != current:
4234 main.log.error( "ONOS" + str( i + 1 ) +
4235 " has incorrect view" +
4236 " of set " + onosSetName + ":\n" +
4237 str( getResponses[ i ] ) )
4238 main.log.debug( "Expected: " + str( onosSet ) )
4239 main.log.debug( "Actual: " + str( current ) )
4240 getResults = main.FALSE
4241 else:
4242 # error, set is not a set
4243 main.log.error( "ONOS" + str( i + 1 ) +
4244 " has repeat elements in" +
4245 " set " + onosSetName + ":\n" +
4246 str( getResponses[ i ] ) )
4247 getResults = main.FALSE
4248 elif getResponses[ i ] == main.ERROR:
4249 getResults = main.FALSE
4250 sizeResponses = []
4251 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004252 for i in range( main.numCtrls ):
4253 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004254 name="setTestSize-" + str( i ),
4255 args=[ onosSetName ] )
4256 threads.append( t )
4257 t.start()
4258 for t in threads:
4259 t.join()
4260 sizeResponses.append( t.result )
4261 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004262 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004263 if size != sizeResponses[ i ]:
4264 sizeResults = main.FALSE
4265 main.log.error( "ONOS" + str( i + 1 ) +
4266 " expected a size of " + str( size ) +
4267 " for set " + onosSetName +
4268 " but got " + str( sizeResponses[ i ] ) )
4269 addAllResults = addAllResults and getResults and sizeResults
4270 utilities.assert_equals( expect=main.TRUE,
4271 actual=addAllResults,
4272 onpass="Set addAll correct",
4273 onfail="Set addAll was incorrect" )
4274
4275 main.step( "Distributed Set retain()" )
4276 onosSet.intersection_update( retainValue.split() )
4277 retainResponses = []
4278 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004279 for i in range( main.numCtrls ):
4280 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004281 name="setTestRetain-" + str( i ),
4282 args=[ onosSetName, retainValue ],
4283 kwargs={ "retain": True } )
4284 threads.append( t )
4285 t.start()
4286 for t in threads:
4287 t.join()
4288 retainResponses.append( t.result )
4289
4290 # main.TRUE = successfully changed the set
4291 # main.FALSE = action resulted in no change in set
4292 # main.ERROR - Some error in executing the function
4293 retainResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004294 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004295 if retainResponses[ i ] == main.TRUE:
4296 # All is well
4297 pass
4298 elif retainResponses[ i ] == main.FALSE:
4299 # Already in set, probably fine
4300 pass
4301 elif retainResponses[ i ] == main.ERROR:
4302 # Error in execution
4303 retainResults = main.FALSE
4304 else:
4305 # unexpected result
4306 retainResults = main.FALSE
4307 if retainResults != main.TRUE:
4308 main.log.error( "Error executing set retain" )
4309
4310 # Check if set is still correct
4311 size = len( onosSet )
4312 getResponses = []
4313 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004314 for i in range( main.numCtrls ):
4315 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004316 name="setTestGet-" + str( i ),
4317 args=[ onosSetName ] )
4318 threads.append( t )
4319 t.start()
4320 for t in threads:
4321 t.join()
4322 getResponses.append( t.result )
4323 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004324 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004325 if isinstance( getResponses[ i ], list):
4326 current = set( getResponses[ i ] )
4327 if len( current ) == len( getResponses[ i ] ):
4328 # no repeats
4329 if onosSet != current:
4330 main.log.error( "ONOS" + str( i + 1 ) +
4331 " has incorrect view" +
4332 " of set " + onosSetName + ":\n" +
4333 str( getResponses[ i ] ) )
4334 main.log.debug( "Expected: " + str( onosSet ) )
4335 main.log.debug( "Actual: " + str( current ) )
4336 getResults = main.FALSE
4337 else:
4338 # error, set is not a set
4339 main.log.error( "ONOS" + str( i + 1 ) +
4340 " has repeat elements in" +
4341 " set " + onosSetName + ":\n" +
4342 str( getResponses[ i ] ) )
4343 getResults = main.FALSE
4344 elif getResponses[ i ] == main.ERROR:
4345 getResults = main.FALSE
4346 sizeResponses = []
4347 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004348 for i in range( main.numCtrls ):
4349 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004350 name="setTestSize-" + str( i ),
4351 args=[ onosSetName ] )
4352 threads.append( t )
4353 t.start()
4354 for t in threads:
4355 t.join()
4356 sizeResponses.append( t.result )
4357 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004358 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004359 if size != sizeResponses[ i ]:
4360 sizeResults = main.FALSE
4361 main.log.error( "ONOS" + str( i + 1 ) +
4362 " expected a size of " +
4363 str( size ) + " for set " + onosSetName +
4364 " but got " + str( sizeResponses[ i ] ) )
4365 retainResults = retainResults and getResults and sizeResults
4366 utilities.assert_equals( expect=main.TRUE,
4367 actual=retainResults,
4368 onpass="Set retain correct",
4369 onfail="Set retain was incorrect" )
4370
Jon Hall2a5002c2015-08-21 16:49:11 -07004371 # Transactional maps
4372 main.step( "Partitioned Transactional maps put" )
4373 tMapValue = "Testing"
4374 numKeys = 100
4375 putResult = True
4376 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue )
4377 if len( putResponses ) == 100:
4378 for i in putResponses:
4379 if putResponses[ i ][ 'value' ] != tMapValue:
4380 putResult = False
4381 else:
4382 putResult = False
4383 if not putResult:
4384 main.log.debug( "Put response values: " + str( putResponses ) )
4385 utilities.assert_equals( expect=True,
4386 actual=putResult,
4387 onpass="Partitioned Transactional Map put successful",
4388 onfail="Partitioned Transactional Map put values are incorrect" )
4389
4390 main.step( "Partitioned Transactional maps get" )
4391 getCheck = True
4392 for n in range( 1, numKeys + 1 ):
4393 getResponses = []
4394 threads = []
4395 valueCheck = True
4396 for i in range( main.numCtrls ):
4397 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4398 name="TMap-get-" + str( i ),
4399 args=[ "Key" + str ( n ) ] )
4400 threads.append( t )
4401 t.start()
4402 for t in threads:
4403 t.join()
4404 getResponses.append( t.result )
4405 for node in getResponses:
4406 if node != tMapValue:
4407 valueCheck = False
4408 if not valueCheck:
4409 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4410 main.log.warn( getResponses )
4411 getCheck = getCheck and valueCheck
4412 utilities.assert_equals( expect=True,
4413 actual=getCheck,
4414 onpass="Partitioned Transactional Map get values were correct",
4415 onfail="Partitioned Transactional Map values incorrect" )
4416
4417 main.step( "In-memory Transactional maps put" )
4418 tMapValue = "Testing"
4419 numKeys = 100
4420 putResult = True
4421 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue, inMemory=True )
4422 if len( putResponses ) == 100:
4423 for i in putResponses:
4424 if putResponses[ i ][ 'value' ] != tMapValue:
4425 putResult = False
4426 else:
4427 putResult = False
4428 if not putResult:
4429 main.log.debug( "Put response values: " + str( putResponses ) )
4430 utilities.assert_equals( expect=True,
4431 actual=putResult,
4432 onpass="In-Memory Transactional Map put successful",
4433 onfail="In-Memory Transactional Map put values are incorrect" )
4434
4435 main.step( "In-Memory Transactional maps get" )
4436 getCheck = True
4437 for n in range( 1, numKeys + 1 ):
4438 getResponses = []
4439 threads = []
4440 valueCheck = True
4441 for i in range( main.numCtrls ):
4442 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4443 name="TMap-get-" + str( i ),
4444 args=[ "Key" + str ( n ) ],
4445 kwargs={ "inMemory": True } )
4446 threads.append( t )
4447 t.start()
4448 for t in threads:
4449 t.join()
4450 getResponses.append( t.result )
4451 for node in getResponses:
4452 if node != tMapValue:
4453 valueCheck = False
4454 if not valueCheck:
4455 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4456 main.log.warn( getResponses )
4457 getCheck = getCheck and valueCheck
4458 utilities.assert_equals( expect=True,
4459 actual=getCheck,
4460 onpass="In-Memory Transactional Map get values were correct",
4461 onfail="In-Memory Transactional Map values incorrect" )