blob: 2dc2b8f1112e8d84f4fd4c92550860205ba62908 [file] [log] [blame]
Jon Hall5cf14d52015-07-16 12:15:19 -07001"""
2Description: This test is to determine if ONOS can handle
3 all of it's nodes restarting
4
5List of test cases:
6CASE1: Compile ONOS and push it to the test machines
7CASE2: Assign devices to controllers
8CASE21: Assign mastership to controllers
9CASE3: Assign intents
10CASE4: Ping across added host intents
11CASE5: Reading state of ONOS
12CASE6: The Failure case.
13CASE7: Check state after control plane failure
14CASE8: Compare topo
15CASE9: Link s3-s28 down
16CASE10: Link s3-s28 up
17CASE11: Switch down
18CASE12: Switch up
19CASE13: Clean up
20CASE14: start election app on all onos nodes
21CASE15: Check that Leadership Election is still functional
22CASE16: Install Distributed Primitives app
23CASE17: Check for basic functionality with distributed primitives
24"""
25
26
27class HAclusterRestart:
28
29 def __init__( self ):
30 self.default = ''
31
32 def CASE1( self, main ):
33 """
34 CASE1 is to compile ONOS and push it to the test machines
35
36 Startup sequence:
37 cell <name>
38 onos-verify-cell
39 NOTE: temporary - onos-remove-raft-logs
40 onos-uninstall
41 start mininet
42 git pull
43 mvn clean install
44 onos-package
45 onos-install -f
46 onos-wait-for-start
47 start cli sessions
48 start tcpdump
49 """
Jon Halle1a3b752015-07-22 13:02:46 -070050 import imp
Jon Hall5cf14d52015-07-16 12:15:19 -070051 main.log.info( "ONOS HA test: Restart all ONOS nodes - " +
52 "initialization" )
53 main.case( "Setting up test environment" )
Jon Hall783bbf92015-07-23 14:33:19 -070054 main.caseExplanation = "Setup the test environment including " +\
Jon Hall5cf14d52015-07-16 12:15:19 -070055 "installing ONOS, starting Mininet and ONOS" +\
56 "cli sessions."
57 # TODO: save all the timers and output them for plotting
58
59 # load some variables from the params file
60 PULLCODE = False
61 if main.params[ 'Git' ] == 'True':
62 PULLCODE = True
63 gitBranch = main.params[ 'branch' ]
64 cellName = main.params[ 'ENV' ][ 'cellName' ]
65
Jon Halle1a3b752015-07-22 13:02:46 -070066 main.numCtrls = int( main.params[ 'num_controllers' ] )
Jon Hall5cf14d52015-07-16 12:15:19 -070067 if main.ONOSbench.maxNodes:
Jon Halle1a3b752015-07-22 13:02:46 -070068 if main.ONOSbench.maxNodes < main.numCtrls:
69 main.numCtrls = int( main.ONOSbench.maxNodes )
70 # set global variables
Jon Hall5cf14d52015-07-16 12:15:19 -070071 global ONOS1Port
72 global ONOS2Port
73 global ONOS3Port
74 global ONOS4Port
75 global ONOS5Port
76 global ONOS6Port
77 global ONOS7Port
78 # These are for csv plotting in jenkins
79 global labels
80 global data
81 labels = []
82 data = []
83
84 # FIXME: just get controller port from params?
85 # TODO: do we really need all these?
86 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
87 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
88 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
89 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
90 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
91 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
92 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
93
Jon Halle1a3b752015-07-22 13:02:46 -070094 try:
95 fileName = "Counters"
96 path = main.params[ 'imports' ][ 'path' ]
97 main.Counters = imp.load_source( fileName,
98 path + fileName + ".py" )
99 except Exception as e:
100 main.log.exception( e )
101 main.cleanup()
102 main.exit()
103
104 main.CLIs = []
105 main.nodes = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700106 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700107 for i in range( 1, main.numCtrls + 1 ):
108 try:
109 main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
110 main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
111 ipList.append( main.nodes[ -1 ].ip_address )
112 except AttributeError:
113 break
Jon Hall5cf14d52015-07-16 12:15:19 -0700114
115 main.step( "Create cell file" )
116 cellAppString = main.params[ 'ENV' ][ 'appString' ]
117 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
118 main.Mininet1.ip_address,
119 cellAppString, ipList )
120 main.step( "Applying cell variable to environment" )
121 cellResult = main.ONOSbench.setCell( cellName )
122 verifyResult = main.ONOSbench.verifyCell()
123
124 # FIXME:this is short term fix
125 main.log.info( "Removing raft logs" )
126 main.ONOSbench.onosRemoveRaftLogs()
127
128 main.log.info( "Uninstalling ONOS" )
Jon Halle1a3b752015-07-22 13:02:46 -0700129 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700130 main.ONOSbench.onosUninstall( node.ip_address )
131
132 # Make sure ONOS is DEAD
133 main.log.info( "Killing any ONOS processes" )
134 killResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700135 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700136 killed = main.ONOSbench.onosKill( node.ip_address )
137 killResults = killResults and killed
138
139 cleanInstallResult = main.TRUE
140 gitPullResult = main.TRUE
141
142 main.step( "Starting Mininet" )
143 # scp topo file to mininet
144 # TODO: move to params?
145 topoName = "obelisk.py"
146 filePath = main.ONOSbench.home + "/tools/test/topos/"
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700147 main.ONOSbench.scp( main.Mininet1,
148 filePath + topoName,
149 main.Mininet1.home,
150 direction="to" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700151 mnResult = main.Mininet1.startNet( )
152 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
153 onpass="Mininet Started",
154 onfail="Error starting Mininet" )
155
156 main.step( "Git checkout and pull " + gitBranch )
157 if PULLCODE:
158 main.ONOSbench.gitCheckout( gitBranch )
159 gitPullResult = main.ONOSbench.gitPull()
160 # values of 1 or 3 are good
161 utilities.assert_lesser( expect=0, actual=gitPullResult,
162 onpass="Git pull successful",
163 onfail="Git pull failed" )
164 main.ONOSbench.getVersion( report=True )
165
166 main.step( "Using mvn clean install" )
167 cleanInstallResult = main.TRUE
168 if PULLCODE and gitPullResult == main.TRUE:
169 cleanInstallResult = main.ONOSbench.cleanInstall()
170 else:
171 main.log.warn( "Did not pull new code so skipping mvn " +
172 "clean install" )
173 utilities.assert_equals( expect=main.TRUE,
174 actual=cleanInstallResult,
175 onpass="MCI successful",
176 onfail="MCI failed" )
177 # GRAPHS
178 # NOTE: important params here:
179 # job = name of Jenkins job
180 # Plot Name = Plot-HA, only can be used if multiple plots
181 # index = The number of the graph under plot name
182 job = "HAclusterRestart"
183 plotName = "Plot-HA"
184 graphs = '<ac:structured-macro ac:name="html">\n'
185 graphs += '<ac:plain-text-body><![CDATA[\n'
186 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
187 '/plot/' + plotName + '/getPlot?index=0' +\
188 '&width=500&height=300"' +\
189 'noborder="0" width="500" height="300" scrolling="yes" ' +\
190 'seamless="seamless"></iframe>\n'
191 graphs += ']]></ac:plain-text-body>\n'
192 graphs += '</ac:structured-macro>\n'
193 main.log.wiki(graphs)
194
195 main.step( "Creating ONOS package" )
196 packageResult = main.ONOSbench.onosPackage()
197 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
198 onpass="ONOS package successful",
199 onfail="ONOS package failed" )
200
201 main.step( "Installing ONOS package" )
202 onosInstallResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700203 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700204 tmpResult = main.ONOSbench.onosInstall( options="-f",
205 node=node.ip_address )
206 onosInstallResult = onosInstallResult and tmpResult
207 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
208 onpass="ONOS install successful",
209 onfail="ONOS install failed" )
210
211 main.step( "Checking if ONOS is up yet" )
212 for i in range( 2 ):
213 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700214 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700215 started = main.ONOSbench.isup( node.ip_address )
216 if not started:
217 main.log.error( node.name + " didn't start!" )
218 main.ONOSbench.onosStop( node.ip_address )
219 main.ONOSbench.onosStart( node.ip_address )
220 onosIsupResult = onosIsupResult and started
221 if onosIsupResult == main.TRUE:
222 break
223 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
224 onpass="ONOS startup successful",
225 onfail="ONOS startup failed" )
226
227 main.log.step( "Starting ONOS CLI sessions" )
228 cliResults = main.TRUE
229 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700230 for i in range( main.numCtrls ):
231 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -0700232 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -0700233 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -0700234 threads.append( t )
235 t.start()
236
237 for t in threads:
238 t.join()
239 cliResults = cliResults and t.result
240 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
241 onpass="ONOS cli startup successful",
242 onfail="ONOS cli startup failed" )
243
244 if main.params[ 'tcpdump' ].lower() == "true":
245 main.step( "Start Packet Capture MN" )
246 main.Mininet2.startTcpdump(
247 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
248 + "-MN.pcap",
249 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
250 port=main.params[ 'MNtcpdump' ][ 'port' ] )
251
252 main.step( "App Ids check" )
253 appCheck = main.TRUE
254 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700255 for i in range( main.numCtrls ):
256 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700257 name="appToIDCheck-" + str( i ),
258 args=[] )
259 threads.append( t )
260 t.start()
261
262 for t in threads:
263 t.join()
264 appCheck = appCheck and t.result
265 if appCheck != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700266 main.log.warn( main.CLIs[0].apps() )
267 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700268 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
269 onpass="App Ids seem to be correct",
270 onfail="Something is wrong with app Ids" )
271
272 if cliResults == main.FALSE:
273 main.log.error( "Failed to start ONOS, stopping test" )
274 main.cleanup()
275 main.exit()
276
277 def CASE2( self, main ):
278 """
279 Assign devices to controllers
280 """
281 import re
Jon Halle1a3b752015-07-22 13:02:46 -0700282 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700283 assert main, "main not defined"
284 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700285 assert main.CLIs, "main.CLIs not defined"
286 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700287 assert ONOS1Port, "ONOS1Port not defined"
288 assert ONOS2Port, "ONOS2Port not defined"
289 assert ONOS3Port, "ONOS3Port not defined"
290 assert ONOS4Port, "ONOS4Port not defined"
291 assert ONOS5Port, "ONOS5Port not defined"
292 assert ONOS6Port, "ONOS6Port not defined"
293 assert ONOS7Port, "ONOS7Port not defined"
294
295 main.case( "Assigning devices to controllers" )
Jon Hall783bbf92015-07-23 14:33:19 -0700296 main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700297 "and check that an ONOS node becomes the " +\
298 "master of the device."
299 main.step( "Assign switches to controllers" )
300
301 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700302 for i in range( main.numCtrls ):
303 ipList.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -0700304 swList = []
305 for i in range( 1, 29 ):
306 swList.append( "s" + str( i ) )
307 main.Mininet1.assignSwController( sw=swList, ip=ipList )
308
309 mastershipCheck = main.TRUE
310 for i in range( 1, 29 ):
311 response = main.Mininet1.getSwController( "s" + str( i ) )
312 try:
313 main.log.info( str( response ) )
314 except Exception:
315 main.log.info( repr( response ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700316 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700317 if re.search( "tcp:" + node.ip_address, response ):
318 mastershipCheck = mastershipCheck and main.TRUE
319 else:
320 main.log.error( "Error, node " + node.ip_address + " is " +
321 "not in the list of controllers s" +
322 str( i ) + " is connecting to." )
323 mastershipCheck = main.FALSE
324 utilities.assert_equals(
325 expect=main.TRUE,
326 actual=mastershipCheck,
327 onpass="Switch mastership assigned correctly",
328 onfail="Switches not assigned correctly to controllers" )
329
330 def CASE21( self, main ):
331 """
332 Assign mastership to controllers
333 """
Jon Hall5cf14d52015-07-16 12:15:19 -0700334 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700335 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700336 assert main, "main not defined"
337 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700338 assert main.CLIs, "main.CLIs not defined"
339 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700340 assert ONOS1Port, "ONOS1Port not defined"
341 assert ONOS2Port, "ONOS2Port not defined"
342 assert ONOS3Port, "ONOS3Port not defined"
343 assert ONOS4Port, "ONOS4Port not defined"
344 assert ONOS5Port, "ONOS5Port not defined"
345 assert ONOS6Port, "ONOS6Port not defined"
346 assert ONOS7Port, "ONOS7Port not defined"
347
348 main.case( "Assigning Controller roles for switches" )
Jon Hall783bbf92015-07-23 14:33:19 -0700349 main.caseExplanation = "Check that ONOS is connected to each " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700350 "device. Then manually assign" +\
351 " mastership to specific ONOS nodes using" +\
352 " 'device-role'"
353 main.step( "Assign mastership of switches to specific controllers" )
354 # Manually assign mastership to the controller we want
355 roleCall = main.TRUE
356
357 ipList = [ ]
358 deviceList = []
359 try:
360 # Assign mastership to specific controllers. This assignment was
361 # determined for a 7 node cluser, but will work with any sized
362 # cluster
363 for i in range( 1, 29 ): # switches 1 through 28
364 # set up correct variables:
365 if i == 1:
366 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700367 ip = main.nodes[ c ].ip_address # ONOS1
Jon Hall5cf14d52015-07-16 12:15:19 -0700368 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
369 elif i == 2:
Jon Halle1a3b752015-07-22 13:02:46 -0700370 c = 1 % main.numCtrls
371 ip = main.nodes[ c ].ip_address # ONOS2
Jon Hall5cf14d52015-07-16 12:15:19 -0700372 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
373 elif i == 3:
Jon Halle1a3b752015-07-22 13:02:46 -0700374 c = 1 % main.numCtrls
375 ip = main.nodes[ c ].ip_address # ONOS2
Jon Hall5cf14d52015-07-16 12:15:19 -0700376 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
377 elif i == 4:
Jon Halle1a3b752015-07-22 13:02:46 -0700378 c = 3 % main.numCtrls
379 ip = main.nodes[ c ].ip_address # ONOS4
Jon Hall5cf14d52015-07-16 12:15:19 -0700380 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
381 elif i == 5:
Jon Halle1a3b752015-07-22 13:02:46 -0700382 c = 2 % main.numCtrls
383 ip = main.nodes[ c ].ip_address # ONOS3
Jon Hall5cf14d52015-07-16 12:15:19 -0700384 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
385 elif i == 6:
Jon Halle1a3b752015-07-22 13:02:46 -0700386 c = 2 % main.numCtrls
387 ip = main.nodes[ c ].ip_address # ONOS3
Jon Hall5cf14d52015-07-16 12:15:19 -0700388 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
389 elif i == 7:
Jon Halle1a3b752015-07-22 13:02:46 -0700390 c = 5 % main.numCtrls
391 ip = main.nodes[ c ].ip_address # ONOS6
Jon Hall5cf14d52015-07-16 12:15:19 -0700392 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
393 elif i >= 8 and i <= 17:
Jon Halle1a3b752015-07-22 13:02:46 -0700394 c = 4 % main.numCtrls
395 ip = main.nodes[ c ].ip_address # ONOS5
Jon Hall5cf14d52015-07-16 12:15:19 -0700396 dpid = '3' + str( i ).zfill( 3 )
397 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
398 elif i >= 18 and i <= 27:
Jon Halle1a3b752015-07-22 13:02:46 -0700399 c = 6 % main.numCtrls
400 ip = main.nodes[ c ].ip_address # ONOS7
Jon Hall5cf14d52015-07-16 12:15:19 -0700401 dpid = '6' + str( i ).zfill( 3 )
402 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
403 elif i == 28:
404 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700405 ip = main.nodes[ c ].ip_address # ONOS1
Jon Hall5cf14d52015-07-16 12:15:19 -0700406 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
407 else:
408 main.log.error( "You didn't write an else statement for " +
409 "switch s" + str( i ) )
410 roleCall = main.FALSE
411 # Assign switch
412 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
413 # TODO: make this controller dynamic
414 roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
415 ip )
416 ipList.append( ip )
417 deviceList.append( deviceId )
418 except ( AttributeError, AssertionError ):
419 main.log.exception( "Something is wrong with ONOS device view" )
420 main.log.info( main.ONOScli1.devices() )
421 utilities.assert_equals(
422 expect=main.TRUE,
423 actual=roleCall,
424 onpass="Re-assigned switch mastership to designated controller",
425 onfail="Something wrong with deviceRole calls" )
426
427 main.step( "Check mastership was correctly assigned" )
428 roleCheck = main.TRUE
429 # NOTE: This is due to the fact that device mastership change is not
430 # atomic and is actually a multi step process
431 time.sleep( 5 )
432 for i in range( len( ipList ) ):
433 ip = ipList[i]
434 deviceId = deviceList[i]
435 # Check assignment
436 master = main.ONOScli1.getRole( deviceId ).get( 'master' )
437 if ip in master:
438 roleCheck = roleCheck and main.TRUE
439 else:
440 roleCheck = roleCheck and main.FALSE
441 main.log.error( "Error, controller " + ip + " is not" +
442 " master " + "of device " +
443 str( deviceId ) + ". Master is " +
444 repr( master ) + "." )
445 utilities.assert_equals(
446 expect=main.TRUE,
447 actual=roleCheck,
448 onpass="Switches were successfully reassigned to designated " +
449 "controller",
450 onfail="Switches were not successfully reassigned" )
451
452 def CASE3( self, main ):
453 """
454 Assign intents
455 """
456 import time
457 import json
Jon Halle1a3b752015-07-22 13:02:46 -0700458 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700459 assert main, "main not defined"
460 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700461 assert main.CLIs, "main.CLIs not defined"
462 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700463 try:
464 labels
465 except NameError:
466 main.log.error( "labels not defined, setting to []" )
467 labels = []
468 try:
469 data
470 except NameError:
471 main.log.error( "data not defined, setting to []" )
472 data = []
473 # NOTE: we must reinstall intents until we have a persistant intent
474 # datastore!
475 main.case( "Adding host Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700476 main.caseExplanation = "Discover hosts by using pingall then " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700477 "assign predetermined host-to-host intents." +\
478 " After installation, check that the intent" +\
479 " is distributed to all nodes and the state" +\
480 " is INSTALLED"
481
482 # install onos-app-fwd
483 main.step( "Install reactive forwarding app" )
Jon Halle1a3b752015-07-22 13:02:46 -0700484 installResults = main.CLIs[0].activateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700485 utilities.assert_equals( expect=main.TRUE, actual=installResults,
486 onpass="Install fwd successful",
487 onfail="Install fwd failed" )
488
489 main.step( "Check app ids" )
490 appCheck = main.TRUE
491 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700492 for i in range( main.numCtrls ):
493 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700494 name="appToIDCheck-" + str( i ),
495 args=[] )
496 threads.append( t )
497 t.start()
498
499 for t in threads:
500 t.join()
501 appCheck = appCheck and t.result
502 if appCheck != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700503 main.log.warn( main.CLIs[0].apps() )
504 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700505 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
506 onpass="App Ids seem to be correct",
507 onfail="Something is wrong with app Ids" )
508
509 main.step( "Discovering Hosts( Via pingall for now )" )
510 # FIXME: Once we have a host discovery mechanism, use that instead
511 # REACTIVE FWD test
512 pingResult = main.FALSE
Jon Hall96091e62015-09-21 17:34:17 -0700513 passMsg = "Reactive Pingall test passed"
514 time1 = time.time()
515 pingResult = main.Mininet1.pingall()
516 time2 = time.time()
517 if not pingResult:
518 main.log.warn("First pingall failed. Trying again...")
Jon Hall5cf14d52015-07-16 12:15:19 -0700519 pingResult = main.Mininet1.pingall()
Jon Hall96091e62015-09-21 17:34:17 -0700520 passMsg += " on the second try"
521 utilities.assert_equals(
522 expect=main.TRUE,
523 actual=pingResult,
524 onpass= passMsg,
525 onfail="Reactive Pingall failed, " +
526 "one or more ping pairs failed" )
527 main.log.info( "Time for pingall: %2f seconds" %
528 ( time2 - time1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -0700529 # timeout for fwd flows
530 time.sleep( 11 )
531 # uninstall onos-app-fwd
532 main.step( "Uninstall reactive forwarding app" )
Jon Halle1a3b752015-07-22 13:02:46 -0700533 uninstallResult = main.CLIs[0].deactivateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700534 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
535 onpass="Uninstall fwd successful",
536 onfail="Uninstall fwd failed" )
537
538 main.step( "Check app ids" )
539 threads = []
540 appCheck2 = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700541 for i in range( main.numCtrls ):
542 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700543 name="appToIDCheck-" + str( i ),
544 args=[] )
545 threads.append( t )
546 t.start()
547
548 for t in threads:
549 t.join()
550 appCheck2 = appCheck2 and t.result
551 if appCheck2 != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700552 main.log.warn( main.CLIs[0].apps() )
553 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700554 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
555 onpass="App Ids seem to be correct",
556 onfail="Something is wrong with app Ids" )
557
558 main.step( "Add host intents via cli" )
559 intentIds = []
560 # TODO: move the host numbers to params
561 # Maybe look at all the paths we ping?
562 intentAddResult = True
563 hostResult = main.TRUE
564 for i in range( 8, 18 ):
565 main.log.info( "Adding host intent between h" + str( i ) +
566 " and h" + str( i + 10 ) )
567 host1 = "00:00:00:00:00:" + \
568 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
569 host2 = "00:00:00:00:00:" + \
570 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
571 # NOTE: getHost can return None
572 host1Dict = main.ONOScli1.getHost( host1 )
573 host2Dict = main.ONOScli1.getHost( host2 )
574 host1Id = None
575 host2Id = None
576 if host1Dict and host2Dict:
577 host1Id = host1Dict.get( 'id', None )
578 host2Id = host2Dict.get( 'id', None )
579 if host1Id and host2Id:
Jon Halle1a3b752015-07-22 13:02:46 -0700580 nodeNum = ( i % main.numCtrls )
581 tmpId = main.CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
Jon Hall5cf14d52015-07-16 12:15:19 -0700582 if tmpId:
583 main.log.info( "Added intent with id: " + tmpId )
584 intentIds.append( tmpId )
585 else:
586 main.log.error( "addHostIntent returned: " +
587 repr( tmpId ) )
588 else:
589 main.log.error( "Error, getHost() failed for h" + str( i ) +
590 " and/or h" + str( i + 10 ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700591 hosts = main.CLIs[ 0 ].hosts()
Jon Hall5cf14d52015-07-16 12:15:19 -0700592 main.log.warn( "Hosts output: " )
593 try:
594 main.log.warn( json.dumps( json.loads( hosts ),
595 sort_keys=True,
596 indent=4,
597 separators=( ',', ': ' ) ) )
598 except ( ValueError, TypeError ):
599 main.log.warn( repr( hosts ) )
600 hostResult = main.FALSE
601 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
602 onpass="Found a host id for each host",
603 onfail="Error looking up host ids" )
604
605 intentStart = time.time()
606 onosIds = main.ONOScli1.getAllIntentsId()
607 main.log.info( "Submitted intents: " + str( intentIds ) )
608 main.log.info( "Intents in ONOS: " + str( onosIds ) )
609 for intent in intentIds:
610 if intent in onosIds:
611 pass # intent submitted is in onos
612 else:
613 intentAddResult = False
614 if intentAddResult:
615 intentStop = time.time()
616 else:
617 intentStop = None
618 # Print the intent states
619 intents = main.ONOScli1.intents()
620 intentStates = []
621 installedCheck = True
622 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
623 count = 0
624 try:
625 for intent in json.loads( intents ):
626 state = intent.get( 'state', None )
627 if "INSTALLED" not in state:
628 installedCheck = False
629 intentId = intent.get( 'id', None )
630 intentStates.append( ( intentId, state ) )
631 except ( ValueError, TypeError ):
632 main.log.exception( "Error parsing intents" )
633 # add submitted intents not in the store
634 tmplist = [ i for i, s in intentStates ]
635 missingIntents = False
636 for i in intentIds:
637 if i not in tmplist:
638 intentStates.append( ( i, " - " ) )
639 missingIntents = True
640 intentStates.sort()
641 for i, s in intentStates:
642 count += 1
643 main.log.info( "%-6s%-15s%-15s" %
644 ( str( count ), str( i ), str( s ) ) )
645 leaders = main.ONOScli1.leaders()
646 try:
647 missing = False
648 if leaders:
649 parsedLeaders = json.loads( leaders )
650 main.log.warn( json.dumps( parsedLeaders,
651 sort_keys=True,
652 indent=4,
653 separators=( ',', ': ' ) ) )
654 # check for all intent partitions
655 topics = []
656 for i in range( 14 ):
657 topics.append( "intent-partition-" + str( i ) )
658 main.log.debug( topics )
659 ONOStopics = [ j['topic'] for j in parsedLeaders ]
660 for topic in topics:
661 if topic not in ONOStopics:
662 main.log.error( "Error: " + topic +
663 " not in leaders" )
664 missing = True
665 else:
666 main.log.error( "leaders() returned None" )
667 except ( ValueError, TypeError ):
668 main.log.exception( "Error parsing leaders" )
669 main.log.error( repr( leaders ) )
670 # Check all nodes
671 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -0700672 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700673 response = node.leaders( jsonFormat=False)
674 main.log.warn( str( node.name ) + " leaders output: \n" +
675 str( response ) )
676
677 partitions = main.ONOScli1.partitions()
678 try:
679 if partitions :
680 parsedPartitions = json.loads( partitions )
681 main.log.warn( json.dumps( parsedPartitions,
682 sort_keys=True,
683 indent=4,
684 separators=( ',', ': ' ) ) )
685 # TODO check for a leader in all paritions
686 # TODO check for consistency among nodes
687 else:
688 main.log.error( "partitions() returned None" )
689 except ( ValueError, TypeError ):
690 main.log.exception( "Error parsing partitions" )
691 main.log.error( repr( partitions ) )
692 pendingMap = main.ONOScli1.pendingMap()
693 try:
694 if pendingMap :
695 parsedPending = json.loads( pendingMap )
696 main.log.warn( json.dumps( parsedPending,
697 sort_keys=True,
698 indent=4,
699 separators=( ',', ': ' ) ) )
700 # TODO check something here?
701 else:
702 main.log.error( "pendingMap() returned None" )
703 except ( ValueError, TypeError ):
704 main.log.exception( "Error parsing pending map" )
705 main.log.error( repr( pendingMap ) )
706
707 intentAddResult = bool( intentAddResult and not missingIntents and
708 installedCheck )
709 if not intentAddResult:
710 main.log.error( "Error in pushing host intents to ONOS" )
711
712 main.step( "Intent Anti-Entropy dispersion" )
713 for i in range(100):
714 correct = True
715 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700716 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700717 onosIds = []
718 ids = cli.getAllIntentsId()
719 onosIds.append( ids )
720 main.log.debug( "Intents in " + cli.name + ": " +
721 str( sorted( onosIds ) ) )
722 if sorted( ids ) != sorted( intentIds ):
723 main.log.warn( "Set of intent IDs doesn't match" )
724 correct = False
725 break
726 else:
727 intents = json.loads( cli.intents() )
728 for intent in intents:
729 if intent[ 'state' ] != "INSTALLED":
730 main.log.warn( "Intent " + intent[ 'id' ] +
731 " is " + intent[ 'state' ] )
732 correct = False
733 break
734 if correct:
735 break
736 else:
737 time.sleep(1)
738 if not intentStop:
739 intentStop = time.time()
740 global gossipTime
741 gossipTime = intentStop - intentStart
742 main.log.info( "It took about " + str( gossipTime ) +
743 " seconds for all intents to appear in each node" )
744 append = False
745 title = "Gossip Intents"
746 count = 1
747 while append is False:
748 curTitle = title + str( count )
749 if curTitle not in labels:
750 labels.append( curTitle )
751 data.append( str( gossipTime ) )
752 append = True
753 else:
754 count += 1
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700755 gossipPeriod = int( main.params['timers']['gossip'] )
756 maxGossipTime = gossipPeriod * len( main.nodes )
Jon Hall5cf14d52015-07-16 12:15:19 -0700757 utilities.assert_greater_equals(
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700758 expect=maxGossipTime, actual=gossipTime,
Jon Hall5cf14d52015-07-16 12:15:19 -0700759 onpass="ECM anti-entropy for intents worked within " +
760 "expected time",
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700761 onfail="Intent ECM anti-entropy took too long. " +
762 "Expected time:{}, Actual time:{}".format( maxGossipTime,
763 gossipTime ) )
764 if gossipTime <= maxGossipTime:
Jon Hall5cf14d52015-07-16 12:15:19 -0700765 intentAddResult = True
766
767 if not intentAddResult or "key" in pendingMap:
768 import time
769 installedCheck = True
770 main.log.info( "Sleeping 60 seconds to see if intents are found" )
771 time.sleep( 60 )
772 onosIds = main.ONOScli1.getAllIntentsId()
773 main.log.info( "Submitted intents: " + str( intentIds ) )
774 main.log.info( "Intents in ONOS: " + str( onosIds ) )
775 # Print the intent states
776 intents = main.ONOScli1.intents()
777 intentStates = []
778 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
779 count = 0
780 try:
781 for intent in json.loads( intents ):
782 # Iter through intents of a node
783 state = intent.get( 'state', None )
784 if "INSTALLED" not in state:
785 installedCheck = False
786 intentId = intent.get( 'id', None )
787 intentStates.append( ( intentId, state ) )
788 except ( ValueError, TypeError ):
789 main.log.exception( "Error parsing intents" )
790 # add submitted intents not in the store
791 tmplist = [ i for i, s in intentStates ]
792 for i in intentIds:
793 if i not in tmplist:
794 intentStates.append( ( i, " - " ) )
795 intentStates.sort()
796 for i, s in intentStates:
797 count += 1
798 main.log.info( "%-6s%-15s%-15s" %
799 ( str( count ), str( i ), str( s ) ) )
800 leaders = main.ONOScli1.leaders()
801 try:
802 missing = False
803 if leaders:
804 parsedLeaders = json.loads( leaders )
805 main.log.warn( json.dumps( parsedLeaders,
806 sort_keys=True,
807 indent=4,
808 separators=( ',', ': ' ) ) )
809 # check for all intent partitions
810 # check for election
811 topics = []
812 for i in range( 14 ):
813 topics.append( "intent-partition-" + str( i ) )
814 # FIXME: this should only be after we start the app
815 topics.append( "org.onosproject.election" )
816 main.log.debug( topics )
817 ONOStopics = [ j['topic'] for j in parsedLeaders ]
818 for topic in topics:
819 if topic not in ONOStopics:
820 main.log.error( "Error: " + topic +
821 " not in leaders" )
822 missing = True
823 else:
824 main.log.error( "leaders() returned None" )
825 except ( ValueError, TypeError ):
826 main.log.exception( "Error parsing leaders" )
827 main.log.error( repr( leaders ) )
828 # Check all nodes
829 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -0700830 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700831 response = node.leaders( jsonFormat=False)
832 main.log.warn( str( node.name ) + " leaders output: \n" +
833 str( response ) )
834
835 partitions = main.ONOScli1.partitions()
836 try:
837 if partitions :
838 parsedPartitions = json.loads( partitions )
839 main.log.warn( json.dumps( parsedPartitions,
840 sort_keys=True,
841 indent=4,
842 separators=( ',', ': ' ) ) )
843 # TODO check for a leader in all paritions
844 # TODO check for consistency among nodes
845 else:
846 main.log.error( "partitions() returned None" )
847 except ( ValueError, TypeError ):
848 main.log.exception( "Error parsing partitions" )
849 main.log.error( repr( partitions ) )
850 pendingMap = main.ONOScli1.pendingMap()
851 try:
852 if pendingMap :
853 parsedPending = json.loads( pendingMap )
854 main.log.warn( json.dumps( parsedPending,
855 sort_keys=True,
856 indent=4,
857 separators=( ',', ': ' ) ) )
858 # TODO check something here?
859 else:
860 main.log.error( "pendingMap() returned None" )
861 except ( ValueError, TypeError ):
862 main.log.exception( "Error parsing pending map" )
863 main.log.error( repr( pendingMap ) )
864
865 def CASE4( self, main ):
866 """
867 Ping across added host intents
868 """
869 import json
870 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700871 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700872 assert main, "main not defined"
873 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700874 assert main.CLIs, "main.CLIs not defined"
875 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700876 main.case( "Verify connectivity by sendind traffic across Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700877 main.caseExplanation = "Ping across added host intents to check " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700878 "functionality and check the state of " +\
879 "the intent"
880 main.step( "Ping across added host intents" )
881 PingResult = main.TRUE
882 for i in range( 8, 18 ):
883 ping = main.Mininet1.pingHost( src="h" + str( i ),
884 target="h" + str( i + 10 ) )
885 PingResult = PingResult and ping
886 if ping == main.FALSE:
887 main.log.warn( "Ping failed between h" + str( i ) +
888 " and h" + str( i + 10 ) )
889 elif ping == main.TRUE:
890 main.log.info( "Ping test passed!" )
891 # Don't set PingResult or you'd override failures
892 if PingResult == main.FALSE:
893 main.log.error(
894 "Intents have not been installed correctly, pings failed." )
895 # TODO: pretty print
896 main.log.warn( "ONOS1 intents: " )
897 try:
898 tmpIntents = main.ONOScli1.intents()
899 main.log.warn( json.dumps( json.loads( tmpIntents ),
900 sort_keys=True,
901 indent=4,
902 separators=( ',', ': ' ) ) )
903 except ( ValueError, TypeError ):
904 main.log.warn( repr( tmpIntents ) )
905 utilities.assert_equals(
906 expect=main.TRUE,
907 actual=PingResult,
908 onpass="Intents have been installed correctly and pings work",
909 onfail="Intents have not been installed correctly, pings failed." )
910
911 main.step( "Check Intent state" )
912 installedCheck = False
913 loopCount = 0
914 while not installedCheck and loopCount < 40:
915 installedCheck = True
916 # Print the intent states
917 intents = main.ONOScli1.intents()
918 intentStates = []
919 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700920 count = 0
Jon Hall5cf14d52015-07-16 12:15:19 -0700921 # Iter through intents of a node
922 try:
923 for intent in json.loads( intents ):
924 state = intent.get( 'state', None )
925 if "INSTALLED" not in state:
926 installedCheck = False
927 intentId = intent.get( 'id', None )
928 intentStates.append( ( intentId, state ) )
929 except ( ValueError, TypeError ):
930 main.log.exception( "Error parsing intents." )
931 # Print states
932 intentStates.sort()
933 for i, s in intentStates:
934 count += 1
935 main.log.info( "%-6s%-15s%-15s" %
936 ( str( count ), str( i ), str( s ) ) )
937 if not installedCheck:
938 time.sleep( 1 )
939 loopCount += 1
940 utilities.assert_equals( expect=True, actual=installedCheck,
941 onpass="Intents are all INSTALLED",
942 onfail="Intents are not all in " +
943 "INSTALLED state" )
944
945 main.step( "Check leadership of topics" )
946 leaders = main.ONOScli1.leaders()
947 topicCheck = main.TRUE
948 try:
949 if leaders:
950 parsedLeaders = json.loads( leaders )
951 main.log.warn( json.dumps( parsedLeaders,
952 sort_keys=True,
953 indent=4,
954 separators=( ',', ': ' ) ) )
955 # check for all intent partitions
956 # check for election
957 # TODO: Look at Devices as topics now that it uses this system
958 topics = []
959 for i in range( 14 ):
960 topics.append( "intent-partition-" + str( i ) )
961 # FIXME: this should only be after we start the app
962 # FIXME: topics.append( "org.onosproject.election" )
963 # Print leaders output
964 main.log.debug( topics )
965 ONOStopics = [ j['topic'] for j in parsedLeaders ]
966 for topic in topics:
967 if topic not in ONOStopics:
968 main.log.error( "Error: " + topic +
969 " not in leaders" )
970 topicCheck = main.FALSE
971 else:
972 main.log.error( "leaders() returned None" )
973 topicCheck = main.FALSE
974 except ( ValueError, TypeError ):
975 topicCheck = main.FALSE
976 main.log.exception( "Error parsing leaders" )
977 main.log.error( repr( leaders ) )
978 # TODO: Check for a leader of these topics
979 # Check all nodes
980 if topicCheck:
Jon Halle1a3b752015-07-22 13:02:46 -0700981 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700982 response = node.leaders( jsonFormat=False)
983 main.log.warn( str( node.name ) + " leaders output: \n" +
984 str( response ) )
985
986 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
987 onpass="intent Partitions is in leaders",
988 onfail="Some topics were lost " )
989 # Print partitions
990 partitions = main.ONOScli1.partitions()
991 try:
992 if partitions :
993 parsedPartitions = json.loads( partitions )
994 main.log.warn( json.dumps( parsedPartitions,
995 sort_keys=True,
996 indent=4,
997 separators=( ',', ': ' ) ) )
998 # TODO check for a leader in all paritions
999 # TODO check for consistency among nodes
1000 else:
1001 main.log.error( "partitions() returned None" )
1002 except ( ValueError, TypeError ):
1003 main.log.exception( "Error parsing partitions" )
1004 main.log.error( repr( partitions ) )
1005 # Print Pending Map
1006 pendingMap = main.ONOScli1.pendingMap()
1007 try:
1008 if pendingMap :
1009 parsedPending = json.loads( pendingMap )
1010 main.log.warn( json.dumps( parsedPending,
1011 sort_keys=True,
1012 indent=4,
1013 separators=( ',', ': ' ) ) )
1014 # TODO check something here?
1015 else:
1016 main.log.error( "pendingMap() returned None" )
1017 except ( ValueError, TypeError ):
1018 main.log.exception( "Error parsing pending map" )
1019 main.log.error( repr( pendingMap ) )
1020
1021 if not installedCheck:
1022 main.log.info( "Waiting 60 seconds to see if the state of " +
1023 "intents change" )
1024 time.sleep( 60 )
1025 # Print the intent states
1026 intents = main.ONOScli1.intents()
1027 intentStates = []
1028 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
1029 count = 0
1030 # Iter through intents of a node
1031 try:
1032 for intent in json.loads( intents ):
1033 state = intent.get( 'state', None )
1034 if "INSTALLED" not in state:
1035 installedCheck = False
1036 intentId = intent.get( 'id', None )
1037 intentStates.append( ( intentId, state ) )
1038 except ( ValueError, TypeError ):
1039 main.log.exception( "Error parsing intents." )
1040 intentStates.sort()
1041 for i, s in intentStates:
1042 count += 1
1043 main.log.info( "%-6s%-15s%-15s" %
1044 ( str( count ), str( i ), str( s ) ) )
1045 leaders = main.ONOScli1.leaders()
1046 try:
1047 missing = False
1048 if leaders:
1049 parsedLeaders = json.loads( leaders )
1050 main.log.warn( json.dumps( parsedLeaders,
1051 sort_keys=True,
1052 indent=4,
1053 separators=( ',', ': ' ) ) )
1054 # check for all intent partitions
1055 # check for election
1056 topics = []
1057 for i in range( 14 ):
1058 topics.append( "intent-partition-" + str( i ) )
1059 # FIXME: this should only be after we start the app
1060 topics.append( "org.onosproject.election" )
1061 main.log.debug( topics )
1062 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1063 for topic in topics:
1064 if topic not in ONOStopics:
1065 main.log.error( "Error: " + topic +
1066 " not in leaders" )
1067 missing = True
1068 else:
1069 main.log.error( "leaders() returned None" )
1070 except ( ValueError, TypeError ):
1071 main.log.exception( "Error parsing leaders" )
1072 main.log.error( repr( leaders ) )
1073 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -07001074 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07001075 response = node.leaders( jsonFormat=False)
1076 main.log.warn( str( node.name ) + " leaders output: \n" +
1077 str( response ) )
1078
1079 partitions = main.ONOScli1.partitions()
1080 try:
1081 if partitions :
1082 parsedPartitions = json.loads( partitions )
1083 main.log.warn( json.dumps( parsedPartitions,
1084 sort_keys=True,
1085 indent=4,
1086 separators=( ',', ': ' ) ) )
1087 # TODO check for a leader in all paritions
1088 # TODO check for consistency among nodes
1089 else:
1090 main.log.error( "partitions() returned None" )
1091 except ( ValueError, TypeError ):
1092 main.log.exception( "Error parsing partitions" )
1093 main.log.error( repr( partitions ) )
1094 pendingMap = main.ONOScli1.pendingMap()
1095 try:
1096 if pendingMap :
1097 parsedPending = json.loads( pendingMap )
1098 main.log.warn( json.dumps( parsedPending,
1099 sort_keys=True,
1100 indent=4,
1101 separators=( ',', ': ' ) ) )
1102 # TODO check something here?
1103 else:
1104 main.log.error( "pendingMap() returned None" )
1105 except ( ValueError, TypeError ):
1106 main.log.exception( "Error parsing pending map" )
1107 main.log.error( repr( pendingMap ) )
1108 # Print flowrules
Jon Halle1a3b752015-07-22 13:02:46 -07001109 main.log.debug( main.CLIs[0].flows( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001110 main.step( "Wait a minute then ping again" )
1111 # the wait is above
1112 PingResult = main.TRUE
1113 for i in range( 8, 18 ):
1114 ping = main.Mininet1.pingHost( src="h" + str( i ),
1115 target="h" + str( i + 10 ) )
1116 PingResult = PingResult and ping
1117 if ping == main.FALSE:
1118 main.log.warn( "Ping failed between h" + str( i ) +
1119 " and h" + str( i + 10 ) )
1120 elif ping == main.TRUE:
1121 main.log.info( "Ping test passed!" )
1122 # Don't set PingResult or you'd override failures
1123 if PingResult == main.FALSE:
1124 main.log.error(
1125 "Intents have not been installed correctly, pings failed." )
1126 # TODO: pretty print
1127 main.log.warn( "ONOS1 intents: " )
1128 try:
1129 tmpIntents = main.ONOScli1.intents()
1130 main.log.warn( json.dumps( json.loads( tmpIntents ),
1131 sort_keys=True,
1132 indent=4,
1133 separators=( ',', ': ' ) ) )
1134 except ( ValueError, TypeError ):
1135 main.log.warn( repr( tmpIntents ) )
1136 utilities.assert_equals(
1137 expect=main.TRUE,
1138 actual=PingResult,
1139 onpass="Intents have been installed correctly and pings work",
1140 onfail="Intents have not been installed correctly, pings failed." )
1141
1142 def CASE5( self, main ):
1143 """
1144 Reading state of ONOS
1145 """
1146 import json
1147 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001148 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001149 assert main, "main not defined"
1150 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001151 assert main.CLIs, "main.CLIs not defined"
1152 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001153
1154 main.case( "Setting up and gathering data for current state" )
1155 # The general idea for this test case is to pull the state of
1156 # ( intents,flows, topology,... ) from each ONOS node
1157 # We can then compare them with each other and also with past states
1158
1159 main.step( "Check that each switch has a master" )
1160 global mastershipState
1161 mastershipState = '[]'
1162
1163 # Assert that each device has a master
1164 rolesNotNull = main.TRUE
1165 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001166 for i in range( main.numCtrls ):
1167 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001168 name="rolesNotNull-" + str( i ),
1169 args=[] )
1170 threads.append( t )
1171 t.start()
1172
1173 for t in threads:
1174 t.join()
1175 rolesNotNull = rolesNotNull and t.result
1176 utilities.assert_equals(
1177 expect=main.TRUE,
1178 actual=rolesNotNull,
1179 onpass="Each device has a master",
1180 onfail="Some devices don't have a master assigned" )
1181
1182 main.step( "Get the Mastership of each switch from each controller" )
1183 ONOSMastership = []
1184 mastershipCheck = main.FALSE
1185 consistentMastership = True
1186 rolesResults = True
1187 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001188 for i in range( main.numCtrls ):
1189 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001190 name="roles-" + str( i ),
1191 args=[] )
1192 threads.append( t )
1193 t.start()
1194
1195 for t in threads:
1196 t.join()
1197 ONOSMastership.append( t.result )
1198
Jon Halle1a3b752015-07-22 13:02:46 -07001199 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001200 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1201 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1202 " roles" )
1203 main.log.warn(
1204 "ONOS" + str( i + 1 ) + " mastership response: " +
1205 repr( ONOSMastership[i] ) )
1206 rolesResults = False
1207 utilities.assert_equals(
1208 expect=True,
1209 actual=rolesResults,
1210 onpass="No error in reading roles output",
1211 onfail="Error in reading roles from ONOS" )
1212
1213 main.step( "Check for consistency in roles from each controller" )
1214 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1215 main.log.info(
1216 "Switch roles are consistent across all ONOS nodes" )
1217 else:
1218 consistentMastership = False
1219 utilities.assert_equals(
1220 expect=True,
1221 actual=consistentMastership,
1222 onpass="Switch roles are consistent across all ONOS nodes",
1223 onfail="ONOS nodes have different views of switch roles" )
1224
1225 if rolesResults and not consistentMastership:
Jon Halle1a3b752015-07-22 13:02:46 -07001226 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001227 try:
1228 main.log.warn(
1229 "ONOS" + str( i + 1 ) + " roles: ",
1230 json.dumps(
1231 json.loads( ONOSMastership[ i ] ),
1232 sort_keys=True,
1233 indent=4,
1234 separators=( ',', ': ' ) ) )
1235 except ( ValueError, TypeError ):
1236 main.log.warn( repr( ONOSMastership[ i ] ) )
1237 elif rolesResults and consistentMastership:
1238 mastershipCheck = main.TRUE
1239 mastershipState = ONOSMastership[ 0 ]
1240
1241 main.step( "Get the intents from each controller" )
1242 global intentState
1243 intentState = []
1244 ONOSIntents = []
1245 intentCheck = main.FALSE
1246 consistentIntents = True
1247 intentsResults = True
1248 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001249 for i in range( main.numCtrls ):
1250 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001251 name="intents-" + str( i ),
1252 args=[],
1253 kwargs={ 'jsonFormat': True } )
1254 threads.append( t )
1255 t.start()
1256
1257 for t in threads:
1258 t.join()
1259 ONOSIntents.append( t.result )
1260
Jon Halle1a3b752015-07-22 13:02:46 -07001261 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001262 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1263 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1264 " intents" )
1265 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1266 repr( ONOSIntents[ i ] ) )
1267 intentsResults = False
1268 utilities.assert_equals(
1269 expect=True,
1270 actual=intentsResults,
1271 onpass="No error in reading intents output",
1272 onfail="Error in reading intents from ONOS" )
1273
1274 main.step( "Check for consistency in Intents from each controller" )
1275 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1276 main.log.info( "Intents are consistent across all ONOS " +
1277 "nodes" )
1278 else:
1279 consistentIntents = False
1280 main.log.error( "Intents not consistent" )
1281 utilities.assert_equals(
1282 expect=True,
1283 actual=consistentIntents,
1284 onpass="Intents are consistent across all ONOS nodes",
1285 onfail="ONOS nodes have different views of intents" )
1286
1287 if intentsResults:
1288 # Try to make it easy to figure out what is happening
1289 #
1290 # Intent ONOS1 ONOS2 ...
1291 # 0x01 INSTALLED INSTALLING
1292 # ... ... ...
1293 # ... ... ...
1294 title = " Id"
Jon Halle1a3b752015-07-22 13:02:46 -07001295 for n in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001296 title += " " * 10 + "ONOS" + str( n + 1 )
1297 main.log.warn( title )
1298 # get all intent keys in the cluster
1299 keys = []
1300 for nodeStr in ONOSIntents:
1301 node = json.loads( nodeStr )
1302 for intent in node:
1303 keys.append( intent.get( 'id' ) )
1304 keys = set( keys )
1305 for key in keys:
1306 row = "%-13s" % key
1307 for nodeStr in ONOSIntents:
1308 node = json.loads( nodeStr )
1309 for intent in node:
1310 if intent.get( 'id', "Error" ) == key:
1311 row += "%-15s" % intent.get( 'state' )
1312 main.log.warn( row )
1313 # End table view
1314
1315 if intentsResults and not consistentIntents:
1316 # print the json objects
1317 n = len(ONOSIntents)
1318 main.log.debug( "ONOS" + str( n ) + " intents: " )
1319 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1320 sort_keys=True,
1321 indent=4,
1322 separators=( ',', ': ' ) ) )
Jon Halle1a3b752015-07-22 13:02:46 -07001323 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001324 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
1325 main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
1326 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1327 sort_keys=True,
1328 indent=4,
1329 separators=( ',', ': ' ) ) )
1330 else:
Jon Halle1a3b752015-07-22 13:02:46 -07001331 main.log.debug( main.nodes[ i ].name + " intents match ONOS" +
Jon Hall5cf14d52015-07-16 12:15:19 -07001332 str( n ) + " intents" )
1333 elif intentsResults and consistentIntents:
1334 intentCheck = main.TRUE
1335 intentState = ONOSIntents[ 0 ]
1336
1337 main.step( "Get the flows from each controller" )
1338 global flowState
1339 flowState = []
1340 ONOSFlows = []
1341 ONOSFlowsJson = []
1342 flowCheck = main.FALSE
1343 consistentFlows = True
1344 flowsResults = True
1345 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001346 for i in range( main.numCtrls ):
1347 t = main.Thread( target=main.CLIs[i].flows,
Jon Hall5cf14d52015-07-16 12:15:19 -07001348 name="flows-" + str( i ),
1349 args=[],
1350 kwargs={ 'jsonFormat': True } )
1351 threads.append( t )
1352 t.start()
1353
1354 # NOTE: Flows command can take some time to run
1355 time.sleep(30)
1356 for t in threads:
1357 t.join()
1358 result = t.result
1359 ONOSFlows.append( result )
1360
Jon Halle1a3b752015-07-22 13:02:46 -07001361 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001362 num = str( i + 1 )
1363 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1364 main.log.error( "Error in getting ONOS" + num + " flows" )
1365 main.log.warn( "ONOS" + num + " flows response: " +
1366 repr( ONOSFlows[ i ] ) )
1367 flowsResults = False
1368 ONOSFlowsJson.append( None )
1369 else:
1370 try:
1371 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1372 except ( ValueError, TypeError ):
1373 # FIXME: change this to log.error?
1374 main.log.exception( "Error in parsing ONOS" + num +
1375 " response as json." )
1376 main.log.error( repr( ONOSFlows[ i ] ) )
1377 ONOSFlowsJson.append( None )
1378 flowsResults = False
1379 utilities.assert_equals(
1380 expect=True,
1381 actual=flowsResults,
1382 onpass="No error in reading flows output",
1383 onfail="Error in reading flows from ONOS" )
1384
1385 main.step( "Check for consistency in Flows from each controller" )
1386 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1387 if all( tmp ):
1388 main.log.info( "Flow count is consistent across all ONOS nodes" )
1389 else:
1390 consistentFlows = False
1391 utilities.assert_equals(
1392 expect=True,
1393 actual=consistentFlows,
1394 onpass="The flow count is consistent across all ONOS nodes",
1395 onfail="ONOS nodes have different flow counts" )
1396
1397 if flowsResults and not consistentFlows:
Jon Halle1a3b752015-07-22 13:02:46 -07001398 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001399 try:
1400 main.log.warn(
1401 "ONOS" + str( i + 1 ) + " flows: " +
1402 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1403 indent=4, separators=( ',', ': ' ) ) )
1404 except ( ValueError, TypeError ):
1405 main.log.warn(
1406 "ONOS" + str( i + 1 ) + " flows: " +
1407 repr( ONOSFlows[ i ] ) )
1408 elif flowsResults and consistentFlows:
1409 flowCheck = main.TRUE
1410 flowState = ONOSFlows[ 0 ]
1411
1412 main.step( "Get the OF Table entries" )
1413 global flows
1414 flows = []
1415 for i in range( 1, 29 ):
Jon Hallca7ac292015-11-11 09:28:12 -08001416 flows.append( main.Mininet1.getFlowTable( "s" + str( i ), version="1.3" ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001417 if flowCheck == main.FALSE:
1418 for table in flows:
1419 main.log.warn( table )
1420 # TODO: Compare switch flow tables with ONOS flow tables
1421
1422 main.step( "Start continuous pings" )
1423 main.Mininet2.pingLong(
1424 src=main.params[ 'PING' ][ 'source1' ],
1425 target=main.params[ 'PING' ][ 'target1' ],
1426 pingTime=500 )
1427 main.Mininet2.pingLong(
1428 src=main.params[ 'PING' ][ 'source2' ],
1429 target=main.params[ 'PING' ][ 'target2' ],
1430 pingTime=500 )
1431 main.Mininet2.pingLong(
1432 src=main.params[ 'PING' ][ 'source3' ],
1433 target=main.params[ 'PING' ][ 'target3' ],
1434 pingTime=500 )
1435 main.Mininet2.pingLong(
1436 src=main.params[ 'PING' ][ 'source4' ],
1437 target=main.params[ 'PING' ][ 'target4' ],
1438 pingTime=500 )
1439 main.Mininet2.pingLong(
1440 src=main.params[ 'PING' ][ 'source5' ],
1441 target=main.params[ 'PING' ][ 'target5' ],
1442 pingTime=500 )
1443 main.Mininet2.pingLong(
1444 src=main.params[ 'PING' ][ 'source6' ],
1445 target=main.params[ 'PING' ][ 'target6' ],
1446 pingTime=500 )
1447 main.Mininet2.pingLong(
1448 src=main.params[ 'PING' ][ 'source7' ],
1449 target=main.params[ 'PING' ][ 'target7' ],
1450 pingTime=500 )
1451 main.Mininet2.pingLong(
1452 src=main.params[ 'PING' ][ 'source8' ],
1453 target=main.params[ 'PING' ][ 'target8' ],
1454 pingTime=500 )
1455 main.Mininet2.pingLong(
1456 src=main.params[ 'PING' ][ 'source9' ],
1457 target=main.params[ 'PING' ][ 'target9' ],
1458 pingTime=500 )
1459 main.Mininet2.pingLong(
1460 src=main.params[ 'PING' ][ 'source10' ],
1461 target=main.params[ 'PING' ][ 'target10' ],
1462 pingTime=500 )
1463
1464 main.step( "Collecting topology information from ONOS" )
1465 devices = []
1466 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001467 for i in range( main.numCtrls ):
1468 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07001469 name="devices-" + str( i ),
1470 args=[ ] )
1471 threads.append( t )
1472 t.start()
1473
1474 for t in threads:
1475 t.join()
1476 devices.append( t.result )
1477 hosts = []
1478 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001479 for i in range( main.numCtrls ):
1480 t = main.Thread( target=main.CLIs[i].hosts,
Jon Hall5cf14d52015-07-16 12:15:19 -07001481 name="hosts-" + str( i ),
1482 args=[ ] )
1483 threads.append( t )
1484 t.start()
1485
1486 for t in threads:
1487 t.join()
1488 try:
1489 hosts.append( json.loads( t.result ) )
1490 except ( ValueError, TypeError ):
1491 # FIXME: better handling of this, print which node
1492 # Maybe use thread name?
1493 main.log.exception( "Error parsing json output of hosts" )
1494 # FIXME: should this be an empty json object instead?
1495 hosts.append( None )
1496
1497 ports = []
1498 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001499 for i in range( main.numCtrls ):
1500 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07001501 name="ports-" + str( i ),
1502 args=[ ] )
1503 threads.append( t )
1504 t.start()
1505
1506 for t in threads:
1507 t.join()
1508 ports.append( t.result )
1509 links = []
1510 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001511 for i in range( main.numCtrls ):
1512 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07001513 name="links-" + str( i ),
1514 args=[ ] )
1515 threads.append( t )
1516 t.start()
1517
1518 for t in threads:
1519 t.join()
1520 links.append( t.result )
1521 clusters = []
1522 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001523 for i in range( main.numCtrls ):
1524 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07001525 name="clusters-" + str( i ),
1526 args=[ ] )
1527 threads.append( t )
1528 t.start()
1529
1530 for t in threads:
1531 t.join()
1532 clusters.append( t.result )
1533 # Compare json objects for hosts and dataplane clusters
1534
1535 # hosts
1536 main.step( "Host view is consistent across ONOS nodes" )
1537 consistentHostsResult = main.TRUE
1538 for controller in range( len( hosts ) ):
1539 controllerStr = str( controller + 1 )
1540 if "Error" not in hosts[ controller ]:
1541 if hosts[ controller ] == hosts[ 0 ]:
1542 continue
1543 else: # hosts not consistent
1544 main.log.error( "hosts from ONOS" +
1545 controllerStr +
1546 " is inconsistent with ONOS1" )
1547 main.log.warn( repr( hosts[ controller ] ) )
1548 consistentHostsResult = main.FALSE
1549
1550 else:
1551 main.log.error( "Error in getting ONOS hosts from ONOS" +
1552 controllerStr )
1553 consistentHostsResult = main.FALSE
1554 main.log.warn( "ONOS" + controllerStr +
1555 " hosts response: " +
1556 repr( hosts[ controller ] ) )
1557 utilities.assert_equals(
1558 expect=main.TRUE,
1559 actual=consistentHostsResult,
1560 onpass="Hosts view is consistent across all ONOS nodes",
1561 onfail="ONOS nodes have different views of hosts" )
1562
1563 main.step( "Each host has an IP address" )
1564 ipResult = main.TRUE
1565 for controller in range( 0, len( hosts ) ):
1566 controllerStr = str( controller + 1 )
1567 for host in hosts[ controller ]:
1568 if not host.get( 'ipAddresses', [ ] ):
1569 main.log.error( "DEBUG:Error with host ips on controller" +
1570 controllerStr + ": " + str( host ) )
1571 ipResult = main.FALSE
1572 utilities.assert_equals(
1573 expect=main.TRUE,
1574 actual=ipResult,
1575 onpass="The ips of the hosts aren't empty",
1576 onfail="The ip of at least one host is missing" )
1577
1578 # Strongly connected clusters of devices
1579 main.step( "Cluster view is consistent across ONOS nodes" )
1580 consistentClustersResult = main.TRUE
1581 for controller in range( len( clusters ) ):
1582 controllerStr = str( controller + 1 )
1583 if "Error" not in clusters[ controller ]:
1584 if clusters[ controller ] == clusters[ 0 ]:
1585 continue
1586 else: # clusters not consistent
1587 main.log.error( "clusters from ONOS" + controllerStr +
1588 " is inconsistent with ONOS1" )
1589 consistentClustersResult = main.FALSE
1590
1591 else:
1592 main.log.error( "Error in getting dataplane clusters " +
1593 "from ONOS" + controllerStr )
1594 consistentClustersResult = main.FALSE
1595 main.log.warn( "ONOS" + controllerStr +
1596 " clusters response: " +
1597 repr( clusters[ controller ] ) )
1598 utilities.assert_equals(
1599 expect=main.TRUE,
1600 actual=consistentClustersResult,
1601 onpass="Clusters view is consistent across all ONOS nodes",
1602 onfail="ONOS nodes have different views of clusters" )
1603 # there should always only be one cluster
1604 main.step( "Cluster view correct across ONOS nodes" )
1605 try:
1606 numClusters = len( json.loads( clusters[ 0 ] ) )
1607 except ( ValueError, TypeError ):
1608 main.log.exception( "Error parsing clusters[0]: " +
1609 repr( clusters[ 0 ] ) )
1610 clusterResults = main.FALSE
1611 if numClusters == 1:
1612 clusterResults = main.TRUE
1613 utilities.assert_equals(
1614 expect=1,
1615 actual=numClusters,
1616 onpass="ONOS shows 1 SCC",
1617 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1618
1619 main.step( "Comparing ONOS topology to MN" )
1620 devicesResults = main.TRUE
1621 linksResults = main.TRUE
1622 hostsResults = main.TRUE
1623 mnSwitches = main.Mininet1.getSwitches()
1624 mnLinks = main.Mininet1.getLinks()
1625 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07001626 for controller in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001627 controllerStr = str( controller + 1 )
1628 if devices[ controller ] and ports[ controller ] and\
1629 "Error" not in devices[ controller ] and\
1630 "Error" not in ports[ controller ]:
Jon Halle1a3b752015-07-22 13:02:46 -07001631 currentDevicesResult = main.Mininet1.compareSwitches(
1632 mnSwitches,
1633 json.loads( devices[ controller ] ),
1634 json.loads( ports[ controller ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001635 else:
1636 currentDevicesResult = main.FALSE
1637 utilities.assert_equals( expect=main.TRUE,
1638 actual=currentDevicesResult,
1639 onpass="ONOS" + controllerStr +
1640 " Switches view is correct",
1641 onfail="ONOS" + controllerStr +
1642 " Switches view is incorrect" )
1643 if links[ controller ] and "Error" not in links[ controller ]:
1644 currentLinksResult = main.Mininet1.compareLinks(
1645 mnSwitches, mnLinks,
1646 json.loads( links[ controller ] ) )
1647 else:
1648 currentLinksResult = main.FALSE
1649 utilities.assert_equals( expect=main.TRUE,
1650 actual=currentLinksResult,
1651 onpass="ONOS" + controllerStr +
1652 " links view is correct",
1653 onfail="ONOS" + controllerStr +
1654 " links view is incorrect" )
1655
1656 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1657 currentHostsResult = main.Mininet1.compareHosts(
1658 mnHosts,
1659 hosts[ controller ] )
1660 else:
1661 currentHostsResult = main.FALSE
1662 utilities.assert_equals( expect=main.TRUE,
1663 actual=currentHostsResult,
1664 onpass="ONOS" + controllerStr +
1665 " hosts exist in Mininet",
1666 onfail="ONOS" + controllerStr +
1667 " hosts don't match Mininet" )
1668
1669 devicesResults = devicesResults and currentDevicesResult
1670 linksResults = linksResults and currentLinksResult
1671 hostsResults = hostsResults and currentHostsResult
1672
1673 main.step( "Device information is correct" )
1674 utilities.assert_equals(
1675 expect=main.TRUE,
1676 actual=devicesResults,
1677 onpass="Device information is correct",
1678 onfail="Device information is incorrect" )
1679
1680 main.step( "Links are correct" )
1681 utilities.assert_equals(
1682 expect=main.TRUE,
1683 actual=linksResults,
1684 onpass="Link are correct",
1685 onfail="Links are incorrect" )
1686
1687 main.step( "Hosts are correct" )
1688 utilities.assert_equals(
1689 expect=main.TRUE,
1690 actual=hostsResults,
1691 onpass="Hosts are correct",
1692 onfail="Hosts are incorrect" )
1693
1694 def CASE6( self, main ):
1695 """
1696 The Failure case.
1697 """
1698 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001699 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001700 assert main, "main not defined"
1701 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001702 assert main.CLIs, "main.CLIs not defined"
1703 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001704 try:
1705 labels
1706 except NameError:
1707 main.log.error( "labels not defined, setting to []" )
1708 global labels
1709 labels = []
1710 try:
1711 data
1712 except NameError:
1713 main.log.error( "data not defined, setting to []" )
1714 global data
1715 data = []
1716 # Reset non-persistent variables
1717 try:
1718 iCounterValue = 0
1719 except NameError:
1720 main.log.error( "iCounterValue not defined, setting to 0" )
1721 iCounterValue = 0
1722
1723 main.case( "Restart entire ONOS cluster" )
1724
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001725 main.step( "Checking ONOS Logs for errors" )
1726 for node in main.nodes:
1727 main.log.debug( "Checking logs for errors on " + node.name + ":" )
1728 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
1729
Jon Hall5cf14d52015-07-16 12:15:19 -07001730 main.step( "Killing ONOS nodes" )
1731 killResults = main.TRUE
1732 killTime = time.time()
Jon Halle1a3b752015-07-22 13:02:46 -07001733 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001734 killed = main.ONOSbench.onosKill( node.ip_address )
1735 killResults = killResults and killed
1736 utilities.assert_equals( expect=main.TRUE, actual=killResults,
1737 onpass="ONOS nodes killed",
1738 onfail="ONOS kill unsuccessful" )
1739
1740 main.step( "Checking if ONOS is up yet" )
1741 for i in range( 2 ):
1742 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001743 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001744 started = main.ONOSbench.isup( node.ip_address )
1745 if not started:
1746 main.log.error( node.name + " didn't start!" )
1747 onosIsupResult = onosIsupResult and started
1748 if onosIsupResult == main.TRUE:
1749 break
1750 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1751 onpass="ONOS restarted",
1752 onfail="ONOS restart NOT successful" )
1753
1754 main.log.step( "Starting ONOS CLI sessions" )
1755 cliResults = main.TRUE
1756 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001757 for i in range( main.numCtrls ):
1758 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -07001759 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -07001760 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -07001761 threads.append( t )
1762 t.start()
1763
1764 for t in threads:
1765 t.join()
1766 cliResults = cliResults and t.result
1767 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1768 onpass="ONOS cli started",
1769 onfail="ONOS clis did not restart" )
1770
1771 # Grab the time of restart so we chan check how long the gossip
1772 # protocol has had time to work
1773 main.restartTime = time.time() - killTime
1774 main.log.debug( "Restart time: " + str( main.restartTime ) )
1775 labels.append( "Restart" )
1776 data.append( str( main.restartTime ) )
1777
1778 # FIXME: revisit test plan for election with madan
1779 # Rerun for election on restarted nodes
1780 runResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001781 for cli in main.CLIs:
1782 run = main.CLIs[0].electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07001783 if run != main.TRUE:
1784 main.log.error( "Error running for election on " + cli.name )
1785 runResults = runResults and run
1786 utilities.assert_equals( expect=main.TRUE, actual=runResults,
1787 onpass="Reran for election",
1788 onfail="Failed to rerun for election" )
1789
1790 # TODO: Make this configurable
1791 time.sleep( 60 )
Jon Halle1a3b752015-07-22 13:02:46 -07001792 main.log.debug( main.CLIs[0].nodes( jsonFormat=False ) )
1793 main.log.debug( main.CLIs[0].leaders( jsonFormat=False ) )
1794 main.log.debug( main.CLIs[0].partitions( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001795
1796 def CASE7( self, main ):
1797 """
1798 Check state after ONOS failure
1799 """
1800 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001801 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001802 assert main, "main not defined"
1803 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001804 assert main.CLIs, "main.CLIs not defined"
1805 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001806 main.case( "Running ONOS Constant State Tests" )
1807
1808 main.step( "Check that each switch has a master" )
1809 # Assert that each device has a master
1810 rolesNotNull = main.TRUE
1811 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001812 for i in range( main.numCtrls ):
1813 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001814 name="rolesNotNull-" + str( i ),
1815 args=[ ] )
1816 threads.append( t )
1817 t.start()
1818
1819 for t in threads:
1820 t.join()
1821 rolesNotNull = rolesNotNull and t.result
1822 utilities.assert_equals(
1823 expect=main.TRUE,
1824 actual=rolesNotNull,
1825 onpass="Each device has a master",
1826 onfail="Some devices don't have a master assigned" )
1827
1828 main.step( "Read device roles from ONOS" )
1829 ONOSMastership = []
1830 mastershipCheck = main.FALSE
1831 consistentMastership = True
1832 rolesResults = True
1833 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001834 for i in range( main.numCtrls ):
1835 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001836 name="roles-" + str( i ),
1837 args=[] )
1838 threads.append( t )
1839 t.start()
1840
1841 for t in threads:
1842 t.join()
1843 ONOSMastership.append( t.result )
1844
Jon Halle1a3b752015-07-22 13:02:46 -07001845 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001846 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1847 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1848 " roles" )
1849 main.log.warn(
1850 "ONOS" + str( i + 1 ) + " mastership response: " +
1851 repr( ONOSMastership[i] ) )
1852 rolesResults = False
1853 utilities.assert_equals(
1854 expect=True,
1855 actual=rolesResults,
1856 onpass="No error in reading roles output",
1857 onfail="Error in reading roles from ONOS" )
1858
1859 main.step( "Check for consistency in roles from each controller" )
1860 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1861 main.log.info(
1862 "Switch roles are consistent across all ONOS nodes" )
1863 else:
1864 consistentMastership = False
1865 utilities.assert_equals(
1866 expect=True,
1867 actual=consistentMastership,
1868 onpass="Switch roles are consistent across all ONOS nodes",
1869 onfail="ONOS nodes have different views of switch roles" )
1870
1871 if rolesResults and not consistentMastership:
Jon Halle1a3b752015-07-22 13:02:46 -07001872 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001873 main.log.warn(
1874 "ONOS" + str( i + 1 ) + " roles: ",
1875 json.dumps(
1876 json.loads( ONOSMastership[ i ] ),
1877 sort_keys=True,
1878 indent=4,
1879 separators=( ',', ': ' ) ) )
1880 elif rolesResults and not consistentMastership:
1881 mastershipCheck = main.TRUE
1882
1883 '''
1884 description2 = "Compare switch roles from before failure"
1885 main.step( description2 )
1886 try:
1887 currentJson = json.loads( ONOSMastership[0] )
1888 oldJson = json.loads( mastershipState )
1889 except ( ValueError, TypeError ):
1890 main.log.exception( "Something is wrong with parsing " +
1891 "ONOSMastership[0] or mastershipState" )
1892 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1893 main.log.error( "mastershipState" + repr( mastershipState ) )
1894 main.cleanup()
1895 main.exit()
1896 mastershipCheck = main.TRUE
1897 for i in range( 1, 29 ):
1898 switchDPID = str(
1899 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
1900 current = [ switch[ 'master' ] for switch in currentJson
1901 if switchDPID in switch[ 'id' ] ]
1902 old = [ switch[ 'master' ] for switch in oldJson
1903 if switchDPID in switch[ 'id' ] ]
1904 if current == old:
1905 mastershipCheck = mastershipCheck and main.TRUE
1906 else:
1907 main.log.warn( "Mastership of switch %s changed" % switchDPID )
1908 mastershipCheck = main.FALSE
1909 utilities.assert_equals(
1910 expect=main.TRUE,
1911 actual=mastershipCheck,
1912 onpass="Mastership of Switches was not changed",
1913 onfail="Mastership of some switches changed" )
1914 '''
1915 # NOTE: we expect mastership to change on controller failure
1916
1917 main.step( "Get the intents and compare across all nodes" )
1918 ONOSIntents = []
1919 intentCheck = main.FALSE
1920 consistentIntents = True
1921 intentsResults = True
1922 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001923 for i in range( main.numCtrls ):
1924 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001925 name="intents-" + str( i ),
1926 args=[],
1927 kwargs={ 'jsonFormat': True } )
1928 threads.append( t )
1929 t.start()
1930
1931 for t in threads:
1932 t.join()
1933 ONOSIntents.append( t.result )
1934
Jon Halle1a3b752015-07-22 13:02:46 -07001935 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001936 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1937 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1938 " intents" )
1939 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1940 repr( ONOSIntents[ i ] ) )
1941 intentsResults = False
1942 utilities.assert_equals(
1943 expect=True,
1944 actual=intentsResults,
1945 onpass="No error in reading intents output",
1946 onfail="Error in reading intents from ONOS" )
1947
1948 main.step( "Check for consistency in Intents from each controller" )
1949 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1950 main.log.info( "Intents are consistent across all ONOS " +
1951 "nodes" )
1952 else:
1953 consistentIntents = False
1954
1955 # Try to make it easy to figure out what is happening
1956 #
1957 # Intent ONOS1 ONOS2 ...
1958 # 0x01 INSTALLED INSTALLING
1959 # ... ... ...
1960 # ... ... ...
1961 title = " ID"
Jon Halle1a3b752015-07-22 13:02:46 -07001962 for n in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001963 title += " " * 10 + "ONOS" + str( n + 1 )
1964 main.log.warn( title )
1965 # get all intent keys in the cluster
1966 keys = []
1967 for nodeStr in ONOSIntents:
1968 node = json.loads( nodeStr )
1969 for intent in node:
1970 keys.append( intent.get( 'id' ) )
1971 keys = set( keys )
1972 for key in keys:
1973 row = "%-13s" % key
1974 for nodeStr in ONOSIntents:
1975 node = json.loads( nodeStr )
1976 for intent in node:
1977 if intent.get( 'id' ) == key:
1978 row += "%-15s" % intent.get( 'state' )
1979 main.log.warn( row )
1980 # End table view
1981
1982 utilities.assert_equals(
1983 expect=True,
1984 actual=consistentIntents,
1985 onpass="Intents are consistent across all ONOS nodes",
1986 onfail="ONOS nodes have different views of intents" )
1987 intentStates = []
1988 for node in ONOSIntents: # Iter through ONOS nodes
1989 nodeStates = []
1990 # Iter through intents of a node
1991 try:
1992 for intent in json.loads( node ):
1993 nodeStates.append( intent[ 'state' ] )
1994 except ( ValueError, TypeError ):
1995 main.log.exception( "Error in parsing intents" )
1996 main.log.error( repr( node ) )
1997 intentStates.append( nodeStates )
1998 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1999 main.log.info( dict( out ) )
2000
2001 if intentsResults and not consistentIntents:
Jon Halle1a3b752015-07-22 13:02:46 -07002002 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07002003 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
2004 main.log.warn( json.dumps(
2005 json.loads( ONOSIntents[ i ] ),
2006 sort_keys=True,
2007 indent=4,
2008 separators=( ',', ': ' ) ) )
2009 elif intentsResults and consistentIntents:
2010 intentCheck = main.TRUE
2011
2012 # NOTE: Store has no durability, so intents are lost across system
2013 # restarts
2014 """
2015 main.step( "Compare current intents with intents before the failure" )
2016 # NOTE: this requires case 5 to pass for intentState to be set.
2017 # maybe we should stop the test if that fails?
2018 sameIntents = main.FALSE
2019 if intentState and intentState == ONOSIntents[ 0 ]:
2020 sameIntents = main.TRUE
2021 main.log.info( "Intents are consistent with before failure" )
2022 # TODO: possibly the states have changed? we may need to figure out
2023 # what the acceptable states are
2024 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
2025 sameIntents = main.TRUE
2026 try:
2027 before = json.loads( intentState )
2028 after = json.loads( ONOSIntents[ 0 ] )
2029 for intent in before:
2030 if intent not in after:
2031 sameIntents = main.FALSE
2032 main.log.debug( "Intent is not currently in ONOS " +
2033 "(at least in the same form):" )
2034 main.log.debug( json.dumps( intent ) )
2035 except ( ValueError, TypeError ):
2036 main.log.exception( "Exception printing intents" )
2037 main.log.debug( repr( ONOSIntents[0] ) )
2038 main.log.debug( repr( intentState ) )
2039 if sameIntents == main.FALSE:
2040 try:
2041 main.log.debug( "ONOS intents before: " )
2042 main.log.debug( json.dumps( json.loads( intentState ),
2043 sort_keys=True, indent=4,
2044 separators=( ',', ': ' ) ) )
2045 main.log.debug( "Current ONOS intents: " )
2046 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
2047 sort_keys=True, indent=4,
2048 separators=( ',', ': ' ) ) )
2049 except ( ValueError, TypeError ):
2050 main.log.exception( "Exception printing intents" )
2051 main.log.debug( repr( ONOSIntents[0] ) )
2052 main.log.debug( repr( intentState ) )
2053 utilities.assert_equals(
2054 expect=main.TRUE,
2055 actual=sameIntents,
2056 onpass="Intents are consistent with before failure",
2057 onfail="The Intents changed during failure" )
2058 intentCheck = intentCheck and sameIntents
2059 """
2060 main.step( "Get the OF Table entries and compare to before " +
2061 "component failure" )
2062 FlowTables = main.TRUE
2063 flows2 = []
2064 for i in range( 28 ):
2065 main.log.info( "Checking flow table on s" + str( i + 1 ) )
Jon Hallca7ac292015-11-11 09:28:12 -08002066 tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3" )
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
acsmars29233db2015-11-04 11:15:00 -08002884 candidateDiscrepancy = False # Boolean of candidate mismatches
acsmars9475b1c2015-08-28 18:02:08 -07002885 for candidates in oldAllCandidates:
2886 if set( candidates ) != set( oldCandidates ):
2887 sameResult = main.FALSE
acsmars29233db2015-11-04 11:15:00 -08002888 candidateDiscrepancy = True
2889
2890 if candidateDiscrepancy:
2891 failMessage += " and candidates"
acsmars9475b1c2015-08-28 18:02:08 -07002892
Jon Hall5cf14d52015-07-16 12:15:19 -07002893 utilities.assert_equals(
2894 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002895 actual=sameResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002896 onpass="Leadership is consistent for the election topic",
acsmars9475b1c2015-08-28 18:02:08 -07002897 onfail=failMessage )
Jon Hall5cf14d52015-07-16 12:15:19 -07002898
2899 main.step( "Find current leader and withdraw" )
acsmars9475b1c2015-08-28 18:02:08 -07002900 withdrawResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002901 # do some sanity checking on leader before using it
acsmars9475b1c2015-08-28 18:02:08 -07002902 if oldLeader is None:
2903 main.log.error( "Leadership isn't consistent." )
2904 withdrawResult = main.FALSE
2905 # Get the CLI of the oldLeader
Jon Halle1a3b752015-07-22 13:02:46 -07002906 for i in range( len( main.CLIs ) ):
acsmars9475b1c2015-08-28 18:02:08 -07002907 if oldLeader == main.nodes[ i ].ip_address:
2908 oldLeaderCLI = main.CLIs[ i ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002909 break
2910 else: # FOR/ELSE statement
2911 main.log.error( "Leader election, could not find current leader" )
2912 if oldLeader:
acsmars9475b1c2015-08-28 18:02:08 -07002913 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall5cf14d52015-07-16 12:15:19 -07002914 utilities.assert_equals(
2915 expect=main.TRUE,
2916 actual=withdrawResult,
2917 onpass="Node was withdrawn from election",
2918 onfail="Node was not withdrawn from election" )
2919
acsmars9475b1c2015-08-28 18:02:08 -07002920 main.step( "Check that a new node was elected leader" )
acsmars71adceb2015-08-31 15:09:26 -07002921
Jon Hall5cf14d52015-07-16 12:15:19 -07002922 # FIXME: use threads
acsmars9475b1c2015-08-28 18:02:08 -07002923 newLeaderResult = main.TRUE
2924 failMessage = "Nodes have different leaders"
2925
2926 # Get new leaders and candidates
Jon Halle1a3b752015-07-22 13:02:46 -07002927 for cli in main.CLIs:
acsmars9475b1c2015-08-28 18:02:08 -07002928 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
acsmars71adceb2015-08-31 15:09:26 -07002929 # elections might no have finished yet
2930 if node[ 0 ] == 'none' and not expectNoLeader:
acsmars9475b1c2015-08-28 18:02:08 -07002931 main.log.info( "Node has no leader, waiting 5 seconds to be " +
2932 "sure elections are complete." )
2933 time.sleep(5)
2934 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
acsmars71adceb2015-08-31 15:09:26 -07002935 # election still isn't done or there is a problem
2936 if node[ 0 ] == 'none':
2937 main.log.error( "No leader was elected on at least 1 node" )
2938 newLeaderResult = main.FALSE
acsmars9475b1c2015-08-28 18:02:08 -07002939 newAllCandidates.append( node )
2940 newLeaders.append( node[ 0 ] )
2941 newCandidates = newAllCandidates[ 0 ]
2942
2943 # Check that each node has the same leader. Defines newLeader
2944 if len( set( newLeaders ) ) != 1:
2945 newLeaderResult = main.FALSE
2946 main.log.error( "Nodes have different leaders: " +
2947 str( newLeaders ) )
2948 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07002949 else:
acsmars9475b1c2015-08-28 18:02:08 -07002950 newLeader = newLeaders[ 0 ]
2951
acsmars71adceb2015-08-31 15:09:26 -07002952 # Check that each node's candidate list is the same
2953 for candidates in newAllCandidates:
2954 if set( candidates ) != set( newCandidates ):
2955 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07002956 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07002957
acsmars9475b1c2015-08-28 18:02:08 -07002958 # Check that the new leader is not the older leader, which was withdrawn
2959 if newLeader == oldLeader:
2960 newLeaderResult = main.FALSE
2961 main.log.error( "All nodes still see old leader: " + oldLeader +
2962 " as the current leader" )
2963
Jon Hall5cf14d52015-07-16 12:15:19 -07002964 utilities.assert_equals(
2965 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07002966 actual=newLeaderResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002967 onpass="Leadership election passed",
2968 onfail="Something went wrong with Leadership election" )
2969
acsmars9475b1c2015-08-28 18:02:08 -07002970 main.step( "Check that that new leader was the candidate of old leader")
2971 # candidates[ 2 ] should be come the top candidate after withdrawl
2972 correctCandidateResult = main.TRUE
acsmars71adceb2015-08-31 15:09:26 -07002973 if expectNoLeader:
2974 if newLeader == 'none':
2975 main.log.info( "No leader expected. None found. Pass" )
2976 correctCandidateResult = main.TRUE
2977 else:
2978 main.log.info( "Expected no leader, got: " + str( newLeader ) )
2979 correctCandidateResult = main.FALSE
2980 elif newLeader != oldCandidates[ 2 ]:
acsmars9475b1c2015-08-28 18:02:08 -07002981 correctCandidateResult = main.FALSE
2982 main.log.error( "Candidate " + newLeader + " was elected. " +
2983 oldCandidates[ 2 ] + " should have had priority." )
2984
2985 utilities.assert_equals(
2986 expect=main.TRUE,
2987 actual=correctCandidateResult,
2988 onpass="Correct Candidate Elected",
2989 onfail="Incorrect Candidate Elected" )
2990
Jon Hall5cf14d52015-07-16 12:15:19 -07002991 main.step( "Run for election on old leader( just so everyone " +
2992 "is in the hat )" )
acsmars9475b1c2015-08-28 18:02:08 -07002993 if oldLeaderCLI is not None:
2994 runResult = oldLeaderCLI.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07002995 else:
acsmars9475b1c2015-08-28 18:02:08 -07002996 main.log.error( "No old leader to re-elect" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002997 runResult = main.FALSE
2998 utilities.assert_equals(
2999 expect=main.TRUE,
3000 actual=runResult,
3001 onpass="App re-ran for election",
3002 onfail="App failed to run for election" )
acsmars9475b1c2015-08-28 18:02:08 -07003003 main.step(
3004 "Check that oldLeader is a candidate, and leader if only 1 node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003005 # verify leader didn't just change
acsmars9475b1c2015-08-28 18:02:08 -07003006 positionResult = main.TRUE
3007 # Get new leaders and candidates, wait if oldLeader is not a candidate yet
3008
3009 # Reset and reuse the new candidate and leaders lists
3010 newAllCandidates = []
3011 newCandidates = []
3012 newLeaders = []
3013 for cli in main.CLIs:
3014 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
3015 if oldLeader not in node: # election might no have finished yet
3016 main.log.info( "Old Leader not elected, waiting 5 seconds to " +
3017 "be sure elections are complete" )
3018 time.sleep(5)
3019 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
3020 if oldLeader not in node: # election still isn't done, errors
3021 main.log.error(
3022 "Old leader was not elected on at least one node" )
3023 positionResult = main.FALSE
3024 newAllCandidates.append( node )
3025 newLeaders.append( node[ 0 ] )
3026 newCandidates = newAllCandidates[ 0 ]
3027
3028 # Check that each node has the same leader. Defines newLeader
3029 if len( set( newLeaders ) ) != 1:
3030 positionResult = main.FALSE
3031 main.log.error( "Nodes have different leaders: " +
3032 str( newLeaders ) )
3033 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07003034 else:
acsmars9475b1c2015-08-28 18:02:08 -07003035 newLeader = newLeaders[ 0 ]
3036
acsmars71adceb2015-08-31 15:09:26 -07003037 # Check that each node's candidate list is the same
3038 for candidates in newAllCandidates:
3039 if set( candidates ) != set( newCandidates ):
3040 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07003041 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07003042
acsmars9475b1c2015-08-28 18:02:08 -07003043 # Check that the re-elected node is last on the candidate List
3044 if oldLeader != newCandidates[ -1 ]:
3045 main.log.error( "Old Leader (" + oldLeader + ") not in the proper position " +
3046 str( newCandidates ) )
3047 positionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07003048
3049 utilities.assert_equals(
3050 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07003051 actual=positionResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07003052 onpass="Old leader successfully re-ran for election",
3053 onfail="Something went wrong with Leadership election after " +
3054 "the old leader re-ran for election" )
3055
3056 def CASE16( self, main ):
3057 """
3058 Install Distributed Primitives app
3059 """
3060 import time
Jon Halle1a3b752015-07-22 13:02:46 -07003061 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003062 assert main, "main not defined"
3063 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003064 assert main.CLIs, "main.CLIs not defined"
3065 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003066
3067 # Variables for the distributed primitives tests
3068 global pCounterName
3069 global iCounterName
3070 global pCounterValue
3071 global iCounterValue
3072 global onosSet
3073 global onosSetName
3074 pCounterName = "TestON-Partitions"
3075 iCounterName = "TestON-inMemory"
3076 pCounterValue = 0
3077 iCounterValue = 0
3078 onosSet = set([])
3079 onosSetName = "TestON-set"
3080
3081 description = "Install Primitives app"
3082 main.case( description )
3083 main.step( "Install Primitives app" )
3084 appName = "org.onosproject.distributedprimitives"
Jon Halle1a3b752015-07-22 13:02:46 -07003085 appResults = main.CLIs[0].activateApp( appName )
Jon Hall5cf14d52015-07-16 12:15:19 -07003086 utilities.assert_equals( expect=main.TRUE,
3087 actual=appResults,
3088 onpass="Primitives app activated",
3089 onfail="Primitives app not activated" )
3090 time.sleep( 5 ) # To allow all nodes to activate
3091
3092 def CASE17( self, main ):
3093 """
3094 Check for basic functionality with distributed primitives
3095 """
Jon Hall5cf14d52015-07-16 12:15:19 -07003096 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07003097 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003098 assert main, "main not defined"
3099 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003100 assert main.CLIs, "main.CLIs not defined"
3101 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003102 assert pCounterName, "pCounterName not defined"
3103 assert iCounterName, "iCounterName not defined"
3104 assert onosSetName, "onosSetName not defined"
3105 # NOTE: assert fails if value is 0/None/Empty/False
3106 try:
3107 pCounterValue
3108 except NameError:
3109 main.log.error( "pCounterValue not defined, setting to 0" )
3110 pCounterValue = 0
3111 try:
3112 iCounterValue
3113 except NameError:
3114 main.log.error( "iCounterValue not defined, setting to 0" )
3115 iCounterValue = 0
3116 try:
3117 onosSet
3118 except NameError:
3119 main.log.error( "onosSet not defined, setting to empty Set" )
3120 onosSet = set([])
3121 # Variables for the distributed primitives tests. These are local only
3122 addValue = "a"
3123 addAllValue = "a b c d e f"
3124 retainValue = "c d e f"
3125
3126 description = "Check for basic functionality with distributed " +\
3127 "primitives"
3128 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07003129 main.caseExplanation = "Test the methods of the distributed " +\
3130 "primitives (counters and sets) throught the cli"
Jon Hall5cf14d52015-07-16 12:15:19 -07003131 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07003132 # Partitioned counters
3133 main.step( "Increment then get a default counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003134 pCounters = []
3135 threads = []
3136 addedPValues = []
Jon Halle1a3b752015-07-22 13:02:46 -07003137 for i in range( main.numCtrls ):
3138 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3139 name="counterAddAndGet-" + str( i ),
Jon Hall5cf14d52015-07-16 12:15:19 -07003140 args=[ pCounterName ] )
3141 pCounterValue += 1
3142 addedPValues.append( pCounterValue )
3143 threads.append( t )
3144 t.start()
3145
3146 for t in threads:
3147 t.join()
3148 pCounters.append( t.result )
3149 # Check that counter incremented numController times
3150 pCounterResults = True
3151 for i in addedPValues:
3152 tmpResult = i in pCounters
3153 pCounterResults = pCounterResults and tmpResult
3154 if not tmpResult:
3155 main.log.error( str( i ) + " is not in partitioned "
3156 "counter incremented results" )
3157 utilities.assert_equals( expect=True,
3158 actual=pCounterResults,
3159 onpass="Default counter incremented",
3160 onfail="Error incrementing default" +
3161 " counter" )
3162
Jon Halle1a3b752015-07-22 13:02:46 -07003163 main.step( "Get then Increment a default counter on each node" )
3164 pCounters = []
3165 threads = []
3166 addedPValues = []
3167 for i in range( main.numCtrls ):
3168 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3169 name="counterGetAndAdd-" + str( i ),
3170 args=[ pCounterName ] )
3171 addedPValues.append( pCounterValue )
3172 pCounterValue += 1
3173 threads.append( t )
3174 t.start()
3175
3176 for t in threads:
3177 t.join()
3178 pCounters.append( t.result )
3179 # Check that counter incremented numController times
3180 pCounterResults = True
3181 for i in addedPValues:
3182 tmpResult = i in pCounters
3183 pCounterResults = pCounterResults and tmpResult
3184 if not tmpResult:
3185 main.log.error( str( i ) + " is not in partitioned "
3186 "counter incremented results" )
3187 utilities.assert_equals( expect=True,
3188 actual=pCounterResults,
3189 onpass="Default counter incremented",
3190 onfail="Error incrementing default" +
3191 " counter" )
3192
3193 main.step( "Counters we added have the correct values" )
3194 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3195 utilities.assert_equals( expect=main.TRUE,
3196 actual=incrementCheck,
3197 onpass="Added counters are correct",
3198 onfail="Added counters are incorrect" )
3199
3200 main.step( "Add -8 to then get a default counter on each node" )
3201 pCounters = []
3202 threads = []
3203 addedPValues = []
3204 for i in range( main.numCtrls ):
3205 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3206 name="counterIncrement-" + str( i ),
3207 args=[ pCounterName ],
3208 kwargs={ "delta": -8 } )
3209 pCounterValue += -8
3210 addedPValues.append( pCounterValue )
3211 threads.append( t )
3212 t.start()
3213
3214 for t in threads:
3215 t.join()
3216 pCounters.append( t.result )
3217 # Check that counter incremented numController times
3218 pCounterResults = True
3219 for i in addedPValues:
3220 tmpResult = i in pCounters
3221 pCounterResults = pCounterResults and tmpResult
3222 if not tmpResult:
3223 main.log.error( str( i ) + " is not in partitioned "
3224 "counter incremented results" )
3225 utilities.assert_equals( expect=True,
3226 actual=pCounterResults,
3227 onpass="Default counter incremented",
3228 onfail="Error incrementing default" +
3229 " counter" )
3230
3231 main.step( "Add 5 to then get a default counter on each node" )
3232 pCounters = []
3233 threads = []
3234 addedPValues = []
3235 for i in range( main.numCtrls ):
3236 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3237 name="counterIncrement-" + str( i ),
3238 args=[ pCounterName ],
3239 kwargs={ "delta": 5 } )
3240 pCounterValue += 5
3241 addedPValues.append( pCounterValue )
3242 threads.append( t )
3243 t.start()
3244
3245 for t in threads:
3246 t.join()
3247 pCounters.append( t.result )
3248 # Check that counter incremented numController times
3249 pCounterResults = True
3250 for i in addedPValues:
3251 tmpResult = i in pCounters
3252 pCounterResults = pCounterResults and tmpResult
3253 if not tmpResult:
3254 main.log.error( str( i ) + " is not in partitioned "
3255 "counter incremented results" )
3256 utilities.assert_equals( expect=True,
3257 actual=pCounterResults,
3258 onpass="Default counter incremented",
3259 onfail="Error incrementing default" +
3260 " counter" )
3261
3262 main.step( "Get then add 5 to a default counter on each node" )
3263 pCounters = []
3264 threads = []
3265 addedPValues = []
3266 for i in range( main.numCtrls ):
3267 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3268 name="counterIncrement-" + str( i ),
3269 args=[ pCounterName ],
3270 kwargs={ "delta": 5 } )
3271 addedPValues.append( pCounterValue )
3272 pCounterValue += 5
3273 threads.append( t )
3274 t.start()
3275
3276 for t in threads:
3277 t.join()
3278 pCounters.append( t.result )
3279 # Check that counter incremented numController times
3280 pCounterResults = True
3281 for i in addedPValues:
3282 tmpResult = i in pCounters
3283 pCounterResults = pCounterResults and tmpResult
3284 if not tmpResult:
3285 main.log.error( str( i ) + " is not in partitioned "
3286 "counter incremented results" )
3287 utilities.assert_equals( expect=True,
3288 actual=pCounterResults,
3289 onpass="Default counter incremented",
3290 onfail="Error incrementing default" +
3291 " counter" )
3292
3293 main.step( "Counters we added have the correct values" )
3294 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3295 utilities.assert_equals( expect=main.TRUE,
3296 actual=incrementCheck,
3297 onpass="Added counters are correct",
3298 onfail="Added counters are incorrect" )
3299
3300 # In-Memory counters
3301 main.step( "Increment and get an in-memory counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003302 iCounters = []
3303 addedIValues = []
3304 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003305 for i in range( main.numCtrls ):
3306 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003307 name="icounterIncrement-" + str( i ),
3308 args=[ iCounterName ],
3309 kwargs={ "inMemory": True } )
3310 iCounterValue += 1
3311 addedIValues.append( iCounterValue )
3312 threads.append( t )
3313 t.start()
3314
3315 for t in threads:
3316 t.join()
3317 iCounters.append( t.result )
3318 # Check that counter incremented numController times
3319 iCounterResults = True
3320 for i in addedIValues:
3321 tmpResult = i in iCounters
3322 iCounterResults = iCounterResults and tmpResult
3323 if not tmpResult:
3324 main.log.error( str( i ) + " is not in the in-memory "
3325 "counter incremented results" )
3326 utilities.assert_equals( expect=True,
3327 actual=iCounterResults,
Jon Halle1a3b752015-07-22 13:02:46 -07003328 onpass="In-memory counter incremented",
3329 onfail="Error incrementing in-memory" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003330 " counter" )
3331
Jon Halle1a3b752015-07-22 13:02:46 -07003332 main.step( "Get then Increment a in-memory counter on each node" )
3333 iCounters = []
3334 threads = []
3335 addedIValues = []
3336 for i in range( main.numCtrls ):
3337 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3338 name="counterGetAndAdd-" + str( i ),
3339 args=[ iCounterName ],
3340 kwargs={ "inMemory": True } )
3341 addedIValues.append( iCounterValue )
3342 iCounterValue += 1
3343 threads.append( t )
3344 t.start()
3345
3346 for t in threads:
3347 t.join()
3348 iCounters.append( t.result )
3349 # Check that counter incremented numController times
3350 iCounterResults = True
3351 for i in addedIValues:
3352 tmpResult = i in iCounters
3353 iCounterResults = iCounterResults and tmpResult
3354 if not tmpResult:
3355 main.log.error( str( i ) + " is not in in-memory "
3356 "counter incremented results" )
3357 utilities.assert_equals( expect=True,
3358 actual=iCounterResults,
3359 onpass="In-memory counter incremented",
3360 onfail="Error incrementing in-memory" +
3361 " counter" )
3362
3363 main.step( "Counters we added have the correct values" )
3364 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3365 utilities.assert_equals( expect=main.TRUE,
3366 actual=incrementCheck,
3367 onpass="Added counters are correct",
3368 onfail="Added counters are incorrect" )
3369
3370 main.step( "Add -8 to then get a in-memory counter on each node" )
3371 iCounters = []
3372 threads = []
3373 addedIValues = []
3374 for i in range( main.numCtrls ):
3375 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3376 name="counterIncrement-" + str( i ),
3377 args=[ iCounterName ],
3378 kwargs={ "delta": -8, "inMemory": True } )
3379 iCounterValue += -8
3380 addedIValues.append( iCounterValue )
3381 threads.append( t )
3382 t.start()
3383
3384 for t in threads:
3385 t.join()
3386 iCounters.append( t.result )
3387 # Check that counter incremented numController times
3388 iCounterResults = True
3389 for i in addedIValues:
3390 tmpResult = i in iCounters
3391 iCounterResults = iCounterResults and tmpResult
3392 if not tmpResult:
3393 main.log.error( str( i ) + " is not in in-memory "
3394 "counter incremented results" )
3395 utilities.assert_equals( expect=True,
3396 actual=pCounterResults,
3397 onpass="In-memory counter incremented",
3398 onfail="Error incrementing in-memory" +
3399 " counter" )
3400
3401 main.step( "Add 5 to then get a in-memory counter on each node" )
3402 iCounters = []
3403 threads = []
3404 addedIValues = []
3405 for i in range( main.numCtrls ):
3406 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3407 name="counterIncrement-" + str( i ),
3408 args=[ iCounterName ],
3409 kwargs={ "delta": 5, "inMemory": True } )
3410 iCounterValue += 5
3411 addedIValues.append( iCounterValue )
3412 threads.append( t )
3413 t.start()
3414
3415 for t in threads:
3416 t.join()
3417 iCounters.append( t.result )
3418 # Check that counter incremented numController times
3419 iCounterResults = True
3420 for i in addedIValues:
3421 tmpResult = i in iCounters
3422 iCounterResults = iCounterResults and tmpResult
3423 if not tmpResult:
3424 main.log.error( str( i ) + " is not in in-memory "
3425 "counter incremented results" )
3426 utilities.assert_equals( expect=True,
3427 actual=pCounterResults,
3428 onpass="In-memory counter incremented",
3429 onfail="Error incrementing in-memory" +
3430 " counter" )
3431
3432 main.step( "Get then add 5 to a in-memory counter on each node" )
3433 iCounters = []
3434 threads = []
3435 addedIValues = []
3436 for i in range( main.numCtrls ):
3437 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3438 name="counterIncrement-" + str( i ),
3439 args=[ iCounterName ],
3440 kwargs={ "delta": 5, "inMemory": True } )
3441 addedIValues.append( iCounterValue )
3442 iCounterValue += 5
3443 threads.append( t )
3444 t.start()
3445
3446 for t in threads:
3447 t.join()
3448 iCounters.append( t.result )
3449 # Check that counter incremented numController times
3450 iCounterResults = True
3451 for i in addedIValues:
3452 tmpResult = i in iCounters
3453 iCounterResults = iCounterResults and tmpResult
3454 if not tmpResult:
3455 main.log.error( str( i ) + " is not in in-memory "
3456 "counter incremented results" )
3457 utilities.assert_equals( expect=True,
3458 actual=iCounterResults,
3459 onpass="In-memory counter incremented",
3460 onfail="Error incrementing in-memory" +
3461 " counter" )
3462
3463 main.step( "Counters we added have the correct values" )
3464 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3465 utilities.assert_equals( expect=main.TRUE,
3466 actual=incrementCheck,
3467 onpass="Added counters are correct",
3468 onfail="Added counters are incorrect" )
3469
Jon Hall5cf14d52015-07-16 12:15:19 -07003470 main.step( "Check counters are consistant across nodes" )
Jon Hall57b50432015-10-22 10:20:10 -07003471 onosCounters, consistentCounterResults = main.Counters.consistentCheck()
Jon Hall5cf14d52015-07-16 12:15:19 -07003472 utilities.assert_equals( expect=main.TRUE,
3473 actual=consistentCounterResults,
3474 onpass="ONOS counters are consistent " +
3475 "across nodes",
3476 onfail="ONOS Counters are inconsistent " +
3477 "across nodes" )
3478
3479 main.step( "Counters we added have the correct values" )
Jon Halle1a3b752015-07-22 13:02:46 -07003480 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3481 incrementCheck = incrementCheck and \
3482 main.Counters.counterCheck( iCounterName, iCounterValue )
Jon Hall5cf14d52015-07-16 12:15:19 -07003483 utilities.assert_equals( expect=main.TRUE,
Jon Halle1a3b752015-07-22 13:02:46 -07003484 actual=incrementCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -07003485 onpass="Added counters are correct",
3486 onfail="Added counters are incorrect" )
3487 # DISTRIBUTED SETS
3488 main.step( "Distributed Set get" )
3489 size = len( onosSet )
3490 getResponses = []
3491 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003492 for i in range( main.numCtrls ):
3493 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003494 name="setTestGet-" + str( i ),
3495 args=[ onosSetName ] )
3496 threads.append( t )
3497 t.start()
3498 for t in threads:
3499 t.join()
3500 getResponses.append( t.result )
3501
3502 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003503 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003504 if isinstance( getResponses[ i ], list):
3505 current = set( getResponses[ i ] )
3506 if len( current ) == len( getResponses[ i ] ):
3507 # no repeats
3508 if onosSet != current:
3509 main.log.error( "ONOS" + str( i + 1 ) +
3510 " has incorrect view" +
3511 " of set " + onosSetName + ":\n" +
3512 str( getResponses[ i ] ) )
3513 main.log.debug( "Expected: " + str( onosSet ) )
3514 main.log.debug( "Actual: " + str( current ) )
3515 getResults = main.FALSE
3516 else:
3517 # error, set is not a set
3518 main.log.error( "ONOS" + str( i + 1 ) +
3519 " has repeat elements in" +
3520 " set " + onosSetName + ":\n" +
3521 str( getResponses[ i ] ) )
3522 getResults = main.FALSE
3523 elif getResponses[ i ] == main.ERROR:
3524 getResults = main.FALSE
3525 utilities.assert_equals( expect=main.TRUE,
3526 actual=getResults,
3527 onpass="Set elements are correct",
3528 onfail="Set elements are incorrect" )
3529
3530 main.step( "Distributed Set size" )
3531 sizeResponses = []
3532 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003533 for i in range( main.numCtrls ):
3534 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003535 name="setTestSize-" + str( i ),
3536 args=[ onosSetName ] )
3537 threads.append( t )
3538 t.start()
3539 for t in threads:
3540 t.join()
3541 sizeResponses.append( t.result )
3542
3543 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003544 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003545 if size != sizeResponses[ i ]:
3546 sizeResults = main.FALSE
3547 main.log.error( "ONOS" + str( i + 1 ) +
3548 " expected a size of " + str( size ) +
3549 " for set " + onosSetName +
3550 " but got " + str( sizeResponses[ i ] ) )
3551 utilities.assert_equals( expect=main.TRUE,
3552 actual=sizeResults,
3553 onpass="Set sizes are correct",
3554 onfail="Set sizes are incorrect" )
3555
3556 main.step( "Distributed Set add()" )
3557 onosSet.add( addValue )
3558 addResponses = []
3559 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003560 for i in range( main.numCtrls ):
3561 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003562 name="setTestAdd-" + str( i ),
3563 args=[ onosSetName, addValue ] )
3564 threads.append( t )
3565 t.start()
3566 for t in threads:
3567 t.join()
3568 addResponses.append( t.result )
3569
3570 # main.TRUE = successfully changed the set
3571 # main.FALSE = action resulted in no change in set
3572 # main.ERROR - Some error in executing the function
3573 addResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003574 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003575 if addResponses[ i ] == main.TRUE:
3576 # All is well
3577 pass
3578 elif addResponses[ i ] == main.FALSE:
3579 # Already in set, probably fine
3580 pass
3581 elif addResponses[ i ] == main.ERROR:
3582 # Error in execution
3583 addResults = main.FALSE
3584 else:
3585 # unexpected result
3586 addResults = main.FALSE
3587 if addResults != main.TRUE:
3588 main.log.error( "Error executing set add" )
3589
3590 # Check if set is still correct
3591 size = len( onosSet )
3592 getResponses = []
3593 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003594 for i in range( main.numCtrls ):
3595 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003596 name="setTestGet-" + str( i ),
3597 args=[ onosSetName ] )
3598 threads.append( t )
3599 t.start()
3600 for t in threads:
3601 t.join()
3602 getResponses.append( t.result )
3603 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003604 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003605 if isinstance( getResponses[ i ], list):
3606 current = set( getResponses[ i ] )
3607 if len( current ) == len( getResponses[ i ] ):
3608 # no repeats
3609 if onosSet != current:
3610 main.log.error( "ONOS" + str( i + 1 ) +
3611 " has incorrect view" +
3612 " of set " + onosSetName + ":\n" +
3613 str( getResponses[ i ] ) )
3614 main.log.debug( "Expected: " + str( onosSet ) )
3615 main.log.debug( "Actual: " + str( current ) )
3616 getResults = main.FALSE
3617 else:
3618 # error, set is not a set
3619 main.log.error( "ONOS" + str( i + 1 ) +
3620 " has repeat elements in" +
3621 " set " + onosSetName + ":\n" +
3622 str( getResponses[ i ] ) )
3623 getResults = main.FALSE
3624 elif getResponses[ i ] == main.ERROR:
3625 getResults = main.FALSE
3626 sizeResponses = []
3627 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003628 for i in range( main.numCtrls ):
3629 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003630 name="setTestSize-" + str( i ),
3631 args=[ onosSetName ] )
3632 threads.append( t )
3633 t.start()
3634 for t in threads:
3635 t.join()
3636 sizeResponses.append( t.result )
3637 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003638 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003639 if size != sizeResponses[ i ]:
3640 sizeResults = main.FALSE
3641 main.log.error( "ONOS" + str( i + 1 ) +
3642 " expected a size of " + str( size ) +
3643 " for set " + onosSetName +
3644 " but got " + str( sizeResponses[ i ] ) )
3645 addResults = addResults and getResults and sizeResults
3646 utilities.assert_equals( expect=main.TRUE,
3647 actual=addResults,
3648 onpass="Set add correct",
3649 onfail="Set add was incorrect" )
3650
3651 main.step( "Distributed Set addAll()" )
3652 onosSet.update( addAllValue.split() )
3653 addResponses = []
3654 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003655 for i in range( main.numCtrls ):
3656 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003657 name="setTestAddAll-" + str( i ),
3658 args=[ onosSetName, addAllValue ] )
3659 threads.append( t )
3660 t.start()
3661 for t in threads:
3662 t.join()
3663 addResponses.append( t.result )
3664
3665 # main.TRUE = successfully changed the set
3666 # main.FALSE = action resulted in no change in set
3667 # main.ERROR - Some error in executing the function
3668 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003669 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003670 if addResponses[ i ] == main.TRUE:
3671 # All is well
3672 pass
3673 elif addResponses[ i ] == main.FALSE:
3674 # Already in set, probably fine
3675 pass
3676 elif addResponses[ i ] == main.ERROR:
3677 # Error in execution
3678 addAllResults = main.FALSE
3679 else:
3680 # unexpected result
3681 addAllResults = main.FALSE
3682 if addAllResults != main.TRUE:
3683 main.log.error( "Error executing set addAll" )
3684
3685 # Check if set is still correct
3686 size = len( onosSet )
3687 getResponses = []
3688 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003689 for i in range( main.numCtrls ):
3690 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003691 name="setTestGet-" + str( i ),
3692 args=[ onosSetName ] )
3693 threads.append( t )
3694 t.start()
3695 for t in threads:
3696 t.join()
3697 getResponses.append( t.result )
3698 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003699 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003700 if isinstance( getResponses[ i ], list):
3701 current = set( getResponses[ i ] )
3702 if len( current ) == len( getResponses[ i ] ):
3703 # no repeats
3704 if onosSet != current:
3705 main.log.error( "ONOS" + str( i + 1 ) +
3706 " has incorrect view" +
3707 " of set " + onosSetName + ":\n" +
3708 str( getResponses[ i ] ) )
3709 main.log.debug( "Expected: " + str( onosSet ) )
3710 main.log.debug( "Actual: " + str( current ) )
3711 getResults = main.FALSE
3712 else:
3713 # error, set is not a set
3714 main.log.error( "ONOS" + str( i + 1 ) +
3715 " has repeat elements in" +
3716 " set " + onosSetName + ":\n" +
3717 str( getResponses[ i ] ) )
3718 getResults = main.FALSE
3719 elif getResponses[ i ] == main.ERROR:
3720 getResults = main.FALSE
3721 sizeResponses = []
3722 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003723 for i in range( main.numCtrls ):
3724 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003725 name="setTestSize-" + str( i ),
3726 args=[ onosSetName ] )
3727 threads.append( t )
3728 t.start()
3729 for t in threads:
3730 t.join()
3731 sizeResponses.append( t.result )
3732 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003733 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003734 if size != sizeResponses[ i ]:
3735 sizeResults = main.FALSE
3736 main.log.error( "ONOS" + str( i + 1 ) +
3737 " expected a size of " + str( size ) +
3738 " for set " + onosSetName +
3739 " but got " + str( sizeResponses[ i ] ) )
3740 addAllResults = addAllResults and getResults and sizeResults
3741 utilities.assert_equals( expect=main.TRUE,
3742 actual=addAllResults,
3743 onpass="Set addAll correct",
3744 onfail="Set addAll was incorrect" )
3745
3746 main.step( "Distributed Set contains()" )
3747 containsResponses = []
3748 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003749 for i in range( main.numCtrls ):
3750 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003751 name="setContains-" + str( i ),
3752 args=[ onosSetName ],
3753 kwargs={ "values": addValue } )
3754 threads.append( t )
3755 t.start()
3756 for t in threads:
3757 t.join()
3758 # NOTE: This is the tuple
3759 containsResponses.append( t.result )
3760
3761 containsResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003762 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003763 if containsResponses[ i ] == main.ERROR:
3764 containsResults = main.FALSE
3765 else:
3766 containsResults = containsResults and\
3767 containsResponses[ i ][ 1 ]
3768 utilities.assert_equals( expect=main.TRUE,
3769 actual=containsResults,
3770 onpass="Set contains is functional",
3771 onfail="Set contains failed" )
3772
3773 main.step( "Distributed Set containsAll()" )
3774 containsAllResponses = []
3775 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003776 for i in range( main.numCtrls ):
3777 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003778 name="setContainsAll-" + str( i ),
3779 args=[ onosSetName ],
3780 kwargs={ "values": addAllValue } )
3781 threads.append( t )
3782 t.start()
3783 for t in threads:
3784 t.join()
3785 # NOTE: This is the tuple
3786 containsAllResponses.append( t.result )
3787
3788 containsAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003789 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003790 if containsResponses[ i ] == main.ERROR:
3791 containsResults = main.FALSE
3792 else:
3793 containsResults = containsResults and\
3794 containsResponses[ i ][ 1 ]
3795 utilities.assert_equals( expect=main.TRUE,
3796 actual=containsAllResults,
3797 onpass="Set containsAll is functional",
3798 onfail="Set containsAll failed" )
3799
3800 main.step( "Distributed Set remove()" )
3801 onosSet.remove( addValue )
3802 removeResponses = []
3803 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003804 for i in range( main.numCtrls ):
3805 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003806 name="setTestRemove-" + str( i ),
3807 args=[ onosSetName, addValue ] )
3808 threads.append( t )
3809 t.start()
3810 for t in threads:
3811 t.join()
3812 removeResponses.append( t.result )
3813
3814 # main.TRUE = successfully changed the set
3815 # main.FALSE = action resulted in no change in set
3816 # main.ERROR - Some error in executing the function
3817 removeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003818 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003819 if removeResponses[ i ] == main.TRUE:
3820 # All is well
3821 pass
3822 elif removeResponses[ i ] == main.FALSE:
3823 # not in set, probably fine
3824 pass
3825 elif removeResponses[ i ] == main.ERROR:
3826 # Error in execution
3827 removeResults = main.FALSE
3828 else:
3829 # unexpected result
3830 removeResults = main.FALSE
3831 if removeResults != main.TRUE:
3832 main.log.error( "Error executing set remove" )
3833
3834 # Check if set is still correct
3835 size = len( onosSet )
3836 getResponses = []
3837 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003838 for i in range( main.numCtrls ):
3839 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003840 name="setTestGet-" + str( i ),
3841 args=[ onosSetName ] )
3842 threads.append( t )
3843 t.start()
3844 for t in threads:
3845 t.join()
3846 getResponses.append( t.result )
3847 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003848 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003849 if isinstance( getResponses[ i ], list):
3850 current = set( getResponses[ i ] )
3851 if len( current ) == len( getResponses[ i ] ):
3852 # no repeats
3853 if onosSet != current:
3854 main.log.error( "ONOS" + str( i + 1 ) +
3855 " has incorrect view" +
3856 " of set " + onosSetName + ":\n" +
3857 str( getResponses[ i ] ) )
3858 main.log.debug( "Expected: " + str( onosSet ) )
3859 main.log.debug( "Actual: " + str( current ) )
3860 getResults = main.FALSE
3861 else:
3862 # error, set is not a set
3863 main.log.error( "ONOS" + str( i + 1 ) +
3864 " has repeat elements in" +
3865 " set " + onosSetName + ":\n" +
3866 str( getResponses[ i ] ) )
3867 getResults = main.FALSE
3868 elif getResponses[ i ] == main.ERROR:
3869 getResults = main.FALSE
3870 sizeResponses = []
3871 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003872 for i in range( main.numCtrls ):
3873 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003874 name="setTestSize-" + str( i ),
3875 args=[ onosSetName ] )
3876 threads.append( t )
3877 t.start()
3878 for t in threads:
3879 t.join()
3880 sizeResponses.append( t.result )
3881 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003882 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003883 if size != sizeResponses[ i ]:
3884 sizeResults = main.FALSE
3885 main.log.error( "ONOS" + str( i + 1 ) +
3886 " expected a size of " + str( size ) +
3887 " for set " + onosSetName +
3888 " but got " + str( sizeResponses[ i ] ) )
3889 removeResults = removeResults and getResults and sizeResults
3890 utilities.assert_equals( expect=main.TRUE,
3891 actual=removeResults,
3892 onpass="Set remove correct",
3893 onfail="Set remove was incorrect" )
3894
3895 main.step( "Distributed Set removeAll()" )
3896 onosSet.difference_update( addAllValue.split() )
3897 removeAllResponses = []
3898 threads = []
3899 try:
Jon Halle1a3b752015-07-22 13:02:46 -07003900 for i in range( main.numCtrls ):
3901 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003902 name="setTestRemoveAll-" + str( i ),
3903 args=[ onosSetName, addAllValue ] )
3904 threads.append( t )
3905 t.start()
3906 for t in threads:
3907 t.join()
3908 removeAllResponses.append( t.result )
3909 except Exception, e:
3910 main.log.exception(e)
3911
3912 # main.TRUE = successfully changed the set
3913 # main.FALSE = action resulted in no change in set
3914 # main.ERROR - Some error in executing the function
3915 removeAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003916 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003917 if removeAllResponses[ i ] == main.TRUE:
3918 # All is well
3919 pass
3920 elif removeAllResponses[ i ] == main.FALSE:
3921 # not in set, probably fine
3922 pass
3923 elif removeAllResponses[ i ] == main.ERROR:
3924 # Error in execution
3925 removeAllResults = main.FALSE
3926 else:
3927 # unexpected result
3928 removeAllResults = main.FALSE
3929 if removeAllResults != main.TRUE:
3930 main.log.error( "Error executing set removeAll" )
3931
3932 # Check if set is still correct
3933 size = len( onosSet )
3934 getResponses = []
3935 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003936 for i in range( main.numCtrls ):
3937 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003938 name="setTestGet-" + str( i ),
3939 args=[ onosSetName ] )
3940 threads.append( t )
3941 t.start()
3942 for t in threads:
3943 t.join()
3944 getResponses.append( t.result )
3945 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003946 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003947 if isinstance( getResponses[ i ], list):
3948 current = set( getResponses[ i ] )
3949 if len( current ) == len( getResponses[ i ] ):
3950 # no repeats
3951 if onosSet != current:
3952 main.log.error( "ONOS" + str( i + 1 ) +
3953 " has incorrect view" +
3954 " of set " + onosSetName + ":\n" +
3955 str( getResponses[ i ] ) )
3956 main.log.debug( "Expected: " + str( onosSet ) )
3957 main.log.debug( "Actual: " + str( current ) )
3958 getResults = main.FALSE
3959 else:
3960 # error, set is not a set
3961 main.log.error( "ONOS" + str( i + 1 ) +
3962 " has repeat elements in" +
3963 " set " + onosSetName + ":\n" +
3964 str( getResponses[ i ] ) )
3965 getResults = main.FALSE
3966 elif getResponses[ i ] == main.ERROR:
3967 getResults = main.FALSE
3968 sizeResponses = []
3969 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003970 for i in range( main.numCtrls ):
3971 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003972 name="setTestSize-" + str( i ),
3973 args=[ onosSetName ] )
3974 threads.append( t )
3975 t.start()
3976 for t in threads:
3977 t.join()
3978 sizeResponses.append( t.result )
3979 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003980 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003981 if size != sizeResponses[ i ]:
3982 sizeResults = main.FALSE
3983 main.log.error( "ONOS" + str( i + 1 ) +
3984 " expected a size of " + str( size ) +
3985 " for set " + onosSetName +
3986 " but got " + str( sizeResponses[ i ] ) )
3987 removeAllResults = removeAllResults and getResults and sizeResults
3988 utilities.assert_equals( expect=main.TRUE,
3989 actual=removeAllResults,
3990 onpass="Set removeAll correct",
3991 onfail="Set removeAll was incorrect" )
3992
3993 main.step( "Distributed Set addAll()" )
3994 onosSet.update( addAllValue.split() )
3995 addResponses = []
3996 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003997 for i in range( main.numCtrls ):
3998 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003999 name="setTestAddAll-" + str( i ),
4000 args=[ onosSetName, addAllValue ] )
4001 threads.append( t )
4002 t.start()
4003 for t in threads:
4004 t.join()
4005 addResponses.append( t.result )
4006
4007 # main.TRUE = successfully changed the set
4008 # main.FALSE = action resulted in no change in set
4009 # main.ERROR - Some error in executing the function
4010 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004011 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004012 if addResponses[ i ] == main.TRUE:
4013 # All is well
4014 pass
4015 elif addResponses[ i ] == main.FALSE:
4016 # Already in set, probably fine
4017 pass
4018 elif addResponses[ i ] == main.ERROR:
4019 # Error in execution
4020 addAllResults = main.FALSE
4021 else:
4022 # unexpected result
4023 addAllResults = main.FALSE
4024 if addAllResults != main.TRUE:
4025 main.log.error( "Error executing set addAll" )
4026
4027 # Check if set is still correct
4028 size = len( onosSet )
4029 getResponses = []
4030 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004031 for i in range( main.numCtrls ):
4032 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004033 name="setTestGet-" + str( i ),
4034 args=[ onosSetName ] )
4035 threads.append( t )
4036 t.start()
4037 for t in threads:
4038 t.join()
4039 getResponses.append( t.result )
4040 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004041 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004042 if isinstance( getResponses[ i ], list):
4043 current = set( getResponses[ i ] )
4044 if len( current ) == len( getResponses[ i ] ):
4045 # no repeats
4046 if onosSet != current:
4047 main.log.error( "ONOS" + str( i + 1 ) +
4048 " has incorrect view" +
4049 " of set " + onosSetName + ":\n" +
4050 str( getResponses[ i ] ) )
4051 main.log.debug( "Expected: " + str( onosSet ) )
4052 main.log.debug( "Actual: " + str( current ) )
4053 getResults = main.FALSE
4054 else:
4055 # error, set is not a set
4056 main.log.error( "ONOS" + str( i + 1 ) +
4057 " has repeat elements in" +
4058 " set " + onosSetName + ":\n" +
4059 str( getResponses[ i ] ) )
4060 getResults = main.FALSE
4061 elif getResponses[ i ] == main.ERROR:
4062 getResults = main.FALSE
4063 sizeResponses = []
4064 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004065 for i in range( main.numCtrls ):
4066 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004067 name="setTestSize-" + str( i ),
4068 args=[ onosSetName ] )
4069 threads.append( t )
4070 t.start()
4071 for t in threads:
4072 t.join()
4073 sizeResponses.append( t.result )
4074 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004075 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004076 if size != sizeResponses[ i ]:
4077 sizeResults = main.FALSE
4078 main.log.error( "ONOS" + str( i + 1 ) +
4079 " expected a size of " + str( size ) +
4080 " for set " + onosSetName +
4081 " but got " + str( sizeResponses[ i ] ) )
4082 addAllResults = addAllResults and getResults and sizeResults
4083 utilities.assert_equals( expect=main.TRUE,
4084 actual=addAllResults,
4085 onpass="Set addAll correct",
4086 onfail="Set addAll was incorrect" )
4087
4088 main.step( "Distributed Set clear()" )
4089 onosSet.clear()
4090 clearResponses = []
4091 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004092 for i in range( main.numCtrls ):
4093 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004094 name="setTestClear-" + str( i ),
4095 args=[ onosSetName, " "], # Values doesn't matter
4096 kwargs={ "clear": True } )
4097 threads.append( t )
4098 t.start()
4099 for t in threads:
4100 t.join()
4101 clearResponses.append( t.result )
4102
4103 # main.TRUE = successfully changed the set
4104 # main.FALSE = action resulted in no change in set
4105 # main.ERROR - Some error in executing the function
4106 clearResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004107 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004108 if clearResponses[ i ] == main.TRUE:
4109 # All is well
4110 pass
4111 elif clearResponses[ i ] == main.FALSE:
4112 # Nothing set, probably fine
4113 pass
4114 elif clearResponses[ i ] == main.ERROR:
4115 # Error in execution
4116 clearResults = main.FALSE
4117 else:
4118 # unexpected result
4119 clearResults = main.FALSE
4120 if clearResults != main.TRUE:
4121 main.log.error( "Error executing set clear" )
4122
4123 # Check if set is still correct
4124 size = len( onosSet )
4125 getResponses = []
4126 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004127 for i in range( main.numCtrls ):
4128 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004129 name="setTestGet-" + str( i ),
4130 args=[ onosSetName ] )
4131 threads.append( t )
4132 t.start()
4133 for t in threads:
4134 t.join()
4135 getResponses.append( t.result )
4136 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004137 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004138 if isinstance( getResponses[ i ], list):
4139 current = set( getResponses[ i ] )
4140 if len( current ) == len( getResponses[ i ] ):
4141 # no repeats
4142 if onosSet != current:
4143 main.log.error( "ONOS" + str( i + 1 ) +
4144 " has incorrect view" +
4145 " of set " + onosSetName + ":\n" +
4146 str( getResponses[ i ] ) )
4147 main.log.debug( "Expected: " + str( onosSet ) )
4148 main.log.debug( "Actual: " + str( current ) )
4149 getResults = main.FALSE
4150 else:
4151 # error, set is not a set
4152 main.log.error( "ONOS" + str( i + 1 ) +
4153 " has repeat elements in" +
4154 " set " + onosSetName + ":\n" +
4155 str( getResponses[ i ] ) )
4156 getResults = main.FALSE
4157 elif getResponses[ i ] == main.ERROR:
4158 getResults = main.FALSE
4159 sizeResponses = []
4160 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004161 for i in range( main.numCtrls ):
4162 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004163 name="setTestSize-" + str( i ),
4164 args=[ onosSetName ] )
4165 threads.append( t )
4166 t.start()
4167 for t in threads:
4168 t.join()
4169 sizeResponses.append( t.result )
4170 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004171 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004172 if size != sizeResponses[ i ]:
4173 sizeResults = main.FALSE
4174 main.log.error( "ONOS" + str( i + 1 ) +
4175 " expected a size of " + str( size ) +
4176 " for set " + onosSetName +
4177 " but got " + str( sizeResponses[ i ] ) )
4178 clearResults = clearResults and getResults and sizeResults
4179 utilities.assert_equals( expect=main.TRUE,
4180 actual=clearResults,
4181 onpass="Set clear correct",
4182 onfail="Set clear was incorrect" )
4183
4184 main.step( "Distributed Set addAll()" )
4185 onosSet.update( addAllValue.split() )
4186 addResponses = []
4187 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004188 for i in range( main.numCtrls ):
4189 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004190 name="setTestAddAll-" + str( i ),
4191 args=[ onosSetName, addAllValue ] )
4192 threads.append( t )
4193 t.start()
4194 for t in threads:
4195 t.join()
4196 addResponses.append( t.result )
4197
4198 # main.TRUE = successfully changed the set
4199 # main.FALSE = action resulted in no change in set
4200 # main.ERROR - Some error in executing the function
4201 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004202 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004203 if addResponses[ i ] == main.TRUE:
4204 # All is well
4205 pass
4206 elif addResponses[ i ] == main.FALSE:
4207 # Already in set, probably fine
4208 pass
4209 elif addResponses[ i ] == main.ERROR:
4210 # Error in execution
4211 addAllResults = main.FALSE
4212 else:
4213 # unexpected result
4214 addAllResults = main.FALSE
4215 if addAllResults != main.TRUE:
4216 main.log.error( "Error executing set addAll" )
4217
4218 # Check if set is still correct
4219 size = len( onosSet )
4220 getResponses = []
4221 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004222 for i in range( main.numCtrls ):
4223 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004224 name="setTestGet-" + str( i ),
4225 args=[ onosSetName ] )
4226 threads.append( t )
4227 t.start()
4228 for t in threads:
4229 t.join()
4230 getResponses.append( t.result )
4231 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004232 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004233 if isinstance( getResponses[ i ], list):
4234 current = set( getResponses[ i ] )
4235 if len( current ) == len( getResponses[ i ] ):
4236 # no repeats
4237 if onosSet != current:
4238 main.log.error( "ONOS" + str( i + 1 ) +
4239 " has incorrect view" +
4240 " of set " + onosSetName + ":\n" +
4241 str( getResponses[ i ] ) )
4242 main.log.debug( "Expected: " + str( onosSet ) )
4243 main.log.debug( "Actual: " + str( current ) )
4244 getResults = main.FALSE
4245 else:
4246 # error, set is not a set
4247 main.log.error( "ONOS" + str( i + 1 ) +
4248 " has repeat elements in" +
4249 " set " + onosSetName + ":\n" +
4250 str( getResponses[ i ] ) )
4251 getResults = main.FALSE
4252 elif getResponses[ i ] == main.ERROR:
4253 getResults = main.FALSE
4254 sizeResponses = []
4255 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004256 for i in range( main.numCtrls ):
4257 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004258 name="setTestSize-" + str( i ),
4259 args=[ onosSetName ] )
4260 threads.append( t )
4261 t.start()
4262 for t in threads:
4263 t.join()
4264 sizeResponses.append( t.result )
4265 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004266 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004267 if size != sizeResponses[ i ]:
4268 sizeResults = main.FALSE
4269 main.log.error( "ONOS" + str( i + 1 ) +
4270 " expected a size of " + str( size ) +
4271 " for set " + onosSetName +
4272 " but got " + str( sizeResponses[ i ] ) )
4273 addAllResults = addAllResults and getResults and sizeResults
4274 utilities.assert_equals( expect=main.TRUE,
4275 actual=addAllResults,
4276 onpass="Set addAll correct",
4277 onfail="Set addAll was incorrect" )
4278
4279 main.step( "Distributed Set retain()" )
4280 onosSet.intersection_update( retainValue.split() )
4281 retainResponses = []
4282 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004283 for i in range( main.numCtrls ):
4284 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004285 name="setTestRetain-" + str( i ),
4286 args=[ onosSetName, retainValue ],
4287 kwargs={ "retain": True } )
4288 threads.append( t )
4289 t.start()
4290 for t in threads:
4291 t.join()
4292 retainResponses.append( t.result )
4293
4294 # main.TRUE = successfully changed the set
4295 # main.FALSE = action resulted in no change in set
4296 # main.ERROR - Some error in executing the function
4297 retainResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004298 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004299 if retainResponses[ i ] == main.TRUE:
4300 # All is well
4301 pass
4302 elif retainResponses[ i ] == main.FALSE:
4303 # Already in set, probably fine
4304 pass
4305 elif retainResponses[ i ] == main.ERROR:
4306 # Error in execution
4307 retainResults = main.FALSE
4308 else:
4309 # unexpected result
4310 retainResults = main.FALSE
4311 if retainResults != main.TRUE:
4312 main.log.error( "Error executing set retain" )
4313
4314 # Check if set is still correct
4315 size = len( onosSet )
4316 getResponses = []
4317 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004318 for i in range( main.numCtrls ):
4319 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004320 name="setTestGet-" + str( i ),
4321 args=[ onosSetName ] )
4322 threads.append( t )
4323 t.start()
4324 for t in threads:
4325 t.join()
4326 getResponses.append( t.result )
4327 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004328 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004329 if isinstance( getResponses[ i ], list):
4330 current = set( getResponses[ i ] )
4331 if len( current ) == len( getResponses[ i ] ):
4332 # no repeats
4333 if onosSet != current:
4334 main.log.error( "ONOS" + str( i + 1 ) +
4335 " has incorrect view" +
4336 " of set " + onosSetName + ":\n" +
4337 str( getResponses[ i ] ) )
4338 main.log.debug( "Expected: " + str( onosSet ) )
4339 main.log.debug( "Actual: " + str( current ) )
4340 getResults = main.FALSE
4341 else:
4342 # error, set is not a set
4343 main.log.error( "ONOS" + str( i + 1 ) +
4344 " has repeat elements in" +
4345 " set " + onosSetName + ":\n" +
4346 str( getResponses[ i ] ) )
4347 getResults = main.FALSE
4348 elif getResponses[ i ] == main.ERROR:
4349 getResults = main.FALSE
4350 sizeResponses = []
4351 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004352 for i in range( main.numCtrls ):
4353 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004354 name="setTestSize-" + str( i ),
4355 args=[ onosSetName ] )
4356 threads.append( t )
4357 t.start()
4358 for t in threads:
4359 t.join()
4360 sizeResponses.append( t.result )
4361 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004362 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004363 if size != sizeResponses[ i ]:
4364 sizeResults = main.FALSE
4365 main.log.error( "ONOS" + str( i + 1 ) +
4366 " expected a size of " +
4367 str( size ) + " for set " + onosSetName +
4368 " but got " + str( sizeResponses[ i ] ) )
4369 retainResults = retainResults and getResults and sizeResults
4370 utilities.assert_equals( expect=main.TRUE,
4371 actual=retainResults,
4372 onpass="Set retain correct",
4373 onfail="Set retain was incorrect" )
4374
Jon Hall2a5002c2015-08-21 16:49:11 -07004375 # Transactional maps
4376 main.step( "Partitioned Transactional maps put" )
4377 tMapValue = "Testing"
4378 numKeys = 100
4379 putResult = True
4380 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue )
4381 if len( putResponses ) == 100:
4382 for i in putResponses:
4383 if putResponses[ i ][ 'value' ] != tMapValue:
4384 putResult = False
4385 else:
4386 putResult = False
4387 if not putResult:
4388 main.log.debug( "Put response values: " + str( putResponses ) )
4389 utilities.assert_equals( expect=True,
4390 actual=putResult,
4391 onpass="Partitioned Transactional Map put successful",
4392 onfail="Partitioned Transactional Map put values are incorrect" )
4393
4394 main.step( "Partitioned Transactional maps get" )
4395 getCheck = True
4396 for n in range( 1, numKeys + 1 ):
4397 getResponses = []
4398 threads = []
4399 valueCheck = True
4400 for i in range( main.numCtrls ):
4401 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4402 name="TMap-get-" + str( i ),
4403 args=[ "Key" + str ( n ) ] )
4404 threads.append( t )
4405 t.start()
4406 for t in threads:
4407 t.join()
4408 getResponses.append( t.result )
4409 for node in getResponses:
4410 if node != tMapValue:
4411 valueCheck = False
4412 if not valueCheck:
4413 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4414 main.log.warn( getResponses )
4415 getCheck = getCheck and valueCheck
4416 utilities.assert_equals( expect=True,
4417 actual=getCheck,
4418 onpass="Partitioned Transactional Map get values were correct",
4419 onfail="Partitioned Transactional Map values incorrect" )
4420
4421 main.step( "In-memory Transactional maps put" )
4422 tMapValue = "Testing"
4423 numKeys = 100
4424 putResult = True
4425 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue, inMemory=True )
4426 if len( putResponses ) == 100:
4427 for i in putResponses:
4428 if putResponses[ i ][ 'value' ] != tMapValue:
4429 putResult = False
4430 else:
4431 putResult = False
4432 if not putResult:
4433 main.log.debug( "Put response values: " + str( putResponses ) )
4434 utilities.assert_equals( expect=True,
4435 actual=putResult,
4436 onpass="In-Memory Transactional Map put successful",
4437 onfail="In-Memory Transactional Map put values are incorrect" )
4438
4439 main.step( "In-Memory Transactional maps get" )
4440 getCheck = True
4441 for n in range( 1, numKeys + 1 ):
4442 getResponses = []
4443 threads = []
4444 valueCheck = True
4445 for i in range( main.numCtrls ):
4446 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4447 name="TMap-get-" + str( i ),
4448 args=[ "Key" + str ( n ) ],
4449 kwargs={ "inMemory": True } )
4450 threads.append( t )
4451 t.start()
4452 for t in threads:
4453 t.join()
4454 getResponses.append( t.result )
4455 for node in getResponses:
4456 if node != tMapValue:
4457 valueCheck = False
4458 if not valueCheck:
4459 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4460 main.log.warn( getResponses )
4461 getCheck = getCheck and valueCheck
4462 utilities.assert_equals( expect=True,
4463 actual=getCheck,
4464 onpass="In-Memory Transactional Map get values were correct",
4465 onfail="In-Memory Transactional Map values incorrect" )