blob: 58b113c272fa17c94f9b67e14fcf09e721f9f270 [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 Hallf3d16e72015-12-16 17:45:08 -080051 import time
Jon Hall5cf14d52015-07-16 12:15:19 -070052 main.log.info( "ONOS HA test: Restart all ONOS nodes - " +
53 "initialization" )
54 main.case( "Setting up test environment" )
Jon Hall783bbf92015-07-23 14:33:19 -070055 main.caseExplanation = "Setup the test environment including " +\
Jon Hall5cf14d52015-07-16 12:15:19 -070056 "installing ONOS, starting Mininet and ONOS" +\
57 "cli sessions."
58 # TODO: save all the timers and output them for plotting
59
60 # load some variables from the params file
61 PULLCODE = False
62 if main.params[ 'Git' ] == 'True':
63 PULLCODE = True
64 gitBranch = main.params[ 'branch' ]
65 cellName = main.params[ 'ENV' ][ 'cellName' ]
66
Jon Halle1a3b752015-07-22 13:02:46 -070067 main.numCtrls = int( main.params[ 'num_controllers' ] )
Jon Hall5cf14d52015-07-16 12:15:19 -070068 if main.ONOSbench.maxNodes:
Jon Halle1a3b752015-07-22 13:02:46 -070069 if main.ONOSbench.maxNodes < main.numCtrls:
70 main.numCtrls = int( main.ONOSbench.maxNodes )
71 # set global variables
Jon Hall5cf14d52015-07-16 12:15:19 -070072 global ONOS1Port
73 global ONOS2Port
74 global ONOS3Port
75 global ONOS4Port
76 global ONOS5Port
77 global ONOS6Port
78 global ONOS7Port
79 # These are for csv plotting in jenkins
80 global labels
81 global data
82 labels = []
83 data = []
84
85 # FIXME: just get controller port from params?
86 # TODO: do we really need all these?
87 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
88 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
89 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
90 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
91 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
92 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
93 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
94
Jon Halle1a3b752015-07-22 13:02:46 -070095 try:
96 fileName = "Counters"
97 path = main.params[ 'imports' ][ 'path' ]
98 main.Counters = imp.load_source( fileName,
99 path + fileName + ".py" )
100 except Exception as e:
101 main.log.exception( e )
102 main.cleanup()
103 main.exit()
104
105 main.CLIs = []
106 main.nodes = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700107 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700108 for i in range( 1, main.numCtrls + 1 ):
109 try:
110 main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
111 main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
112 ipList.append( main.nodes[ -1 ].ip_address )
113 except AttributeError:
114 break
Jon Hall5cf14d52015-07-16 12:15:19 -0700115
116 main.step( "Create cell file" )
117 cellAppString = main.params[ 'ENV' ][ 'appString' ]
118 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
119 main.Mininet1.ip_address,
120 cellAppString, ipList )
121 main.step( "Applying cell variable to environment" )
122 cellResult = main.ONOSbench.setCell( cellName )
123 verifyResult = main.ONOSbench.verifyCell()
124
125 # FIXME:this is short term fix
126 main.log.info( "Removing raft logs" )
127 main.ONOSbench.onosRemoveRaftLogs()
128
129 main.log.info( "Uninstalling ONOS" )
Jon Halle1a3b752015-07-22 13:02:46 -0700130 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700131 main.ONOSbench.onosUninstall( node.ip_address )
132
133 # Make sure ONOS is DEAD
134 main.log.info( "Killing any ONOS processes" )
135 killResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700136 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700137 killed = main.ONOSbench.onosKill( node.ip_address )
138 killResults = killResults and killed
139
140 cleanInstallResult = main.TRUE
141 gitPullResult = main.TRUE
142
143 main.step( "Starting Mininet" )
144 # scp topo file to mininet
145 # TODO: move to params?
146 topoName = "obelisk.py"
147 filePath = main.ONOSbench.home + "/tools/test/topos/"
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700148 main.ONOSbench.scp( main.Mininet1,
149 filePath + topoName,
150 main.Mininet1.home,
151 direction="to" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700152 mnResult = main.Mininet1.startNet( )
153 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
154 onpass="Mininet Started",
155 onfail="Error starting Mininet" )
156
157 main.step( "Git checkout and pull " + gitBranch )
158 if PULLCODE:
159 main.ONOSbench.gitCheckout( gitBranch )
160 gitPullResult = main.ONOSbench.gitPull()
161 # values of 1 or 3 are good
162 utilities.assert_lesser( expect=0, actual=gitPullResult,
163 onpass="Git pull successful",
164 onfail="Git pull failed" )
165 main.ONOSbench.getVersion( report=True )
166
167 main.step( "Using mvn clean install" )
168 cleanInstallResult = main.TRUE
169 if PULLCODE and gitPullResult == main.TRUE:
170 cleanInstallResult = main.ONOSbench.cleanInstall()
171 else:
172 main.log.warn( "Did not pull new code so skipping mvn " +
173 "clean install" )
174 utilities.assert_equals( expect=main.TRUE,
175 actual=cleanInstallResult,
176 onpass="MCI successful",
177 onfail="MCI failed" )
178 # GRAPHS
179 # NOTE: important params here:
180 # job = name of Jenkins job
181 # Plot Name = Plot-HA, only can be used if multiple plots
182 # index = The number of the graph under plot name
183 job = "HAclusterRestart"
184 plotName = "Plot-HA"
Jon Hallff566d52016-01-15 14:45:36 -0800185 index = "1"
Jon Hall5cf14d52015-07-16 12:15:19 -0700186 graphs = '<ac:structured-macro ac:name="html">\n'
187 graphs += '<ac:plain-text-body><![CDATA[\n'
188 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
Jon Halla9845df2016-01-15 14:55:58 -0800189 '/plot/' + plotName + '/getPlot?index=' + index +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700190 '&width=500&height=300"' +\
191 'noborder="0" width="500" height="300" scrolling="yes" ' +\
192 'seamless="seamless"></iframe>\n'
193 graphs += ']]></ac:plain-text-body>\n'
194 graphs += '</ac:structured-macro>\n'
195 main.log.wiki(graphs)
196
197 main.step( "Creating ONOS package" )
198 packageResult = main.ONOSbench.onosPackage()
199 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
200 onpass="ONOS package successful",
201 onfail="ONOS package failed" )
202
203 main.step( "Installing ONOS package" )
204 onosInstallResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700205 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700206 tmpResult = main.ONOSbench.onosInstall( options="-f",
207 node=node.ip_address )
208 onosInstallResult = onosInstallResult and tmpResult
209 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
210 onpass="ONOS install successful",
211 onfail="ONOS install failed" )
212
213 main.step( "Checking if ONOS is up yet" )
214 for i in range( 2 ):
215 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700216 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700217 started = main.ONOSbench.isup( node.ip_address )
218 if not started:
219 main.log.error( node.name + " didn't start!" )
220 main.ONOSbench.onosStop( node.ip_address )
221 main.ONOSbench.onosStart( node.ip_address )
222 onosIsupResult = onosIsupResult and started
223 if onosIsupResult == main.TRUE:
224 break
225 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
226 onpass="ONOS startup successful",
227 onfail="ONOS startup failed" )
228
229 main.log.step( "Starting ONOS CLI sessions" )
230 cliResults = main.TRUE
231 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700232 for i in range( main.numCtrls ):
233 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -0700234 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -0700235 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -0700236 threads.append( t )
237 t.start()
238
239 for t in threads:
240 t.join()
241 cliResults = cliResults and t.result
242 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
243 onpass="ONOS cli startup successful",
244 onfail="ONOS cli startup failed" )
245
246 if main.params[ 'tcpdump' ].lower() == "true":
247 main.step( "Start Packet Capture MN" )
248 main.Mininet2.startTcpdump(
249 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
250 + "-MN.pcap",
251 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
252 port=main.params[ 'MNtcpdump' ][ 'port' ] )
253
254 main.step( "App Ids check" )
Jon Hallf3d16e72015-12-16 17:45:08 -0800255 time.sleep(60)
Jon Hall5cf14d52015-07-16 12:15:19 -0700256 appCheck = main.TRUE
257 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700258 for i in range( main.numCtrls ):
259 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700260 name="appToIDCheck-" + str( i ),
261 args=[] )
262 threads.append( t )
263 t.start()
264
265 for t in threads:
266 t.join()
267 appCheck = appCheck and t.result
268 if appCheck != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700269 main.log.warn( main.CLIs[0].apps() )
270 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700271 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
272 onpass="App Ids seem to be correct",
273 onfail="Something is wrong with app Ids" )
274
275 if cliResults == main.FALSE:
276 main.log.error( "Failed to start ONOS, stopping test" )
277 main.cleanup()
278 main.exit()
279
280 def CASE2( self, main ):
281 """
282 Assign devices to controllers
283 """
284 import re
Jon Halle1a3b752015-07-22 13:02:46 -0700285 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700286 assert main, "main not defined"
287 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700288 assert main.CLIs, "main.CLIs not defined"
289 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700290 assert ONOS1Port, "ONOS1Port not defined"
291 assert ONOS2Port, "ONOS2Port not defined"
292 assert ONOS3Port, "ONOS3Port not defined"
293 assert ONOS4Port, "ONOS4Port not defined"
294 assert ONOS5Port, "ONOS5Port not defined"
295 assert ONOS6Port, "ONOS6Port not defined"
296 assert ONOS7Port, "ONOS7Port not defined"
297
298 main.case( "Assigning devices to controllers" )
Jon Hall783bbf92015-07-23 14:33:19 -0700299 main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700300 "and check that an ONOS node becomes the " +\
301 "master of the device."
302 main.step( "Assign switches to controllers" )
303
304 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700305 for i in range( main.numCtrls ):
306 ipList.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -0700307 swList = []
308 for i in range( 1, 29 ):
309 swList.append( "s" + str( i ) )
310 main.Mininet1.assignSwController( sw=swList, ip=ipList )
311
312 mastershipCheck = main.TRUE
313 for i in range( 1, 29 ):
314 response = main.Mininet1.getSwController( "s" + str( i ) )
315 try:
316 main.log.info( str( response ) )
317 except Exception:
318 main.log.info( repr( response ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700319 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700320 if re.search( "tcp:" + node.ip_address, response ):
321 mastershipCheck = mastershipCheck and main.TRUE
322 else:
323 main.log.error( "Error, node " + node.ip_address + " is " +
324 "not in the list of controllers s" +
325 str( i ) + " is connecting to." )
326 mastershipCheck = main.FALSE
327 utilities.assert_equals(
328 expect=main.TRUE,
329 actual=mastershipCheck,
330 onpass="Switch mastership assigned correctly",
331 onfail="Switches not assigned correctly to controllers" )
332
333 def CASE21( self, main ):
334 """
335 Assign mastership to controllers
336 """
Jon Hall5cf14d52015-07-16 12:15:19 -0700337 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700338 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700339 assert main, "main not defined"
340 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700341 assert main.CLIs, "main.CLIs not defined"
342 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700343 assert ONOS1Port, "ONOS1Port not defined"
344 assert ONOS2Port, "ONOS2Port not defined"
345 assert ONOS3Port, "ONOS3Port not defined"
346 assert ONOS4Port, "ONOS4Port not defined"
347 assert ONOS5Port, "ONOS5Port not defined"
348 assert ONOS6Port, "ONOS6Port not defined"
349 assert ONOS7Port, "ONOS7Port not defined"
350
351 main.case( "Assigning Controller roles for switches" )
Jon Hall783bbf92015-07-23 14:33:19 -0700352 main.caseExplanation = "Check that ONOS is connected to each " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700353 "device. Then manually assign" +\
354 " mastership to specific ONOS nodes using" +\
355 " 'device-role'"
356 main.step( "Assign mastership of switches to specific controllers" )
357 # Manually assign mastership to the controller we want
358 roleCall = main.TRUE
359
360 ipList = [ ]
361 deviceList = []
362 try:
363 # Assign mastership to specific controllers. This assignment was
364 # determined for a 7 node cluser, but will work with any sized
365 # cluster
366 for i in range( 1, 29 ): # switches 1 through 28
367 # set up correct variables:
368 if i == 1:
369 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700370 ip = main.nodes[ c ].ip_address # ONOS1
Jon Hall5cf14d52015-07-16 12:15:19 -0700371 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
372 elif i == 2:
Jon Halle1a3b752015-07-22 13:02:46 -0700373 c = 1 % main.numCtrls
374 ip = main.nodes[ c ].ip_address # ONOS2
Jon Hall5cf14d52015-07-16 12:15:19 -0700375 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
376 elif i == 3:
Jon Halle1a3b752015-07-22 13:02:46 -0700377 c = 1 % main.numCtrls
378 ip = main.nodes[ c ].ip_address # ONOS2
Jon Hall5cf14d52015-07-16 12:15:19 -0700379 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
380 elif i == 4:
Jon Halle1a3b752015-07-22 13:02:46 -0700381 c = 3 % main.numCtrls
382 ip = main.nodes[ c ].ip_address # ONOS4
Jon Hall5cf14d52015-07-16 12:15:19 -0700383 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
384 elif i == 5:
Jon Halle1a3b752015-07-22 13:02:46 -0700385 c = 2 % main.numCtrls
386 ip = main.nodes[ c ].ip_address # ONOS3
Jon Hall5cf14d52015-07-16 12:15:19 -0700387 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
388 elif i == 6:
Jon Halle1a3b752015-07-22 13:02:46 -0700389 c = 2 % main.numCtrls
390 ip = main.nodes[ c ].ip_address # ONOS3
Jon Hall5cf14d52015-07-16 12:15:19 -0700391 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
392 elif i == 7:
Jon Halle1a3b752015-07-22 13:02:46 -0700393 c = 5 % main.numCtrls
394 ip = main.nodes[ c ].ip_address # ONOS6
Jon Hall5cf14d52015-07-16 12:15:19 -0700395 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
396 elif i >= 8 and i <= 17:
Jon Halle1a3b752015-07-22 13:02:46 -0700397 c = 4 % main.numCtrls
398 ip = main.nodes[ c ].ip_address # ONOS5
Jon Hall5cf14d52015-07-16 12:15:19 -0700399 dpid = '3' + str( i ).zfill( 3 )
400 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
401 elif i >= 18 and i <= 27:
Jon Halle1a3b752015-07-22 13:02:46 -0700402 c = 6 % main.numCtrls
403 ip = main.nodes[ c ].ip_address # ONOS7
Jon Hall5cf14d52015-07-16 12:15:19 -0700404 dpid = '6' + str( i ).zfill( 3 )
405 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
406 elif i == 28:
407 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700408 ip = main.nodes[ c ].ip_address # ONOS1
Jon Hall5cf14d52015-07-16 12:15:19 -0700409 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
410 else:
411 main.log.error( "You didn't write an else statement for " +
412 "switch s" + str( i ) )
413 roleCall = main.FALSE
414 # Assign switch
415 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
416 # TODO: make this controller dynamic
417 roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
418 ip )
419 ipList.append( ip )
420 deviceList.append( deviceId )
421 except ( AttributeError, AssertionError ):
422 main.log.exception( "Something is wrong with ONOS device view" )
423 main.log.info( main.ONOScli1.devices() )
424 utilities.assert_equals(
425 expect=main.TRUE,
426 actual=roleCall,
427 onpass="Re-assigned switch mastership to designated controller",
428 onfail="Something wrong with deviceRole calls" )
429
430 main.step( "Check mastership was correctly assigned" )
431 roleCheck = main.TRUE
432 # NOTE: This is due to the fact that device mastership change is not
433 # atomic and is actually a multi step process
434 time.sleep( 5 )
435 for i in range( len( ipList ) ):
436 ip = ipList[i]
437 deviceId = deviceList[i]
438 # Check assignment
439 master = main.ONOScli1.getRole( deviceId ).get( 'master' )
440 if ip in master:
441 roleCheck = roleCheck and main.TRUE
442 else:
443 roleCheck = roleCheck and main.FALSE
444 main.log.error( "Error, controller " + ip + " is not" +
445 " master " + "of device " +
446 str( deviceId ) + ". Master is " +
447 repr( master ) + "." )
448 utilities.assert_equals(
449 expect=main.TRUE,
450 actual=roleCheck,
451 onpass="Switches were successfully reassigned to designated " +
452 "controller",
453 onfail="Switches were not successfully reassigned" )
454
455 def CASE3( self, main ):
456 """
457 Assign intents
458 """
459 import time
460 import json
Jon Halle1a3b752015-07-22 13:02:46 -0700461 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700462 assert main, "main not defined"
463 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700464 assert main.CLIs, "main.CLIs not defined"
465 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700466 try:
467 labels
468 except NameError:
469 main.log.error( "labels not defined, setting to []" )
470 labels = []
471 try:
472 data
473 except NameError:
474 main.log.error( "data not defined, setting to []" )
475 data = []
476 # NOTE: we must reinstall intents until we have a persistant intent
477 # datastore!
478 main.case( "Adding host Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700479 main.caseExplanation = "Discover hosts by using pingall then " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700480 "assign predetermined host-to-host intents." +\
481 " After installation, check that the intent" +\
482 " is distributed to all nodes and the state" +\
483 " is INSTALLED"
484
485 # install onos-app-fwd
486 main.step( "Install reactive forwarding app" )
Jon Halle1a3b752015-07-22 13:02:46 -0700487 installResults = main.CLIs[0].activateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700488 utilities.assert_equals( expect=main.TRUE, actual=installResults,
489 onpass="Install fwd successful",
490 onfail="Install fwd failed" )
491
492 main.step( "Check app ids" )
493 appCheck = main.TRUE
494 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700495 for i in range( main.numCtrls ):
496 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700497 name="appToIDCheck-" + str( i ),
498 args=[] )
499 threads.append( t )
500 t.start()
501
502 for t in threads:
503 t.join()
504 appCheck = appCheck and t.result
505 if appCheck != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700506 main.log.warn( main.CLIs[0].apps() )
507 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700508 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
509 onpass="App Ids seem to be correct",
510 onfail="Something is wrong with app Ids" )
511
512 main.step( "Discovering Hosts( Via pingall for now )" )
513 # FIXME: Once we have a host discovery mechanism, use that instead
514 # REACTIVE FWD test
515 pingResult = main.FALSE
Jon Hall96091e62015-09-21 17:34:17 -0700516 passMsg = "Reactive Pingall test passed"
517 time1 = time.time()
518 pingResult = main.Mininet1.pingall()
519 time2 = time.time()
520 if not pingResult:
521 main.log.warn("First pingall failed. Trying again...")
Jon Hall5cf14d52015-07-16 12:15:19 -0700522 pingResult = main.Mininet1.pingall()
Jon Hall96091e62015-09-21 17:34:17 -0700523 passMsg += " on the second try"
524 utilities.assert_equals(
525 expect=main.TRUE,
526 actual=pingResult,
527 onpass= passMsg,
528 onfail="Reactive Pingall failed, " +
529 "one or more ping pairs failed" )
530 main.log.info( "Time for pingall: %2f seconds" %
531 ( time2 - time1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -0700532 # timeout for fwd flows
533 time.sleep( 11 )
534 # uninstall onos-app-fwd
535 main.step( "Uninstall reactive forwarding app" )
Jon Halle1a3b752015-07-22 13:02:46 -0700536 uninstallResult = main.CLIs[0].deactivateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700537 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
538 onpass="Uninstall fwd successful",
539 onfail="Uninstall fwd failed" )
540
541 main.step( "Check app ids" )
542 threads = []
543 appCheck2 = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700544 for i in range( main.numCtrls ):
545 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700546 name="appToIDCheck-" + str( i ),
547 args=[] )
548 threads.append( t )
549 t.start()
550
551 for t in threads:
552 t.join()
553 appCheck2 = appCheck2 and t.result
554 if appCheck2 != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700555 main.log.warn( main.CLIs[0].apps() )
556 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700557 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
558 onpass="App Ids seem to be correct",
559 onfail="Something is wrong with app Ids" )
560
561 main.step( "Add host intents via cli" )
562 intentIds = []
563 # TODO: move the host numbers to params
564 # Maybe look at all the paths we ping?
565 intentAddResult = True
566 hostResult = main.TRUE
567 for i in range( 8, 18 ):
568 main.log.info( "Adding host intent between h" + str( i ) +
569 " and h" + str( i + 10 ) )
570 host1 = "00:00:00:00:00:" + \
571 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
572 host2 = "00:00:00:00:00:" + \
573 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
574 # NOTE: getHost can return None
575 host1Dict = main.ONOScli1.getHost( host1 )
576 host2Dict = main.ONOScli1.getHost( host2 )
577 host1Id = None
578 host2Id = None
579 if host1Dict and host2Dict:
580 host1Id = host1Dict.get( 'id', None )
581 host2Id = host2Dict.get( 'id', None )
582 if host1Id and host2Id:
Jon Halle1a3b752015-07-22 13:02:46 -0700583 nodeNum = ( i % main.numCtrls )
584 tmpId = main.CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
Jon Hall5cf14d52015-07-16 12:15:19 -0700585 if tmpId:
586 main.log.info( "Added intent with id: " + tmpId )
587 intentIds.append( tmpId )
588 else:
589 main.log.error( "addHostIntent returned: " +
590 repr( tmpId ) )
591 else:
592 main.log.error( "Error, getHost() failed for h" + str( i ) +
593 " and/or h" + str( i + 10 ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700594 hosts = main.CLIs[ 0 ].hosts()
Jon Hall5cf14d52015-07-16 12:15:19 -0700595 main.log.warn( "Hosts output: " )
596 try:
597 main.log.warn( json.dumps( json.loads( hosts ),
598 sort_keys=True,
599 indent=4,
600 separators=( ',', ': ' ) ) )
601 except ( ValueError, TypeError ):
602 main.log.warn( repr( hosts ) )
603 hostResult = main.FALSE
604 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
605 onpass="Found a host id for each host",
606 onfail="Error looking up host ids" )
607
608 intentStart = time.time()
609 onosIds = main.ONOScli1.getAllIntentsId()
610 main.log.info( "Submitted intents: " + str( intentIds ) )
611 main.log.info( "Intents in ONOS: " + str( onosIds ) )
612 for intent in intentIds:
613 if intent in onosIds:
614 pass # intent submitted is in onos
615 else:
616 intentAddResult = False
617 if intentAddResult:
618 intentStop = time.time()
619 else:
620 intentStop = None
621 # Print the intent states
622 intents = main.ONOScli1.intents()
623 intentStates = []
624 installedCheck = True
625 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
626 count = 0
627 try:
628 for intent in json.loads( intents ):
629 state = intent.get( 'state', None )
630 if "INSTALLED" not in state:
631 installedCheck = False
632 intentId = intent.get( 'id', None )
633 intentStates.append( ( intentId, state ) )
634 except ( ValueError, TypeError ):
635 main.log.exception( "Error parsing intents" )
636 # add submitted intents not in the store
637 tmplist = [ i for i, s in intentStates ]
638 missingIntents = False
639 for i in intentIds:
640 if i not in tmplist:
641 intentStates.append( ( i, " - " ) )
642 missingIntents = True
643 intentStates.sort()
644 for i, s in intentStates:
645 count += 1
646 main.log.info( "%-6s%-15s%-15s" %
647 ( str( count ), str( i ), str( s ) ) )
648 leaders = main.ONOScli1.leaders()
649 try:
650 missing = False
651 if leaders:
652 parsedLeaders = json.loads( leaders )
653 main.log.warn( json.dumps( parsedLeaders,
654 sort_keys=True,
655 indent=4,
656 separators=( ',', ': ' ) ) )
657 # check for all intent partitions
658 topics = []
659 for i in range( 14 ):
660 topics.append( "intent-partition-" + str( i ) )
661 main.log.debug( topics )
662 ONOStopics = [ j['topic'] for j in parsedLeaders ]
663 for topic in topics:
664 if topic not in ONOStopics:
665 main.log.error( "Error: " + topic +
666 " not in leaders" )
667 missing = True
668 else:
669 main.log.error( "leaders() returned None" )
670 except ( ValueError, TypeError ):
671 main.log.exception( "Error parsing leaders" )
672 main.log.error( repr( leaders ) )
673 # Check all nodes
674 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -0700675 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700676 response = node.leaders( jsonFormat=False)
677 main.log.warn( str( node.name ) + " leaders output: \n" +
678 str( response ) )
679
680 partitions = main.ONOScli1.partitions()
681 try:
682 if partitions :
683 parsedPartitions = json.loads( partitions )
684 main.log.warn( json.dumps( parsedPartitions,
685 sort_keys=True,
686 indent=4,
687 separators=( ',', ': ' ) ) )
688 # TODO check for a leader in all paritions
689 # TODO check for consistency among nodes
690 else:
691 main.log.error( "partitions() returned None" )
692 except ( ValueError, TypeError ):
693 main.log.exception( "Error parsing partitions" )
694 main.log.error( repr( partitions ) )
695 pendingMap = main.ONOScli1.pendingMap()
696 try:
697 if pendingMap :
698 parsedPending = json.loads( pendingMap )
699 main.log.warn( json.dumps( parsedPending,
700 sort_keys=True,
701 indent=4,
702 separators=( ',', ': ' ) ) )
703 # TODO check something here?
704 else:
705 main.log.error( "pendingMap() returned None" )
706 except ( ValueError, TypeError ):
707 main.log.exception( "Error parsing pending map" )
708 main.log.error( repr( pendingMap ) )
709
710 intentAddResult = bool( intentAddResult and not missingIntents and
711 installedCheck )
712 if not intentAddResult:
713 main.log.error( "Error in pushing host intents to ONOS" )
714
715 main.step( "Intent Anti-Entropy dispersion" )
716 for i in range(100):
717 correct = True
718 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700719 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700720 onosIds = []
721 ids = cli.getAllIntentsId()
722 onosIds.append( ids )
723 main.log.debug( "Intents in " + cli.name + ": " +
724 str( sorted( onosIds ) ) )
725 if sorted( ids ) != sorted( intentIds ):
726 main.log.warn( "Set of intent IDs doesn't match" )
727 correct = False
728 break
729 else:
730 intents = json.loads( cli.intents() )
731 for intent in intents:
732 if intent[ 'state' ] != "INSTALLED":
733 main.log.warn( "Intent " + intent[ 'id' ] +
734 " is " + intent[ 'state' ] )
735 correct = False
736 break
737 if correct:
738 break
739 else:
740 time.sleep(1)
741 if not intentStop:
742 intentStop = time.time()
743 global gossipTime
744 gossipTime = intentStop - intentStart
745 main.log.info( "It took about " + str( gossipTime ) +
746 " seconds for all intents to appear in each node" )
747 append = False
748 title = "Gossip Intents"
749 count = 1
750 while append is False:
751 curTitle = title + str( count )
752 if curTitle not in labels:
753 labels.append( curTitle )
754 data.append( str( gossipTime ) )
755 append = True
756 else:
757 count += 1
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700758 gossipPeriod = int( main.params['timers']['gossip'] )
759 maxGossipTime = gossipPeriod * len( main.nodes )
Jon Hall5cf14d52015-07-16 12:15:19 -0700760 utilities.assert_greater_equals(
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700761 expect=maxGossipTime, actual=gossipTime,
Jon Hall5cf14d52015-07-16 12:15:19 -0700762 onpass="ECM anti-entropy for intents worked within " +
763 "expected time",
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700764 onfail="Intent ECM anti-entropy took too long. " +
765 "Expected time:{}, Actual time:{}".format( maxGossipTime,
766 gossipTime ) )
767 if gossipTime <= maxGossipTime:
Jon Hall5cf14d52015-07-16 12:15:19 -0700768 intentAddResult = True
769
770 if not intentAddResult or "key" in pendingMap:
771 import time
772 installedCheck = True
773 main.log.info( "Sleeping 60 seconds to see if intents are found" )
774 time.sleep( 60 )
775 onosIds = main.ONOScli1.getAllIntentsId()
776 main.log.info( "Submitted intents: " + str( intentIds ) )
777 main.log.info( "Intents in ONOS: " + str( onosIds ) )
778 # Print the intent states
779 intents = main.ONOScli1.intents()
780 intentStates = []
781 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
782 count = 0
783 try:
784 for intent in json.loads( intents ):
785 # Iter through intents of a node
786 state = intent.get( 'state', None )
787 if "INSTALLED" not in state:
788 installedCheck = False
789 intentId = intent.get( 'id', None )
790 intentStates.append( ( intentId, state ) )
791 except ( ValueError, TypeError ):
792 main.log.exception( "Error parsing intents" )
793 # add submitted intents not in the store
794 tmplist = [ i for i, s in intentStates ]
795 for i in intentIds:
796 if i not in tmplist:
797 intentStates.append( ( i, " - " ) )
798 intentStates.sort()
799 for i, s in intentStates:
800 count += 1
801 main.log.info( "%-6s%-15s%-15s" %
802 ( str( count ), str( i ), str( s ) ) )
803 leaders = main.ONOScli1.leaders()
804 try:
805 missing = False
806 if leaders:
807 parsedLeaders = json.loads( leaders )
808 main.log.warn( json.dumps( parsedLeaders,
809 sort_keys=True,
810 indent=4,
811 separators=( ',', ': ' ) ) )
812 # check for all intent partitions
813 # check for election
814 topics = []
815 for i in range( 14 ):
816 topics.append( "intent-partition-" + str( i ) )
817 # FIXME: this should only be after we start the app
818 topics.append( "org.onosproject.election" )
819 main.log.debug( topics )
820 ONOStopics = [ j['topic'] for j in parsedLeaders ]
821 for topic in topics:
822 if topic not in ONOStopics:
823 main.log.error( "Error: " + topic +
824 " not in leaders" )
825 missing = True
826 else:
827 main.log.error( "leaders() returned None" )
828 except ( ValueError, TypeError ):
829 main.log.exception( "Error parsing leaders" )
830 main.log.error( repr( leaders ) )
831 # Check all nodes
832 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -0700833 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700834 response = node.leaders( jsonFormat=False)
835 main.log.warn( str( node.name ) + " leaders output: \n" +
836 str( response ) )
837
838 partitions = main.ONOScli1.partitions()
839 try:
840 if partitions :
841 parsedPartitions = json.loads( partitions )
842 main.log.warn( json.dumps( parsedPartitions,
843 sort_keys=True,
844 indent=4,
845 separators=( ',', ': ' ) ) )
846 # TODO check for a leader in all paritions
847 # TODO check for consistency among nodes
848 else:
849 main.log.error( "partitions() returned None" )
850 except ( ValueError, TypeError ):
851 main.log.exception( "Error parsing partitions" )
852 main.log.error( repr( partitions ) )
853 pendingMap = main.ONOScli1.pendingMap()
854 try:
855 if pendingMap :
856 parsedPending = json.loads( pendingMap )
857 main.log.warn( json.dumps( parsedPending,
858 sort_keys=True,
859 indent=4,
860 separators=( ',', ': ' ) ) )
861 # TODO check something here?
862 else:
863 main.log.error( "pendingMap() returned None" )
864 except ( ValueError, TypeError ):
865 main.log.exception( "Error parsing pending map" )
866 main.log.error( repr( pendingMap ) )
867
868 def CASE4( self, main ):
869 """
870 Ping across added host intents
871 """
872 import json
873 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700874 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700875 assert main, "main not defined"
876 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700877 assert main.CLIs, "main.CLIs not defined"
878 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700879 main.case( "Verify connectivity by sendind traffic across Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700880 main.caseExplanation = "Ping across added host intents to check " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700881 "functionality and check the state of " +\
882 "the intent"
883 main.step( "Ping across added host intents" )
884 PingResult = main.TRUE
885 for i in range( 8, 18 ):
886 ping = main.Mininet1.pingHost( src="h" + str( i ),
887 target="h" + str( i + 10 ) )
888 PingResult = PingResult and ping
889 if ping == main.FALSE:
890 main.log.warn( "Ping failed between h" + str( i ) +
891 " and h" + str( i + 10 ) )
892 elif ping == main.TRUE:
893 main.log.info( "Ping test passed!" )
894 # Don't set PingResult or you'd override failures
895 if PingResult == main.FALSE:
896 main.log.error(
897 "Intents have not been installed correctly, pings failed." )
898 # TODO: pretty print
899 main.log.warn( "ONOS1 intents: " )
900 try:
901 tmpIntents = main.ONOScli1.intents()
902 main.log.warn( json.dumps( json.loads( tmpIntents ),
903 sort_keys=True,
904 indent=4,
905 separators=( ',', ': ' ) ) )
906 except ( ValueError, TypeError ):
907 main.log.warn( repr( tmpIntents ) )
908 utilities.assert_equals(
909 expect=main.TRUE,
910 actual=PingResult,
911 onpass="Intents have been installed correctly and pings work",
912 onfail="Intents have not been installed correctly, pings failed." )
913
914 main.step( "Check Intent state" )
915 installedCheck = False
916 loopCount = 0
917 while not installedCheck and loopCount < 40:
918 installedCheck = True
919 # Print the intent states
920 intents = main.ONOScli1.intents()
921 intentStates = []
922 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700923 count = 0
Jon Hall5cf14d52015-07-16 12:15:19 -0700924 # Iter through intents of a node
925 try:
926 for intent in json.loads( intents ):
927 state = intent.get( 'state', None )
928 if "INSTALLED" not in state:
929 installedCheck = False
930 intentId = intent.get( 'id', None )
931 intentStates.append( ( intentId, state ) )
932 except ( ValueError, TypeError ):
933 main.log.exception( "Error parsing intents." )
934 # Print states
935 intentStates.sort()
936 for i, s in intentStates:
937 count += 1
938 main.log.info( "%-6s%-15s%-15s" %
939 ( str( count ), str( i ), str( s ) ) )
940 if not installedCheck:
941 time.sleep( 1 )
942 loopCount += 1
943 utilities.assert_equals( expect=True, actual=installedCheck,
944 onpass="Intents are all INSTALLED",
945 onfail="Intents are not all in " +
946 "INSTALLED state" )
947
948 main.step( "Check leadership of topics" )
949 leaders = main.ONOScli1.leaders()
950 topicCheck = main.TRUE
951 try:
952 if leaders:
953 parsedLeaders = json.loads( leaders )
954 main.log.warn( json.dumps( parsedLeaders,
955 sort_keys=True,
956 indent=4,
957 separators=( ',', ': ' ) ) )
958 # check for all intent partitions
959 # check for election
960 # TODO: Look at Devices as topics now that it uses this system
961 topics = []
962 for i in range( 14 ):
963 topics.append( "intent-partition-" + str( i ) )
964 # FIXME: this should only be after we start the app
965 # FIXME: topics.append( "org.onosproject.election" )
966 # Print leaders output
967 main.log.debug( topics )
968 ONOStopics = [ j['topic'] for j in parsedLeaders ]
969 for topic in topics:
970 if topic not in ONOStopics:
971 main.log.error( "Error: " + topic +
972 " not in leaders" )
973 topicCheck = main.FALSE
974 else:
975 main.log.error( "leaders() returned None" )
976 topicCheck = main.FALSE
977 except ( ValueError, TypeError ):
978 topicCheck = main.FALSE
979 main.log.exception( "Error parsing leaders" )
980 main.log.error( repr( leaders ) )
981 # TODO: Check for a leader of these topics
982 # Check all nodes
983 if topicCheck:
Jon Halle1a3b752015-07-22 13:02:46 -0700984 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700985 response = node.leaders( jsonFormat=False)
986 main.log.warn( str( node.name ) + " leaders output: \n" +
987 str( response ) )
988
989 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
990 onpass="intent Partitions is in leaders",
991 onfail="Some topics were lost " )
992 # Print partitions
993 partitions = main.ONOScli1.partitions()
994 try:
995 if partitions :
996 parsedPartitions = json.loads( partitions )
997 main.log.warn( json.dumps( parsedPartitions,
998 sort_keys=True,
999 indent=4,
1000 separators=( ',', ': ' ) ) )
1001 # TODO check for a leader in all paritions
1002 # TODO check for consistency among nodes
1003 else:
1004 main.log.error( "partitions() returned None" )
1005 except ( ValueError, TypeError ):
1006 main.log.exception( "Error parsing partitions" )
1007 main.log.error( repr( partitions ) )
1008 # Print Pending Map
1009 pendingMap = main.ONOScli1.pendingMap()
1010 try:
1011 if pendingMap :
1012 parsedPending = json.loads( pendingMap )
1013 main.log.warn( json.dumps( parsedPending,
1014 sort_keys=True,
1015 indent=4,
1016 separators=( ',', ': ' ) ) )
1017 # TODO check something here?
1018 else:
1019 main.log.error( "pendingMap() returned None" )
1020 except ( ValueError, TypeError ):
1021 main.log.exception( "Error parsing pending map" )
1022 main.log.error( repr( pendingMap ) )
1023
1024 if not installedCheck:
1025 main.log.info( "Waiting 60 seconds to see if the state of " +
1026 "intents change" )
1027 time.sleep( 60 )
1028 # Print the intent states
1029 intents = main.ONOScli1.intents()
1030 intentStates = []
1031 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
1032 count = 0
1033 # Iter through intents of a node
1034 try:
1035 for intent in json.loads( intents ):
1036 state = intent.get( 'state', None )
1037 if "INSTALLED" not in state:
1038 installedCheck = False
1039 intentId = intent.get( 'id', None )
1040 intentStates.append( ( intentId, state ) )
1041 except ( ValueError, TypeError ):
1042 main.log.exception( "Error parsing intents." )
1043 intentStates.sort()
1044 for i, s in intentStates:
1045 count += 1
1046 main.log.info( "%-6s%-15s%-15s" %
1047 ( str( count ), str( i ), str( s ) ) )
1048 leaders = main.ONOScli1.leaders()
1049 try:
1050 missing = False
1051 if leaders:
1052 parsedLeaders = json.loads( leaders )
1053 main.log.warn( json.dumps( parsedLeaders,
1054 sort_keys=True,
1055 indent=4,
1056 separators=( ',', ': ' ) ) )
1057 # check for all intent partitions
1058 # check for election
1059 topics = []
1060 for i in range( 14 ):
1061 topics.append( "intent-partition-" + str( i ) )
1062 # FIXME: this should only be after we start the app
1063 topics.append( "org.onosproject.election" )
1064 main.log.debug( topics )
1065 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1066 for topic in topics:
1067 if topic not in ONOStopics:
1068 main.log.error( "Error: " + topic +
1069 " not in leaders" )
1070 missing = True
1071 else:
1072 main.log.error( "leaders() returned None" )
1073 except ( ValueError, TypeError ):
1074 main.log.exception( "Error parsing leaders" )
1075 main.log.error( repr( leaders ) )
1076 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -07001077 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07001078 response = node.leaders( jsonFormat=False)
1079 main.log.warn( str( node.name ) + " leaders output: \n" +
1080 str( response ) )
1081
1082 partitions = main.ONOScli1.partitions()
1083 try:
1084 if partitions :
1085 parsedPartitions = json.loads( partitions )
1086 main.log.warn( json.dumps( parsedPartitions,
1087 sort_keys=True,
1088 indent=4,
1089 separators=( ',', ': ' ) ) )
1090 # TODO check for a leader in all paritions
1091 # TODO check for consistency among nodes
1092 else:
1093 main.log.error( "partitions() returned None" )
1094 except ( ValueError, TypeError ):
1095 main.log.exception( "Error parsing partitions" )
1096 main.log.error( repr( partitions ) )
1097 pendingMap = main.ONOScli1.pendingMap()
1098 try:
1099 if pendingMap :
1100 parsedPending = json.loads( pendingMap )
1101 main.log.warn( json.dumps( parsedPending,
1102 sort_keys=True,
1103 indent=4,
1104 separators=( ',', ': ' ) ) )
1105 # TODO check something here?
1106 else:
1107 main.log.error( "pendingMap() returned None" )
1108 except ( ValueError, TypeError ):
1109 main.log.exception( "Error parsing pending map" )
1110 main.log.error( repr( pendingMap ) )
1111 # Print flowrules
Jon Halle1a3b752015-07-22 13:02:46 -07001112 main.log.debug( main.CLIs[0].flows( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001113 main.step( "Wait a minute then ping again" )
1114 # the wait is above
1115 PingResult = main.TRUE
1116 for i in range( 8, 18 ):
1117 ping = main.Mininet1.pingHost( src="h" + str( i ),
1118 target="h" + str( i + 10 ) )
1119 PingResult = PingResult and ping
1120 if ping == main.FALSE:
1121 main.log.warn( "Ping failed between h" + str( i ) +
1122 " and h" + str( i + 10 ) )
1123 elif ping == main.TRUE:
1124 main.log.info( "Ping test passed!" )
1125 # Don't set PingResult or you'd override failures
1126 if PingResult == main.FALSE:
1127 main.log.error(
1128 "Intents have not been installed correctly, pings failed." )
1129 # TODO: pretty print
1130 main.log.warn( "ONOS1 intents: " )
1131 try:
1132 tmpIntents = main.ONOScli1.intents()
1133 main.log.warn( json.dumps( json.loads( tmpIntents ),
1134 sort_keys=True,
1135 indent=4,
1136 separators=( ',', ': ' ) ) )
1137 except ( ValueError, TypeError ):
1138 main.log.warn( repr( tmpIntents ) )
1139 utilities.assert_equals(
1140 expect=main.TRUE,
1141 actual=PingResult,
1142 onpass="Intents have been installed correctly and pings work",
1143 onfail="Intents have not been installed correctly, pings failed." )
1144
1145 def CASE5( self, main ):
1146 """
1147 Reading state of ONOS
1148 """
1149 import json
1150 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001151 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001152 assert main, "main not defined"
1153 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001154 assert main.CLIs, "main.CLIs not defined"
1155 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001156
1157 main.case( "Setting up and gathering data for current state" )
1158 # The general idea for this test case is to pull the state of
1159 # ( intents,flows, topology,... ) from each ONOS node
1160 # We can then compare them with each other and also with past states
1161
1162 main.step( "Check that each switch has a master" )
1163 global mastershipState
1164 mastershipState = '[]'
1165
1166 # Assert that each device has a master
1167 rolesNotNull = main.TRUE
1168 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001169 for i in range( main.numCtrls ):
1170 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001171 name="rolesNotNull-" + str( i ),
1172 args=[] )
1173 threads.append( t )
1174 t.start()
1175
1176 for t in threads:
1177 t.join()
1178 rolesNotNull = rolesNotNull and t.result
1179 utilities.assert_equals(
1180 expect=main.TRUE,
1181 actual=rolesNotNull,
1182 onpass="Each device has a master",
1183 onfail="Some devices don't have a master assigned" )
1184
1185 main.step( "Get the Mastership of each switch from each controller" )
1186 ONOSMastership = []
1187 mastershipCheck = main.FALSE
1188 consistentMastership = True
1189 rolesResults = True
1190 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001191 for i in range( main.numCtrls ):
1192 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001193 name="roles-" + str( i ),
1194 args=[] )
1195 threads.append( t )
1196 t.start()
1197
1198 for t in threads:
1199 t.join()
1200 ONOSMastership.append( t.result )
1201
Jon Halle1a3b752015-07-22 13:02:46 -07001202 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001203 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1204 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1205 " roles" )
1206 main.log.warn(
1207 "ONOS" + str( i + 1 ) + " mastership response: " +
1208 repr( ONOSMastership[i] ) )
1209 rolesResults = False
1210 utilities.assert_equals(
1211 expect=True,
1212 actual=rolesResults,
1213 onpass="No error in reading roles output",
1214 onfail="Error in reading roles from ONOS" )
1215
1216 main.step( "Check for consistency in roles from each controller" )
1217 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1218 main.log.info(
1219 "Switch roles are consistent across all ONOS nodes" )
1220 else:
1221 consistentMastership = False
1222 utilities.assert_equals(
1223 expect=True,
1224 actual=consistentMastership,
1225 onpass="Switch roles are consistent across all ONOS nodes",
1226 onfail="ONOS nodes have different views of switch roles" )
1227
1228 if rolesResults and not consistentMastership:
Jon Halle1a3b752015-07-22 13:02:46 -07001229 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001230 try:
1231 main.log.warn(
1232 "ONOS" + str( i + 1 ) + " roles: ",
1233 json.dumps(
1234 json.loads( ONOSMastership[ i ] ),
1235 sort_keys=True,
1236 indent=4,
1237 separators=( ',', ': ' ) ) )
1238 except ( ValueError, TypeError ):
1239 main.log.warn( repr( ONOSMastership[ i ] ) )
1240 elif rolesResults and consistentMastership:
1241 mastershipCheck = main.TRUE
1242 mastershipState = ONOSMastership[ 0 ]
1243
1244 main.step( "Get the intents from each controller" )
1245 global intentState
1246 intentState = []
1247 ONOSIntents = []
1248 intentCheck = main.FALSE
1249 consistentIntents = True
1250 intentsResults = True
1251 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001252 for i in range( main.numCtrls ):
1253 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001254 name="intents-" + str( i ),
1255 args=[],
1256 kwargs={ 'jsonFormat': True } )
1257 threads.append( t )
1258 t.start()
1259
1260 for t in threads:
1261 t.join()
1262 ONOSIntents.append( t.result )
1263
Jon Halle1a3b752015-07-22 13:02:46 -07001264 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001265 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1266 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1267 " intents" )
1268 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1269 repr( ONOSIntents[ i ] ) )
1270 intentsResults = False
1271 utilities.assert_equals(
1272 expect=True,
1273 actual=intentsResults,
1274 onpass="No error in reading intents output",
1275 onfail="Error in reading intents from ONOS" )
1276
1277 main.step( "Check for consistency in Intents from each controller" )
1278 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1279 main.log.info( "Intents are consistent across all ONOS " +
1280 "nodes" )
1281 else:
1282 consistentIntents = False
1283 main.log.error( "Intents not consistent" )
1284 utilities.assert_equals(
1285 expect=True,
1286 actual=consistentIntents,
1287 onpass="Intents are consistent across all ONOS nodes",
1288 onfail="ONOS nodes have different views of intents" )
1289
1290 if intentsResults:
1291 # Try to make it easy to figure out what is happening
1292 #
1293 # Intent ONOS1 ONOS2 ...
1294 # 0x01 INSTALLED INSTALLING
1295 # ... ... ...
1296 # ... ... ...
1297 title = " Id"
Jon Halle1a3b752015-07-22 13:02:46 -07001298 for n in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001299 title += " " * 10 + "ONOS" + str( n + 1 )
1300 main.log.warn( title )
1301 # get all intent keys in the cluster
1302 keys = []
1303 for nodeStr in ONOSIntents:
1304 node = json.loads( nodeStr )
1305 for intent in node:
1306 keys.append( intent.get( 'id' ) )
1307 keys = set( keys )
1308 for key in keys:
1309 row = "%-13s" % key
1310 for nodeStr in ONOSIntents:
1311 node = json.loads( nodeStr )
1312 for intent in node:
1313 if intent.get( 'id', "Error" ) == key:
1314 row += "%-15s" % intent.get( 'state' )
1315 main.log.warn( row )
1316 # End table view
1317
1318 if intentsResults and not consistentIntents:
1319 # print the json objects
1320 n = len(ONOSIntents)
1321 main.log.debug( "ONOS" + str( n ) + " intents: " )
1322 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1323 sort_keys=True,
1324 indent=4,
1325 separators=( ',', ': ' ) ) )
Jon Halle1a3b752015-07-22 13:02:46 -07001326 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001327 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
1328 main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
1329 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1330 sort_keys=True,
1331 indent=4,
1332 separators=( ',', ': ' ) ) )
1333 else:
Jon Halle1a3b752015-07-22 13:02:46 -07001334 main.log.debug( main.nodes[ i ].name + " intents match ONOS" +
Jon Hall5cf14d52015-07-16 12:15:19 -07001335 str( n ) + " intents" )
1336 elif intentsResults and consistentIntents:
1337 intentCheck = main.TRUE
1338 intentState = ONOSIntents[ 0 ]
1339
1340 main.step( "Get the flows from each controller" )
1341 global flowState
1342 flowState = []
1343 ONOSFlows = []
1344 ONOSFlowsJson = []
1345 flowCheck = main.FALSE
1346 consistentFlows = True
1347 flowsResults = True
1348 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001349 for i in range( main.numCtrls ):
1350 t = main.Thread( target=main.CLIs[i].flows,
Jon Hall5cf14d52015-07-16 12:15:19 -07001351 name="flows-" + str( i ),
1352 args=[],
1353 kwargs={ 'jsonFormat': True } )
1354 threads.append( t )
1355 t.start()
1356
1357 # NOTE: Flows command can take some time to run
1358 time.sleep(30)
1359 for t in threads:
1360 t.join()
1361 result = t.result
1362 ONOSFlows.append( result )
1363
Jon Halle1a3b752015-07-22 13:02:46 -07001364 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001365 num = str( i + 1 )
1366 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1367 main.log.error( "Error in getting ONOS" + num + " flows" )
1368 main.log.warn( "ONOS" + num + " flows response: " +
1369 repr( ONOSFlows[ i ] ) )
1370 flowsResults = False
1371 ONOSFlowsJson.append( None )
1372 else:
1373 try:
1374 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1375 except ( ValueError, TypeError ):
1376 # FIXME: change this to log.error?
1377 main.log.exception( "Error in parsing ONOS" + num +
1378 " response as json." )
1379 main.log.error( repr( ONOSFlows[ i ] ) )
1380 ONOSFlowsJson.append( None )
1381 flowsResults = False
1382 utilities.assert_equals(
1383 expect=True,
1384 actual=flowsResults,
1385 onpass="No error in reading flows output",
1386 onfail="Error in reading flows from ONOS" )
1387
1388 main.step( "Check for consistency in Flows from each controller" )
1389 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1390 if all( tmp ):
1391 main.log.info( "Flow count is consistent across all ONOS nodes" )
1392 else:
1393 consistentFlows = False
1394 utilities.assert_equals(
1395 expect=True,
1396 actual=consistentFlows,
1397 onpass="The flow count is consistent across all ONOS nodes",
1398 onfail="ONOS nodes have different flow counts" )
1399
1400 if flowsResults and not consistentFlows:
Jon Halle1a3b752015-07-22 13:02:46 -07001401 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001402 try:
1403 main.log.warn(
1404 "ONOS" + str( i + 1 ) + " flows: " +
1405 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1406 indent=4, separators=( ',', ': ' ) ) )
1407 except ( ValueError, TypeError ):
1408 main.log.warn(
1409 "ONOS" + str( i + 1 ) + " flows: " +
1410 repr( ONOSFlows[ i ] ) )
1411 elif flowsResults and consistentFlows:
1412 flowCheck = main.TRUE
1413 flowState = ONOSFlows[ 0 ]
1414
1415 main.step( "Get the OF Table entries" )
1416 global flows
1417 flows = []
1418 for i in range( 1, 29 ):
Jon Hallca7ac292015-11-11 09:28:12 -08001419 flows.append( main.Mininet1.getFlowTable( "s" + str( i ), version="1.3" ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001420 if flowCheck == main.FALSE:
1421 for table in flows:
1422 main.log.warn( table )
1423 # TODO: Compare switch flow tables with ONOS flow tables
1424
1425 main.step( "Start continuous pings" )
1426 main.Mininet2.pingLong(
1427 src=main.params[ 'PING' ][ 'source1' ],
1428 target=main.params[ 'PING' ][ 'target1' ],
1429 pingTime=500 )
1430 main.Mininet2.pingLong(
1431 src=main.params[ 'PING' ][ 'source2' ],
1432 target=main.params[ 'PING' ][ 'target2' ],
1433 pingTime=500 )
1434 main.Mininet2.pingLong(
1435 src=main.params[ 'PING' ][ 'source3' ],
1436 target=main.params[ 'PING' ][ 'target3' ],
1437 pingTime=500 )
1438 main.Mininet2.pingLong(
1439 src=main.params[ 'PING' ][ 'source4' ],
1440 target=main.params[ 'PING' ][ 'target4' ],
1441 pingTime=500 )
1442 main.Mininet2.pingLong(
1443 src=main.params[ 'PING' ][ 'source5' ],
1444 target=main.params[ 'PING' ][ 'target5' ],
1445 pingTime=500 )
1446 main.Mininet2.pingLong(
1447 src=main.params[ 'PING' ][ 'source6' ],
1448 target=main.params[ 'PING' ][ 'target6' ],
1449 pingTime=500 )
1450 main.Mininet2.pingLong(
1451 src=main.params[ 'PING' ][ 'source7' ],
1452 target=main.params[ 'PING' ][ 'target7' ],
1453 pingTime=500 )
1454 main.Mininet2.pingLong(
1455 src=main.params[ 'PING' ][ 'source8' ],
1456 target=main.params[ 'PING' ][ 'target8' ],
1457 pingTime=500 )
1458 main.Mininet2.pingLong(
1459 src=main.params[ 'PING' ][ 'source9' ],
1460 target=main.params[ 'PING' ][ 'target9' ],
1461 pingTime=500 )
1462 main.Mininet2.pingLong(
1463 src=main.params[ 'PING' ][ 'source10' ],
1464 target=main.params[ 'PING' ][ 'target10' ],
1465 pingTime=500 )
1466
1467 main.step( "Collecting topology information from ONOS" )
1468 devices = []
1469 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001470 for i in range( main.numCtrls ):
1471 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07001472 name="devices-" + str( i ),
1473 args=[ ] )
1474 threads.append( t )
1475 t.start()
1476
1477 for t in threads:
1478 t.join()
1479 devices.append( t.result )
1480 hosts = []
1481 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001482 for i in range( main.numCtrls ):
1483 t = main.Thread( target=main.CLIs[i].hosts,
Jon Hall5cf14d52015-07-16 12:15:19 -07001484 name="hosts-" + str( i ),
1485 args=[ ] )
1486 threads.append( t )
1487 t.start()
1488
1489 for t in threads:
1490 t.join()
1491 try:
1492 hosts.append( json.loads( t.result ) )
1493 except ( ValueError, TypeError ):
1494 # FIXME: better handling of this, print which node
1495 # Maybe use thread name?
1496 main.log.exception( "Error parsing json output of hosts" )
Jon Hall3afe4c92015-12-14 19:30:38 -08001497 main.log.warn( repr( t.result ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001498 hosts.append( None )
1499
1500 ports = []
1501 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001502 for i in range( main.numCtrls ):
1503 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07001504 name="ports-" + str( i ),
1505 args=[ ] )
1506 threads.append( t )
1507 t.start()
1508
1509 for t in threads:
1510 t.join()
1511 ports.append( t.result )
1512 links = []
1513 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001514 for i in range( main.numCtrls ):
1515 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07001516 name="links-" + str( i ),
1517 args=[ ] )
1518 threads.append( t )
1519 t.start()
1520
1521 for t in threads:
1522 t.join()
1523 links.append( t.result )
1524 clusters = []
1525 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001526 for i in range( main.numCtrls ):
1527 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07001528 name="clusters-" + str( i ),
1529 args=[ ] )
1530 threads.append( t )
1531 t.start()
1532
1533 for t in threads:
1534 t.join()
1535 clusters.append( t.result )
1536 # Compare json objects for hosts and dataplane clusters
1537
1538 # hosts
1539 main.step( "Host view is consistent across ONOS nodes" )
1540 consistentHostsResult = main.TRUE
1541 for controller in range( len( hosts ) ):
1542 controllerStr = str( controller + 1 )
Jon Hall3afe4c92015-12-14 19:30:38 -08001543 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001544 if hosts[ controller ] == hosts[ 0 ]:
1545 continue
1546 else: # hosts not consistent
1547 main.log.error( "hosts from ONOS" +
1548 controllerStr +
1549 " is inconsistent with ONOS1" )
1550 main.log.warn( repr( hosts[ controller ] ) )
1551 consistentHostsResult = main.FALSE
1552
1553 else:
1554 main.log.error( "Error in getting ONOS hosts from ONOS" +
1555 controllerStr )
1556 consistentHostsResult = main.FALSE
1557 main.log.warn( "ONOS" + controllerStr +
1558 " hosts response: " +
1559 repr( hosts[ controller ] ) )
1560 utilities.assert_equals(
1561 expect=main.TRUE,
1562 actual=consistentHostsResult,
1563 onpass="Hosts view is consistent across all ONOS nodes",
1564 onfail="ONOS nodes have different views of hosts" )
1565
1566 main.step( "Each host has an IP address" )
1567 ipResult = main.TRUE
1568 for controller in range( 0, len( hosts ) ):
1569 controllerStr = str( controller + 1 )
Jon Hall3afe4c92015-12-14 19:30:38 -08001570 if hosts[ controller ]:
1571 for host in hosts[ controller ]:
1572 if not host.get( 'ipAddresses', [ ] ):
Jon Hallf3d16e72015-12-16 17:45:08 -08001573 main.log.error( "Error with host ips on controller" +
Jon Hall3afe4c92015-12-14 19:30:38 -08001574 controllerStr + ": " + str( host ) )
1575 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07001576 utilities.assert_equals(
1577 expect=main.TRUE,
1578 actual=ipResult,
1579 onpass="The ips of the hosts aren't empty",
1580 onfail="The ip of at least one host is missing" )
1581
1582 # Strongly connected clusters of devices
1583 main.step( "Cluster view is consistent across ONOS nodes" )
1584 consistentClustersResult = main.TRUE
1585 for controller in range( len( clusters ) ):
1586 controllerStr = str( controller + 1 )
1587 if "Error" not in clusters[ controller ]:
1588 if clusters[ controller ] == clusters[ 0 ]:
1589 continue
1590 else: # clusters not consistent
1591 main.log.error( "clusters from ONOS" + controllerStr +
1592 " is inconsistent with ONOS1" )
1593 consistentClustersResult = main.FALSE
1594
1595 else:
1596 main.log.error( "Error in getting dataplane clusters " +
1597 "from ONOS" + controllerStr )
1598 consistentClustersResult = main.FALSE
1599 main.log.warn( "ONOS" + controllerStr +
1600 " clusters response: " +
1601 repr( clusters[ controller ] ) )
1602 utilities.assert_equals(
1603 expect=main.TRUE,
1604 actual=consistentClustersResult,
1605 onpass="Clusters view is consistent across all ONOS nodes",
1606 onfail="ONOS nodes have different views of clusters" )
1607 # there should always only be one cluster
1608 main.step( "Cluster view correct across ONOS nodes" )
1609 try:
1610 numClusters = len( json.loads( clusters[ 0 ] ) )
1611 except ( ValueError, TypeError ):
1612 main.log.exception( "Error parsing clusters[0]: " +
1613 repr( clusters[ 0 ] ) )
1614 clusterResults = main.FALSE
1615 if numClusters == 1:
1616 clusterResults = main.TRUE
1617 utilities.assert_equals(
1618 expect=1,
1619 actual=numClusters,
1620 onpass="ONOS shows 1 SCC",
1621 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1622
1623 main.step( "Comparing ONOS topology to MN" )
1624 devicesResults = main.TRUE
1625 linksResults = main.TRUE
1626 hostsResults = main.TRUE
1627 mnSwitches = main.Mininet1.getSwitches()
1628 mnLinks = main.Mininet1.getLinks()
1629 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07001630 for controller in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001631 controllerStr = str( controller + 1 )
1632 if devices[ controller ] and ports[ controller ] and\
1633 "Error" not in devices[ controller ] and\
1634 "Error" not in ports[ controller ]:
Jon Halle1a3b752015-07-22 13:02:46 -07001635 currentDevicesResult = main.Mininet1.compareSwitches(
1636 mnSwitches,
1637 json.loads( devices[ controller ] ),
1638 json.loads( ports[ controller ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001639 else:
1640 currentDevicesResult = main.FALSE
1641 utilities.assert_equals( expect=main.TRUE,
1642 actual=currentDevicesResult,
1643 onpass="ONOS" + controllerStr +
1644 " Switches view is correct",
1645 onfail="ONOS" + controllerStr +
1646 " Switches view is incorrect" )
1647 if links[ controller ] and "Error" not in links[ controller ]:
1648 currentLinksResult = main.Mininet1.compareLinks(
1649 mnSwitches, mnLinks,
1650 json.loads( links[ controller ] ) )
1651 else:
1652 currentLinksResult = main.FALSE
1653 utilities.assert_equals( expect=main.TRUE,
1654 actual=currentLinksResult,
1655 onpass="ONOS" + controllerStr +
1656 " links view is correct",
1657 onfail="ONOS" + controllerStr +
1658 " links view is incorrect" )
1659
Jon Hall657cdf62015-12-17 14:40:51 -08001660 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001661 currentHostsResult = main.Mininet1.compareHosts(
1662 mnHosts,
1663 hosts[ controller ] )
1664 else:
1665 currentHostsResult = main.FALSE
1666 utilities.assert_equals( expect=main.TRUE,
1667 actual=currentHostsResult,
1668 onpass="ONOS" + controllerStr +
1669 " hosts exist in Mininet",
1670 onfail="ONOS" + controllerStr +
1671 " hosts don't match Mininet" )
1672
1673 devicesResults = devicesResults and currentDevicesResult
1674 linksResults = linksResults and currentLinksResult
1675 hostsResults = hostsResults and currentHostsResult
1676
1677 main.step( "Device information is correct" )
1678 utilities.assert_equals(
1679 expect=main.TRUE,
1680 actual=devicesResults,
1681 onpass="Device information is correct",
1682 onfail="Device information is incorrect" )
1683
1684 main.step( "Links are correct" )
1685 utilities.assert_equals(
1686 expect=main.TRUE,
1687 actual=linksResults,
1688 onpass="Link are correct",
1689 onfail="Links are incorrect" )
1690
1691 main.step( "Hosts are correct" )
1692 utilities.assert_equals(
1693 expect=main.TRUE,
1694 actual=hostsResults,
1695 onpass="Hosts are correct",
1696 onfail="Hosts are incorrect" )
1697
1698 def CASE6( self, main ):
1699 """
1700 The Failure case.
1701 """
1702 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001703 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001704 assert main, "main not defined"
1705 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001706 assert main.CLIs, "main.CLIs not defined"
1707 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001708 try:
1709 labels
1710 except NameError:
1711 main.log.error( "labels not defined, setting to []" )
1712 global labels
1713 labels = []
1714 try:
1715 data
1716 except NameError:
1717 main.log.error( "data not defined, setting to []" )
1718 global data
1719 data = []
1720 # Reset non-persistent variables
1721 try:
1722 iCounterValue = 0
1723 except NameError:
1724 main.log.error( "iCounterValue not defined, setting to 0" )
1725 iCounterValue = 0
1726
1727 main.case( "Restart entire ONOS cluster" )
1728
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001729 main.step( "Checking ONOS Logs for errors" )
1730 for node in main.nodes:
1731 main.log.debug( "Checking logs for errors on " + node.name + ":" )
1732 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
1733
Jon Hall5cf14d52015-07-16 12:15:19 -07001734 main.step( "Killing ONOS nodes" )
1735 killResults = main.TRUE
1736 killTime = time.time()
Jon Halle1a3b752015-07-22 13:02:46 -07001737 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001738 killed = main.ONOSbench.onosKill( node.ip_address )
1739 killResults = killResults and killed
1740 utilities.assert_equals( expect=main.TRUE, actual=killResults,
1741 onpass="ONOS nodes killed",
1742 onfail="ONOS kill unsuccessful" )
1743
1744 main.step( "Checking if ONOS is up yet" )
1745 for i in range( 2 ):
1746 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001747 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001748 started = main.ONOSbench.isup( node.ip_address )
1749 if not started:
1750 main.log.error( node.name + " didn't start!" )
1751 onosIsupResult = onosIsupResult and started
1752 if onosIsupResult == main.TRUE:
1753 break
1754 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1755 onpass="ONOS restarted",
1756 onfail="ONOS restart NOT successful" )
1757
1758 main.log.step( "Starting ONOS CLI sessions" )
1759 cliResults = main.TRUE
1760 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001761 for i in range( main.numCtrls ):
1762 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -07001763 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -07001764 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -07001765 threads.append( t )
1766 t.start()
1767
1768 for t in threads:
1769 t.join()
1770 cliResults = cliResults and t.result
1771 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1772 onpass="ONOS cli started",
1773 onfail="ONOS clis did not restart" )
1774
1775 # Grab the time of restart so we chan check how long the gossip
1776 # protocol has had time to work
1777 main.restartTime = time.time() - killTime
1778 main.log.debug( "Restart time: " + str( main.restartTime ) )
1779 labels.append( "Restart" )
1780 data.append( str( main.restartTime ) )
1781
1782 # FIXME: revisit test plan for election with madan
1783 # Rerun for election on restarted nodes
1784 runResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001785 for cli in main.CLIs:
1786 run = main.CLIs[0].electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07001787 if run != main.TRUE:
1788 main.log.error( "Error running for election on " + cli.name )
1789 runResults = runResults and run
1790 utilities.assert_equals( expect=main.TRUE, actual=runResults,
1791 onpass="Reran for election",
1792 onfail="Failed to rerun for election" )
1793
1794 # TODO: Make this configurable
1795 time.sleep( 60 )
Jon Halle1a3b752015-07-22 13:02:46 -07001796 main.log.debug( main.CLIs[0].nodes( jsonFormat=False ) )
1797 main.log.debug( main.CLIs[0].leaders( jsonFormat=False ) )
1798 main.log.debug( main.CLIs[0].partitions( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001799
1800 def CASE7( self, main ):
1801 """
1802 Check state after ONOS failure
1803 """
1804 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001805 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001806 assert main, "main not defined"
1807 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001808 assert main.CLIs, "main.CLIs not defined"
1809 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001810 main.case( "Running ONOS Constant State Tests" )
1811
1812 main.step( "Check that each switch has a master" )
1813 # Assert that each device has a master
1814 rolesNotNull = main.TRUE
1815 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001816 for i in range( main.numCtrls ):
1817 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001818 name="rolesNotNull-" + str( i ),
1819 args=[ ] )
1820 threads.append( t )
1821 t.start()
1822
1823 for t in threads:
1824 t.join()
1825 rolesNotNull = rolesNotNull and t.result
1826 utilities.assert_equals(
1827 expect=main.TRUE,
1828 actual=rolesNotNull,
1829 onpass="Each device has a master",
1830 onfail="Some devices don't have a master assigned" )
1831
1832 main.step( "Read device roles from ONOS" )
1833 ONOSMastership = []
1834 mastershipCheck = main.FALSE
1835 consistentMastership = True
1836 rolesResults = True
1837 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001838 for i in range( main.numCtrls ):
1839 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001840 name="roles-" + str( i ),
1841 args=[] )
1842 threads.append( t )
1843 t.start()
1844
1845 for t in threads:
1846 t.join()
1847 ONOSMastership.append( t.result )
1848
Jon Halle1a3b752015-07-22 13:02:46 -07001849 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001850 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1851 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1852 " roles" )
1853 main.log.warn(
1854 "ONOS" + str( i + 1 ) + " mastership response: " +
1855 repr( ONOSMastership[i] ) )
1856 rolesResults = False
1857 utilities.assert_equals(
1858 expect=True,
1859 actual=rolesResults,
1860 onpass="No error in reading roles output",
1861 onfail="Error in reading roles from ONOS" )
1862
1863 main.step( "Check for consistency in roles from each controller" )
1864 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1865 main.log.info(
1866 "Switch roles are consistent across all ONOS nodes" )
1867 else:
1868 consistentMastership = False
1869 utilities.assert_equals(
1870 expect=True,
1871 actual=consistentMastership,
1872 onpass="Switch roles are consistent across all ONOS nodes",
1873 onfail="ONOS nodes have different views of switch roles" )
1874
1875 if rolesResults and not consistentMastership:
Jon Halle1a3b752015-07-22 13:02:46 -07001876 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001877 main.log.warn(
1878 "ONOS" + str( i + 1 ) + " roles: ",
1879 json.dumps(
1880 json.loads( ONOSMastership[ i ] ),
1881 sort_keys=True,
1882 indent=4,
1883 separators=( ',', ': ' ) ) )
1884 elif rolesResults and not consistentMastership:
1885 mastershipCheck = main.TRUE
1886
1887 '''
1888 description2 = "Compare switch roles from before failure"
1889 main.step( description2 )
1890 try:
1891 currentJson = json.loads( ONOSMastership[0] )
1892 oldJson = json.loads( mastershipState )
1893 except ( ValueError, TypeError ):
1894 main.log.exception( "Something is wrong with parsing " +
1895 "ONOSMastership[0] or mastershipState" )
1896 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1897 main.log.error( "mastershipState" + repr( mastershipState ) )
1898 main.cleanup()
1899 main.exit()
1900 mastershipCheck = main.TRUE
1901 for i in range( 1, 29 ):
1902 switchDPID = str(
1903 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
1904 current = [ switch[ 'master' ] for switch in currentJson
1905 if switchDPID in switch[ 'id' ] ]
1906 old = [ switch[ 'master' ] for switch in oldJson
1907 if switchDPID in switch[ 'id' ] ]
1908 if current == old:
1909 mastershipCheck = mastershipCheck and main.TRUE
1910 else:
1911 main.log.warn( "Mastership of switch %s changed" % switchDPID )
1912 mastershipCheck = main.FALSE
1913 utilities.assert_equals(
1914 expect=main.TRUE,
1915 actual=mastershipCheck,
1916 onpass="Mastership of Switches was not changed",
1917 onfail="Mastership of some switches changed" )
1918 '''
1919 # NOTE: we expect mastership to change on controller failure
1920
1921 main.step( "Get the intents and compare across all nodes" )
1922 ONOSIntents = []
1923 intentCheck = main.FALSE
1924 consistentIntents = True
1925 intentsResults = True
1926 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001927 for i in range( main.numCtrls ):
1928 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001929 name="intents-" + str( i ),
1930 args=[],
1931 kwargs={ 'jsonFormat': True } )
1932 threads.append( t )
1933 t.start()
1934
1935 for t in threads:
1936 t.join()
1937 ONOSIntents.append( t.result )
1938
Jon Halle1a3b752015-07-22 13:02:46 -07001939 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001940 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1941 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1942 " intents" )
1943 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1944 repr( ONOSIntents[ i ] ) )
1945 intentsResults = False
1946 utilities.assert_equals(
1947 expect=True,
1948 actual=intentsResults,
1949 onpass="No error in reading intents output",
1950 onfail="Error in reading intents from ONOS" )
1951
1952 main.step( "Check for consistency in Intents from each controller" )
1953 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1954 main.log.info( "Intents are consistent across all ONOS " +
1955 "nodes" )
1956 else:
1957 consistentIntents = False
1958
1959 # Try to make it easy to figure out what is happening
1960 #
1961 # Intent ONOS1 ONOS2 ...
1962 # 0x01 INSTALLED INSTALLING
1963 # ... ... ...
1964 # ... ... ...
1965 title = " ID"
Jon Halle1a3b752015-07-22 13:02:46 -07001966 for n in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001967 title += " " * 10 + "ONOS" + str( n + 1 )
1968 main.log.warn( title )
1969 # get all intent keys in the cluster
1970 keys = []
1971 for nodeStr in ONOSIntents:
1972 node = json.loads( nodeStr )
1973 for intent in node:
1974 keys.append( intent.get( 'id' ) )
1975 keys = set( keys )
1976 for key in keys:
1977 row = "%-13s" % key
1978 for nodeStr in ONOSIntents:
1979 node = json.loads( nodeStr )
1980 for intent in node:
1981 if intent.get( 'id' ) == key:
1982 row += "%-15s" % intent.get( 'state' )
1983 main.log.warn( row )
1984 # End table view
1985
1986 utilities.assert_equals(
1987 expect=True,
1988 actual=consistentIntents,
1989 onpass="Intents are consistent across all ONOS nodes",
1990 onfail="ONOS nodes have different views of intents" )
1991 intentStates = []
1992 for node in ONOSIntents: # Iter through ONOS nodes
1993 nodeStates = []
1994 # Iter through intents of a node
1995 try:
1996 for intent in json.loads( node ):
1997 nodeStates.append( intent[ 'state' ] )
1998 except ( ValueError, TypeError ):
1999 main.log.exception( "Error in parsing intents" )
2000 main.log.error( repr( node ) )
2001 intentStates.append( nodeStates )
2002 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
2003 main.log.info( dict( out ) )
2004
2005 if intentsResults and not consistentIntents:
Jon Halle1a3b752015-07-22 13:02:46 -07002006 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07002007 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
2008 main.log.warn( json.dumps(
2009 json.loads( ONOSIntents[ i ] ),
2010 sort_keys=True,
2011 indent=4,
2012 separators=( ',', ': ' ) ) )
2013 elif intentsResults and consistentIntents:
2014 intentCheck = main.TRUE
2015
2016 # NOTE: Store has no durability, so intents are lost across system
2017 # restarts
2018 """
2019 main.step( "Compare current intents with intents before the failure" )
2020 # NOTE: this requires case 5 to pass for intentState to be set.
2021 # maybe we should stop the test if that fails?
2022 sameIntents = main.FALSE
2023 if intentState and intentState == ONOSIntents[ 0 ]:
2024 sameIntents = main.TRUE
2025 main.log.info( "Intents are consistent with before failure" )
2026 # TODO: possibly the states have changed? we may need to figure out
2027 # what the acceptable states are
2028 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
2029 sameIntents = main.TRUE
2030 try:
2031 before = json.loads( intentState )
2032 after = json.loads( ONOSIntents[ 0 ] )
2033 for intent in before:
2034 if intent not in after:
2035 sameIntents = main.FALSE
2036 main.log.debug( "Intent is not currently in ONOS " +
2037 "(at least in the same form):" )
2038 main.log.debug( json.dumps( intent ) )
2039 except ( ValueError, TypeError ):
2040 main.log.exception( "Exception printing intents" )
2041 main.log.debug( repr( ONOSIntents[0] ) )
2042 main.log.debug( repr( intentState ) )
2043 if sameIntents == main.FALSE:
2044 try:
2045 main.log.debug( "ONOS intents before: " )
2046 main.log.debug( json.dumps( json.loads( intentState ),
2047 sort_keys=True, indent=4,
2048 separators=( ',', ': ' ) ) )
2049 main.log.debug( "Current ONOS intents: " )
2050 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
2051 sort_keys=True, indent=4,
2052 separators=( ',', ': ' ) ) )
2053 except ( ValueError, TypeError ):
2054 main.log.exception( "Exception printing intents" )
2055 main.log.debug( repr( ONOSIntents[0] ) )
2056 main.log.debug( repr( intentState ) )
2057 utilities.assert_equals(
2058 expect=main.TRUE,
2059 actual=sameIntents,
2060 onpass="Intents are consistent with before failure",
2061 onfail="The Intents changed during failure" )
2062 intentCheck = intentCheck and sameIntents
2063 """
2064 main.step( "Get the OF Table entries and compare to before " +
2065 "component failure" )
2066 FlowTables = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002067 for i in range( 28 ):
2068 main.log.info( "Checking flow table on s" + str( i + 1 ) )
GlennRC68467eb2015-11-16 18:01:01 -08002069 tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
2070 FlowTables = FlowTables and main.Mininet1.flowTableComp( flows[i], tmpFlows )
Jon Hall5cf14d52015-07-16 12:15:19 -07002071 if FlowTables == main.FALSE:
GlennRC68467eb2015-11-16 18:01:01 -08002072 main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
2073
Jon Hall5cf14d52015-07-16 12:15:19 -07002074 utilities.assert_equals(
2075 expect=main.TRUE,
2076 actual=FlowTables,
2077 onpass="No changes were found in the flow tables",
2078 onfail="Changes were found in the flow tables" )
2079
2080 main.Mininet2.pingLongKill()
2081 '''
2082 # main.step( "Check the continuous pings to ensure that no packets " +
2083 # "were dropped during component failure" )
2084 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
2085 main.params[ 'TESTONIP' ] )
2086 LossInPings = main.FALSE
2087 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
2088 for i in range( 8, 18 ):
2089 main.log.info(
2090 "Checking for a loss in pings along flow from s" +
2091 str( i ) )
2092 LossInPings = main.Mininet2.checkForLoss(
2093 "/tmp/ping.h" +
2094 str( i ) ) or LossInPings
2095 if LossInPings == main.TRUE:
2096 main.log.info( "Loss in ping detected" )
2097 elif LossInPings == main.ERROR:
2098 main.log.info( "There are multiple mininet process running" )
2099 elif LossInPings == main.FALSE:
2100 main.log.info( "No Loss in the pings" )
2101 main.log.info( "No loss of dataplane connectivity" )
2102 # utilities.assert_equals(
2103 # expect=main.FALSE,
2104 # actual=LossInPings,
2105 # onpass="No Loss of connectivity",
2106 # onfail="Loss of dataplane connectivity detected" )
2107
2108 # NOTE: Since intents are not persisted with IntnentStore,
2109 # we expect loss in dataplane connectivity
2110 LossInPings = main.FALSE
2111 '''
2112
2113 main.step( "Leadership Election is still functional" )
2114 # Test of LeadershipElection
2115 leaderList = []
2116 leaderResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002117 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002118 leaderN = cli.electionTestLeader()
2119 leaderList.append( leaderN )
2120 if leaderN == main.FALSE:
2121 # error in response
2122 main.log.error( "Something is wrong with " +
2123 "electionTestLeader function, check the" +
2124 " error logs" )
2125 leaderResult = main.FALSE
2126 elif leaderN is None:
2127 main.log.error( cli.name +
2128 " shows no leader for the election-app." )
2129 leaderResult = main.FALSE
2130 if len( set( leaderList ) ) != 1:
2131 leaderResult = main.FALSE
2132 main.log.error(
2133 "Inconsistent view of leader for the election test app" )
2134 # TODO: print the list
2135 utilities.assert_equals(
2136 expect=main.TRUE,
2137 actual=leaderResult,
2138 onpass="Leadership election passed",
2139 onfail="Something went wrong with Leadership election" )
2140
2141 def CASE8( self, main ):
2142 """
2143 Compare topo
2144 """
2145 import json
2146 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002147 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002148 assert main, "main not defined"
2149 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002150 assert main.CLIs, "main.CLIs not defined"
2151 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002152
2153 main.case( "Compare ONOS Topology view to Mininet topology" )
Jon Hall783bbf92015-07-23 14:33:19 -07002154 main.caseExplanation = "Compare topology objects between Mininet" +\
Jon Hall5cf14d52015-07-16 12:15:19 -07002155 " and ONOS"
Jon Hall5cf14d52015-07-16 12:15:19 -07002156 topoResult = main.FALSE
2157 elapsed = 0
2158 count = 0
Jon Halle9b1fa32015-12-08 15:32:21 -08002159 main.step( "Comparing ONOS topology to MN topology" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002160 startTime = time.time()
2161 # Give time for Gossip to work
Jon Halle9b1fa32015-12-08 15:32:21 -08002162 while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
Jon Hallba609822015-09-18 12:00:21 -07002163 devicesResults = main.TRUE
2164 linksResults = main.TRUE
2165 hostsResults = main.TRUE
2166 hostAttachmentResults = True
Jon Hall5cf14d52015-07-16 12:15:19 -07002167 count += 1
2168 cliStart = time.time()
2169 devices = []
2170 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002171 for i in range( main.numCtrls ):
2172 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07002173 name="devices-" + str( i ),
2174 args=[ ] )
2175 threads.append( t )
2176 t.start()
2177
2178 for t in threads:
2179 t.join()
2180 devices.append( t.result )
2181 hosts = []
2182 ipResult = main.TRUE
2183 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002184 for i in range( main.numCtrls ):
Jon Halld8f6de82015-12-17 17:04:34 -08002185 t = main.Thread( target=utilities.retry,
Jon Hall5cf14d52015-07-16 12:15:19 -07002186 name="hosts-" + str( i ),
Jon Halld8f6de82015-12-17 17:04:34 -08002187 args=[ main.CLIs[i].hosts, [ None ] ],
2188 kwargs= { 'sleep': 5, 'attempts': 5,
2189 'randomTime': True } )
Jon Hall5cf14d52015-07-16 12:15:19 -07002190 threads.append( t )
2191 t.start()
2192
2193 for t in threads:
2194 t.join()
2195 try:
2196 hosts.append( json.loads( t.result ) )
2197 except ( ValueError, TypeError ):
2198 main.log.exception( "Error parsing hosts results" )
2199 main.log.error( repr( t.result ) )
Jon Hall3afe4c92015-12-14 19:30:38 -08002200 hosts.append( None )
Jon Hall5cf14d52015-07-16 12:15:19 -07002201 for controller in range( 0, len( hosts ) ):
2202 controllerStr = str( controller + 1 )
Jon Hallacd1b182015-12-17 11:43:20 -08002203 if hosts[ controller ]:
2204 for host in hosts[ controller ]:
2205 if host is None or host.get( 'ipAddresses', [] ) == []:
2206 main.log.error(
2207 "Error with host ipAddresses on controller" +
2208 controllerStr + ": " + str( host ) )
2209 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002210 ports = []
2211 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002212 for i in range( main.numCtrls ):
2213 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07002214 name="ports-" + str( i ),
2215 args=[ ] )
2216 threads.append( t )
2217 t.start()
2218
2219 for t in threads:
2220 t.join()
2221 ports.append( t.result )
2222 links = []
2223 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002224 for i in range( main.numCtrls ):
2225 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07002226 name="links-" + str( i ),
2227 args=[ ] )
2228 threads.append( t )
2229 t.start()
2230
2231 for t in threads:
2232 t.join()
2233 links.append( t.result )
2234 clusters = []
2235 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002236 for i in range( main.numCtrls ):
2237 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07002238 name="clusters-" + str( i ),
2239 args=[ ] )
2240 threads.append( t )
2241 t.start()
2242
2243 for t in threads:
2244 t.join()
2245 clusters.append( t.result )
2246
2247 elapsed = time.time() - startTime
2248 cliTime = time.time() - cliStart
2249 print "Elapsed time: " + str( elapsed )
2250 print "CLI time: " + str( cliTime )
2251
2252 mnSwitches = main.Mininet1.getSwitches()
2253 mnLinks = main.Mininet1.getLinks()
2254 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07002255 for controller in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07002256 controllerStr = str( controller + 1 )
2257 if devices[ controller ] and ports[ controller ] and\
2258 "Error" not in devices[ controller ] and\
2259 "Error" not in ports[ controller ]:
2260
2261 currentDevicesResult = main.Mininet1.compareSwitches(
2262 mnSwitches,
2263 json.loads( devices[ controller ] ),
2264 json.loads( ports[ controller ] ) )
2265 else:
2266 currentDevicesResult = main.FALSE
2267 utilities.assert_equals( expect=main.TRUE,
2268 actual=currentDevicesResult,
2269 onpass="ONOS" + controllerStr +
2270 " Switches view is correct",
2271 onfail="ONOS" + controllerStr +
2272 " Switches view is incorrect" )
2273
2274 if links[ controller ] and "Error" not in links[ controller ]:
2275 currentLinksResult = main.Mininet1.compareLinks(
2276 mnSwitches, mnLinks,
2277 json.loads( links[ controller ] ) )
2278 else:
2279 currentLinksResult = main.FALSE
2280 utilities.assert_equals( expect=main.TRUE,
2281 actual=currentLinksResult,
2282 onpass="ONOS" + controllerStr +
2283 " links view is correct",
2284 onfail="ONOS" + controllerStr +
2285 " links view is incorrect" )
Jon Hall657cdf62015-12-17 14:40:51 -08002286 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002287 currentHostsResult = main.Mininet1.compareHosts(
2288 mnHosts,
2289 hosts[ controller ] )
Jon Hall13b446e2016-01-05 12:17:01 -08002290 elif hosts[ controller ] == []:
2291 currentHostsResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002292 else:
2293 currentHostsResult = main.FALSE
2294 utilities.assert_equals( expect=main.TRUE,
2295 actual=currentHostsResult,
2296 onpass="ONOS" + controllerStr +
2297 " hosts exist in Mininet",
2298 onfail="ONOS" + controllerStr +
2299 " hosts don't match Mininet" )
2300 # CHECKING HOST ATTACHMENT POINTS
2301 hostAttachment = True
2302 noHosts = False
2303 # FIXME: topo-HA/obelisk specific mappings:
2304 # key is mac and value is dpid
2305 mappings = {}
2306 for i in range( 1, 29 ): # hosts 1 through 28
2307 # set up correct variables:
2308 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2309 if i == 1:
2310 deviceId = "1000".zfill(16)
2311 elif i == 2:
2312 deviceId = "2000".zfill(16)
2313 elif i == 3:
2314 deviceId = "3000".zfill(16)
2315 elif i == 4:
2316 deviceId = "3004".zfill(16)
2317 elif i == 5:
2318 deviceId = "5000".zfill(16)
2319 elif i == 6:
2320 deviceId = "6000".zfill(16)
2321 elif i == 7:
2322 deviceId = "6007".zfill(16)
2323 elif i >= 8 and i <= 17:
2324 dpid = '3' + str( i ).zfill( 3 )
2325 deviceId = dpid.zfill(16)
2326 elif i >= 18 and i <= 27:
2327 dpid = '6' + str( i ).zfill( 3 )
2328 deviceId = dpid.zfill(16)
2329 elif i == 28:
2330 deviceId = "2800".zfill(16)
2331 mappings[ macId ] = deviceId
Jon Halld8f6de82015-12-17 17:04:34 -08002332 if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002333 if hosts[ controller ] == []:
2334 main.log.warn( "There are no hosts discovered" )
2335 noHosts = True
2336 else:
2337 for host in hosts[ controller ]:
2338 mac = None
2339 location = None
2340 device = None
2341 port = None
2342 try:
2343 mac = host.get( 'mac' )
2344 assert mac, "mac field could not be found for this host object"
2345
2346 location = host.get( 'location' )
2347 assert location, "location field could not be found for this host object"
2348
2349 # Trim the protocol identifier off deviceId
2350 device = str( location.get( 'elementId' ) ).split(':')[1]
2351 assert device, "elementId field could not be found for this host location object"
2352
2353 port = location.get( 'port' )
2354 assert port, "port field could not be found for this host location object"
2355
2356 # Now check if this matches where they should be
2357 if mac and device and port:
2358 if str( port ) != "1":
2359 main.log.error( "The attachment port is incorrect for " +
2360 "host " + str( mac ) +
2361 ". Expected: 1 Actual: " + str( port) )
2362 hostAttachment = False
2363 if device != mappings[ str( mac ) ]:
2364 main.log.error( "The attachment device is incorrect for " +
2365 "host " + str( mac ) +
2366 ". Expected: " + mappings[ str( mac ) ] +
2367 " Actual: " + device )
2368 hostAttachment = False
2369 else:
2370 hostAttachment = False
2371 except AssertionError:
2372 main.log.exception( "Json object not as expected" )
2373 main.log.error( repr( host ) )
2374 hostAttachment = False
2375 else:
2376 main.log.error( "No hosts json output or \"Error\"" +
2377 " in output. hosts = " +
2378 repr( hosts[ controller ] ) )
2379 if noHosts is False:
2380 # TODO: Find a way to know if there should be hosts in a
2381 # given point of the test
2382 hostAttachment = True
2383
2384 # END CHECKING HOST ATTACHMENT POINTS
2385 devicesResults = devicesResults and currentDevicesResult
2386 linksResults = linksResults and currentLinksResult
2387 hostsResults = hostsResults and currentHostsResult
2388 hostAttachmentResults = hostAttachmentResults and\
2389 hostAttachment
2390 topoResult = ( devicesResults and linksResults
2391 and hostsResults and ipResult and
2392 hostAttachmentResults )
Jon Halle9b1fa32015-12-08 15:32:21 -08002393 utilities.assert_equals( expect=True,
2394 actual=topoResult,
2395 onpass="ONOS topology matches Mininet",
2396 onfail="ONOS topology don't match Mininet" )
2397 # End of While loop to pull ONOS state
Jon Hall5cf14d52015-07-16 12:15:19 -07002398
2399 # Compare json objects for hosts and dataplane clusters
2400
2401 # hosts
2402 main.step( "Hosts view is consistent across all ONOS nodes" )
2403 consistentHostsResult = main.TRUE
2404 for controller in range( len( hosts ) ):
2405 controllerStr = str( controller + 1 )
Jon Hall13b446e2016-01-05 12:17:01 -08002406 if hosts[ controller ] is not None and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002407 if hosts[ controller ] == hosts[ 0 ]:
2408 continue
2409 else: # hosts not consistent
2410 main.log.error( "hosts from ONOS" + controllerStr +
2411 " is inconsistent with ONOS1" )
2412 main.log.warn( repr( hosts[ controller ] ) )
2413 consistentHostsResult = main.FALSE
2414
2415 else:
2416 main.log.error( "Error in getting ONOS hosts from ONOS" +
2417 controllerStr )
2418 consistentHostsResult = main.FALSE
2419 main.log.warn( "ONOS" + controllerStr +
2420 " hosts response: " +
2421 repr( hosts[ controller ] ) )
2422 utilities.assert_equals(
2423 expect=main.TRUE,
2424 actual=consistentHostsResult,
2425 onpass="Hosts view is consistent across all ONOS nodes",
2426 onfail="ONOS nodes have different views of hosts" )
2427
2428 main.step( "Hosts information is correct" )
2429 hostsResults = hostsResults and ipResult
2430 utilities.assert_equals(
2431 expect=main.TRUE,
2432 actual=hostsResults,
2433 onpass="Host information is correct",
2434 onfail="Host information is incorrect" )
2435
2436 main.step( "Host attachment points to the network" )
2437 utilities.assert_equals(
2438 expect=True,
2439 actual=hostAttachmentResults,
2440 onpass="Hosts are correctly attached to the network",
2441 onfail="ONOS did not correctly attach hosts to the network" )
2442
2443 # Strongly connected clusters of devices
2444 main.step( "Clusters view is consistent across all ONOS nodes" )
2445 consistentClustersResult = main.TRUE
2446 for controller in range( len( clusters ) ):
2447 controllerStr = str( controller + 1 )
2448 if "Error" not in clusters[ controller ]:
2449 if clusters[ controller ] == clusters[ 0 ]:
2450 continue
2451 else: # clusters not consistent
2452 main.log.error( "clusters from ONOS" +
2453 controllerStr +
2454 " is inconsistent with ONOS1" )
2455 consistentClustersResult = main.FALSE
2456
2457 else:
2458 main.log.error( "Error in getting dataplane clusters " +
2459 "from ONOS" + controllerStr )
2460 consistentClustersResult = main.FALSE
2461 main.log.warn( "ONOS" + controllerStr +
2462 " clusters response: " +
2463 repr( clusters[ controller ] ) )
2464 utilities.assert_equals(
2465 expect=main.TRUE,
2466 actual=consistentClustersResult,
2467 onpass="Clusters view is consistent across all ONOS nodes",
2468 onfail="ONOS nodes have different views of clusters" )
2469
2470 main.step( "There is only one SCC" )
2471 # there should always only be one cluster
2472 try:
2473 numClusters = len( json.loads( clusters[ 0 ] ) )
2474 except ( ValueError, TypeError ):
2475 main.log.exception( "Error parsing clusters[0]: " +
2476 repr( clusters[0] ) )
2477 clusterResults = main.FALSE
2478 if numClusters == 1:
2479 clusterResults = main.TRUE
2480 utilities.assert_equals(
2481 expect=1,
2482 actual=numClusters,
2483 onpass="ONOS shows 1 SCC",
2484 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2485
2486 topoResult = ( devicesResults and linksResults
2487 and hostsResults and consistentHostsResult
2488 and consistentClustersResult and clusterResults
2489 and ipResult and hostAttachmentResults )
2490
2491 topoResult = topoResult and int( count <= 2 )
2492 note = "note it takes about " + str( int( cliTime ) ) + \
2493 " seconds for the test to make all the cli calls to fetch " +\
2494 "the topology from each ONOS instance"
2495 main.log.info(
2496 "Very crass estimate for topology discovery/convergence( " +
2497 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2498 str( count ) + " tries" )
2499
2500 main.step( "Device information is correct" )
2501 utilities.assert_equals(
2502 expect=main.TRUE,
2503 actual=devicesResults,
2504 onpass="Device information is correct",
2505 onfail="Device information is incorrect" )
2506
2507 main.step( "Links are correct" )
2508 utilities.assert_equals(
2509 expect=main.TRUE,
2510 actual=linksResults,
2511 onpass="Link are correct",
2512 onfail="Links are incorrect" )
2513
2514 # FIXME: move this to an ONOS state case
2515 main.step( "Checking ONOS nodes" )
2516 nodesOutput = []
2517 nodeResults = main.TRUE
2518 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002519 for i in range( main.numCtrls ):
2520 t = main.Thread( target=main.CLIs[i].nodes,
Jon Hall5cf14d52015-07-16 12:15:19 -07002521 name="nodes-" + str( i ),
2522 args=[ ] )
2523 threads.append( t )
2524 t.start()
2525
2526 for t in threads:
2527 t.join()
2528 nodesOutput.append( t.result )
Jon Halle1a3b752015-07-22 13:02:46 -07002529 ips = [ node.ip_address for node in main.nodes ]
Jon Halle9b1fa32015-12-08 15:32:21 -08002530 ips.sort()
Jon Hall5cf14d52015-07-16 12:15:19 -07002531 for i in nodesOutput:
2532 try:
2533 current = json.loads( i )
Jon Halle9b1fa32015-12-08 15:32:21 -08002534 activeIps = []
2535 currentResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002536 for node in current:
Jon Halle9b1fa32015-12-08 15:32:21 -08002537 if node['state'] == 'ACTIVE':
2538 activeIps.append( node['ip'] )
2539 activeIps.sort()
2540 if ips == activeIps:
2541 currentResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002542 except ( ValueError, TypeError ):
2543 main.log.error( "Error parsing nodes output" )
2544 main.log.warn( repr( i ) )
Jon Halle9b1fa32015-12-08 15:32:21 -08002545 currentResult = main.FALSE
2546 nodeResults = nodeResults and currentResult
Jon Hall5cf14d52015-07-16 12:15:19 -07002547 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2548 onpass="Nodes check successful",
2549 onfail="Nodes check NOT successful" )
2550
2551 def CASE9( self, main ):
2552 """
2553 Link s3-s28 down
2554 """
2555 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002556 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002557 assert main, "main not defined"
2558 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002559 assert main.CLIs, "main.CLIs not defined"
2560 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002561 # NOTE: You should probably run a topology check after this
2562
2563 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2564
2565 description = "Turn off a link to ensure that Link Discovery " +\
2566 "is working properly"
2567 main.case( description )
2568
2569 main.step( "Kill Link between s3 and s28" )
2570 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
2571 main.log.info( "Waiting " + str( linkSleep ) +
2572 " seconds for link down to be discovered" )
2573 time.sleep( linkSleep )
2574 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
2575 onpass="Link down successful",
2576 onfail="Failed to bring link down" )
2577 # TODO do some sort of check here
2578
2579 def CASE10( self, main ):
2580 """
2581 Link s3-s28 up
2582 """
2583 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002584 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002585 assert main, "main not defined"
2586 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002587 assert main.CLIs, "main.CLIs not defined"
2588 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002589 # NOTE: You should probably run a topology check after this
2590
2591 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2592
2593 description = "Restore a link to ensure that Link Discovery is " + \
2594 "working properly"
2595 main.case( description )
2596
2597 main.step( "Bring link between s3 and s28 back up" )
2598 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
2599 main.log.info( "Waiting " + str( linkSleep ) +
2600 " seconds for link up to be discovered" )
2601 time.sleep( linkSleep )
2602 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
2603 onpass="Link up successful",
2604 onfail="Failed to bring link up" )
2605 # TODO do some sort of check here
2606
2607 def CASE11( self, main ):
2608 """
2609 Switch Down
2610 """
2611 # NOTE: You should probably run a topology check after this
2612 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002613 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002614 assert main, "main not defined"
2615 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002616 assert main.CLIs, "main.CLIs not defined"
2617 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002618
2619 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2620
2621 description = "Killing a switch to ensure it is discovered correctly"
2622 main.case( description )
2623 switch = main.params[ 'kill' ][ 'switch' ]
2624 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2625
2626 # TODO: Make this switch parameterizable
2627 main.step( "Kill " + switch )
2628 main.log.info( "Deleting " + switch )
2629 main.Mininet1.delSwitch( switch )
2630 main.log.info( "Waiting " + str( switchSleep ) +
2631 " seconds for switch down to be discovered" )
2632 time.sleep( switchSleep )
2633 device = main.ONOScli1.getDevice( dpid=switchDPID )
2634 # Peek at the deleted switch
2635 main.log.warn( str( device ) )
2636 result = main.FALSE
2637 if device and device[ 'available' ] is False:
2638 result = main.TRUE
2639 utilities.assert_equals( expect=main.TRUE, actual=result,
2640 onpass="Kill switch successful",
2641 onfail="Failed to kill switch?" )
2642
2643 def CASE12( self, main ):
2644 """
2645 Switch Up
2646 """
2647 # NOTE: You should probably run a topology check after this
2648 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002649 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002650 assert main, "main not defined"
2651 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002652 assert main.CLIs, "main.CLIs not defined"
2653 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002654 assert ONOS1Port, "ONOS1Port not defined"
2655 assert ONOS2Port, "ONOS2Port not defined"
2656 assert ONOS3Port, "ONOS3Port not defined"
2657 assert ONOS4Port, "ONOS4Port not defined"
2658 assert ONOS5Port, "ONOS5Port not defined"
2659 assert ONOS6Port, "ONOS6Port not defined"
2660 assert ONOS7Port, "ONOS7Port not defined"
2661
2662 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2663 switch = main.params[ 'kill' ][ 'switch' ]
2664 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2665 links = main.params[ 'kill' ][ 'links' ].split()
2666 description = "Adding a switch to ensure it is discovered correctly"
2667 main.case( description )
2668
2669 main.step( "Add back " + switch )
2670 main.Mininet1.addSwitch( switch, dpid=switchDPID )
2671 for peer in links:
2672 main.Mininet1.addLink( switch, peer )
2673 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -07002674 for i in range( main.numCtrls ):
2675 ipList.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -07002676 main.Mininet1.assignSwController( sw=switch, ip=ipList )
2677 main.log.info( "Waiting " + str( switchSleep ) +
2678 " seconds for switch up to be discovered" )
2679 time.sleep( switchSleep )
2680 device = main.ONOScli1.getDevice( dpid=switchDPID )
2681 # Peek at the deleted switch
2682 main.log.warn( str( device ) )
2683 result = main.FALSE
2684 if device and device[ 'available' ]:
2685 result = main.TRUE
2686 utilities.assert_equals( expect=main.TRUE, actual=result,
2687 onpass="add switch successful",
2688 onfail="Failed to add switch?" )
2689
2690 def CASE13( self, main ):
2691 """
2692 Clean up
2693 """
2694 import os
2695 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002696 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002697 assert main, "main not defined"
2698 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002699 assert main.CLIs, "main.CLIs not defined"
2700 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002701
2702 # printing colors to terminal
2703 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2704 'blue': '\033[94m', 'green': '\033[92m',
2705 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
2706 main.case( "Test Cleanup" )
2707 main.step( "Killing tcpdumps" )
2708 main.Mininet2.stopTcpdump()
2709
2710 testname = main.TEST
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002711 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall5cf14d52015-07-16 12:15:19 -07002712 main.step( "Copying MN pcap and ONOS log files to test station" )
2713 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
2714 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
Jon Hall96091e62015-09-21 17:34:17 -07002715 # NOTE: MN Pcap file is being saved to logdir.
2716 # We scp this file as MN and TestON aren't necessarily the same vm
2717
2718 # FIXME: To be replaced with a Jenkin's post script
Jon Hall5cf14d52015-07-16 12:15:19 -07002719 # TODO: Load these from params
2720 # NOTE: must end in /
2721 logFolder = "/opt/onos/log/"
2722 logFiles = [ "karaf.log", "karaf.log.1" ]
2723 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002724 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002725 for node in main.nodes:
Jon Hall96091e62015-09-21 17:34:17 -07002726 dstName = main.logdir + "/" + node.name + "-" + f
2727 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2728 logFolder + f, dstName )
Jon Hall5cf14d52015-07-16 12:15:19 -07002729 # std*.log's
2730 # NOTE: must end in /
2731 logFolder = "/opt/onos/var/"
2732 logFiles = [ "stderr.log", "stdout.log" ]
2733 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002734 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002735 for node in main.nodes:
Jon Hall96091e62015-09-21 17:34:17 -07002736 dstName = main.logdir + "/" + node.name + "-" + f
2737 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2738 logFolder + f, dstName )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002739 else:
2740 main.log.debug( "skipping saving log files" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002741
2742 main.step( "Stopping Mininet" )
2743 mnResult = main.Mininet1.stopNet()
2744 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2745 onpass="Mininet stopped",
2746 onfail="MN cleanup NOT successful" )
2747
2748 main.step( "Checking ONOS Logs for errors" )
Jon Halle1a3b752015-07-22 13:02:46 -07002749 for node in main.nodes:
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002750 main.log.debug( "Checking logs for errors on " + node.name + ":" )
2751 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002752
2753 try:
2754 timerLog = open( main.logdir + "/Timers.csv", 'w')
2755 main.log.error( ", ".join( labels ) + "\n" + ", ".join( data ) )
2756 timerLog.write( ", ".join( labels ) + "\n" + ", ".join( data ) )
2757 timerLog.close()
2758 except NameError, e:
2759 main.log.exception(e)
2760
2761 def CASE14( self, main ):
2762 """
2763 start election app on all onos nodes
2764 """
Jon Halle1a3b752015-07-22 13:02:46 -07002765 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002766 assert main, "main not defined"
2767 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002768 assert main.CLIs, "main.CLIs not defined"
2769 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002770
2771 main.case("Start Leadership Election app")
2772 main.step( "Install leadership election app" )
2773 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
2774 utilities.assert_equals(
2775 expect=main.TRUE,
2776 actual=appResult,
2777 onpass="Election app installed",
2778 onfail="Something went wrong with installing Leadership election" )
2779
2780 main.step( "Run for election on each node" )
2781 leaderResult = main.TRUE
2782 leaders = []
Jon Halle1a3b752015-07-22 13:02:46 -07002783 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002784 cli.electionTestRun()
Jon Halle1a3b752015-07-22 13:02:46 -07002785 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002786 leader = cli.electionTestLeader()
2787 if leader is None or leader == main.FALSE:
2788 main.log.error( cli.name + ": Leader for the election app " +
2789 "should be an ONOS node, instead got '" +
2790 str( leader ) + "'" )
2791 leaderResult = main.FALSE
2792 leaders.append( leader )
2793 utilities.assert_equals(
2794 expect=main.TRUE,
2795 actual=leaderResult,
2796 onpass="Successfully ran for leadership",
2797 onfail="Failed to run for leadership" )
2798
2799 main.step( "Check that each node shows the same leader" )
2800 sameLeader = main.TRUE
2801 if len( set( leaders ) ) != 1:
2802 sameLeader = main.FALSE
2803 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2804 str( leaders ) )
2805 utilities.assert_equals(
2806 expect=main.TRUE,
2807 actual=sameLeader,
2808 onpass="Leadership is consistent for the election topic",
2809 onfail="Nodes have different leaders" )
2810
2811 def CASE15( self, main ):
2812 """
2813 Check that Leadership Election is still functional
acsmars9475b1c2015-08-28 18:02:08 -07002814 15.1 Run election on each node
2815 15.2 Check that each node has the same leaders and candidates
2816 15.3 Find current leader and withdraw
2817 15.4 Check that a new node was elected leader
2818 15.5 Check that that new leader was the candidate of old leader
2819 15.6 Run for election on old leader
2820 15.7 Check that oldLeader is a candidate, and leader if only 1 node
2821 15.8 Make sure that the old leader was added to the candidate list
2822
2823 old and new variable prefixes refer to data from before vs after
2824 withdrawl and later before withdrawl vs after re-election
Jon Hall5cf14d52015-07-16 12:15:19 -07002825 """
2826 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002827 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002828 assert main, "main not defined"
2829 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002830 assert main.CLIs, "main.CLIs not defined"
2831 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002832
Jon Hall5cf14d52015-07-16 12:15:19 -07002833 description = "Check that Leadership Election is still functional"
2834 main.case( description )
2835 # NOTE: Need to re-run since being a canidate is not persistant
acsmars9475b1c2015-08-28 18:02:08 -07002836 # TODO: add check for "Command not found:" in the driver, this
2837 # means the election test app isn't loaded
2838
2839 oldLeaders = [] # leaders by node before withdrawl from candidates
2840 newLeaders = [] # leaders by node after withdrawl from candidates
2841 oldAllCandidates = [] # list of lists of each nodes' candidates before
2842 newAllCandidates = [] # list of lists of each nodes' candidates after
2843 oldCandidates = [] # list of candidates from node 0 before withdrawl
2844 newCandidates = [] # list of candidates from node 0 after withdrawl
2845 oldLeader = '' # the old leader from oldLeaders, None if not same
2846 newLeader = '' # the new leaders fron newLoeaders, None if not same
2847 oldLeaderCLI = None # the CLI of the old leader used for re-electing
acsmars71adceb2015-08-31 15:09:26 -07002848 expectNoLeader = False # True when there is only one leader
2849 if main.numCtrls == 1:
2850 expectNoLeader = True
acsmars9475b1c2015-08-28 18:02:08 -07002851
Jon Hall5cf14d52015-07-16 12:15:19 -07002852 main.step( "Run for election on each node" )
acsmars9475b1c2015-08-28 18:02:08 -07002853 electionResult = main.TRUE
2854
2855 for cli in main.CLIs: # run test election on each node
2856 if cli.electionTestRun() == main.FALSE:
2857 electionResult = main.FALSE
2858
Jon Hall5cf14d52015-07-16 12:15:19 -07002859 utilities.assert_equals(
2860 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07002861 actual=electionResult,
2862 onpass="All nodes successfully ran for leadership",
2863 onfail="At least one node failed to run for leadership" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002864
acsmars3a72bde2015-09-02 14:16:22 -07002865 if electionResult == main.FALSE:
2866 main.log.error(
2867 "Skipping Test Case because Election Test App isn't loaded" )
2868 main.skipCase()
2869
acsmars9475b1c2015-08-28 18:02:08 -07002870 main.step( "Check that each node shows the same leader and candidates" )
2871 sameResult = main.TRUE
2872 failMessage = "Nodes have different leaders"
2873 for cli in main.CLIs:
2874 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2875 oldAllCandidates.append( node )
2876 oldLeaders.append( node[ 0 ] )
2877 oldCandidates = oldAllCandidates[ 0 ]
2878
2879 # Check that each node has the same leader. Defines oldLeader
2880 if len( set( oldLeaders ) ) != 1:
2881 sameResult = main.FALSE
acsmars71adceb2015-08-31 15:09:26 -07002882 main.log.error( "More than one leader present:" + str( oldLeaders ) )
acsmars9475b1c2015-08-28 18:02:08 -07002883 oldLeader = None
2884 else:
2885 oldLeader = oldLeaders[ 0 ]
2886
2887 # Check that each node's candidate list is the same
acsmars29233db2015-11-04 11:15:00 -08002888 candidateDiscrepancy = False # Boolean of candidate mismatches
acsmars9475b1c2015-08-28 18:02:08 -07002889 for candidates in oldAllCandidates:
2890 if set( candidates ) != set( oldCandidates ):
2891 sameResult = main.FALSE
acsmars29233db2015-11-04 11:15:00 -08002892 candidateDiscrepancy = True
2893
2894 if candidateDiscrepancy:
2895 failMessage += " and candidates"
acsmars9475b1c2015-08-28 18:02:08 -07002896
Jon Hall5cf14d52015-07-16 12:15:19 -07002897 utilities.assert_equals(
2898 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002899 actual=sameResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002900 onpass="Leadership is consistent for the election topic",
acsmars9475b1c2015-08-28 18:02:08 -07002901 onfail=failMessage )
Jon Hall5cf14d52015-07-16 12:15:19 -07002902
2903 main.step( "Find current leader and withdraw" )
acsmars9475b1c2015-08-28 18:02:08 -07002904 withdrawResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002905 # do some sanity checking on leader before using it
acsmars9475b1c2015-08-28 18:02:08 -07002906 if oldLeader is None:
2907 main.log.error( "Leadership isn't consistent." )
2908 withdrawResult = main.FALSE
2909 # Get the CLI of the oldLeader
Jon Halle1a3b752015-07-22 13:02:46 -07002910 for i in range( len( main.CLIs ) ):
acsmars9475b1c2015-08-28 18:02:08 -07002911 if oldLeader == main.nodes[ i ].ip_address:
2912 oldLeaderCLI = main.CLIs[ i ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002913 break
2914 else: # FOR/ELSE statement
2915 main.log.error( "Leader election, could not find current leader" )
2916 if oldLeader:
acsmars9475b1c2015-08-28 18:02:08 -07002917 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall5cf14d52015-07-16 12:15:19 -07002918 utilities.assert_equals(
2919 expect=main.TRUE,
2920 actual=withdrawResult,
2921 onpass="Node was withdrawn from election",
2922 onfail="Node was not withdrawn from election" )
2923
acsmars9475b1c2015-08-28 18:02:08 -07002924 main.step( "Check that a new node was elected leader" )
acsmars71adceb2015-08-31 15:09:26 -07002925
Jon Hall5cf14d52015-07-16 12:15:19 -07002926 # FIXME: use threads
acsmars9475b1c2015-08-28 18:02:08 -07002927 newLeaderResult = main.TRUE
2928 failMessage = "Nodes have different leaders"
2929
2930 # Get new leaders and candidates
Jon Halle1a3b752015-07-22 13:02:46 -07002931 for cli in main.CLIs:
acsmars9475b1c2015-08-28 18:02:08 -07002932 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
acsmars71adceb2015-08-31 15:09:26 -07002933 # elections might no have finished yet
2934 if node[ 0 ] == 'none' and not expectNoLeader:
acsmars9475b1c2015-08-28 18:02:08 -07002935 main.log.info( "Node has no leader, waiting 5 seconds to be " +
2936 "sure elections are complete." )
2937 time.sleep(5)
2938 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
acsmars71adceb2015-08-31 15:09:26 -07002939 # election still isn't done or there is a problem
2940 if node[ 0 ] == 'none':
2941 main.log.error( "No leader was elected on at least 1 node" )
2942 newLeaderResult = main.FALSE
acsmars9475b1c2015-08-28 18:02:08 -07002943 newAllCandidates.append( node )
2944 newLeaders.append( node[ 0 ] )
2945 newCandidates = newAllCandidates[ 0 ]
2946
2947 # Check that each node has the same leader. Defines newLeader
2948 if len( set( newLeaders ) ) != 1:
2949 newLeaderResult = main.FALSE
2950 main.log.error( "Nodes have different leaders: " +
2951 str( newLeaders ) )
2952 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07002953 else:
acsmars9475b1c2015-08-28 18:02:08 -07002954 newLeader = newLeaders[ 0 ]
2955
acsmars71adceb2015-08-31 15:09:26 -07002956 # Check that each node's candidate list is the same
2957 for candidates in newAllCandidates:
2958 if set( candidates ) != set( newCandidates ):
2959 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07002960 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07002961
acsmars9475b1c2015-08-28 18:02:08 -07002962 # Check that the new leader is not the older leader, which was withdrawn
2963 if newLeader == oldLeader:
2964 newLeaderResult = main.FALSE
2965 main.log.error( "All nodes still see old leader: " + oldLeader +
2966 " as the current leader" )
2967
Jon Hall5cf14d52015-07-16 12:15:19 -07002968 utilities.assert_equals(
2969 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07002970 actual=newLeaderResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002971 onpass="Leadership election passed",
2972 onfail="Something went wrong with Leadership election" )
2973
acsmars9475b1c2015-08-28 18:02:08 -07002974 main.step( "Check that that new leader was the candidate of old leader")
2975 # candidates[ 2 ] should be come the top candidate after withdrawl
2976 correctCandidateResult = main.TRUE
acsmars71adceb2015-08-31 15:09:26 -07002977 if expectNoLeader:
2978 if newLeader == 'none':
2979 main.log.info( "No leader expected. None found. Pass" )
2980 correctCandidateResult = main.TRUE
2981 else:
2982 main.log.info( "Expected no leader, got: " + str( newLeader ) )
2983 correctCandidateResult = main.FALSE
2984 elif newLeader != oldCandidates[ 2 ]:
acsmars9475b1c2015-08-28 18:02:08 -07002985 correctCandidateResult = main.FALSE
2986 main.log.error( "Candidate " + newLeader + " was elected. " +
2987 oldCandidates[ 2 ] + " should have had priority." )
2988
2989 utilities.assert_equals(
2990 expect=main.TRUE,
2991 actual=correctCandidateResult,
2992 onpass="Correct Candidate Elected",
2993 onfail="Incorrect Candidate Elected" )
2994
Jon Hall5cf14d52015-07-16 12:15:19 -07002995 main.step( "Run for election on old leader( just so everyone " +
2996 "is in the hat )" )
acsmars9475b1c2015-08-28 18:02:08 -07002997 if oldLeaderCLI is not None:
2998 runResult = oldLeaderCLI.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07002999 else:
acsmars9475b1c2015-08-28 18:02:08 -07003000 main.log.error( "No old leader to re-elect" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003001 runResult = main.FALSE
3002 utilities.assert_equals(
3003 expect=main.TRUE,
3004 actual=runResult,
3005 onpass="App re-ran for election",
3006 onfail="App failed to run for election" )
acsmars9475b1c2015-08-28 18:02:08 -07003007 main.step(
3008 "Check that oldLeader is a candidate, and leader if only 1 node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003009 # verify leader didn't just change
acsmars9475b1c2015-08-28 18:02:08 -07003010 positionResult = main.TRUE
3011 # Get new leaders and candidates, wait if oldLeader is not a candidate yet
3012
3013 # Reset and reuse the new candidate and leaders lists
3014 newAllCandidates = []
3015 newCandidates = []
3016 newLeaders = []
3017 for cli in main.CLIs:
3018 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
3019 if oldLeader not in node: # election might no have finished yet
3020 main.log.info( "Old Leader not elected, waiting 5 seconds to " +
3021 "be sure elections are complete" )
3022 time.sleep(5)
3023 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
3024 if oldLeader not in node: # election still isn't done, errors
3025 main.log.error(
3026 "Old leader was not elected on at least one node" )
3027 positionResult = main.FALSE
3028 newAllCandidates.append( node )
3029 newLeaders.append( node[ 0 ] )
3030 newCandidates = newAllCandidates[ 0 ]
3031
3032 # Check that each node has the same leader. Defines newLeader
3033 if len( set( newLeaders ) ) != 1:
3034 positionResult = main.FALSE
3035 main.log.error( "Nodes have different leaders: " +
3036 str( newLeaders ) )
3037 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07003038 else:
acsmars9475b1c2015-08-28 18:02:08 -07003039 newLeader = newLeaders[ 0 ]
3040
acsmars71adceb2015-08-31 15:09:26 -07003041 # Check that each node's candidate list is the same
3042 for candidates in newAllCandidates:
3043 if set( candidates ) != set( newCandidates ):
3044 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07003045 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07003046
acsmars9475b1c2015-08-28 18:02:08 -07003047 # Check that the re-elected node is last on the candidate List
3048 if oldLeader != newCandidates[ -1 ]:
3049 main.log.error( "Old Leader (" + oldLeader + ") not in the proper position " +
3050 str( newCandidates ) )
3051 positionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07003052
3053 utilities.assert_equals(
3054 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07003055 actual=positionResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07003056 onpass="Old leader successfully re-ran for election",
3057 onfail="Something went wrong with Leadership election after " +
3058 "the old leader re-ran for election" )
3059
3060 def CASE16( self, main ):
3061 """
3062 Install Distributed Primitives app
3063 """
3064 import time
Jon Halle1a3b752015-07-22 13:02:46 -07003065 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003066 assert main, "main not defined"
3067 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003068 assert main.CLIs, "main.CLIs not defined"
3069 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003070
3071 # Variables for the distributed primitives tests
3072 global pCounterName
3073 global iCounterName
3074 global pCounterValue
3075 global iCounterValue
3076 global onosSet
3077 global onosSetName
3078 pCounterName = "TestON-Partitions"
3079 iCounterName = "TestON-inMemory"
3080 pCounterValue = 0
3081 iCounterValue = 0
3082 onosSet = set([])
3083 onosSetName = "TestON-set"
3084
3085 description = "Install Primitives app"
3086 main.case( description )
3087 main.step( "Install Primitives app" )
3088 appName = "org.onosproject.distributedprimitives"
Jon Halle1a3b752015-07-22 13:02:46 -07003089 appResults = main.CLIs[0].activateApp( appName )
Jon Hall5cf14d52015-07-16 12:15:19 -07003090 utilities.assert_equals( expect=main.TRUE,
3091 actual=appResults,
3092 onpass="Primitives app activated",
3093 onfail="Primitives app not activated" )
3094 time.sleep( 5 ) # To allow all nodes to activate
3095
3096 def CASE17( self, main ):
3097 """
3098 Check for basic functionality with distributed primitives
3099 """
Jon Hall5cf14d52015-07-16 12:15:19 -07003100 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07003101 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003102 assert main, "main not defined"
3103 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003104 assert main.CLIs, "main.CLIs not defined"
3105 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003106 assert pCounterName, "pCounterName not defined"
3107 assert iCounterName, "iCounterName not defined"
3108 assert onosSetName, "onosSetName not defined"
3109 # NOTE: assert fails if value is 0/None/Empty/False
3110 try:
3111 pCounterValue
3112 except NameError:
3113 main.log.error( "pCounterValue not defined, setting to 0" )
3114 pCounterValue = 0
3115 try:
3116 iCounterValue
3117 except NameError:
3118 main.log.error( "iCounterValue not defined, setting to 0" )
3119 iCounterValue = 0
3120 try:
3121 onosSet
3122 except NameError:
3123 main.log.error( "onosSet not defined, setting to empty Set" )
3124 onosSet = set([])
3125 # Variables for the distributed primitives tests. These are local only
3126 addValue = "a"
3127 addAllValue = "a b c d e f"
3128 retainValue = "c d e f"
3129
3130 description = "Check for basic functionality with distributed " +\
3131 "primitives"
3132 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07003133 main.caseExplanation = "Test the methods of the distributed " +\
3134 "primitives (counters and sets) throught the cli"
Jon Hall5cf14d52015-07-16 12:15:19 -07003135 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07003136 # Partitioned counters
3137 main.step( "Increment then get a default counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003138 pCounters = []
3139 threads = []
3140 addedPValues = []
Jon Halle1a3b752015-07-22 13:02:46 -07003141 for i in range( main.numCtrls ):
3142 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3143 name="counterAddAndGet-" + str( i ),
Jon Hall5cf14d52015-07-16 12:15:19 -07003144 args=[ pCounterName ] )
3145 pCounterValue += 1
3146 addedPValues.append( pCounterValue )
3147 threads.append( t )
3148 t.start()
3149
3150 for t in threads:
3151 t.join()
3152 pCounters.append( t.result )
3153 # Check that counter incremented numController times
3154 pCounterResults = True
3155 for i in addedPValues:
3156 tmpResult = i in pCounters
3157 pCounterResults = pCounterResults and tmpResult
3158 if not tmpResult:
3159 main.log.error( str( i ) + " is not in partitioned "
3160 "counter incremented results" )
3161 utilities.assert_equals( expect=True,
3162 actual=pCounterResults,
3163 onpass="Default counter incremented",
3164 onfail="Error incrementing default" +
3165 " counter" )
3166
Jon Halle1a3b752015-07-22 13:02:46 -07003167 main.step( "Get then Increment a default counter on each node" )
3168 pCounters = []
3169 threads = []
3170 addedPValues = []
3171 for i in range( main.numCtrls ):
3172 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3173 name="counterGetAndAdd-" + str( i ),
3174 args=[ pCounterName ] )
3175 addedPValues.append( pCounterValue )
3176 pCounterValue += 1
3177 threads.append( t )
3178 t.start()
3179
3180 for t in threads:
3181 t.join()
3182 pCounters.append( t.result )
3183 # Check that counter incremented numController times
3184 pCounterResults = True
3185 for i in addedPValues:
3186 tmpResult = i in pCounters
3187 pCounterResults = pCounterResults and tmpResult
3188 if not tmpResult:
3189 main.log.error( str( i ) + " is not in partitioned "
3190 "counter incremented results" )
3191 utilities.assert_equals( expect=True,
3192 actual=pCounterResults,
3193 onpass="Default counter incremented",
3194 onfail="Error incrementing default" +
3195 " counter" )
3196
3197 main.step( "Counters we added have the correct values" )
3198 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3199 utilities.assert_equals( expect=main.TRUE,
3200 actual=incrementCheck,
3201 onpass="Added counters are correct",
3202 onfail="Added counters are incorrect" )
3203
3204 main.step( "Add -8 to then get a default counter on each node" )
3205 pCounters = []
3206 threads = []
3207 addedPValues = []
3208 for i in range( main.numCtrls ):
3209 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3210 name="counterIncrement-" + str( i ),
3211 args=[ pCounterName ],
3212 kwargs={ "delta": -8 } )
3213 pCounterValue += -8
3214 addedPValues.append( pCounterValue )
3215 threads.append( t )
3216 t.start()
3217
3218 for t in threads:
3219 t.join()
3220 pCounters.append( t.result )
3221 # Check that counter incremented numController times
3222 pCounterResults = True
3223 for i in addedPValues:
3224 tmpResult = i in pCounters
3225 pCounterResults = pCounterResults and tmpResult
3226 if not tmpResult:
3227 main.log.error( str( i ) + " is not in partitioned "
3228 "counter incremented results" )
3229 utilities.assert_equals( expect=True,
3230 actual=pCounterResults,
3231 onpass="Default counter incremented",
3232 onfail="Error incrementing default" +
3233 " counter" )
3234
3235 main.step( "Add 5 to then get a default counter on each node" )
3236 pCounters = []
3237 threads = []
3238 addedPValues = []
3239 for i in range( main.numCtrls ):
3240 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3241 name="counterIncrement-" + str( i ),
3242 args=[ pCounterName ],
3243 kwargs={ "delta": 5 } )
3244 pCounterValue += 5
3245 addedPValues.append( pCounterValue )
3246 threads.append( t )
3247 t.start()
3248
3249 for t in threads:
3250 t.join()
3251 pCounters.append( t.result )
3252 # Check that counter incremented numController times
3253 pCounterResults = True
3254 for i in addedPValues:
3255 tmpResult = i in pCounters
3256 pCounterResults = pCounterResults and tmpResult
3257 if not tmpResult:
3258 main.log.error( str( i ) + " is not in partitioned "
3259 "counter incremented results" )
3260 utilities.assert_equals( expect=True,
3261 actual=pCounterResults,
3262 onpass="Default counter incremented",
3263 onfail="Error incrementing default" +
3264 " counter" )
3265
3266 main.step( "Get then add 5 to a default counter on each node" )
3267 pCounters = []
3268 threads = []
3269 addedPValues = []
3270 for i in range( main.numCtrls ):
3271 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3272 name="counterIncrement-" + str( i ),
3273 args=[ pCounterName ],
3274 kwargs={ "delta": 5 } )
3275 addedPValues.append( pCounterValue )
3276 pCounterValue += 5
3277 threads.append( t )
3278 t.start()
3279
3280 for t in threads:
3281 t.join()
3282 pCounters.append( t.result )
3283 # Check that counter incremented numController times
3284 pCounterResults = True
3285 for i in addedPValues:
3286 tmpResult = i in pCounters
3287 pCounterResults = pCounterResults and tmpResult
3288 if not tmpResult:
3289 main.log.error( str( i ) + " is not in partitioned "
3290 "counter incremented results" )
3291 utilities.assert_equals( expect=True,
3292 actual=pCounterResults,
3293 onpass="Default counter incremented",
3294 onfail="Error incrementing default" +
3295 " counter" )
3296
3297 main.step( "Counters we added have the correct values" )
3298 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3299 utilities.assert_equals( expect=main.TRUE,
3300 actual=incrementCheck,
3301 onpass="Added counters are correct",
3302 onfail="Added counters are incorrect" )
3303
3304 # In-Memory counters
3305 main.step( "Increment and get an in-memory counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003306 iCounters = []
3307 addedIValues = []
3308 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003309 for i in range( main.numCtrls ):
3310 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003311 name="icounterIncrement-" + str( i ),
3312 args=[ iCounterName ],
3313 kwargs={ "inMemory": True } )
3314 iCounterValue += 1
3315 addedIValues.append( iCounterValue )
3316 threads.append( t )
3317 t.start()
3318
3319 for t in threads:
3320 t.join()
3321 iCounters.append( t.result )
3322 # Check that counter incremented numController times
3323 iCounterResults = True
3324 for i in addedIValues:
3325 tmpResult = i in iCounters
3326 iCounterResults = iCounterResults and tmpResult
3327 if not tmpResult:
3328 main.log.error( str( i ) + " is not in the in-memory "
3329 "counter incremented results" )
3330 utilities.assert_equals( expect=True,
3331 actual=iCounterResults,
Jon Halle1a3b752015-07-22 13:02:46 -07003332 onpass="In-memory counter incremented",
3333 onfail="Error incrementing in-memory" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003334 " counter" )
3335
Jon Halle1a3b752015-07-22 13:02:46 -07003336 main.step( "Get then Increment a in-memory counter on each node" )
3337 iCounters = []
3338 threads = []
3339 addedIValues = []
3340 for i in range( main.numCtrls ):
3341 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3342 name="counterGetAndAdd-" + str( i ),
3343 args=[ iCounterName ],
3344 kwargs={ "inMemory": True } )
3345 addedIValues.append( iCounterValue )
3346 iCounterValue += 1
3347 threads.append( t )
3348 t.start()
3349
3350 for t in threads:
3351 t.join()
3352 iCounters.append( t.result )
3353 # Check that counter incremented numController times
3354 iCounterResults = True
3355 for i in addedIValues:
3356 tmpResult = i in iCounters
3357 iCounterResults = iCounterResults and tmpResult
3358 if not tmpResult:
3359 main.log.error( str( i ) + " is not in in-memory "
3360 "counter incremented results" )
3361 utilities.assert_equals( expect=True,
3362 actual=iCounterResults,
3363 onpass="In-memory counter incremented",
3364 onfail="Error incrementing in-memory" +
3365 " counter" )
3366
3367 main.step( "Counters we added have the correct values" )
3368 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3369 utilities.assert_equals( expect=main.TRUE,
3370 actual=incrementCheck,
3371 onpass="Added counters are correct",
3372 onfail="Added counters are incorrect" )
3373
3374 main.step( "Add -8 to then get a in-memory counter on each node" )
3375 iCounters = []
3376 threads = []
3377 addedIValues = []
3378 for i in range( main.numCtrls ):
3379 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3380 name="counterIncrement-" + str( i ),
3381 args=[ iCounterName ],
3382 kwargs={ "delta": -8, "inMemory": True } )
3383 iCounterValue += -8
3384 addedIValues.append( iCounterValue )
3385 threads.append( t )
3386 t.start()
3387
3388 for t in threads:
3389 t.join()
3390 iCounters.append( t.result )
3391 # Check that counter incremented numController times
3392 iCounterResults = True
3393 for i in addedIValues:
3394 tmpResult = i in iCounters
3395 iCounterResults = iCounterResults and tmpResult
3396 if not tmpResult:
3397 main.log.error( str( i ) + " is not in in-memory "
3398 "counter incremented results" )
3399 utilities.assert_equals( expect=True,
3400 actual=pCounterResults,
3401 onpass="In-memory counter incremented",
3402 onfail="Error incrementing in-memory" +
3403 " counter" )
3404
3405 main.step( "Add 5 to then get a in-memory counter on each node" )
3406 iCounters = []
3407 threads = []
3408 addedIValues = []
3409 for i in range( main.numCtrls ):
3410 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3411 name="counterIncrement-" + str( i ),
3412 args=[ iCounterName ],
3413 kwargs={ "delta": 5, "inMemory": True } )
3414 iCounterValue += 5
3415 addedIValues.append( iCounterValue )
3416 threads.append( t )
3417 t.start()
3418
3419 for t in threads:
3420 t.join()
3421 iCounters.append( t.result )
3422 # Check that counter incremented numController times
3423 iCounterResults = True
3424 for i in addedIValues:
3425 tmpResult = i in iCounters
3426 iCounterResults = iCounterResults and tmpResult
3427 if not tmpResult:
3428 main.log.error( str( i ) + " is not in in-memory "
3429 "counter incremented results" )
3430 utilities.assert_equals( expect=True,
3431 actual=pCounterResults,
3432 onpass="In-memory counter incremented",
3433 onfail="Error incrementing in-memory" +
3434 " counter" )
3435
3436 main.step( "Get then add 5 to a in-memory counter on each node" )
3437 iCounters = []
3438 threads = []
3439 addedIValues = []
3440 for i in range( main.numCtrls ):
3441 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3442 name="counterIncrement-" + str( i ),
3443 args=[ iCounterName ],
3444 kwargs={ "delta": 5, "inMemory": True } )
3445 addedIValues.append( iCounterValue )
3446 iCounterValue += 5
3447 threads.append( t )
3448 t.start()
3449
3450 for t in threads:
3451 t.join()
3452 iCounters.append( t.result )
3453 # Check that counter incremented numController times
3454 iCounterResults = True
3455 for i in addedIValues:
3456 tmpResult = i in iCounters
3457 iCounterResults = iCounterResults and tmpResult
3458 if not tmpResult:
3459 main.log.error( str( i ) + " is not in in-memory "
3460 "counter incremented results" )
3461 utilities.assert_equals( expect=True,
3462 actual=iCounterResults,
3463 onpass="In-memory counter incremented",
3464 onfail="Error incrementing in-memory" +
3465 " counter" )
3466
3467 main.step( "Counters we added have the correct values" )
3468 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3469 utilities.assert_equals( expect=main.TRUE,
3470 actual=incrementCheck,
3471 onpass="Added counters are correct",
3472 onfail="Added counters are incorrect" )
3473
Jon Hall5cf14d52015-07-16 12:15:19 -07003474 main.step( "Check counters are consistant across nodes" )
Jon Hall57b50432015-10-22 10:20:10 -07003475 onosCounters, consistentCounterResults = main.Counters.consistentCheck()
Jon Hall5cf14d52015-07-16 12:15:19 -07003476 utilities.assert_equals( expect=main.TRUE,
3477 actual=consistentCounterResults,
3478 onpass="ONOS counters are consistent " +
3479 "across nodes",
3480 onfail="ONOS Counters are inconsistent " +
3481 "across nodes" )
3482
3483 main.step( "Counters we added have the correct values" )
Jon Halle1a3b752015-07-22 13:02:46 -07003484 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3485 incrementCheck = incrementCheck and \
3486 main.Counters.counterCheck( iCounterName, iCounterValue )
Jon Hall5cf14d52015-07-16 12:15:19 -07003487 utilities.assert_equals( expect=main.TRUE,
Jon Halle1a3b752015-07-22 13:02:46 -07003488 actual=incrementCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -07003489 onpass="Added counters are correct",
3490 onfail="Added counters are incorrect" )
3491 # DISTRIBUTED SETS
3492 main.step( "Distributed Set get" )
3493 size = len( onosSet )
3494 getResponses = []
3495 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003496 for i in range( main.numCtrls ):
3497 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003498 name="setTestGet-" + str( i ),
3499 args=[ onosSetName ] )
3500 threads.append( t )
3501 t.start()
3502 for t in threads:
3503 t.join()
3504 getResponses.append( t.result )
3505
3506 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003507 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003508 if isinstance( getResponses[ i ], list):
3509 current = set( getResponses[ i ] )
3510 if len( current ) == len( getResponses[ i ] ):
3511 # no repeats
3512 if onosSet != current:
3513 main.log.error( "ONOS" + str( i + 1 ) +
3514 " has incorrect view" +
3515 " of set " + onosSetName + ":\n" +
3516 str( getResponses[ i ] ) )
3517 main.log.debug( "Expected: " + str( onosSet ) )
3518 main.log.debug( "Actual: " + str( current ) )
3519 getResults = main.FALSE
3520 else:
3521 # error, set is not a set
3522 main.log.error( "ONOS" + str( i + 1 ) +
3523 " has repeat elements in" +
3524 " set " + onosSetName + ":\n" +
3525 str( getResponses[ i ] ) )
3526 getResults = main.FALSE
3527 elif getResponses[ i ] == main.ERROR:
3528 getResults = main.FALSE
3529 utilities.assert_equals( expect=main.TRUE,
3530 actual=getResults,
3531 onpass="Set elements are correct",
3532 onfail="Set elements are incorrect" )
3533
3534 main.step( "Distributed Set size" )
3535 sizeResponses = []
3536 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003537 for i in range( main.numCtrls ):
3538 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003539 name="setTestSize-" + str( i ),
3540 args=[ onosSetName ] )
3541 threads.append( t )
3542 t.start()
3543 for t in threads:
3544 t.join()
3545 sizeResponses.append( t.result )
3546
3547 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003548 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003549 if size != sizeResponses[ i ]:
3550 sizeResults = main.FALSE
3551 main.log.error( "ONOS" + str( i + 1 ) +
3552 " expected a size of " + str( size ) +
3553 " for set " + onosSetName +
3554 " but got " + str( sizeResponses[ i ] ) )
3555 utilities.assert_equals( expect=main.TRUE,
3556 actual=sizeResults,
3557 onpass="Set sizes are correct",
3558 onfail="Set sizes are incorrect" )
3559
3560 main.step( "Distributed Set add()" )
3561 onosSet.add( addValue )
3562 addResponses = []
3563 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003564 for i in range( main.numCtrls ):
3565 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003566 name="setTestAdd-" + str( i ),
3567 args=[ onosSetName, addValue ] )
3568 threads.append( t )
3569 t.start()
3570 for t in threads:
3571 t.join()
3572 addResponses.append( t.result )
3573
3574 # main.TRUE = successfully changed the set
3575 # main.FALSE = action resulted in no change in set
3576 # main.ERROR - Some error in executing the function
3577 addResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003578 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003579 if addResponses[ i ] == main.TRUE:
3580 # All is well
3581 pass
3582 elif addResponses[ i ] == main.FALSE:
3583 # Already in set, probably fine
3584 pass
3585 elif addResponses[ i ] == main.ERROR:
3586 # Error in execution
3587 addResults = main.FALSE
3588 else:
3589 # unexpected result
3590 addResults = main.FALSE
3591 if addResults != main.TRUE:
3592 main.log.error( "Error executing set add" )
3593
3594 # Check if set is still correct
3595 size = len( onosSet )
3596 getResponses = []
3597 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003598 for i in range( main.numCtrls ):
3599 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003600 name="setTestGet-" + str( i ),
3601 args=[ onosSetName ] )
3602 threads.append( t )
3603 t.start()
3604 for t in threads:
3605 t.join()
3606 getResponses.append( t.result )
3607 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003608 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003609 if isinstance( getResponses[ i ], list):
3610 current = set( getResponses[ i ] )
3611 if len( current ) == len( getResponses[ i ] ):
3612 # no repeats
3613 if onosSet != current:
3614 main.log.error( "ONOS" + str( i + 1 ) +
3615 " has incorrect view" +
3616 " of set " + onosSetName + ":\n" +
3617 str( getResponses[ i ] ) )
3618 main.log.debug( "Expected: " + str( onosSet ) )
3619 main.log.debug( "Actual: " + str( current ) )
3620 getResults = main.FALSE
3621 else:
3622 # error, set is not a set
3623 main.log.error( "ONOS" + str( i + 1 ) +
3624 " has repeat elements in" +
3625 " set " + onosSetName + ":\n" +
3626 str( getResponses[ i ] ) )
3627 getResults = main.FALSE
3628 elif getResponses[ i ] == main.ERROR:
3629 getResults = main.FALSE
3630 sizeResponses = []
3631 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003632 for i in range( main.numCtrls ):
3633 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003634 name="setTestSize-" + str( i ),
3635 args=[ onosSetName ] )
3636 threads.append( t )
3637 t.start()
3638 for t in threads:
3639 t.join()
3640 sizeResponses.append( t.result )
3641 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003642 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003643 if size != sizeResponses[ i ]:
3644 sizeResults = main.FALSE
3645 main.log.error( "ONOS" + str( i + 1 ) +
3646 " expected a size of " + str( size ) +
3647 " for set " + onosSetName +
3648 " but got " + str( sizeResponses[ i ] ) )
3649 addResults = addResults and getResults and sizeResults
3650 utilities.assert_equals( expect=main.TRUE,
3651 actual=addResults,
3652 onpass="Set add correct",
3653 onfail="Set add was incorrect" )
3654
3655 main.step( "Distributed Set addAll()" )
3656 onosSet.update( addAllValue.split() )
3657 addResponses = []
3658 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003659 for i in range( main.numCtrls ):
3660 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003661 name="setTestAddAll-" + str( i ),
3662 args=[ onosSetName, addAllValue ] )
3663 threads.append( t )
3664 t.start()
3665 for t in threads:
3666 t.join()
3667 addResponses.append( t.result )
3668
3669 # main.TRUE = successfully changed the set
3670 # main.FALSE = action resulted in no change in set
3671 # main.ERROR - Some error in executing the function
3672 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003673 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003674 if addResponses[ i ] == main.TRUE:
3675 # All is well
3676 pass
3677 elif addResponses[ i ] == main.FALSE:
3678 # Already in set, probably fine
3679 pass
3680 elif addResponses[ i ] == main.ERROR:
3681 # Error in execution
3682 addAllResults = main.FALSE
3683 else:
3684 # unexpected result
3685 addAllResults = main.FALSE
3686 if addAllResults != main.TRUE:
3687 main.log.error( "Error executing set addAll" )
3688
3689 # Check if set is still correct
3690 size = len( onosSet )
3691 getResponses = []
3692 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003693 for i in range( main.numCtrls ):
3694 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003695 name="setTestGet-" + str( i ),
3696 args=[ onosSetName ] )
3697 threads.append( t )
3698 t.start()
3699 for t in threads:
3700 t.join()
3701 getResponses.append( t.result )
3702 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003703 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003704 if isinstance( getResponses[ i ], list):
3705 current = set( getResponses[ i ] )
3706 if len( current ) == len( getResponses[ i ] ):
3707 # no repeats
3708 if onosSet != current:
3709 main.log.error( "ONOS" + str( i + 1 ) +
3710 " has incorrect view" +
3711 " of set " + onosSetName + ":\n" +
3712 str( getResponses[ i ] ) )
3713 main.log.debug( "Expected: " + str( onosSet ) )
3714 main.log.debug( "Actual: " + str( current ) )
3715 getResults = main.FALSE
3716 else:
3717 # error, set is not a set
3718 main.log.error( "ONOS" + str( i + 1 ) +
3719 " has repeat elements in" +
3720 " set " + onosSetName + ":\n" +
3721 str( getResponses[ i ] ) )
3722 getResults = main.FALSE
3723 elif getResponses[ i ] == main.ERROR:
3724 getResults = main.FALSE
3725 sizeResponses = []
3726 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003727 for i in range( main.numCtrls ):
3728 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003729 name="setTestSize-" + str( i ),
3730 args=[ onosSetName ] )
3731 threads.append( t )
3732 t.start()
3733 for t in threads:
3734 t.join()
3735 sizeResponses.append( t.result )
3736 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003737 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003738 if size != sizeResponses[ i ]:
3739 sizeResults = main.FALSE
3740 main.log.error( "ONOS" + str( i + 1 ) +
3741 " expected a size of " + str( size ) +
3742 " for set " + onosSetName +
3743 " but got " + str( sizeResponses[ i ] ) )
3744 addAllResults = addAllResults and getResults and sizeResults
3745 utilities.assert_equals( expect=main.TRUE,
3746 actual=addAllResults,
3747 onpass="Set addAll correct",
3748 onfail="Set addAll was incorrect" )
3749
3750 main.step( "Distributed Set contains()" )
3751 containsResponses = []
3752 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003753 for i in range( main.numCtrls ):
3754 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003755 name="setContains-" + str( i ),
3756 args=[ onosSetName ],
3757 kwargs={ "values": addValue } )
3758 threads.append( t )
3759 t.start()
3760 for t in threads:
3761 t.join()
3762 # NOTE: This is the tuple
3763 containsResponses.append( t.result )
3764
3765 containsResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003766 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003767 if containsResponses[ i ] == main.ERROR:
3768 containsResults = main.FALSE
3769 else:
3770 containsResults = containsResults and\
3771 containsResponses[ i ][ 1 ]
3772 utilities.assert_equals( expect=main.TRUE,
3773 actual=containsResults,
3774 onpass="Set contains is functional",
3775 onfail="Set contains failed" )
3776
3777 main.step( "Distributed Set containsAll()" )
3778 containsAllResponses = []
3779 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003780 for i in range( main.numCtrls ):
3781 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003782 name="setContainsAll-" + str( i ),
3783 args=[ onosSetName ],
3784 kwargs={ "values": addAllValue } )
3785 threads.append( t )
3786 t.start()
3787 for t in threads:
3788 t.join()
3789 # NOTE: This is the tuple
3790 containsAllResponses.append( t.result )
3791
3792 containsAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003793 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003794 if containsResponses[ i ] == main.ERROR:
3795 containsResults = main.FALSE
3796 else:
3797 containsResults = containsResults and\
3798 containsResponses[ i ][ 1 ]
3799 utilities.assert_equals( expect=main.TRUE,
3800 actual=containsAllResults,
3801 onpass="Set containsAll is functional",
3802 onfail="Set containsAll failed" )
3803
3804 main.step( "Distributed Set remove()" )
3805 onosSet.remove( addValue )
3806 removeResponses = []
3807 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003808 for i in range( main.numCtrls ):
3809 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003810 name="setTestRemove-" + str( i ),
3811 args=[ onosSetName, addValue ] )
3812 threads.append( t )
3813 t.start()
3814 for t in threads:
3815 t.join()
3816 removeResponses.append( t.result )
3817
3818 # main.TRUE = successfully changed the set
3819 # main.FALSE = action resulted in no change in set
3820 # main.ERROR - Some error in executing the function
3821 removeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003822 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003823 if removeResponses[ i ] == main.TRUE:
3824 # All is well
3825 pass
3826 elif removeResponses[ i ] == main.FALSE:
3827 # not in set, probably fine
3828 pass
3829 elif removeResponses[ i ] == main.ERROR:
3830 # Error in execution
3831 removeResults = main.FALSE
3832 else:
3833 # unexpected result
3834 removeResults = main.FALSE
3835 if removeResults != main.TRUE:
3836 main.log.error( "Error executing set remove" )
3837
3838 # Check if set is still correct
3839 size = len( onosSet )
3840 getResponses = []
3841 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003842 for i in range( main.numCtrls ):
3843 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003844 name="setTestGet-" + str( i ),
3845 args=[ onosSetName ] )
3846 threads.append( t )
3847 t.start()
3848 for t in threads:
3849 t.join()
3850 getResponses.append( t.result )
3851 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003852 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003853 if isinstance( getResponses[ i ], list):
3854 current = set( getResponses[ i ] )
3855 if len( current ) == len( getResponses[ i ] ):
3856 # no repeats
3857 if onosSet != current:
3858 main.log.error( "ONOS" + str( i + 1 ) +
3859 " has incorrect view" +
3860 " of set " + onosSetName + ":\n" +
3861 str( getResponses[ i ] ) )
3862 main.log.debug( "Expected: " + str( onosSet ) )
3863 main.log.debug( "Actual: " + str( current ) )
3864 getResults = main.FALSE
3865 else:
3866 # error, set is not a set
3867 main.log.error( "ONOS" + str( i + 1 ) +
3868 " has repeat elements in" +
3869 " set " + onosSetName + ":\n" +
3870 str( getResponses[ i ] ) )
3871 getResults = main.FALSE
3872 elif getResponses[ i ] == main.ERROR:
3873 getResults = main.FALSE
3874 sizeResponses = []
3875 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003876 for i in range( main.numCtrls ):
3877 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003878 name="setTestSize-" + str( i ),
3879 args=[ onosSetName ] )
3880 threads.append( t )
3881 t.start()
3882 for t in threads:
3883 t.join()
3884 sizeResponses.append( t.result )
3885 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003886 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003887 if size != sizeResponses[ i ]:
3888 sizeResults = main.FALSE
3889 main.log.error( "ONOS" + str( i + 1 ) +
3890 " expected a size of " + str( size ) +
3891 " for set " + onosSetName +
3892 " but got " + str( sizeResponses[ i ] ) )
3893 removeResults = removeResults and getResults and sizeResults
3894 utilities.assert_equals( expect=main.TRUE,
3895 actual=removeResults,
3896 onpass="Set remove correct",
3897 onfail="Set remove was incorrect" )
3898
3899 main.step( "Distributed Set removeAll()" )
3900 onosSet.difference_update( addAllValue.split() )
3901 removeAllResponses = []
3902 threads = []
3903 try:
Jon Halle1a3b752015-07-22 13:02:46 -07003904 for i in range( main.numCtrls ):
3905 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003906 name="setTestRemoveAll-" + str( i ),
3907 args=[ onosSetName, addAllValue ] )
3908 threads.append( t )
3909 t.start()
3910 for t in threads:
3911 t.join()
3912 removeAllResponses.append( t.result )
3913 except Exception, e:
3914 main.log.exception(e)
3915
3916 # main.TRUE = successfully changed the set
3917 # main.FALSE = action resulted in no change in set
3918 # main.ERROR - Some error in executing the function
3919 removeAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003920 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003921 if removeAllResponses[ i ] == main.TRUE:
3922 # All is well
3923 pass
3924 elif removeAllResponses[ i ] == main.FALSE:
3925 # not in set, probably fine
3926 pass
3927 elif removeAllResponses[ i ] == main.ERROR:
3928 # Error in execution
3929 removeAllResults = main.FALSE
3930 else:
3931 # unexpected result
3932 removeAllResults = main.FALSE
3933 if removeAllResults != main.TRUE:
3934 main.log.error( "Error executing set removeAll" )
3935
3936 # Check if set is still correct
3937 size = len( onosSet )
3938 getResponses = []
3939 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003940 for i in range( main.numCtrls ):
3941 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003942 name="setTestGet-" + str( i ),
3943 args=[ onosSetName ] )
3944 threads.append( t )
3945 t.start()
3946 for t in threads:
3947 t.join()
3948 getResponses.append( t.result )
3949 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003950 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003951 if isinstance( getResponses[ i ], list):
3952 current = set( getResponses[ i ] )
3953 if len( current ) == len( getResponses[ i ] ):
3954 # no repeats
3955 if onosSet != current:
3956 main.log.error( "ONOS" + str( i + 1 ) +
3957 " has incorrect view" +
3958 " of set " + onosSetName + ":\n" +
3959 str( getResponses[ i ] ) )
3960 main.log.debug( "Expected: " + str( onosSet ) )
3961 main.log.debug( "Actual: " + str( current ) )
3962 getResults = main.FALSE
3963 else:
3964 # error, set is not a set
3965 main.log.error( "ONOS" + str( i + 1 ) +
3966 " has repeat elements in" +
3967 " set " + onosSetName + ":\n" +
3968 str( getResponses[ i ] ) )
3969 getResults = main.FALSE
3970 elif getResponses[ i ] == main.ERROR:
3971 getResults = main.FALSE
3972 sizeResponses = []
3973 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003974 for i in range( main.numCtrls ):
3975 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003976 name="setTestSize-" + str( i ),
3977 args=[ onosSetName ] )
3978 threads.append( t )
3979 t.start()
3980 for t in threads:
3981 t.join()
3982 sizeResponses.append( t.result )
3983 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003984 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003985 if size != sizeResponses[ i ]:
3986 sizeResults = main.FALSE
3987 main.log.error( "ONOS" + str( i + 1 ) +
3988 " expected a size of " + str( size ) +
3989 " for set " + onosSetName +
3990 " but got " + str( sizeResponses[ i ] ) )
3991 removeAllResults = removeAllResults and getResults and sizeResults
3992 utilities.assert_equals( expect=main.TRUE,
3993 actual=removeAllResults,
3994 onpass="Set removeAll correct",
3995 onfail="Set removeAll was incorrect" )
3996
3997 main.step( "Distributed Set addAll()" )
3998 onosSet.update( addAllValue.split() )
3999 addResponses = []
4000 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004001 for i in range( main.numCtrls ):
4002 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004003 name="setTestAddAll-" + str( i ),
4004 args=[ onosSetName, addAllValue ] )
4005 threads.append( t )
4006 t.start()
4007 for t in threads:
4008 t.join()
4009 addResponses.append( t.result )
4010
4011 # main.TRUE = successfully changed the set
4012 # main.FALSE = action resulted in no change in set
4013 # main.ERROR - Some error in executing the function
4014 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004015 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004016 if addResponses[ i ] == main.TRUE:
4017 # All is well
4018 pass
4019 elif addResponses[ i ] == main.FALSE:
4020 # Already in set, probably fine
4021 pass
4022 elif addResponses[ i ] == main.ERROR:
4023 # Error in execution
4024 addAllResults = main.FALSE
4025 else:
4026 # unexpected result
4027 addAllResults = main.FALSE
4028 if addAllResults != main.TRUE:
4029 main.log.error( "Error executing set addAll" )
4030
4031 # Check if set is still correct
4032 size = len( onosSet )
4033 getResponses = []
4034 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004035 for i in range( main.numCtrls ):
4036 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004037 name="setTestGet-" + str( i ),
4038 args=[ onosSetName ] )
4039 threads.append( t )
4040 t.start()
4041 for t in threads:
4042 t.join()
4043 getResponses.append( t.result )
4044 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004045 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004046 if isinstance( getResponses[ i ], list):
4047 current = set( getResponses[ i ] )
4048 if len( current ) == len( getResponses[ i ] ):
4049 # no repeats
4050 if onosSet != current:
4051 main.log.error( "ONOS" + str( i + 1 ) +
4052 " has incorrect view" +
4053 " of set " + onosSetName + ":\n" +
4054 str( getResponses[ i ] ) )
4055 main.log.debug( "Expected: " + str( onosSet ) )
4056 main.log.debug( "Actual: " + str( current ) )
4057 getResults = main.FALSE
4058 else:
4059 # error, set is not a set
4060 main.log.error( "ONOS" + str( i + 1 ) +
4061 " has repeat elements in" +
4062 " set " + onosSetName + ":\n" +
4063 str( getResponses[ i ] ) )
4064 getResults = main.FALSE
4065 elif getResponses[ i ] == main.ERROR:
4066 getResults = main.FALSE
4067 sizeResponses = []
4068 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004069 for i in range( main.numCtrls ):
4070 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004071 name="setTestSize-" + str( i ),
4072 args=[ onosSetName ] )
4073 threads.append( t )
4074 t.start()
4075 for t in threads:
4076 t.join()
4077 sizeResponses.append( t.result )
4078 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004079 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004080 if size != sizeResponses[ i ]:
4081 sizeResults = main.FALSE
4082 main.log.error( "ONOS" + str( i + 1 ) +
4083 " expected a size of " + str( size ) +
4084 " for set " + onosSetName +
4085 " but got " + str( sizeResponses[ i ] ) )
4086 addAllResults = addAllResults and getResults and sizeResults
4087 utilities.assert_equals( expect=main.TRUE,
4088 actual=addAllResults,
4089 onpass="Set addAll correct",
4090 onfail="Set addAll was incorrect" )
4091
4092 main.step( "Distributed Set clear()" )
4093 onosSet.clear()
4094 clearResponses = []
4095 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004096 for i in range( main.numCtrls ):
4097 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004098 name="setTestClear-" + str( i ),
4099 args=[ onosSetName, " "], # Values doesn't matter
4100 kwargs={ "clear": True } )
4101 threads.append( t )
4102 t.start()
4103 for t in threads:
4104 t.join()
4105 clearResponses.append( t.result )
4106
4107 # main.TRUE = successfully changed the set
4108 # main.FALSE = action resulted in no change in set
4109 # main.ERROR - Some error in executing the function
4110 clearResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004111 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004112 if clearResponses[ i ] == main.TRUE:
4113 # All is well
4114 pass
4115 elif clearResponses[ i ] == main.FALSE:
4116 # Nothing set, probably fine
4117 pass
4118 elif clearResponses[ i ] == main.ERROR:
4119 # Error in execution
4120 clearResults = main.FALSE
4121 else:
4122 # unexpected result
4123 clearResults = main.FALSE
4124 if clearResults != main.TRUE:
4125 main.log.error( "Error executing set clear" )
4126
4127 # Check if set is still correct
4128 size = len( onosSet )
4129 getResponses = []
4130 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004131 for i in range( main.numCtrls ):
4132 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004133 name="setTestGet-" + str( i ),
4134 args=[ onosSetName ] )
4135 threads.append( t )
4136 t.start()
4137 for t in threads:
4138 t.join()
4139 getResponses.append( t.result )
4140 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004141 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004142 if isinstance( getResponses[ i ], list):
4143 current = set( getResponses[ i ] )
4144 if len( current ) == len( getResponses[ i ] ):
4145 # no repeats
4146 if onosSet != current:
4147 main.log.error( "ONOS" + str( i + 1 ) +
4148 " has incorrect view" +
4149 " of set " + onosSetName + ":\n" +
4150 str( getResponses[ i ] ) )
4151 main.log.debug( "Expected: " + str( onosSet ) )
4152 main.log.debug( "Actual: " + str( current ) )
4153 getResults = main.FALSE
4154 else:
4155 # error, set is not a set
4156 main.log.error( "ONOS" + str( i + 1 ) +
4157 " has repeat elements in" +
4158 " set " + onosSetName + ":\n" +
4159 str( getResponses[ i ] ) )
4160 getResults = main.FALSE
4161 elif getResponses[ i ] == main.ERROR:
4162 getResults = main.FALSE
4163 sizeResponses = []
4164 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004165 for i in range( main.numCtrls ):
4166 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004167 name="setTestSize-" + str( i ),
4168 args=[ onosSetName ] )
4169 threads.append( t )
4170 t.start()
4171 for t in threads:
4172 t.join()
4173 sizeResponses.append( t.result )
4174 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004175 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004176 if size != sizeResponses[ i ]:
4177 sizeResults = main.FALSE
4178 main.log.error( "ONOS" + str( i + 1 ) +
4179 " expected a size of " + str( size ) +
4180 " for set " + onosSetName +
4181 " but got " + str( sizeResponses[ i ] ) )
4182 clearResults = clearResults and getResults and sizeResults
4183 utilities.assert_equals( expect=main.TRUE,
4184 actual=clearResults,
4185 onpass="Set clear correct",
4186 onfail="Set clear was incorrect" )
4187
4188 main.step( "Distributed Set addAll()" )
4189 onosSet.update( addAllValue.split() )
4190 addResponses = []
4191 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004192 for i in range( main.numCtrls ):
4193 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004194 name="setTestAddAll-" + str( i ),
4195 args=[ onosSetName, addAllValue ] )
4196 threads.append( t )
4197 t.start()
4198 for t in threads:
4199 t.join()
4200 addResponses.append( t.result )
4201
4202 # main.TRUE = successfully changed the set
4203 # main.FALSE = action resulted in no change in set
4204 # main.ERROR - Some error in executing the function
4205 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004206 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004207 if addResponses[ i ] == main.TRUE:
4208 # All is well
4209 pass
4210 elif addResponses[ i ] == main.FALSE:
4211 # Already in set, probably fine
4212 pass
4213 elif addResponses[ i ] == main.ERROR:
4214 # Error in execution
4215 addAllResults = main.FALSE
4216 else:
4217 # unexpected result
4218 addAllResults = main.FALSE
4219 if addAllResults != main.TRUE:
4220 main.log.error( "Error executing set addAll" )
4221
4222 # Check if set is still correct
4223 size = len( onosSet )
4224 getResponses = []
4225 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004226 for i in range( main.numCtrls ):
4227 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004228 name="setTestGet-" + str( i ),
4229 args=[ onosSetName ] )
4230 threads.append( t )
4231 t.start()
4232 for t in threads:
4233 t.join()
4234 getResponses.append( t.result )
4235 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004236 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004237 if isinstance( getResponses[ i ], list):
4238 current = set( getResponses[ i ] )
4239 if len( current ) == len( getResponses[ i ] ):
4240 # no repeats
4241 if onosSet != current:
4242 main.log.error( "ONOS" + str( i + 1 ) +
4243 " has incorrect view" +
4244 " of set " + onosSetName + ":\n" +
4245 str( getResponses[ i ] ) )
4246 main.log.debug( "Expected: " + str( onosSet ) )
4247 main.log.debug( "Actual: " + str( current ) )
4248 getResults = main.FALSE
4249 else:
4250 # error, set is not a set
4251 main.log.error( "ONOS" + str( i + 1 ) +
4252 " has repeat elements in" +
4253 " set " + onosSetName + ":\n" +
4254 str( getResponses[ i ] ) )
4255 getResults = main.FALSE
4256 elif getResponses[ i ] == main.ERROR:
4257 getResults = main.FALSE
4258 sizeResponses = []
4259 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004260 for i in range( main.numCtrls ):
4261 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004262 name="setTestSize-" + str( i ),
4263 args=[ onosSetName ] )
4264 threads.append( t )
4265 t.start()
4266 for t in threads:
4267 t.join()
4268 sizeResponses.append( t.result )
4269 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004270 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004271 if size != sizeResponses[ i ]:
4272 sizeResults = main.FALSE
4273 main.log.error( "ONOS" + str( i + 1 ) +
4274 " expected a size of " + str( size ) +
4275 " for set " + onosSetName +
4276 " but got " + str( sizeResponses[ i ] ) )
4277 addAllResults = addAllResults and getResults and sizeResults
4278 utilities.assert_equals( expect=main.TRUE,
4279 actual=addAllResults,
4280 onpass="Set addAll correct",
4281 onfail="Set addAll was incorrect" )
4282
4283 main.step( "Distributed Set retain()" )
4284 onosSet.intersection_update( retainValue.split() )
4285 retainResponses = []
4286 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004287 for i in range( main.numCtrls ):
4288 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004289 name="setTestRetain-" + str( i ),
4290 args=[ onosSetName, retainValue ],
4291 kwargs={ "retain": True } )
4292 threads.append( t )
4293 t.start()
4294 for t in threads:
4295 t.join()
4296 retainResponses.append( t.result )
4297
4298 # main.TRUE = successfully changed the set
4299 # main.FALSE = action resulted in no change in set
4300 # main.ERROR - Some error in executing the function
4301 retainResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004302 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004303 if retainResponses[ i ] == main.TRUE:
4304 # All is well
4305 pass
4306 elif retainResponses[ i ] == main.FALSE:
4307 # Already in set, probably fine
4308 pass
4309 elif retainResponses[ i ] == main.ERROR:
4310 # Error in execution
4311 retainResults = main.FALSE
4312 else:
4313 # unexpected result
4314 retainResults = main.FALSE
4315 if retainResults != main.TRUE:
4316 main.log.error( "Error executing set retain" )
4317
4318 # Check if set is still correct
4319 size = len( onosSet )
4320 getResponses = []
4321 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004322 for i in range( main.numCtrls ):
4323 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004324 name="setTestGet-" + str( i ),
4325 args=[ onosSetName ] )
4326 threads.append( t )
4327 t.start()
4328 for t in threads:
4329 t.join()
4330 getResponses.append( t.result )
4331 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004332 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004333 if isinstance( getResponses[ i ], list):
4334 current = set( getResponses[ i ] )
4335 if len( current ) == len( getResponses[ i ] ):
4336 # no repeats
4337 if onosSet != current:
4338 main.log.error( "ONOS" + str( i + 1 ) +
4339 " has incorrect view" +
4340 " of set " + onosSetName + ":\n" +
4341 str( getResponses[ i ] ) )
4342 main.log.debug( "Expected: " + str( onosSet ) )
4343 main.log.debug( "Actual: " + str( current ) )
4344 getResults = main.FALSE
4345 else:
4346 # error, set is not a set
4347 main.log.error( "ONOS" + str( i + 1 ) +
4348 " has repeat elements in" +
4349 " set " + onosSetName + ":\n" +
4350 str( getResponses[ i ] ) )
4351 getResults = main.FALSE
4352 elif getResponses[ i ] == main.ERROR:
4353 getResults = main.FALSE
4354 sizeResponses = []
4355 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004356 for i in range( main.numCtrls ):
4357 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004358 name="setTestSize-" + str( i ),
4359 args=[ onosSetName ] )
4360 threads.append( t )
4361 t.start()
4362 for t in threads:
4363 t.join()
4364 sizeResponses.append( t.result )
4365 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004366 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004367 if size != sizeResponses[ i ]:
4368 sizeResults = main.FALSE
4369 main.log.error( "ONOS" + str( i + 1 ) +
4370 " expected a size of " +
4371 str( size ) + " for set " + onosSetName +
4372 " but got " + str( sizeResponses[ i ] ) )
4373 retainResults = retainResults and getResults and sizeResults
4374 utilities.assert_equals( expect=main.TRUE,
4375 actual=retainResults,
4376 onpass="Set retain correct",
4377 onfail="Set retain was incorrect" )
4378
Jon Hall2a5002c2015-08-21 16:49:11 -07004379 # Transactional maps
4380 main.step( "Partitioned Transactional maps put" )
4381 tMapValue = "Testing"
4382 numKeys = 100
4383 putResult = True
4384 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue )
4385 if len( putResponses ) == 100:
4386 for i in putResponses:
4387 if putResponses[ i ][ 'value' ] != tMapValue:
4388 putResult = False
4389 else:
4390 putResult = False
4391 if not putResult:
4392 main.log.debug( "Put response values: " + str( putResponses ) )
4393 utilities.assert_equals( expect=True,
4394 actual=putResult,
4395 onpass="Partitioned Transactional Map put successful",
4396 onfail="Partitioned Transactional Map put values are incorrect" )
4397
4398 main.step( "Partitioned Transactional maps get" )
4399 getCheck = True
4400 for n in range( 1, numKeys + 1 ):
4401 getResponses = []
4402 threads = []
4403 valueCheck = True
4404 for i in range( main.numCtrls ):
4405 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4406 name="TMap-get-" + str( i ),
4407 args=[ "Key" + str ( n ) ] )
4408 threads.append( t )
4409 t.start()
4410 for t in threads:
4411 t.join()
4412 getResponses.append( t.result )
4413 for node in getResponses:
4414 if node != tMapValue:
4415 valueCheck = False
4416 if not valueCheck:
4417 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4418 main.log.warn( getResponses )
4419 getCheck = getCheck and valueCheck
4420 utilities.assert_equals( expect=True,
4421 actual=getCheck,
4422 onpass="Partitioned Transactional Map get values were correct",
4423 onfail="Partitioned Transactional Map values incorrect" )
4424
4425 main.step( "In-memory Transactional maps put" )
4426 tMapValue = "Testing"
4427 numKeys = 100
4428 putResult = True
4429 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue, inMemory=True )
4430 if len( putResponses ) == 100:
4431 for i in putResponses:
4432 if putResponses[ i ][ 'value' ] != tMapValue:
4433 putResult = False
4434 else:
4435 putResult = False
4436 if not putResult:
4437 main.log.debug( "Put response values: " + str( putResponses ) )
4438 utilities.assert_equals( expect=True,
4439 actual=putResult,
4440 onpass="In-Memory Transactional Map put successful",
4441 onfail="In-Memory Transactional Map put values are incorrect" )
4442
4443 main.step( "In-Memory Transactional maps get" )
4444 getCheck = True
4445 for n in range( 1, numKeys + 1 ):
4446 getResponses = []
4447 threads = []
4448 valueCheck = True
4449 for i in range( main.numCtrls ):
4450 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4451 name="TMap-get-" + str( i ),
4452 args=[ "Key" + str ( n ) ],
4453 kwargs={ "inMemory": True } )
4454 threads.append( t )
4455 t.start()
4456 for t in threads:
4457 t.join()
4458 getResponses.append( t.result )
4459 for node in getResponses:
4460 if node != tMapValue:
4461 valueCheck = False
4462 if not valueCheck:
4463 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4464 main.log.warn( getResponses )
4465 getCheck = getCheck and valueCheck
4466 utilities.assert_equals( expect=True,
4467 actual=getCheck,
4468 onpass="In-Memory Transactional Map get values were correct",
4469 onfail="In-Memory Transactional Map values incorrect" )