blob: 8c5b1bb1e8ec518a500c1a4ab178f59d6315f294 [file] [log] [blame]
Jon Hall5cf14d52015-07-16 12:15:19 -07001"""
2Description: This test is to determine if ONOS can handle
3 all of it's nodes restarting
4
5List of test cases:
6CASE1: Compile ONOS and push it to the test machines
7CASE2: Assign devices to controllers
8CASE21: Assign mastership to controllers
9CASE3: Assign intents
10CASE4: Ping across added host intents
11CASE5: Reading state of ONOS
12CASE6: The Failure case.
13CASE7: Check state after control plane failure
14CASE8: Compare topo
15CASE9: Link s3-s28 down
16CASE10: Link s3-s28 up
17CASE11: Switch down
18CASE12: Switch up
19CASE13: Clean up
20CASE14: start election app on all onos nodes
21CASE15: Check that Leadership Election is still functional
22CASE16: Install Distributed Primitives app
23CASE17: Check for basic functionality with distributed primitives
24"""
25
26
27class HAclusterRestart:
28
29 def __init__( self ):
30 self.default = ''
31
32 def CASE1( self, main ):
33 """
34 CASE1 is to compile ONOS and push it to the test machines
35
36 Startup sequence:
37 cell <name>
38 onos-verify-cell
39 NOTE: temporary - onos-remove-raft-logs
40 onos-uninstall
41 start mininet
42 git pull
43 mvn clean install
44 onos-package
45 onos-install -f
46 onos-wait-for-start
47 start cli sessions
48 start tcpdump
49 """
Jon Halle1a3b752015-07-22 13:02:46 -070050 import imp
Jon Hall5cf14d52015-07-16 12:15:19 -070051 main.log.info( "ONOS HA test: Restart all ONOS nodes - " +
52 "initialization" )
53 main.case( "Setting up test environment" )
Jon Hall783bbf92015-07-23 14:33:19 -070054 main.caseExplanation = "Setup the test environment including " +\
Jon Hall5cf14d52015-07-16 12:15:19 -070055 "installing ONOS, starting Mininet and ONOS" +\
56 "cli sessions."
57 # TODO: save all the timers and output them for plotting
58
59 # load some variables from the params file
60 PULLCODE = False
61 if main.params[ 'Git' ] == 'True':
62 PULLCODE = True
63 gitBranch = main.params[ 'branch' ]
64 cellName = main.params[ 'ENV' ][ 'cellName' ]
65
Jon Halle1a3b752015-07-22 13:02:46 -070066 main.numCtrls = int( main.params[ 'num_controllers' ] )
Jon Hall5cf14d52015-07-16 12:15:19 -070067 if main.ONOSbench.maxNodes:
Jon Halle1a3b752015-07-22 13:02:46 -070068 if main.ONOSbench.maxNodes < main.numCtrls:
69 main.numCtrls = int( main.ONOSbench.maxNodes )
70 # set global variables
Jon Hall5cf14d52015-07-16 12:15:19 -070071 global ONOS1Port
72 global ONOS2Port
73 global ONOS3Port
74 global ONOS4Port
75 global ONOS5Port
76 global ONOS6Port
77 global ONOS7Port
78 # These are for csv plotting in jenkins
79 global labels
80 global data
81 labels = []
82 data = []
83
84 # FIXME: just get controller port from params?
85 # TODO: do we really need all these?
86 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
87 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
88 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
89 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
90 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
91 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
92 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
93
Jon Halle1a3b752015-07-22 13:02:46 -070094 try:
95 fileName = "Counters"
96 path = main.params[ 'imports' ][ 'path' ]
97 main.Counters = imp.load_source( fileName,
98 path + fileName + ".py" )
99 except Exception as e:
100 main.log.exception( e )
101 main.cleanup()
102 main.exit()
103
104 main.CLIs = []
105 main.nodes = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700106 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700107 for i in range( 1, main.numCtrls + 1 ):
108 try:
109 main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
110 main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
111 ipList.append( main.nodes[ -1 ].ip_address )
112 except AttributeError:
113 break
Jon Hall5cf14d52015-07-16 12:15:19 -0700114
115 main.step( "Create cell file" )
116 cellAppString = main.params[ 'ENV' ][ 'appString' ]
117 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
118 main.Mininet1.ip_address,
119 cellAppString, ipList )
120 main.step( "Applying cell variable to environment" )
121 cellResult = main.ONOSbench.setCell( cellName )
122 verifyResult = main.ONOSbench.verifyCell()
123
124 # FIXME:this is short term fix
125 main.log.info( "Removing raft logs" )
126 main.ONOSbench.onosRemoveRaftLogs()
127
128 main.log.info( "Uninstalling ONOS" )
Jon Halle1a3b752015-07-22 13:02:46 -0700129 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700130 main.ONOSbench.onosUninstall( node.ip_address )
131
132 # Make sure ONOS is DEAD
133 main.log.info( "Killing any ONOS processes" )
134 killResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700135 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700136 killed = main.ONOSbench.onosKill( node.ip_address )
137 killResults = killResults and killed
138
139 cleanInstallResult = main.TRUE
140 gitPullResult = main.TRUE
141
142 main.step( "Starting Mininet" )
143 # scp topo file to mininet
144 # TODO: move to params?
145 topoName = "obelisk.py"
146 filePath = main.ONOSbench.home + "/tools/test/topos/"
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700147 main.ONOSbench.scp( main.Mininet1,
148 filePath + topoName,
149 main.Mininet1.home,
150 direction="to" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700151 mnResult = main.Mininet1.startNet( )
152 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
153 onpass="Mininet Started",
154 onfail="Error starting Mininet" )
155
156 main.step( "Git checkout and pull " + gitBranch )
157 if PULLCODE:
158 main.ONOSbench.gitCheckout( gitBranch )
159 gitPullResult = main.ONOSbench.gitPull()
160 # values of 1 or 3 are good
161 utilities.assert_lesser( expect=0, actual=gitPullResult,
162 onpass="Git pull successful",
163 onfail="Git pull failed" )
164 main.ONOSbench.getVersion( report=True )
165
166 main.step( "Using mvn clean install" )
167 cleanInstallResult = main.TRUE
168 if PULLCODE and gitPullResult == main.TRUE:
169 cleanInstallResult = main.ONOSbench.cleanInstall()
170 else:
171 main.log.warn( "Did not pull new code so skipping mvn " +
172 "clean install" )
173 utilities.assert_equals( expect=main.TRUE,
174 actual=cleanInstallResult,
175 onpass="MCI successful",
176 onfail="MCI failed" )
177 # GRAPHS
178 # NOTE: important params here:
179 # job = name of Jenkins job
180 # Plot Name = Plot-HA, only can be used if multiple plots
181 # index = The number of the graph under plot name
182 job = "HAclusterRestart"
183 plotName = "Plot-HA"
184 graphs = '<ac:structured-macro ac:name="html">\n'
185 graphs += '<ac:plain-text-body><![CDATA[\n'
186 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
187 '/plot/' + plotName + '/getPlot?index=0' +\
188 '&width=500&height=300"' +\
189 'noborder="0" width="500" height="300" scrolling="yes" ' +\
190 'seamless="seamless"></iframe>\n'
191 graphs += ']]></ac:plain-text-body>\n'
192 graphs += '</ac:structured-macro>\n'
193 main.log.wiki(graphs)
194
195 main.step( "Creating ONOS package" )
196 packageResult = main.ONOSbench.onosPackage()
197 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
198 onpass="ONOS package successful",
199 onfail="ONOS package failed" )
200
201 main.step( "Installing ONOS package" )
202 onosInstallResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700203 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700204 tmpResult = main.ONOSbench.onosInstall( options="-f",
205 node=node.ip_address )
206 onosInstallResult = onosInstallResult and tmpResult
207 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
208 onpass="ONOS install successful",
209 onfail="ONOS install failed" )
210
211 main.step( "Checking if ONOS is up yet" )
212 for i in range( 2 ):
213 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700214 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700215 started = main.ONOSbench.isup( node.ip_address )
216 if not started:
217 main.log.error( node.name + " didn't start!" )
218 main.ONOSbench.onosStop( node.ip_address )
219 main.ONOSbench.onosStart( node.ip_address )
220 onosIsupResult = onosIsupResult and started
221 if onosIsupResult == main.TRUE:
222 break
223 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
224 onpass="ONOS startup successful",
225 onfail="ONOS startup failed" )
226
227 main.log.step( "Starting ONOS CLI sessions" )
228 cliResults = main.TRUE
229 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700230 for i in range( main.numCtrls ):
231 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -0700232 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -0700233 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -0700234 threads.append( t )
235 t.start()
236
237 for t in threads:
238 t.join()
239 cliResults = cliResults and t.result
240 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
241 onpass="ONOS cli startup successful",
242 onfail="ONOS cli startup failed" )
243
244 if main.params[ 'tcpdump' ].lower() == "true":
245 main.step( "Start Packet Capture MN" )
246 main.Mininet2.startTcpdump(
247 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
248 + "-MN.pcap",
249 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
250 port=main.params[ 'MNtcpdump' ][ 'port' ] )
251
252 main.step( "App Ids check" )
253 appCheck = main.TRUE
254 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700255 for i in range( main.numCtrls ):
256 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700257 name="appToIDCheck-" + str( i ),
258 args=[] )
259 threads.append( t )
260 t.start()
261
262 for t in threads:
263 t.join()
264 appCheck = appCheck and t.result
265 if appCheck != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700266 main.log.warn( main.CLIs[0].apps() )
267 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700268 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
269 onpass="App Ids seem to be correct",
270 onfail="Something is wrong with app Ids" )
271
272 if cliResults == main.FALSE:
273 main.log.error( "Failed to start ONOS, stopping test" )
274 main.cleanup()
275 main.exit()
276
277 def CASE2( self, main ):
278 """
279 Assign devices to controllers
280 """
281 import re
Jon Halle1a3b752015-07-22 13:02:46 -0700282 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700283 assert main, "main not defined"
284 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700285 assert main.CLIs, "main.CLIs not defined"
286 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700287 assert ONOS1Port, "ONOS1Port not defined"
288 assert ONOS2Port, "ONOS2Port not defined"
289 assert ONOS3Port, "ONOS3Port not defined"
290 assert ONOS4Port, "ONOS4Port not defined"
291 assert ONOS5Port, "ONOS5Port not defined"
292 assert ONOS6Port, "ONOS6Port not defined"
293 assert ONOS7Port, "ONOS7Port not defined"
294
295 main.case( "Assigning devices to controllers" )
Jon Hall783bbf92015-07-23 14:33:19 -0700296 main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700297 "and check that an ONOS node becomes the " +\
298 "master of the device."
299 main.step( "Assign switches to controllers" )
300
301 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700302 for i in range( main.numCtrls ):
303 ipList.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -0700304 swList = []
305 for i in range( 1, 29 ):
306 swList.append( "s" + str( i ) )
307 main.Mininet1.assignSwController( sw=swList, ip=ipList )
308
309 mastershipCheck = main.TRUE
310 for i in range( 1, 29 ):
311 response = main.Mininet1.getSwController( "s" + str( i ) )
312 try:
313 main.log.info( str( response ) )
314 except Exception:
315 main.log.info( repr( response ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700316 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -0700317 if re.search( "tcp:" + node.ip_address, response ):
318 mastershipCheck = mastershipCheck and main.TRUE
319 else:
320 main.log.error( "Error, node " + node.ip_address + " is " +
321 "not in the list of controllers s" +
322 str( i ) + " is connecting to." )
323 mastershipCheck = main.FALSE
324 utilities.assert_equals(
325 expect=main.TRUE,
326 actual=mastershipCheck,
327 onpass="Switch mastership assigned correctly",
328 onfail="Switches not assigned correctly to controllers" )
329
330 def CASE21( self, main ):
331 """
332 Assign mastership to controllers
333 """
Jon Hall5cf14d52015-07-16 12:15:19 -0700334 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700335 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700336 assert main, "main not defined"
337 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700338 assert main.CLIs, "main.CLIs not defined"
339 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700340 assert ONOS1Port, "ONOS1Port not defined"
341 assert ONOS2Port, "ONOS2Port not defined"
342 assert ONOS3Port, "ONOS3Port not defined"
343 assert ONOS4Port, "ONOS4Port not defined"
344 assert ONOS5Port, "ONOS5Port not defined"
345 assert ONOS6Port, "ONOS6Port not defined"
346 assert ONOS7Port, "ONOS7Port not defined"
347
348 main.case( "Assigning Controller roles for switches" )
Jon Hall783bbf92015-07-23 14:33:19 -0700349 main.caseExplanation = "Check that ONOS is connected to each " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700350 "device. Then manually assign" +\
351 " mastership to specific ONOS nodes using" +\
352 " 'device-role'"
353 main.step( "Assign mastership of switches to specific controllers" )
354 # Manually assign mastership to the controller we want
355 roleCall = main.TRUE
356
357 ipList = [ ]
358 deviceList = []
359 try:
360 # Assign mastership to specific controllers. This assignment was
361 # determined for a 7 node cluser, but will work with any sized
362 # cluster
363 for i in range( 1, 29 ): # switches 1 through 28
364 # set up correct variables:
365 if i == 1:
366 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700367 ip = main.nodes[ c ].ip_address # ONOS1
Jon Hall5cf14d52015-07-16 12:15:19 -0700368 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
369 elif i == 2:
Jon Halle1a3b752015-07-22 13:02:46 -0700370 c = 1 % main.numCtrls
371 ip = main.nodes[ c ].ip_address # ONOS2
Jon Hall5cf14d52015-07-16 12:15:19 -0700372 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
373 elif i == 3:
Jon Halle1a3b752015-07-22 13:02:46 -0700374 c = 1 % main.numCtrls
375 ip = main.nodes[ c ].ip_address # ONOS2
Jon Hall5cf14d52015-07-16 12:15:19 -0700376 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
377 elif i == 4:
Jon Halle1a3b752015-07-22 13:02:46 -0700378 c = 3 % main.numCtrls
379 ip = main.nodes[ c ].ip_address # ONOS4
Jon Hall5cf14d52015-07-16 12:15:19 -0700380 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
381 elif i == 5:
Jon Halle1a3b752015-07-22 13:02:46 -0700382 c = 2 % main.numCtrls
383 ip = main.nodes[ c ].ip_address # ONOS3
Jon Hall5cf14d52015-07-16 12:15:19 -0700384 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
385 elif i == 6:
Jon Halle1a3b752015-07-22 13:02:46 -0700386 c = 2 % main.numCtrls
387 ip = main.nodes[ c ].ip_address # ONOS3
Jon Hall5cf14d52015-07-16 12:15:19 -0700388 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
389 elif i == 7:
Jon Halle1a3b752015-07-22 13:02:46 -0700390 c = 5 % main.numCtrls
391 ip = main.nodes[ c ].ip_address # ONOS6
Jon Hall5cf14d52015-07-16 12:15:19 -0700392 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
393 elif i >= 8 and i <= 17:
Jon Halle1a3b752015-07-22 13:02:46 -0700394 c = 4 % main.numCtrls
395 ip = main.nodes[ c ].ip_address # ONOS5
Jon Hall5cf14d52015-07-16 12:15:19 -0700396 dpid = '3' + str( i ).zfill( 3 )
397 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
398 elif i >= 18 and i <= 27:
Jon Halle1a3b752015-07-22 13:02:46 -0700399 c = 6 % main.numCtrls
400 ip = main.nodes[ c ].ip_address # ONOS7
Jon Hall5cf14d52015-07-16 12:15:19 -0700401 dpid = '6' + str( i ).zfill( 3 )
402 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
403 elif i == 28:
404 c = 0
Jon Halle1a3b752015-07-22 13:02:46 -0700405 ip = main.nodes[ c ].ip_address # ONOS1
Jon Hall5cf14d52015-07-16 12:15:19 -0700406 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
407 else:
408 main.log.error( "You didn't write an else statement for " +
409 "switch s" + str( i ) )
410 roleCall = main.FALSE
411 # Assign switch
412 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
413 # TODO: make this controller dynamic
414 roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
415 ip )
416 ipList.append( ip )
417 deviceList.append( deviceId )
418 except ( AttributeError, AssertionError ):
419 main.log.exception( "Something is wrong with ONOS device view" )
420 main.log.info( main.ONOScli1.devices() )
421 utilities.assert_equals(
422 expect=main.TRUE,
423 actual=roleCall,
424 onpass="Re-assigned switch mastership to designated controller",
425 onfail="Something wrong with deviceRole calls" )
426
427 main.step( "Check mastership was correctly assigned" )
428 roleCheck = main.TRUE
429 # NOTE: This is due to the fact that device mastership change is not
430 # atomic and is actually a multi step process
431 time.sleep( 5 )
432 for i in range( len( ipList ) ):
433 ip = ipList[i]
434 deviceId = deviceList[i]
435 # Check assignment
436 master = main.ONOScli1.getRole( deviceId ).get( 'master' )
437 if ip in master:
438 roleCheck = roleCheck and main.TRUE
439 else:
440 roleCheck = roleCheck and main.FALSE
441 main.log.error( "Error, controller " + ip + " is not" +
442 " master " + "of device " +
443 str( deviceId ) + ". Master is " +
444 repr( master ) + "." )
445 utilities.assert_equals(
446 expect=main.TRUE,
447 actual=roleCheck,
448 onpass="Switches were successfully reassigned to designated " +
449 "controller",
450 onfail="Switches were not successfully reassigned" )
451
452 def CASE3( self, main ):
453 """
454 Assign intents
455 """
456 import time
457 import json
Jon Halle1a3b752015-07-22 13:02:46 -0700458 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700459 assert main, "main not defined"
460 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700461 assert main.CLIs, "main.CLIs not defined"
462 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700463 try:
464 labels
465 except NameError:
466 main.log.error( "labels not defined, setting to []" )
467 labels = []
468 try:
469 data
470 except NameError:
471 main.log.error( "data not defined, setting to []" )
472 data = []
473 # NOTE: we must reinstall intents until we have a persistant intent
474 # datastore!
475 main.case( "Adding host Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700476 main.caseExplanation = "Discover hosts by using pingall then " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700477 "assign predetermined host-to-host intents." +\
478 " After installation, check that the intent" +\
479 " is distributed to all nodes and the state" +\
480 " is INSTALLED"
481
482 # install onos-app-fwd
483 main.step( "Install reactive forwarding app" )
Jon Halle1a3b752015-07-22 13:02:46 -0700484 installResults = main.CLIs[0].activateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700485 utilities.assert_equals( expect=main.TRUE, actual=installResults,
486 onpass="Install fwd successful",
487 onfail="Install fwd failed" )
488
489 main.step( "Check app ids" )
490 appCheck = main.TRUE
491 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -0700492 for i in range( main.numCtrls ):
493 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700494 name="appToIDCheck-" + str( i ),
495 args=[] )
496 threads.append( t )
497 t.start()
498
499 for t in threads:
500 t.join()
501 appCheck = appCheck and t.result
502 if appCheck != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700503 main.log.warn( main.CLIs[0].apps() )
504 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700505 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
506 onpass="App Ids seem to be correct",
507 onfail="Something is wrong with app Ids" )
508
509 main.step( "Discovering Hosts( Via pingall for now )" )
510 # FIXME: Once we have a host discovery mechanism, use that instead
511 # REACTIVE FWD test
512 pingResult = main.FALSE
Jon Hall96091e62015-09-21 17:34:17 -0700513 passMsg = "Reactive Pingall test passed"
514 time1 = time.time()
515 pingResult = main.Mininet1.pingall()
516 time2 = time.time()
517 if not pingResult:
518 main.log.warn("First pingall failed. Trying again...")
Jon Hall5cf14d52015-07-16 12:15:19 -0700519 pingResult = main.Mininet1.pingall()
Jon Hall96091e62015-09-21 17:34:17 -0700520 passMsg += " on the second try"
521 utilities.assert_equals(
522 expect=main.TRUE,
523 actual=pingResult,
524 onpass= passMsg,
525 onfail="Reactive Pingall failed, " +
526 "one or more ping pairs failed" )
527 main.log.info( "Time for pingall: %2f seconds" %
528 ( time2 - time1 ) )
Jon Hall5cf14d52015-07-16 12:15:19 -0700529 # timeout for fwd flows
530 time.sleep( 11 )
531 # uninstall onos-app-fwd
532 main.step( "Uninstall reactive forwarding app" )
Jon Halle1a3b752015-07-22 13:02:46 -0700533 uninstallResult = main.CLIs[0].deactivateApp( "org.onosproject.fwd" )
Jon Hall5cf14d52015-07-16 12:15:19 -0700534 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
535 onpass="Uninstall fwd successful",
536 onfail="Uninstall fwd failed" )
537
538 main.step( "Check app ids" )
539 threads = []
540 appCheck2 = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700541 for i in range( main.numCtrls ):
542 t = main.Thread( target=main.CLIs[i].appToIDCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -0700543 name="appToIDCheck-" + str( i ),
544 args=[] )
545 threads.append( t )
546 t.start()
547
548 for t in threads:
549 t.join()
550 appCheck2 = appCheck2 and t.result
551 if appCheck2 != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700552 main.log.warn( main.CLIs[0].apps() )
553 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall5cf14d52015-07-16 12:15:19 -0700554 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
555 onpass="App Ids seem to be correct",
556 onfail="Something is wrong with app Ids" )
557
558 main.step( "Add host intents via cli" )
559 intentIds = []
560 # TODO: move the host numbers to params
561 # Maybe look at all the paths we ping?
562 intentAddResult = True
563 hostResult = main.TRUE
564 for i in range( 8, 18 ):
565 main.log.info( "Adding host intent between h" + str( i ) +
566 " and h" + str( i + 10 ) )
567 host1 = "00:00:00:00:00:" + \
568 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
569 host2 = "00:00:00:00:00:" + \
570 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
571 # NOTE: getHost can return None
572 host1Dict = main.ONOScli1.getHost( host1 )
573 host2Dict = main.ONOScli1.getHost( host2 )
574 host1Id = None
575 host2Id = None
576 if host1Dict and host2Dict:
577 host1Id = host1Dict.get( 'id', None )
578 host2Id = host2Dict.get( 'id', None )
579 if host1Id and host2Id:
Jon Halle1a3b752015-07-22 13:02:46 -0700580 nodeNum = ( i % main.numCtrls )
581 tmpId = main.CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
Jon Hall5cf14d52015-07-16 12:15:19 -0700582 if tmpId:
583 main.log.info( "Added intent with id: " + tmpId )
584 intentIds.append( tmpId )
585 else:
586 main.log.error( "addHostIntent returned: " +
587 repr( tmpId ) )
588 else:
589 main.log.error( "Error, getHost() failed for h" + str( i ) +
590 " and/or h" + str( i + 10 ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700591 hosts = main.CLIs[ 0 ].hosts()
Jon Hall5cf14d52015-07-16 12:15:19 -0700592 main.log.warn( "Hosts output: " )
593 try:
594 main.log.warn( json.dumps( json.loads( hosts ),
595 sort_keys=True,
596 indent=4,
597 separators=( ',', ': ' ) ) )
598 except ( ValueError, TypeError ):
599 main.log.warn( repr( hosts ) )
600 hostResult = main.FALSE
601 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
602 onpass="Found a host id for each host",
603 onfail="Error looking up host ids" )
604
605 intentStart = time.time()
606 onosIds = main.ONOScli1.getAllIntentsId()
607 main.log.info( "Submitted intents: " + str( intentIds ) )
608 main.log.info( "Intents in ONOS: " + str( onosIds ) )
609 for intent in intentIds:
610 if intent in onosIds:
611 pass # intent submitted is in onos
612 else:
613 intentAddResult = False
614 if intentAddResult:
615 intentStop = time.time()
616 else:
617 intentStop = None
618 # Print the intent states
619 intents = main.ONOScli1.intents()
620 intentStates = []
621 installedCheck = True
622 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
623 count = 0
624 try:
625 for intent in json.loads( intents ):
626 state = intent.get( 'state', None )
627 if "INSTALLED" not in state:
628 installedCheck = False
629 intentId = intent.get( 'id', None )
630 intentStates.append( ( intentId, state ) )
631 except ( ValueError, TypeError ):
632 main.log.exception( "Error parsing intents" )
633 # add submitted intents not in the store
634 tmplist = [ i for i, s in intentStates ]
635 missingIntents = False
636 for i in intentIds:
637 if i not in tmplist:
638 intentStates.append( ( i, " - " ) )
639 missingIntents = True
640 intentStates.sort()
641 for i, s in intentStates:
642 count += 1
643 main.log.info( "%-6s%-15s%-15s" %
644 ( str( count ), str( i ), str( s ) ) )
645 leaders = main.ONOScli1.leaders()
646 try:
647 missing = False
648 if leaders:
649 parsedLeaders = json.loads( leaders )
650 main.log.warn( json.dumps( parsedLeaders,
651 sort_keys=True,
652 indent=4,
653 separators=( ',', ': ' ) ) )
654 # check for all intent partitions
655 topics = []
656 for i in range( 14 ):
657 topics.append( "intent-partition-" + str( i ) )
658 main.log.debug( topics )
659 ONOStopics = [ j['topic'] for j in parsedLeaders ]
660 for topic in topics:
661 if topic not in ONOStopics:
662 main.log.error( "Error: " + topic +
663 " not in leaders" )
664 missing = True
665 else:
666 main.log.error( "leaders() returned None" )
667 except ( ValueError, TypeError ):
668 main.log.exception( "Error parsing leaders" )
669 main.log.error( repr( leaders ) )
670 # Check all nodes
671 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -0700672 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700673 response = node.leaders( jsonFormat=False)
674 main.log.warn( str( node.name ) + " leaders output: \n" +
675 str( response ) )
676
677 partitions = main.ONOScli1.partitions()
678 try:
679 if partitions :
680 parsedPartitions = json.loads( partitions )
681 main.log.warn( json.dumps( parsedPartitions,
682 sort_keys=True,
683 indent=4,
684 separators=( ',', ': ' ) ) )
685 # TODO check for a leader in all paritions
686 # TODO check for consistency among nodes
687 else:
688 main.log.error( "partitions() returned None" )
689 except ( ValueError, TypeError ):
690 main.log.exception( "Error parsing partitions" )
691 main.log.error( repr( partitions ) )
692 pendingMap = main.ONOScli1.pendingMap()
693 try:
694 if pendingMap :
695 parsedPending = json.loads( pendingMap )
696 main.log.warn( json.dumps( parsedPending,
697 sort_keys=True,
698 indent=4,
699 separators=( ',', ': ' ) ) )
700 # TODO check something here?
701 else:
702 main.log.error( "pendingMap() returned None" )
703 except ( ValueError, TypeError ):
704 main.log.exception( "Error parsing pending map" )
705 main.log.error( repr( pendingMap ) )
706
707 intentAddResult = bool( intentAddResult and not missingIntents and
708 installedCheck )
709 if not intentAddResult:
710 main.log.error( "Error in pushing host intents to ONOS" )
711
712 main.step( "Intent Anti-Entropy dispersion" )
713 for i in range(100):
714 correct = True
715 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700716 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700717 onosIds = []
718 ids = cli.getAllIntentsId()
719 onosIds.append( ids )
720 main.log.debug( "Intents in " + cli.name + ": " +
721 str( sorted( onosIds ) ) )
722 if sorted( ids ) != sorted( intentIds ):
723 main.log.warn( "Set of intent IDs doesn't match" )
724 correct = False
725 break
726 else:
727 intents = json.loads( cli.intents() )
728 for intent in intents:
729 if intent[ 'state' ] != "INSTALLED":
730 main.log.warn( "Intent " + intent[ 'id' ] +
731 " is " + intent[ 'state' ] )
732 correct = False
733 break
734 if correct:
735 break
736 else:
737 time.sleep(1)
738 if not intentStop:
739 intentStop = time.time()
740 global gossipTime
741 gossipTime = intentStop - intentStart
742 main.log.info( "It took about " + str( gossipTime ) +
743 " seconds for all intents to appear in each node" )
744 append = False
745 title = "Gossip Intents"
746 count = 1
747 while append is False:
748 curTitle = title + str( count )
749 if curTitle not in labels:
750 labels.append( curTitle )
751 data.append( str( gossipTime ) )
752 append = True
753 else:
754 count += 1
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700755 gossipPeriod = int( main.params['timers']['gossip'] )
756 maxGossipTime = gossipPeriod * len( main.nodes )
Jon Hall5cf14d52015-07-16 12:15:19 -0700757 utilities.assert_greater_equals(
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700758 expect=maxGossipTime, actual=gossipTime,
Jon Hall5cf14d52015-07-16 12:15:19 -0700759 onpass="ECM anti-entropy for intents worked within " +
760 "expected time",
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700761 onfail="Intent ECM anti-entropy took too long. " +
762 "Expected time:{}, Actual time:{}".format( maxGossipTime,
763 gossipTime ) )
764 if gossipTime <= maxGossipTime:
Jon Hall5cf14d52015-07-16 12:15:19 -0700765 intentAddResult = True
766
767 if not intentAddResult or "key" in pendingMap:
768 import time
769 installedCheck = True
770 main.log.info( "Sleeping 60 seconds to see if intents are found" )
771 time.sleep( 60 )
772 onosIds = main.ONOScli1.getAllIntentsId()
773 main.log.info( "Submitted intents: " + str( intentIds ) )
774 main.log.info( "Intents in ONOS: " + str( onosIds ) )
775 # Print the intent states
776 intents = main.ONOScli1.intents()
777 intentStates = []
778 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
779 count = 0
780 try:
781 for intent in json.loads( intents ):
782 # Iter through intents of a node
783 state = intent.get( 'state', None )
784 if "INSTALLED" not in state:
785 installedCheck = False
786 intentId = intent.get( 'id', None )
787 intentStates.append( ( intentId, state ) )
788 except ( ValueError, TypeError ):
789 main.log.exception( "Error parsing intents" )
790 # add submitted intents not in the store
791 tmplist = [ i for i, s in intentStates ]
792 for i in intentIds:
793 if i not in tmplist:
794 intentStates.append( ( i, " - " ) )
795 intentStates.sort()
796 for i, s in intentStates:
797 count += 1
798 main.log.info( "%-6s%-15s%-15s" %
799 ( str( count ), str( i ), str( s ) ) )
800 leaders = main.ONOScli1.leaders()
801 try:
802 missing = False
803 if leaders:
804 parsedLeaders = json.loads( leaders )
805 main.log.warn( json.dumps( parsedLeaders,
806 sort_keys=True,
807 indent=4,
808 separators=( ',', ': ' ) ) )
809 # check for all intent partitions
810 # check for election
811 topics = []
812 for i in range( 14 ):
813 topics.append( "intent-partition-" + str( i ) )
814 # FIXME: this should only be after we start the app
815 topics.append( "org.onosproject.election" )
816 main.log.debug( topics )
817 ONOStopics = [ j['topic'] for j in parsedLeaders ]
818 for topic in topics:
819 if topic not in ONOStopics:
820 main.log.error( "Error: " + topic +
821 " not in leaders" )
822 missing = True
823 else:
824 main.log.error( "leaders() returned None" )
825 except ( ValueError, TypeError ):
826 main.log.exception( "Error parsing leaders" )
827 main.log.error( repr( leaders ) )
828 # Check all nodes
829 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -0700830 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700831 response = node.leaders( jsonFormat=False)
832 main.log.warn( str( node.name ) + " leaders output: \n" +
833 str( response ) )
834
835 partitions = main.ONOScli1.partitions()
836 try:
837 if partitions :
838 parsedPartitions = json.loads( partitions )
839 main.log.warn( json.dumps( parsedPartitions,
840 sort_keys=True,
841 indent=4,
842 separators=( ',', ': ' ) ) )
843 # TODO check for a leader in all paritions
844 # TODO check for consistency among nodes
845 else:
846 main.log.error( "partitions() returned None" )
847 except ( ValueError, TypeError ):
848 main.log.exception( "Error parsing partitions" )
849 main.log.error( repr( partitions ) )
850 pendingMap = main.ONOScli1.pendingMap()
851 try:
852 if pendingMap :
853 parsedPending = json.loads( pendingMap )
854 main.log.warn( json.dumps( parsedPending,
855 sort_keys=True,
856 indent=4,
857 separators=( ',', ': ' ) ) )
858 # TODO check something here?
859 else:
860 main.log.error( "pendingMap() returned None" )
861 except ( ValueError, TypeError ):
862 main.log.exception( "Error parsing pending map" )
863 main.log.error( repr( pendingMap ) )
864
865 def CASE4( self, main ):
866 """
867 Ping across added host intents
868 """
869 import json
870 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700871 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700872 assert main, "main not defined"
873 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700874 assert main.CLIs, "main.CLIs not defined"
875 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -0700876 main.case( "Verify connectivity by sendind traffic across Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700877 main.caseExplanation = "Ping across added host intents to check " +\
Jon Hall5cf14d52015-07-16 12:15:19 -0700878 "functionality and check the state of " +\
879 "the intent"
880 main.step( "Ping across added host intents" )
881 PingResult = main.TRUE
882 for i in range( 8, 18 ):
883 ping = main.Mininet1.pingHost( src="h" + str( i ),
884 target="h" + str( i + 10 ) )
885 PingResult = PingResult and ping
886 if ping == main.FALSE:
887 main.log.warn( "Ping failed between h" + str( i ) +
888 " and h" + str( i + 10 ) )
889 elif ping == main.TRUE:
890 main.log.info( "Ping test passed!" )
891 # Don't set PingResult or you'd override failures
892 if PingResult == main.FALSE:
893 main.log.error(
894 "Intents have not been installed correctly, pings failed." )
895 # TODO: pretty print
896 main.log.warn( "ONOS1 intents: " )
897 try:
898 tmpIntents = main.ONOScli1.intents()
899 main.log.warn( json.dumps( json.loads( tmpIntents ),
900 sort_keys=True,
901 indent=4,
902 separators=( ',', ': ' ) ) )
903 except ( ValueError, TypeError ):
904 main.log.warn( repr( tmpIntents ) )
905 utilities.assert_equals(
906 expect=main.TRUE,
907 actual=PingResult,
908 onpass="Intents have been installed correctly and pings work",
909 onfail="Intents have not been installed correctly, pings failed." )
910
911 main.step( "Check Intent state" )
912 installedCheck = False
913 loopCount = 0
914 while not installedCheck and loopCount < 40:
915 installedCheck = True
916 # Print the intent states
917 intents = main.ONOScli1.intents()
918 intentStates = []
919 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700920 count = 0
Jon Hall5cf14d52015-07-16 12:15:19 -0700921 # Iter through intents of a node
922 try:
923 for intent in json.loads( intents ):
924 state = intent.get( 'state', None )
925 if "INSTALLED" not in state:
926 installedCheck = False
927 intentId = intent.get( 'id', None )
928 intentStates.append( ( intentId, state ) )
929 except ( ValueError, TypeError ):
930 main.log.exception( "Error parsing intents." )
931 # Print states
932 intentStates.sort()
933 for i, s in intentStates:
934 count += 1
935 main.log.info( "%-6s%-15s%-15s" %
936 ( str( count ), str( i ), str( s ) ) )
937 if not installedCheck:
938 time.sleep( 1 )
939 loopCount += 1
940 utilities.assert_equals( expect=True, actual=installedCheck,
941 onpass="Intents are all INSTALLED",
942 onfail="Intents are not all in " +
943 "INSTALLED state" )
944
945 main.step( "Check leadership of topics" )
946 leaders = main.ONOScli1.leaders()
947 topicCheck = main.TRUE
948 try:
949 if leaders:
950 parsedLeaders = json.loads( leaders )
951 main.log.warn( json.dumps( parsedLeaders,
952 sort_keys=True,
953 indent=4,
954 separators=( ',', ': ' ) ) )
955 # check for all intent partitions
956 # check for election
957 # TODO: Look at Devices as topics now that it uses this system
958 topics = []
959 for i in range( 14 ):
960 topics.append( "intent-partition-" + str( i ) )
961 # FIXME: this should only be after we start the app
962 # FIXME: topics.append( "org.onosproject.election" )
963 # Print leaders output
964 main.log.debug( topics )
965 ONOStopics = [ j['topic'] for j in parsedLeaders ]
966 for topic in topics:
967 if topic not in ONOStopics:
968 main.log.error( "Error: " + topic +
969 " not in leaders" )
970 topicCheck = main.FALSE
971 else:
972 main.log.error( "leaders() returned None" )
973 topicCheck = main.FALSE
974 except ( ValueError, TypeError ):
975 topicCheck = main.FALSE
976 main.log.exception( "Error parsing leaders" )
977 main.log.error( repr( leaders ) )
978 # TODO: Check for a leader of these topics
979 # Check all nodes
980 if topicCheck:
Jon Halle1a3b752015-07-22 13:02:46 -0700981 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -0700982 response = node.leaders( jsonFormat=False)
983 main.log.warn( str( node.name ) + " leaders output: \n" +
984 str( response ) )
985
986 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
987 onpass="intent Partitions is in leaders",
988 onfail="Some topics were lost " )
989 # Print partitions
990 partitions = main.ONOScli1.partitions()
991 try:
992 if partitions :
993 parsedPartitions = json.loads( partitions )
994 main.log.warn( json.dumps( parsedPartitions,
995 sort_keys=True,
996 indent=4,
997 separators=( ',', ': ' ) ) )
998 # TODO check for a leader in all paritions
999 # TODO check for consistency among nodes
1000 else:
1001 main.log.error( "partitions() returned None" )
1002 except ( ValueError, TypeError ):
1003 main.log.exception( "Error parsing partitions" )
1004 main.log.error( repr( partitions ) )
1005 # Print Pending Map
1006 pendingMap = main.ONOScli1.pendingMap()
1007 try:
1008 if pendingMap :
1009 parsedPending = json.loads( pendingMap )
1010 main.log.warn( json.dumps( parsedPending,
1011 sort_keys=True,
1012 indent=4,
1013 separators=( ',', ': ' ) ) )
1014 # TODO check something here?
1015 else:
1016 main.log.error( "pendingMap() returned None" )
1017 except ( ValueError, TypeError ):
1018 main.log.exception( "Error parsing pending map" )
1019 main.log.error( repr( pendingMap ) )
1020
1021 if not installedCheck:
1022 main.log.info( "Waiting 60 seconds to see if the state of " +
1023 "intents change" )
1024 time.sleep( 60 )
1025 # Print the intent states
1026 intents = main.ONOScli1.intents()
1027 intentStates = []
1028 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
1029 count = 0
1030 # Iter through intents of a node
1031 try:
1032 for intent in json.loads( intents ):
1033 state = intent.get( 'state', None )
1034 if "INSTALLED" not in state:
1035 installedCheck = False
1036 intentId = intent.get( 'id', None )
1037 intentStates.append( ( intentId, state ) )
1038 except ( ValueError, TypeError ):
1039 main.log.exception( "Error parsing intents." )
1040 intentStates.sort()
1041 for i, s in intentStates:
1042 count += 1
1043 main.log.info( "%-6s%-15s%-15s" %
1044 ( str( count ), str( i ), str( s ) ) )
1045 leaders = main.ONOScli1.leaders()
1046 try:
1047 missing = False
1048 if leaders:
1049 parsedLeaders = json.loads( leaders )
1050 main.log.warn( json.dumps( parsedLeaders,
1051 sort_keys=True,
1052 indent=4,
1053 separators=( ',', ': ' ) ) )
1054 # check for all intent partitions
1055 # check for election
1056 topics = []
1057 for i in range( 14 ):
1058 topics.append( "intent-partition-" + str( i ) )
1059 # FIXME: this should only be after we start the app
1060 topics.append( "org.onosproject.election" )
1061 main.log.debug( topics )
1062 ONOStopics = [ j['topic'] for j in parsedLeaders ]
1063 for topic in topics:
1064 if topic not in ONOStopics:
1065 main.log.error( "Error: " + topic +
1066 " not in leaders" )
1067 missing = True
1068 else:
1069 main.log.error( "leaders() returned None" )
1070 except ( ValueError, TypeError ):
1071 main.log.exception( "Error parsing leaders" )
1072 main.log.error( repr( leaders ) )
1073 if missing:
Jon Halle1a3b752015-07-22 13:02:46 -07001074 for node in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07001075 response = node.leaders( jsonFormat=False)
1076 main.log.warn( str( node.name ) + " leaders output: \n" +
1077 str( response ) )
1078
1079 partitions = main.ONOScli1.partitions()
1080 try:
1081 if partitions :
1082 parsedPartitions = json.loads( partitions )
1083 main.log.warn( json.dumps( parsedPartitions,
1084 sort_keys=True,
1085 indent=4,
1086 separators=( ',', ': ' ) ) )
1087 # TODO check for a leader in all paritions
1088 # TODO check for consistency among nodes
1089 else:
1090 main.log.error( "partitions() returned None" )
1091 except ( ValueError, TypeError ):
1092 main.log.exception( "Error parsing partitions" )
1093 main.log.error( repr( partitions ) )
1094 pendingMap = main.ONOScli1.pendingMap()
1095 try:
1096 if pendingMap :
1097 parsedPending = json.loads( pendingMap )
1098 main.log.warn( json.dumps( parsedPending,
1099 sort_keys=True,
1100 indent=4,
1101 separators=( ',', ': ' ) ) )
1102 # TODO check something here?
1103 else:
1104 main.log.error( "pendingMap() returned None" )
1105 except ( ValueError, TypeError ):
1106 main.log.exception( "Error parsing pending map" )
1107 main.log.error( repr( pendingMap ) )
1108 # Print flowrules
Jon Halle1a3b752015-07-22 13:02:46 -07001109 main.log.debug( main.CLIs[0].flows( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001110 main.step( "Wait a minute then ping again" )
1111 # the wait is above
1112 PingResult = main.TRUE
1113 for i in range( 8, 18 ):
1114 ping = main.Mininet1.pingHost( src="h" + str( i ),
1115 target="h" + str( i + 10 ) )
1116 PingResult = PingResult and ping
1117 if ping == main.FALSE:
1118 main.log.warn( "Ping failed between h" + str( i ) +
1119 " and h" + str( i + 10 ) )
1120 elif ping == main.TRUE:
1121 main.log.info( "Ping test passed!" )
1122 # Don't set PingResult or you'd override failures
1123 if PingResult == main.FALSE:
1124 main.log.error(
1125 "Intents have not been installed correctly, pings failed." )
1126 # TODO: pretty print
1127 main.log.warn( "ONOS1 intents: " )
1128 try:
1129 tmpIntents = main.ONOScli1.intents()
1130 main.log.warn( json.dumps( json.loads( tmpIntents ),
1131 sort_keys=True,
1132 indent=4,
1133 separators=( ',', ': ' ) ) )
1134 except ( ValueError, TypeError ):
1135 main.log.warn( repr( tmpIntents ) )
1136 utilities.assert_equals(
1137 expect=main.TRUE,
1138 actual=PingResult,
1139 onpass="Intents have been installed correctly and pings work",
1140 onfail="Intents have not been installed correctly, pings failed." )
1141
1142 def CASE5( self, main ):
1143 """
1144 Reading state of ONOS
1145 """
1146 import json
1147 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001148 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001149 assert main, "main not defined"
1150 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001151 assert main.CLIs, "main.CLIs not defined"
1152 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001153
1154 main.case( "Setting up and gathering data for current state" )
1155 # The general idea for this test case is to pull the state of
1156 # ( intents,flows, topology,... ) from each ONOS node
1157 # We can then compare them with each other and also with past states
1158
1159 main.step( "Check that each switch has a master" )
1160 global mastershipState
1161 mastershipState = '[]'
1162
1163 # Assert that each device has a master
1164 rolesNotNull = main.TRUE
1165 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001166 for i in range( main.numCtrls ):
1167 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001168 name="rolesNotNull-" + str( i ),
1169 args=[] )
1170 threads.append( t )
1171 t.start()
1172
1173 for t in threads:
1174 t.join()
1175 rolesNotNull = rolesNotNull and t.result
1176 utilities.assert_equals(
1177 expect=main.TRUE,
1178 actual=rolesNotNull,
1179 onpass="Each device has a master",
1180 onfail="Some devices don't have a master assigned" )
1181
1182 main.step( "Get the Mastership of each switch from each controller" )
1183 ONOSMastership = []
1184 mastershipCheck = main.FALSE
1185 consistentMastership = True
1186 rolesResults = True
1187 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001188 for i in range( main.numCtrls ):
1189 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001190 name="roles-" + str( i ),
1191 args=[] )
1192 threads.append( t )
1193 t.start()
1194
1195 for t in threads:
1196 t.join()
1197 ONOSMastership.append( t.result )
1198
Jon Halle1a3b752015-07-22 13:02:46 -07001199 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001200 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1201 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1202 " roles" )
1203 main.log.warn(
1204 "ONOS" + str( i + 1 ) + " mastership response: " +
1205 repr( ONOSMastership[i] ) )
1206 rolesResults = False
1207 utilities.assert_equals(
1208 expect=True,
1209 actual=rolesResults,
1210 onpass="No error in reading roles output",
1211 onfail="Error in reading roles from ONOS" )
1212
1213 main.step( "Check for consistency in roles from each controller" )
1214 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1215 main.log.info(
1216 "Switch roles are consistent across all ONOS nodes" )
1217 else:
1218 consistentMastership = False
1219 utilities.assert_equals(
1220 expect=True,
1221 actual=consistentMastership,
1222 onpass="Switch roles are consistent across all ONOS nodes",
1223 onfail="ONOS nodes have different views of switch roles" )
1224
1225 if rolesResults and not consistentMastership:
Jon Halle1a3b752015-07-22 13:02:46 -07001226 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001227 try:
1228 main.log.warn(
1229 "ONOS" + str( i + 1 ) + " roles: ",
1230 json.dumps(
1231 json.loads( ONOSMastership[ i ] ),
1232 sort_keys=True,
1233 indent=4,
1234 separators=( ',', ': ' ) ) )
1235 except ( ValueError, TypeError ):
1236 main.log.warn( repr( ONOSMastership[ i ] ) )
1237 elif rolesResults and consistentMastership:
1238 mastershipCheck = main.TRUE
1239 mastershipState = ONOSMastership[ 0 ]
1240
1241 main.step( "Get the intents from each controller" )
1242 global intentState
1243 intentState = []
1244 ONOSIntents = []
1245 intentCheck = main.FALSE
1246 consistentIntents = True
1247 intentsResults = True
1248 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001249 for i in range( main.numCtrls ):
1250 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001251 name="intents-" + str( i ),
1252 args=[],
1253 kwargs={ 'jsonFormat': True } )
1254 threads.append( t )
1255 t.start()
1256
1257 for t in threads:
1258 t.join()
1259 ONOSIntents.append( t.result )
1260
Jon Halle1a3b752015-07-22 13:02:46 -07001261 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001262 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1263 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1264 " intents" )
1265 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1266 repr( ONOSIntents[ i ] ) )
1267 intentsResults = False
1268 utilities.assert_equals(
1269 expect=True,
1270 actual=intentsResults,
1271 onpass="No error in reading intents output",
1272 onfail="Error in reading intents from ONOS" )
1273
1274 main.step( "Check for consistency in Intents from each controller" )
1275 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1276 main.log.info( "Intents are consistent across all ONOS " +
1277 "nodes" )
1278 else:
1279 consistentIntents = False
1280 main.log.error( "Intents not consistent" )
1281 utilities.assert_equals(
1282 expect=True,
1283 actual=consistentIntents,
1284 onpass="Intents are consistent across all ONOS nodes",
1285 onfail="ONOS nodes have different views of intents" )
1286
1287 if intentsResults:
1288 # Try to make it easy to figure out what is happening
1289 #
1290 # Intent ONOS1 ONOS2 ...
1291 # 0x01 INSTALLED INSTALLING
1292 # ... ... ...
1293 # ... ... ...
1294 title = " Id"
Jon Halle1a3b752015-07-22 13:02:46 -07001295 for n in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001296 title += " " * 10 + "ONOS" + str( n + 1 )
1297 main.log.warn( title )
1298 # get all intent keys in the cluster
1299 keys = []
1300 for nodeStr in ONOSIntents:
1301 node = json.loads( nodeStr )
1302 for intent in node:
1303 keys.append( intent.get( 'id' ) )
1304 keys = set( keys )
1305 for key in keys:
1306 row = "%-13s" % key
1307 for nodeStr in ONOSIntents:
1308 node = json.loads( nodeStr )
1309 for intent in node:
1310 if intent.get( 'id', "Error" ) == key:
1311 row += "%-15s" % intent.get( 'state' )
1312 main.log.warn( row )
1313 # End table view
1314
1315 if intentsResults and not consistentIntents:
1316 # print the json objects
1317 n = len(ONOSIntents)
1318 main.log.debug( "ONOS" + str( n ) + " intents: " )
1319 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1320 sort_keys=True,
1321 indent=4,
1322 separators=( ',', ': ' ) ) )
Jon Halle1a3b752015-07-22 13:02:46 -07001323 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001324 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
1325 main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
1326 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1327 sort_keys=True,
1328 indent=4,
1329 separators=( ',', ': ' ) ) )
1330 else:
Jon Halle1a3b752015-07-22 13:02:46 -07001331 main.log.debug( main.nodes[ i ].name + " intents match ONOS" +
Jon Hall5cf14d52015-07-16 12:15:19 -07001332 str( n ) + " intents" )
1333 elif intentsResults and consistentIntents:
1334 intentCheck = main.TRUE
1335 intentState = ONOSIntents[ 0 ]
1336
1337 main.step( "Get the flows from each controller" )
1338 global flowState
1339 flowState = []
1340 ONOSFlows = []
1341 ONOSFlowsJson = []
1342 flowCheck = main.FALSE
1343 consistentFlows = True
1344 flowsResults = True
1345 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001346 for i in range( main.numCtrls ):
1347 t = main.Thread( target=main.CLIs[i].flows,
Jon Hall5cf14d52015-07-16 12:15:19 -07001348 name="flows-" + str( i ),
1349 args=[],
1350 kwargs={ 'jsonFormat': True } )
1351 threads.append( t )
1352 t.start()
1353
1354 # NOTE: Flows command can take some time to run
1355 time.sleep(30)
1356 for t in threads:
1357 t.join()
1358 result = t.result
1359 ONOSFlows.append( result )
1360
Jon Halle1a3b752015-07-22 13:02:46 -07001361 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001362 num = str( i + 1 )
1363 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1364 main.log.error( "Error in getting ONOS" + num + " flows" )
1365 main.log.warn( "ONOS" + num + " flows response: " +
1366 repr( ONOSFlows[ i ] ) )
1367 flowsResults = False
1368 ONOSFlowsJson.append( None )
1369 else:
1370 try:
1371 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1372 except ( ValueError, TypeError ):
1373 # FIXME: change this to log.error?
1374 main.log.exception( "Error in parsing ONOS" + num +
1375 " response as json." )
1376 main.log.error( repr( ONOSFlows[ i ] ) )
1377 ONOSFlowsJson.append( None )
1378 flowsResults = False
1379 utilities.assert_equals(
1380 expect=True,
1381 actual=flowsResults,
1382 onpass="No error in reading flows output",
1383 onfail="Error in reading flows from ONOS" )
1384
1385 main.step( "Check for consistency in Flows from each controller" )
1386 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1387 if all( tmp ):
1388 main.log.info( "Flow count is consistent across all ONOS nodes" )
1389 else:
1390 consistentFlows = False
1391 utilities.assert_equals(
1392 expect=True,
1393 actual=consistentFlows,
1394 onpass="The flow count is consistent across all ONOS nodes",
1395 onfail="ONOS nodes have different flow counts" )
1396
1397 if flowsResults and not consistentFlows:
Jon Halle1a3b752015-07-22 13:02:46 -07001398 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001399 try:
1400 main.log.warn(
1401 "ONOS" + str( i + 1 ) + " flows: " +
1402 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1403 indent=4, separators=( ',', ': ' ) ) )
1404 except ( ValueError, TypeError ):
1405 main.log.warn(
1406 "ONOS" + str( i + 1 ) + " flows: " +
1407 repr( ONOSFlows[ i ] ) )
1408 elif flowsResults and consistentFlows:
1409 flowCheck = main.TRUE
1410 flowState = ONOSFlows[ 0 ]
1411
1412 main.step( "Get the OF Table entries" )
1413 global flows
1414 flows = []
1415 for i in range( 1, 29 ):
Jon Hallca7ac292015-11-11 09:28:12 -08001416 flows.append( main.Mininet1.getFlowTable( "s" + str( i ), version="1.3" ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001417 if flowCheck == main.FALSE:
1418 for table in flows:
1419 main.log.warn( table )
1420 # TODO: Compare switch flow tables with ONOS flow tables
1421
1422 main.step( "Start continuous pings" )
1423 main.Mininet2.pingLong(
1424 src=main.params[ 'PING' ][ 'source1' ],
1425 target=main.params[ 'PING' ][ 'target1' ],
1426 pingTime=500 )
1427 main.Mininet2.pingLong(
1428 src=main.params[ 'PING' ][ 'source2' ],
1429 target=main.params[ 'PING' ][ 'target2' ],
1430 pingTime=500 )
1431 main.Mininet2.pingLong(
1432 src=main.params[ 'PING' ][ 'source3' ],
1433 target=main.params[ 'PING' ][ 'target3' ],
1434 pingTime=500 )
1435 main.Mininet2.pingLong(
1436 src=main.params[ 'PING' ][ 'source4' ],
1437 target=main.params[ 'PING' ][ 'target4' ],
1438 pingTime=500 )
1439 main.Mininet2.pingLong(
1440 src=main.params[ 'PING' ][ 'source5' ],
1441 target=main.params[ 'PING' ][ 'target5' ],
1442 pingTime=500 )
1443 main.Mininet2.pingLong(
1444 src=main.params[ 'PING' ][ 'source6' ],
1445 target=main.params[ 'PING' ][ 'target6' ],
1446 pingTime=500 )
1447 main.Mininet2.pingLong(
1448 src=main.params[ 'PING' ][ 'source7' ],
1449 target=main.params[ 'PING' ][ 'target7' ],
1450 pingTime=500 )
1451 main.Mininet2.pingLong(
1452 src=main.params[ 'PING' ][ 'source8' ],
1453 target=main.params[ 'PING' ][ 'target8' ],
1454 pingTime=500 )
1455 main.Mininet2.pingLong(
1456 src=main.params[ 'PING' ][ 'source9' ],
1457 target=main.params[ 'PING' ][ 'target9' ],
1458 pingTime=500 )
1459 main.Mininet2.pingLong(
1460 src=main.params[ 'PING' ][ 'source10' ],
1461 target=main.params[ 'PING' ][ 'target10' ],
1462 pingTime=500 )
1463
1464 main.step( "Collecting topology information from ONOS" )
1465 devices = []
1466 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001467 for i in range( main.numCtrls ):
1468 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07001469 name="devices-" + str( i ),
1470 args=[ ] )
1471 threads.append( t )
1472 t.start()
1473
1474 for t in threads:
1475 t.join()
1476 devices.append( t.result )
1477 hosts = []
1478 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001479 for i in range( main.numCtrls ):
1480 t = main.Thread( target=main.CLIs[i].hosts,
Jon Hall5cf14d52015-07-16 12:15:19 -07001481 name="hosts-" + str( i ),
1482 args=[ ] )
1483 threads.append( t )
1484 t.start()
1485
1486 for t in threads:
1487 t.join()
1488 try:
1489 hosts.append( json.loads( t.result ) )
1490 except ( ValueError, TypeError ):
1491 # FIXME: better handling of this, print which node
1492 # Maybe use thread name?
1493 main.log.exception( "Error parsing json output of hosts" )
Jon Hall3afe4c92015-12-14 19:30:38 -08001494 main.log.warn( repr( t.result ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001495 hosts.append( None )
1496
1497 ports = []
1498 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001499 for i in range( main.numCtrls ):
1500 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07001501 name="ports-" + str( i ),
1502 args=[ ] )
1503 threads.append( t )
1504 t.start()
1505
1506 for t in threads:
1507 t.join()
1508 ports.append( t.result )
1509 links = []
1510 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001511 for i in range( main.numCtrls ):
1512 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07001513 name="links-" + str( i ),
1514 args=[ ] )
1515 threads.append( t )
1516 t.start()
1517
1518 for t in threads:
1519 t.join()
1520 links.append( t.result )
1521 clusters = []
1522 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001523 for i in range( main.numCtrls ):
1524 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07001525 name="clusters-" + str( i ),
1526 args=[ ] )
1527 threads.append( t )
1528 t.start()
1529
1530 for t in threads:
1531 t.join()
1532 clusters.append( t.result )
1533 # Compare json objects for hosts and dataplane clusters
1534
1535 # hosts
1536 main.step( "Host view is consistent across ONOS nodes" )
1537 consistentHostsResult = main.TRUE
1538 for controller in range( len( hosts ) ):
1539 controllerStr = str( controller + 1 )
Jon Hall3afe4c92015-12-14 19:30:38 -08001540 if hosts[ controller ] and "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07001541 if hosts[ controller ] == hosts[ 0 ]:
1542 continue
1543 else: # hosts not consistent
1544 main.log.error( "hosts from ONOS" +
1545 controllerStr +
1546 " is inconsistent with ONOS1" )
1547 main.log.warn( repr( hosts[ controller ] ) )
1548 consistentHostsResult = main.FALSE
1549
1550 else:
1551 main.log.error( "Error in getting ONOS hosts from ONOS" +
1552 controllerStr )
1553 consistentHostsResult = main.FALSE
1554 main.log.warn( "ONOS" + controllerStr +
1555 " hosts response: " +
1556 repr( hosts[ controller ] ) )
1557 utilities.assert_equals(
1558 expect=main.TRUE,
1559 actual=consistentHostsResult,
1560 onpass="Hosts view is consistent across all ONOS nodes",
1561 onfail="ONOS nodes have different views of hosts" )
1562
1563 main.step( "Each host has an IP address" )
1564 ipResult = main.TRUE
1565 for controller in range( 0, len( hosts ) ):
1566 controllerStr = str( controller + 1 )
Jon Hall3afe4c92015-12-14 19:30:38 -08001567 if hosts[ controller ]:
1568 for host in hosts[ controller ]:
1569 if not host.get( 'ipAddresses', [ ] ):
1570 main.log.error( "DEBUG:Error with host ips on controller" +
1571 controllerStr + ": " + str( host ) )
1572 ipResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07001573 utilities.assert_equals(
1574 expect=main.TRUE,
1575 actual=ipResult,
1576 onpass="The ips of the hosts aren't empty",
1577 onfail="The ip of at least one host is missing" )
1578
1579 # Strongly connected clusters of devices
1580 main.step( "Cluster view is consistent across ONOS nodes" )
1581 consistentClustersResult = main.TRUE
1582 for controller in range( len( clusters ) ):
1583 controllerStr = str( controller + 1 )
1584 if "Error" not in clusters[ controller ]:
1585 if clusters[ controller ] == clusters[ 0 ]:
1586 continue
1587 else: # clusters not consistent
1588 main.log.error( "clusters from ONOS" + controllerStr +
1589 " is inconsistent with ONOS1" )
1590 consistentClustersResult = main.FALSE
1591
1592 else:
1593 main.log.error( "Error in getting dataplane clusters " +
1594 "from ONOS" + controllerStr )
1595 consistentClustersResult = main.FALSE
1596 main.log.warn( "ONOS" + controllerStr +
1597 " clusters response: " +
1598 repr( clusters[ controller ] ) )
1599 utilities.assert_equals(
1600 expect=main.TRUE,
1601 actual=consistentClustersResult,
1602 onpass="Clusters view is consistent across all ONOS nodes",
1603 onfail="ONOS nodes have different views of clusters" )
1604 # there should always only be one cluster
1605 main.step( "Cluster view correct across ONOS nodes" )
1606 try:
1607 numClusters = len( json.loads( clusters[ 0 ] ) )
1608 except ( ValueError, TypeError ):
1609 main.log.exception( "Error parsing clusters[0]: " +
1610 repr( clusters[ 0 ] ) )
1611 clusterResults = main.FALSE
1612 if numClusters == 1:
1613 clusterResults = main.TRUE
1614 utilities.assert_equals(
1615 expect=1,
1616 actual=numClusters,
1617 onpass="ONOS shows 1 SCC",
1618 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1619
1620 main.step( "Comparing ONOS topology to MN" )
1621 devicesResults = main.TRUE
1622 linksResults = main.TRUE
1623 hostsResults = main.TRUE
1624 mnSwitches = main.Mininet1.getSwitches()
1625 mnLinks = main.Mininet1.getLinks()
1626 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07001627 for controller in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001628 controllerStr = str( controller + 1 )
1629 if devices[ controller ] and ports[ controller ] and\
1630 "Error" not in devices[ controller ] and\
1631 "Error" not in ports[ controller ]:
Jon Halle1a3b752015-07-22 13:02:46 -07001632 currentDevicesResult = main.Mininet1.compareSwitches(
1633 mnSwitches,
1634 json.loads( devices[ controller ] ),
1635 json.loads( ports[ controller ] ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001636 else:
1637 currentDevicesResult = main.FALSE
1638 utilities.assert_equals( expect=main.TRUE,
1639 actual=currentDevicesResult,
1640 onpass="ONOS" + controllerStr +
1641 " Switches view is correct",
1642 onfail="ONOS" + controllerStr +
1643 " Switches view is incorrect" )
1644 if links[ controller ] and "Error" not in links[ controller ]:
1645 currentLinksResult = main.Mininet1.compareLinks(
1646 mnSwitches, mnLinks,
1647 json.loads( links[ controller ] ) )
1648 else:
1649 currentLinksResult = main.FALSE
1650 utilities.assert_equals( expect=main.TRUE,
1651 actual=currentLinksResult,
1652 onpass="ONOS" + controllerStr +
1653 " links view is correct",
1654 onfail="ONOS" + controllerStr +
1655 " links view is incorrect" )
1656
1657 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1658 currentHostsResult = main.Mininet1.compareHosts(
1659 mnHosts,
1660 hosts[ controller ] )
1661 else:
1662 currentHostsResult = main.FALSE
1663 utilities.assert_equals( expect=main.TRUE,
1664 actual=currentHostsResult,
1665 onpass="ONOS" + controllerStr +
1666 " hosts exist in Mininet",
1667 onfail="ONOS" + controllerStr +
1668 " hosts don't match Mininet" )
1669
1670 devicesResults = devicesResults and currentDevicesResult
1671 linksResults = linksResults and currentLinksResult
1672 hostsResults = hostsResults and currentHostsResult
1673
1674 main.step( "Device information is correct" )
1675 utilities.assert_equals(
1676 expect=main.TRUE,
1677 actual=devicesResults,
1678 onpass="Device information is correct",
1679 onfail="Device information is incorrect" )
1680
1681 main.step( "Links are correct" )
1682 utilities.assert_equals(
1683 expect=main.TRUE,
1684 actual=linksResults,
1685 onpass="Link are correct",
1686 onfail="Links are incorrect" )
1687
1688 main.step( "Hosts are correct" )
1689 utilities.assert_equals(
1690 expect=main.TRUE,
1691 actual=hostsResults,
1692 onpass="Hosts are correct",
1693 onfail="Hosts are incorrect" )
1694
1695 def CASE6( self, main ):
1696 """
1697 The Failure case.
1698 """
1699 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001700 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001701 assert main, "main not defined"
1702 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001703 assert main.CLIs, "main.CLIs not defined"
1704 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001705 try:
1706 labels
1707 except NameError:
1708 main.log.error( "labels not defined, setting to []" )
1709 global labels
1710 labels = []
1711 try:
1712 data
1713 except NameError:
1714 main.log.error( "data not defined, setting to []" )
1715 global data
1716 data = []
1717 # Reset non-persistent variables
1718 try:
1719 iCounterValue = 0
1720 except NameError:
1721 main.log.error( "iCounterValue not defined, setting to 0" )
1722 iCounterValue = 0
1723
1724 main.case( "Restart entire ONOS cluster" )
1725
Jon Hall5ec6b1b2015-09-17 18:20:14 -07001726 main.step( "Checking ONOS Logs for errors" )
1727 for node in main.nodes:
1728 main.log.debug( "Checking logs for errors on " + node.name + ":" )
1729 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
1730
Jon Hall5cf14d52015-07-16 12:15:19 -07001731 main.step( "Killing ONOS nodes" )
1732 killResults = main.TRUE
1733 killTime = time.time()
Jon Halle1a3b752015-07-22 13:02:46 -07001734 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001735 killed = main.ONOSbench.onosKill( node.ip_address )
1736 killResults = killResults and killed
1737 utilities.assert_equals( expect=main.TRUE, actual=killResults,
1738 onpass="ONOS nodes killed",
1739 onfail="ONOS kill unsuccessful" )
1740
1741 main.step( "Checking if ONOS is up yet" )
1742 for i in range( 2 ):
1743 onosIsupResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001744 for node in main.nodes:
Jon Hall5cf14d52015-07-16 12:15:19 -07001745 started = main.ONOSbench.isup( node.ip_address )
1746 if not started:
1747 main.log.error( node.name + " didn't start!" )
1748 onosIsupResult = onosIsupResult and started
1749 if onosIsupResult == main.TRUE:
1750 break
1751 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1752 onpass="ONOS restarted",
1753 onfail="ONOS restart NOT successful" )
1754
1755 main.log.step( "Starting ONOS CLI sessions" )
1756 cliResults = main.TRUE
1757 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001758 for i in range( main.numCtrls ):
1759 t = main.Thread( target=main.CLIs[i].startOnosCli,
Jon Hall5cf14d52015-07-16 12:15:19 -07001760 name="startOnosCli-" + str( i ),
Jon Halle1a3b752015-07-22 13:02:46 -07001761 args=[main.nodes[i].ip_address] )
Jon Hall5cf14d52015-07-16 12:15:19 -07001762 threads.append( t )
1763 t.start()
1764
1765 for t in threads:
1766 t.join()
1767 cliResults = cliResults and t.result
1768 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1769 onpass="ONOS cli started",
1770 onfail="ONOS clis did not restart" )
1771
1772 # Grab the time of restart so we chan check how long the gossip
1773 # protocol has had time to work
1774 main.restartTime = time.time() - killTime
1775 main.log.debug( "Restart time: " + str( main.restartTime ) )
1776 labels.append( "Restart" )
1777 data.append( str( main.restartTime ) )
1778
1779 # FIXME: revisit test plan for election with madan
1780 # Rerun for election on restarted nodes
1781 runResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001782 for cli in main.CLIs:
1783 run = main.CLIs[0].electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07001784 if run != main.TRUE:
1785 main.log.error( "Error running for election on " + cli.name )
1786 runResults = runResults and run
1787 utilities.assert_equals( expect=main.TRUE, actual=runResults,
1788 onpass="Reran for election",
1789 onfail="Failed to rerun for election" )
1790
1791 # TODO: Make this configurable
1792 time.sleep( 60 )
Jon Halle1a3b752015-07-22 13:02:46 -07001793 main.log.debug( main.CLIs[0].nodes( jsonFormat=False ) )
1794 main.log.debug( main.CLIs[0].leaders( jsonFormat=False ) )
1795 main.log.debug( main.CLIs[0].partitions( jsonFormat=False ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07001796
1797 def CASE7( self, main ):
1798 """
1799 Check state after ONOS failure
1800 """
1801 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001802 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001803 assert main, "main not defined"
1804 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07001805 assert main.CLIs, "main.CLIs not defined"
1806 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07001807 main.case( "Running ONOS Constant State Tests" )
1808
1809 main.step( "Check that each switch has a master" )
1810 # Assert that each device has a master
1811 rolesNotNull = main.TRUE
1812 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001813 for i in range( main.numCtrls ):
1814 t = main.Thread( target=main.CLIs[i].rolesNotNull,
Jon Hall5cf14d52015-07-16 12:15:19 -07001815 name="rolesNotNull-" + str( i ),
1816 args=[ ] )
1817 threads.append( t )
1818 t.start()
1819
1820 for t in threads:
1821 t.join()
1822 rolesNotNull = rolesNotNull and t.result
1823 utilities.assert_equals(
1824 expect=main.TRUE,
1825 actual=rolesNotNull,
1826 onpass="Each device has a master",
1827 onfail="Some devices don't have a master assigned" )
1828
1829 main.step( "Read device roles from ONOS" )
1830 ONOSMastership = []
1831 mastershipCheck = main.FALSE
1832 consistentMastership = True
1833 rolesResults = True
1834 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001835 for i in range( main.numCtrls ):
1836 t = main.Thread( target=main.CLIs[i].roles,
Jon Hall5cf14d52015-07-16 12:15:19 -07001837 name="roles-" + str( i ),
1838 args=[] )
1839 threads.append( t )
1840 t.start()
1841
1842 for t in threads:
1843 t.join()
1844 ONOSMastership.append( t.result )
1845
Jon Halle1a3b752015-07-22 13:02:46 -07001846 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001847 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1848 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1849 " roles" )
1850 main.log.warn(
1851 "ONOS" + str( i + 1 ) + " mastership response: " +
1852 repr( ONOSMastership[i] ) )
1853 rolesResults = False
1854 utilities.assert_equals(
1855 expect=True,
1856 actual=rolesResults,
1857 onpass="No error in reading roles output",
1858 onfail="Error in reading roles from ONOS" )
1859
1860 main.step( "Check for consistency in roles from each controller" )
1861 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
1862 main.log.info(
1863 "Switch roles are consistent across all ONOS nodes" )
1864 else:
1865 consistentMastership = False
1866 utilities.assert_equals(
1867 expect=True,
1868 actual=consistentMastership,
1869 onpass="Switch roles are consistent across all ONOS nodes",
1870 onfail="ONOS nodes have different views of switch roles" )
1871
1872 if rolesResults and not consistentMastership:
Jon Halle1a3b752015-07-22 13:02:46 -07001873 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001874 main.log.warn(
1875 "ONOS" + str( i + 1 ) + " roles: ",
1876 json.dumps(
1877 json.loads( ONOSMastership[ i ] ),
1878 sort_keys=True,
1879 indent=4,
1880 separators=( ',', ': ' ) ) )
1881 elif rolesResults and not consistentMastership:
1882 mastershipCheck = main.TRUE
1883
1884 '''
1885 description2 = "Compare switch roles from before failure"
1886 main.step( description2 )
1887 try:
1888 currentJson = json.loads( ONOSMastership[0] )
1889 oldJson = json.loads( mastershipState )
1890 except ( ValueError, TypeError ):
1891 main.log.exception( "Something is wrong with parsing " +
1892 "ONOSMastership[0] or mastershipState" )
1893 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1894 main.log.error( "mastershipState" + repr( mastershipState ) )
1895 main.cleanup()
1896 main.exit()
1897 mastershipCheck = main.TRUE
1898 for i in range( 1, 29 ):
1899 switchDPID = str(
1900 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
1901 current = [ switch[ 'master' ] for switch in currentJson
1902 if switchDPID in switch[ 'id' ] ]
1903 old = [ switch[ 'master' ] for switch in oldJson
1904 if switchDPID in switch[ 'id' ] ]
1905 if current == old:
1906 mastershipCheck = mastershipCheck and main.TRUE
1907 else:
1908 main.log.warn( "Mastership of switch %s changed" % switchDPID )
1909 mastershipCheck = main.FALSE
1910 utilities.assert_equals(
1911 expect=main.TRUE,
1912 actual=mastershipCheck,
1913 onpass="Mastership of Switches was not changed",
1914 onfail="Mastership of some switches changed" )
1915 '''
1916 # NOTE: we expect mastership to change on controller failure
1917
1918 main.step( "Get the intents and compare across all nodes" )
1919 ONOSIntents = []
1920 intentCheck = main.FALSE
1921 consistentIntents = True
1922 intentsResults = True
1923 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07001924 for i in range( main.numCtrls ):
1925 t = main.Thread( target=main.CLIs[i].intents,
Jon Hall5cf14d52015-07-16 12:15:19 -07001926 name="intents-" + str( i ),
1927 args=[],
1928 kwargs={ 'jsonFormat': True } )
1929 threads.append( t )
1930 t.start()
1931
1932 for t in threads:
1933 t.join()
1934 ONOSIntents.append( t.result )
1935
Jon Halle1a3b752015-07-22 13:02:46 -07001936 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001937 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1938 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
1939 " intents" )
1940 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1941 repr( ONOSIntents[ i ] ) )
1942 intentsResults = False
1943 utilities.assert_equals(
1944 expect=True,
1945 actual=intentsResults,
1946 onpass="No error in reading intents output",
1947 onfail="Error in reading intents from ONOS" )
1948
1949 main.step( "Check for consistency in Intents from each controller" )
1950 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1951 main.log.info( "Intents are consistent across all ONOS " +
1952 "nodes" )
1953 else:
1954 consistentIntents = False
1955
1956 # Try to make it easy to figure out what is happening
1957 #
1958 # Intent ONOS1 ONOS2 ...
1959 # 0x01 INSTALLED INSTALLING
1960 # ... ... ...
1961 # ... ... ...
1962 title = " ID"
Jon Halle1a3b752015-07-22 13:02:46 -07001963 for n in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07001964 title += " " * 10 + "ONOS" + str( n + 1 )
1965 main.log.warn( title )
1966 # get all intent keys in the cluster
1967 keys = []
1968 for nodeStr in ONOSIntents:
1969 node = json.loads( nodeStr )
1970 for intent in node:
1971 keys.append( intent.get( 'id' ) )
1972 keys = set( keys )
1973 for key in keys:
1974 row = "%-13s" % key
1975 for nodeStr in ONOSIntents:
1976 node = json.loads( nodeStr )
1977 for intent in node:
1978 if intent.get( 'id' ) == key:
1979 row += "%-15s" % intent.get( 'state' )
1980 main.log.warn( row )
1981 # End table view
1982
1983 utilities.assert_equals(
1984 expect=True,
1985 actual=consistentIntents,
1986 onpass="Intents are consistent across all ONOS nodes",
1987 onfail="ONOS nodes have different views of intents" )
1988 intentStates = []
1989 for node in ONOSIntents: # Iter through ONOS nodes
1990 nodeStates = []
1991 # Iter through intents of a node
1992 try:
1993 for intent in json.loads( node ):
1994 nodeStates.append( intent[ 'state' ] )
1995 except ( ValueError, TypeError ):
1996 main.log.exception( "Error in parsing intents" )
1997 main.log.error( repr( node ) )
1998 intentStates.append( nodeStates )
1999 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
2000 main.log.info( dict( out ) )
2001
2002 if intentsResults and not consistentIntents:
Jon Halle1a3b752015-07-22 13:02:46 -07002003 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07002004 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
2005 main.log.warn( json.dumps(
2006 json.loads( ONOSIntents[ i ] ),
2007 sort_keys=True,
2008 indent=4,
2009 separators=( ',', ': ' ) ) )
2010 elif intentsResults and consistentIntents:
2011 intentCheck = main.TRUE
2012
2013 # NOTE: Store has no durability, so intents are lost across system
2014 # restarts
2015 """
2016 main.step( "Compare current intents with intents before the failure" )
2017 # NOTE: this requires case 5 to pass for intentState to be set.
2018 # maybe we should stop the test if that fails?
2019 sameIntents = main.FALSE
2020 if intentState and intentState == ONOSIntents[ 0 ]:
2021 sameIntents = main.TRUE
2022 main.log.info( "Intents are consistent with before failure" )
2023 # TODO: possibly the states have changed? we may need to figure out
2024 # what the acceptable states are
2025 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
2026 sameIntents = main.TRUE
2027 try:
2028 before = json.loads( intentState )
2029 after = json.loads( ONOSIntents[ 0 ] )
2030 for intent in before:
2031 if intent not in after:
2032 sameIntents = main.FALSE
2033 main.log.debug( "Intent is not currently in ONOS " +
2034 "(at least in the same form):" )
2035 main.log.debug( json.dumps( intent ) )
2036 except ( ValueError, TypeError ):
2037 main.log.exception( "Exception printing intents" )
2038 main.log.debug( repr( ONOSIntents[0] ) )
2039 main.log.debug( repr( intentState ) )
2040 if sameIntents == main.FALSE:
2041 try:
2042 main.log.debug( "ONOS intents before: " )
2043 main.log.debug( json.dumps( json.loads( intentState ),
2044 sort_keys=True, indent=4,
2045 separators=( ',', ': ' ) ) )
2046 main.log.debug( "Current ONOS intents: " )
2047 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
2048 sort_keys=True, indent=4,
2049 separators=( ',', ': ' ) ) )
2050 except ( ValueError, TypeError ):
2051 main.log.exception( "Exception printing intents" )
2052 main.log.debug( repr( ONOSIntents[0] ) )
2053 main.log.debug( repr( intentState ) )
2054 utilities.assert_equals(
2055 expect=main.TRUE,
2056 actual=sameIntents,
2057 onpass="Intents are consistent with before failure",
2058 onfail="The Intents changed during failure" )
2059 intentCheck = intentCheck and sameIntents
2060 """
2061 main.step( "Get the OF Table entries and compare to before " +
2062 "component failure" )
2063 FlowTables = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002064 for i in range( 28 ):
2065 main.log.info( "Checking flow table on s" + str( i + 1 ) )
GlennRC68467eb2015-11-16 18:01:01 -08002066 tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
2067 FlowTables = FlowTables and main.Mininet1.flowTableComp( flows[i], tmpFlows )
Jon Hall5cf14d52015-07-16 12:15:19 -07002068 if FlowTables == main.FALSE:
GlennRC68467eb2015-11-16 18:01:01 -08002069 main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
2070
Jon Hall5cf14d52015-07-16 12:15:19 -07002071 utilities.assert_equals(
2072 expect=main.TRUE,
2073 actual=FlowTables,
2074 onpass="No changes were found in the flow tables",
2075 onfail="Changes were found in the flow tables" )
2076
2077 main.Mininet2.pingLongKill()
2078 '''
2079 # main.step( "Check the continuous pings to ensure that no packets " +
2080 # "were dropped during component failure" )
2081 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
2082 main.params[ 'TESTONIP' ] )
2083 LossInPings = main.FALSE
2084 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
2085 for i in range( 8, 18 ):
2086 main.log.info(
2087 "Checking for a loss in pings along flow from s" +
2088 str( i ) )
2089 LossInPings = main.Mininet2.checkForLoss(
2090 "/tmp/ping.h" +
2091 str( i ) ) or LossInPings
2092 if LossInPings == main.TRUE:
2093 main.log.info( "Loss in ping detected" )
2094 elif LossInPings == main.ERROR:
2095 main.log.info( "There are multiple mininet process running" )
2096 elif LossInPings == main.FALSE:
2097 main.log.info( "No Loss in the pings" )
2098 main.log.info( "No loss of dataplane connectivity" )
2099 # utilities.assert_equals(
2100 # expect=main.FALSE,
2101 # actual=LossInPings,
2102 # onpass="No Loss of connectivity",
2103 # onfail="Loss of dataplane connectivity detected" )
2104
2105 # NOTE: Since intents are not persisted with IntnentStore,
2106 # we expect loss in dataplane connectivity
2107 LossInPings = main.FALSE
2108 '''
2109
2110 main.step( "Leadership Election is still functional" )
2111 # Test of LeadershipElection
2112 leaderList = []
2113 leaderResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002114 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002115 leaderN = cli.electionTestLeader()
2116 leaderList.append( leaderN )
2117 if leaderN == main.FALSE:
2118 # error in response
2119 main.log.error( "Something is wrong with " +
2120 "electionTestLeader function, check the" +
2121 " error logs" )
2122 leaderResult = main.FALSE
2123 elif leaderN is None:
2124 main.log.error( cli.name +
2125 " shows no leader for the election-app." )
2126 leaderResult = main.FALSE
2127 if len( set( leaderList ) ) != 1:
2128 leaderResult = main.FALSE
2129 main.log.error(
2130 "Inconsistent view of leader for the election test app" )
2131 # TODO: print the list
2132 utilities.assert_equals(
2133 expect=main.TRUE,
2134 actual=leaderResult,
2135 onpass="Leadership election passed",
2136 onfail="Something went wrong with Leadership election" )
2137
2138 def CASE8( self, main ):
2139 """
2140 Compare topo
2141 """
2142 import json
2143 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002144 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002145 assert main, "main not defined"
2146 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002147 assert main.CLIs, "main.CLIs not defined"
2148 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002149
2150 main.case( "Compare ONOS Topology view to Mininet topology" )
Jon Hall783bbf92015-07-23 14:33:19 -07002151 main.caseExplanation = "Compare topology objects between Mininet" +\
Jon Hall5cf14d52015-07-16 12:15:19 -07002152 " and ONOS"
Jon Hall5cf14d52015-07-16 12:15:19 -07002153 topoResult = main.FALSE
2154 elapsed = 0
2155 count = 0
Jon Halle9b1fa32015-12-08 15:32:21 -08002156 main.step( "Comparing ONOS topology to MN topology" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002157 startTime = time.time()
2158 # Give time for Gossip to work
Jon Halle9b1fa32015-12-08 15:32:21 -08002159 while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
Jon Hallba609822015-09-18 12:00:21 -07002160 devicesResults = main.TRUE
2161 linksResults = main.TRUE
2162 hostsResults = main.TRUE
2163 hostAttachmentResults = True
Jon Hall5cf14d52015-07-16 12:15:19 -07002164 count += 1
2165 cliStart = time.time()
2166 devices = []
2167 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002168 for i in range( main.numCtrls ):
2169 t = main.Thread( target=main.CLIs[i].devices,
Jon Hall5cf14d52015-07-16 12:15:19 -07002170 name="devices-" + str( i ),
2171 args=[ ] )
2172 threads.append( t )
2173 t.start()
2174
2175 for t in threads:
2176 t.join()
2177 devices.append( t.result )
2178 hosts = []
2179 ipResult = main.TRUE
2180 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002181 for i in range( main.numCtrls ):
2182 t = main.Thread( target=main.CLIs[i].hosts,
Jon Hall5cf14d52015-07-16 12:15:19 -07002183 name="hosts-" + str( i ),
2184 args=[ ] )
2185 threads.append( t )
2186 t.start()
2187
2188 for t in threads:
2189 t.join()
2190 try:
2191 hosts.append( json.loads( t.result ) )
2192 except ( ValueError, TypeError ):
2193 main.log.exception( "Error parsing hosts results" )
2194 main.log.error( repr( t.result ) )
Jon Hall3afe4c92015-12-14 19:30:38 -08002195 hosts.append( None )
Jon Hall5cf14d52015-07-16 12:15:19 -07002196 for controller in range( 0, len( hosts ) ):
2197 controllerStr = str( controller + 1 )
2198 for host in hosts[ controller ]:
2199 if host is None or host.get( 'ipAddresses', [] ) == []:
2200 main.log.error(
Jon Hall3afe4c92015-12-14 19:30:38 -08002201 "Error with host ipAddresses on controller" +
Jon Hall5cf14d52015-07-16 12:15:19 -07002202 controllerStr + ": " + str( host ) )
2203 ipResult = main.FALSE
2204 ports = []
2205 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002206 for i in range( main.numCtrls ):
2207 t = main.Thread( target=main.CLIs[i].ports,
Jon Hall5cf14d52015-07-16 12:15:19 -07002208 name="ports-" + str( i ),
2209 args=[ ] )
2210 threads.append( t )
2211 t.start()
2212
2213 for t in threads:
2214 t.join()
2215 ports.append( t.result )
2216 links = []
2217 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002218 for i in range( main.numCtrls ):
2219 t = main.Thread( target=main.CLIs[i].links,
Jon Hall5cf14d52015-07-16 12:15:19 -07002220 name="links-" + str( i ),
2221 args=[ ] )
2222 threads.append( t )
2223 t.start()
2224
2225 for t in threads:
2226 t.join()
2227 links.append( t.result )
2228 clusters = []
2229 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002230 for i in range( main.numCtrls ):
2231 t = main.Thread( target=main.CLIs[i].clusters,
Jon Hall5cf14d52015-07-16 12:15:19 -07002232 name="clusters-" + str( i ),
2233 args=[ ] )
2234 threads.append( t )
2235 t.start()
2236
2237 for t in threads:
2238 t.join()
2239 clusters.append( t.result )
2240
2241 elapsed = time.time() - startTime
2242 cliTime = time.time() - cliStart
2243 print "Elapsed time: " + str( elapsed )
2244 print "CLI time: " + str( cliTime )
2245
2246 mnSwitches = main.Mininet1.getSwitches()
2247 mnLinks = main.Mininet1.getLinks()
2248 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07002249 for controller in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07002250 controllerStr = str( controller + 1 )
2251 if devices[ controller ] and ports[ controller ] and\
2252 "Error" not in devices[ controller ] and\
2253 "Error" not in ports[ controller ]:
2254
2255 currentDevicesResult = main.Mininet1.compareSwitches(
2256 mnSwitches,
2257 json.loads( devices[ controller ] ),
2258 json.loads( ports[ controller ] ) )
2259 else:
2260 currentDevicesResult = main.FALSE
2261 utilities.assert_equals( expect=main.TRUE,
2262 actual=currentDevicesResult,
2263 onpass="ONOS" + controllerStr +
2264 " Switches view is correct",
2265 onfail="ONOS" + controllerStr +
2266 " Switches view is incorrect" )
2267
2268 if links[ controller ] and "Error" not in links[ controller ]:
2269 currentLinksResult = main.Mininet1.compareLinks(
2270 mnSwitches, mnLinks,
2271 json.loads( links[ controller ] ) )
2272 else:
2273 currentLinksResult = main.FALSE
2274 utilities.assert_equals( expect=main.TRUE,
2275 actual=currentLinksResult,
2276 onpass="ONOS" + controllerStr +
2277 " links view is correct",
2278 onfail="ONOS" + controllerStr +
2279 " links view is incorrect" )
2280
2281 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2282 currentHostsResult = main.Mininet1.compareHosts(
2283 mnHosts,
2284 hosts[ controller ] )
2285 else:
2286 currentHostsResult = main.FALSE
2287 utilities.assert_equals( expect=main.TRUE,
2288 actual=currentHostsResult,
2289 onpass="ONOS" + controllerStr +
2290 " hosts exist in Mininet",
2291 onfail="ONOS" + controllerStr +
2292 " hosts don't match Mininet" )
2293 # CHECKING HOST ATTACHMENT POINTS
2294 hostAttachment = True
2295 noHosts = False
2296 # FIXME: topo-HA/obelisk specific mappings:
2297 # key is mac and value is dpid
2298 mappings = {}
2299 for i in range( 1, 29 ): # hosts 1 through 28
2300 # set up correct variables:
2301 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2302 if i == 1:
2303 deviceId = "1000".zfill(16)
2304 elif i == 2:
2305 deviceId = "2000".zfill(16)
2306 elif i == 3:
2307 deviceId = "3000".zfill(16)
2308 elif i == 4:
2309 deviceId = "3004".zfill(16)
2310 elif i == 5:
2311 deviceId = "5000".zfill(16)
2312 elif i == 6:
2313 deviceId = "6000".zfill(16)
2314 elif i == 7:
2315 deviceId = "6007".zfill(16)
2316 elif i >= 8 and i <= 17:
2317 dpid = '3' + str( i ).zfill( 3 )
2318 deviceId = dpid.zfill(16)
2319 elif i >= 18 and i <= 27:
2320 dpid = '6' + str( i ).zfill( 3 )
2321 deviceId = dpid.zfill(16)
2322 elif i == 28:
2323 deviceId = "2800".zfill(16)
2324 mappings[ macId ] = deviceId
2325 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2326 if hosts[ controller ] == []:
2327 main.log.warn( "There are no hosts discovered" )
2328 noHosts = True
2329 else:
2330 for host in hosts[ controller ]:
2331 mac = None
2332 location = None
2333 device = None
2334 port = None
2335 try:
2336 mac = host.get( 'mac' )
2337 assert mac, "mac field could not be found for this host object"
2338
2339 location = host.get( 'location' )
2340 assert location, "location field could not be found for this host object"
2341
2342 # Trim the protocol identifier off deviceId
2343 device = str( location.get( 'elementId' ) ).split(':')[1]
2344 assert device, "elementId field could not be found for this host location object"
2345
2346 port = location.get( 'port' )
2347 assert port, "port field could not be found for this host location object"
2348
2349 # Now check if this matches where they should be
2350 if mac and device and port:
2351 if str( port ) != "1":
2352 main.log.error( "The attachment port is incorrect for " +
2353 "host " + str( mac ) +
2354 ". Expected: 1 Actual: " + str( port) )
2355 hostAttachment = False
2356 if device != mappings[ str( mac ) ]:
2357 main.log.error( "The attachment device is incorrect for " +
2358 "host " + str( mac ) +
2359 ". Expected: " + mappings[ str( mac ) ] +
2360 " Actual: " + device )
2361 hostAttachment = False
2362 else:
2363 hostAttachment = False
2364 except AssertionError:
2365 main.log.exception( "Json object not as expected" )
2366 main.log.error( repr( host ) )
2367 hostAttachment = False
2368 else:
2369 main.log.error( "No hosts json output or \"Error\"" +
2370 " in output. hosts = " +
2371 repr( hosts[ controller ] ) )
2372 if noHosts is False:
2373 # TODO: Find a way to know if there should be hosts in a
2374 # given point of the test
2375 hostAttachment = True
2376
2377 # END CHECKING HOST ATTACHMENT POINTS
2378 devicesResults = devicesResults and currentDevicesResult
2379 linksResults = linksResults and currentLinksResult
2380 hostsResults = hostsResults and currentHostsResult
2381 hostAttachmentResults = hostAttachmentResults and\
2382 hostAttachment
2383 topoResult = ( devicesResults and linksResults
2384 and hostsResults and ipResult and
2385 hostAttachmentResults )
Jon Halle9b1fa32015-12-08 15:32:21 -08002386 utilities.assert_equals( expect=True,
2387 actual=topoResult,
2388 onpass="ONOS topology matches Mininet",
2389 onfail="ONOS topology don't match Mininet" )
2390 # End of While loop to pull ONOS state
Jon Hall5cf14d52015-07-16 12:15:19 -07002391
2392 # Compare json objects for hosts and dataplane clusters
2393
2394 # hosts
2395 main.step( "Hosts view is consistent across all ONOS nodes" )
2396 consistentHostsResult = main.TRUE
2397 for controller in range( len( hosts ) ):
2398 controllerStr = str( controller + 1 )
Jon Hall3afe4c92015-12-14 19:30:38 -08002399 if hosts[ controller ] or "Error" not in hosts[ controller ]:
Jon Hall5cf14d52015-07-16 12:15:19 -07002400 if hosts[ controller ] == hosts[ 0 ]:
2401 continue
2402 else: # hosts not consistent
2403 main.log.error( "hosts from ONOS" + controllerStr +
2404 " is inconsistent with ONOS1" )
2405 main.log.warn( repr( hosts[ controller ] ) )
2406 consistentHostsResult = main.FALSE
2407
2408 else:
2409 main.log.error( "Error in getting ONOS hosts from ONOS" +
2410 controllerStr )
2411 consistentHostsResult = main.FALSE
2412 main.log.warn( "ONOS" + controllerStr +
2413 " hosts response: " +
2414 repr( hosts[ controller ] ) )
2415 utilities.assert_equals(
2416 expect=main.TRUE,
2417 actual=consistentHostsResult,
2418 onpass="Hosts view is consistent across all ONOS nodes",
2419 onfail="ONOS nodes have different views of hosts" )
2420
2421 main.step( "Hosts information is correct" )
2422 hostsResults = hostsResults and ipResult
2423 utilities.assert_equals(
2424 expect=main.TRUE,
2425 actual=hostsResults,
2426 onpass="Host information is correct",
2427 onfail="Host information is incorrect" )
2428
2429 main.step( "Host attachment points to the network" )
2430 utilities.assert_equals(
2431 expect=True,
2432 actual=hostAttachmentResults,
2433 onpass="Hosts are correctly attached to the network",
2434 onfail="ONOS did not correctly attach hosts to the network" )
2435
2436 # Strongly connected clusters of devices
2437 main.step( "Clusters view is consistent across all ONOS nodes" )
2438 consistentClustersResult = main.TRUE
2439 for controller in range( len( clusters ) ):
2440 controllerStr = str( controller + 1 )
2441 if "Error" not in clusters[ controller ]:
2442 if clusters[ controller ] == clusters[ 0 ]:
2443 continue
2444 else: # clusters not consistent
2445 main.log.error( "clusters from ONOS" +
2446 controllerStr +
2447 " is inconsistent with ONOS1" )
2448 consistentClustersResult = main.FALSE
2449
2450 else:
2451 main.log.error( "Error in getting dataplane clusters " +
2452 "from ONOS" + controllerStr )
2453 consistentClustersResult = main.FALSE
2454 main.log.warn( "ONOS" + controllerStr +
2455 " clusters response: " +
2456 repr( clusters[ controller ] ) )
2457 utilities.assert_equals(
2458 expect=main.TRUE,
2459 actual=consistentClustersResult,
2460 onpass="Clusters view is consistent across all ONOS nodes",
2461 onfail="ONOS nodes have different views of clusters" )
2462
2463 main.step( "There is only one SCC" )
2464 # there should always only be one cluster
2465 try:
2466 numClusters = len( json.loads( clusters[ 0 ] ) )
2467 except ( ValueError, TypeError ):
2468 main.log.exception( "Error parsing clusters[0]: " +
2469 repr( clusters[0] ) )
2470 clusterResults = main.FALSE
2471 if numClusters == 1:
2472 clusterResults = main.TRUE
2473 utilities.assert_equals(
2474 expect=1,
2475 actual=numClusters,
2476 onpass="ONOS shows 1 SCC",
2477 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2478
2479 topoResult = ( devicesResults and linksResults
2480 and hostsResults and consistentHostsResult
2481 and consistentClustersResult and clusterResults
2482 and ipResult and hostAttachmentResults )
2483
2484 topoResult = topoResult and int( count <= 2 )
2485 note = "note it takes about " + str( int( cliTime ) ) + \
2486 " seconds for the test to make all the cli calls to fetch " +\
2487 "the topology from each ONOS instance"
2488 main.log.info(
2489 "Very crass estimate for topology discovery/convergence( " +
2490 str( note ) + " ): " + str( elapsed ) + " seconds, " +
2491 str( count ) + " tries" )
2492
2493 main.step( "Device information is correct" )
2494 utilities.assert_equals(
2495 expect=main.TRUE,
2496 actual=devicesResults,
2497 onpass="Device information is correct",
2498 onfail="Device information is incorrect" )
2499
2500 main.step( "Links are correct" )
2501 utilities.assert_equals(
2502 expect=main.TRUE,
2503 actual=linksResults,
2504 onpass="Link are correct",
2505 onfail="Links are incorrect" )
2506
2507 # FIXME: move this to an ONOS state case
2508 main.step( "Checking ONOS nodes" )
2509 nodesOutput = []
2510 nodeResults = main.TRUE
2511 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002512 for i in range( main.numCtrls ):
2513 t = main.Thread( target=main.CLIs[i].nodes,
Jon Hall5cf14d52015-07-16 12:15:19 -07002514 name="nodes-" + str( i ),
2515 args=[ ] )
2516 threads.append( t )
2517 t.start()
2518
2519 for t in threads:
2520 t.join()
2521 nodesOutput.append( t.result )
Jon Halle1a3b752015-07-22 13:02:46 -07002522 ips = [ node.ip_address for node in main.nodes ]
Jon Halle9b1fa32015-12-08 15:32:21 -08002523 ips.sort()
Jon Hall5cf14d52015-07-16 12:15:19 -07002524 for i in nodesOutput:
2525 try:
2526 current = json.loads( i )
Jon Halle9b1fa32015-12-08 15:32:21 -08002527 activeIps = []
2528 currentResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07002529 for node in current:
Jon Halle9b1fa32015-12-08 15:32:21 -08002530 if node['state'] == 'ACTIVE':
2531 activeIps.append( node['ip'] )
2532 activeIps.sort()
2533 if ips == activeIps:
2534 currentResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002535 except ( ValueError, TypeError ):
2536 main.log.error( "Error parsing nodes output" )
2537 main.log.warn( repr( i ) )
Jon Halle9b1fa32015-12-08 15:32:21 -08002538 currentResult = main.FALSE
2539 nodeResults = nodeResults and currentResult
Jon Hall5cf14d52015-07-16 12:15:19 -07002540 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2541 onpass="Nodes check successful",
2542 onfail="Nodes check NOT successful" )
2543
2544 def CASE9( self, main ):
2545 """
2546 Link s3-s28 down
2547 """
2548 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002549 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002550 assert main, "main not defined"
2551 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002552 assert main.CLIs, "main.CLIs not defined"
2553 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002554 # NOTE: You should probably run a topology check after this
2555
2556 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2557
2558 description = "Turn off a link to ensure that Link Discovery " +\
2559 "is working properly"
2560 main.case( description )
2561
2562 main.step( "Kill Link between s3 and s28" )
2563 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
2564 main.log.info( "Waiting " + str( linkSleep ) +
2565 " seconds for link down to be discovered" )
2566 time.sleep( linkSleep )
2567 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
2568 onpass="Link down successful",
2569 onfail="Failed to bring link down" )
2570 # TODO do some sort of check here
2571
2572 def CASE10( self, main ):
2573 """
2574 Link s3-s28 up
2575 """
2576 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002577 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002578 assert main, "main not defined"
2579 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002580 assert main.CLIs, "main.CLIs not defined"
2581 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002582 # NOTE: You should probably run a topology check after this
2583
2584 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
2585
2586 description = "Restore a link to ensure that Link Discovery is " + \
2587 "working properly"
2588 main.case( description )
2589
2590 main.step( "Bring link between s3 and s28 back up" )
2591 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
2592 main.log.info( "Waiting " + str( linkSleep ) +
2593 " seconds for link up to be discovered" )
2594 time.sleep( linkSleep )
2595 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
2596 onpass="Link up successful",
2597 onfail="Failed to bring link up" )
2598 # TODO do some sort of check here
2599
2600 def CASE11( self, main ):
2601 """
2602 Switch Down
2603 """
2604 # NOTE: You should probably run a topology check after this
2605 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002606 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002607 assert main, "main not defined"
2608 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002609 assert main.CLIs, "main.CLIs not defined"
2610 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002611
2612 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2613
2614 description = "Killing a switch to ensure it is discovered correctly"
2615 main.case( description )
2616 switch = main.params[ 'kill' ][ 'switch' ]
2617 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2618
2619 # TODO: Make this switch parameterizable
2620 main.step( "Kill " + switch )
2621 main.log.info( "Deleting " + switch )
2622 main.Mininet1.delSwitch( switch )
2623 main.log.info( "Waiting " + str( switchSleep ) +
2624 " seconds for switch down to be discovered" )
2625 time.sleep( switchSleep )
2626 device = main.ONOScli1.getDevice( dpid=switchDPID )
2627 # Peek at the deleted switch
2628 main.log.warn( str( device ) )
2629 result = main.FALSE
2630 if device and device[ 'available' ] is False:
2631 result = main.TRUE
2632 utilities.assert_equals( expect=main.TRUE, actual=result,
2633 onpass="Kill switch successful",
2634 onfail="Failed to kill switch?" )
2635
2636 def CASE12( self, main ):
2637 """
2638 Switch Up
2639 """
2640 # NOTE: You should probably run a topology check after this
2641 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002642 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002643 assert main, "main not defined"
2644 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002645 assert main.CLIs, "main.CLIs not defined"
2646 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002647 assert ONOS1Port, "ONOS1Port not defined"
2648 assert ONOS2Port, "ONOS2Port not defined"
2649 assert ONOS3Port, "ONOS3Port not defined"
2650 assert ONOS4Port, "ONOS4Port not defined"
2651 assert ONOS5Port, "ONOS5Port not defined"
2652 assert ONOS6Port, "ONOS6Port not defined"
2653 assert ONOS7Port, "ONOS7Port not defined"
2654
2655 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
2656 switch = main.params[ 'kill' ][ 'switch' ]
2657 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2658 links = main.params[ 'kill' ][ 'links' ].split()
2659 description = "Adding a switch to ensure it is discovered correctly"
2660 main.case( description )
2661
2662 main.step( "Add back " + switch )
2663 main.Mininet1.addSwitch( switch, dpid=switchDPID )
2664 for peer in links:
2665 main.Mininet1.addLink( switch, peer )
2666 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -07002667 for i in range( main.numCtrls ):
2668 ipList.append( main.nodes[ i ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -07002669 main.Mininet1.assignSwController( sw=switch, ip=ipList )
2670 main.log.info( "Waiting " + str( switchSleep ) +
2671 " seconds for switch up to be discovered" )
2672 time.sleep( switchSleep )
2673 device = main.ONOScli1.getDevice( dpid=switchDPID )
2674 # Peek at the deleted switch
2675 main.log.warn( str( device ) )
2676 result = main.FALSE
2677 if device and device[ 'available' ]:
2678 result = main.TRUE
2679 utilities.assert_equals( expect=main.TRUE, actual=result,
2680 onpass="add switch successful",
2681 onfail="Failed to add switch?" )
2682
2683 def CASE13( self, main ):
2684 """
2685 Clean up
2686 """
2687 import os
2688 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002689 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002690 assert main, "main not defined"
2691 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002692 assert main.CLIs, "main.CLIs not defined"
2693 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002694
2695 # printing colors to terminal
2696 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2697 'blue': '\033[94m', 'green': '\033[92m',
2698 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
2699 main.case( "Test Cleanup" )
2700 main.step( "Killing tcpdumps" )
2701 main.Mininet2.stopTcpdump()
2702
2703 testname = main.TEST
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002704 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall5cf14d52015-07-16 12:15:19 -07002705 main.step( "Copying MN pcap and ONOS log files to test station" )
2706 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
2707 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
Jon Hall96091e62015-09-21 17:34:17 -07002708 # NOTE: MN Pcap file is being saved to logdir.
2709 # We scp this file as MN and TestON aren't necessarily the same vm
2710
2711 # FIXME: To be replaced with a Jenkin's post script
Jon Hall5cf14d52015-07-16 12:15:19 -07002712 # TODO: Load these from params
2713 # NOTE: must end in /
2714 logFolder = "/opt/onos/log/"
2715 logFiles = [ "karaf.log", "karaf.log.1" ]
2716 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002717 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002718 for node in main.nodes:
Jon Hall96091e62015-09-21 17:34:17 -07002719 dstName = main.logdir + "/" + node.name + "-" + f
2720 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2721 logFolder + f, dstName )
Jon Hall5cf14d52015-07-16 12:15:19 -07002722 # std*.log's
2723 # NOTE: must end in /
2724 logFolder = "/opt/onos/var/"
2725 logFiles = [ "stderr.log", "stdout.log" ]
2726 # NOTE: must end in /
Jon Hall5cf14d52015-07-16 12:15:19 -07002727 for f in logFiles:
Jon Halle1a3b752015-07-22 13:02:46 -07002728 for node in main.nodes:
Jon Hall96091e62015-09-21 17:34:17 -07002729 dstName = main.logdir + "/" + node.name + "-" + f
2730 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
2731 logFolder + f, dstName )
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002732 else:
2733 main.log.debug( "skipping saving log files" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002734
2735 main.step( "Stopping Mininet" )
2736 mnResult = main.Mininet1.stopNet()
2737 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2738 onpass="Mininet stopped",
2739 onfail="MN cleanup NOT successful" )
2740
2741 main.step( "Checking ONOS Logs for errors" )
Jon Halle1a3b752015-07-22 13:02:46 -07002742 for node in main.nodes:
Jon Hall5ec6b1b2015-09-17 18:20:14 -07002743 main.log.debug( "Checking logs for errors on " + node.name + ":" )
2744 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall5cf14d52015-07-16 12:15:19 -07002745
2746 try:
2747 timerLog = open( main.logdir + "/Timers.csv", 'w')
2748 main.log.error( ", ".join( labels ) + "\n" + ", ".join( data ) )
2749 timerLog.write( ", ".join( labels ) + "\n" + ", ".join( data ) )
2750 timerLog.close()
2751 except NameError, e:
2752 main.log.exception(e)
2753
2754 def CASE14( self, main ):
2755 """
2756 start election app on all onos nodes
2757 """
Jon Halle1a3b752015-07-22 13:02:46 -07002758 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002759 assert main, "main not defined"
2760 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002761 assert main.CLIs, "main.CLIs not defined"
2762 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002763
2764 main.case("Start Leadership Election app")
2765 main.step( "Install leadership election app" )
2766 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
2767 utilities.assert_equals(
2768 expect=main.TRUE,
2769 actual=appResult,
2770 onpass="Election app installed",
2771 onfail="Something went wrong with installing Leadership election" )
2772
2773 main.step( "Run for election on each node" )
2774 leaderResult = main.TRUE
2775 leaders = []
Jon Halle1a3b752015-07-22 13:02:46 -07002776 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002777 cli.electionTestRun()
Jon Halle1a3b752015-07-22 13:02:46 -07002778 for cli in main.CLIs:
Jon Hall5cf14d52015-07-16 12:15:19 -07002779 leader = cli.electionTestLeader()
2780 if leader is None or leader == main.FALSE:
2781 main.log.error( cli.name + ": Leader for the election app " +
2782 "should be an ONOS node, instead got '" +
2783 str( leader ) + "'" )
2784 leaderResult = main.FALSE
2785 leaders.append( leader )
2786 utilities.assert_equals(
2787 expect=main.TRUE,
2788 actual=leaderResult,
2789 onpass="Successfully ran for leadership",
2790 onfail="Failed to run for leadership" )
2791
2792 main.step( "Check that each node shows the same leader" )
2793 sameLeader = main.TRUE
2794 if len( set( leaders ) ) != 1:
2795 sameLeader = main.FALSE
2796 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2797 str( leaders ) )
2798 utilities.assert_equals(
2799 expect=main.TRUE,
2800 actual=sameLeader,
2801 onpass="Leadership is consistent for the election topic",
2802 onfail="Nodes have different leaders" )
2803
2804 def CASE15( self, main ):
2805 """
2806 Check that Leadership Election is still functional
acsmars9475b1c2015-08-28 18:02:08 -07002807 15.1 Run election on each node
2808 15.2 Check that each node has the same leaders and candidates
2809 15.3 Find current leader and withdraw
2810 15.4 Check that a new node was elected leader
2811 15.5 Check that that new leader was the candidate of old leader
2812 15.6 Run for election on old leader
2813 15.7 Check that oldLeader is a candidate, and leader if only 1 node
2814 15.8 Make sure that the old leader was added to the candidate list
2815
2816 old and new variable prefixes refer to data from before vs after
2817 withdrawl and later before withdrawl vs after re-election
Jon Hall5cf14d52015-07-16 12:15:19 -07002818 """
2819 import time
Jon Halle1a3b752015-07-22 13:02:46 -07002820 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002821 assert main, "main not defined"
2822 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002823 assert main.CLIs, "main.CLIs not defined"
2824 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07002825
Jon Hall5cf14d52015-07-16 12:15:19 -07002826 description = "Check that Leadership Election is still functional"
2827 main.case( description )
2828 # NOTE: Need to re-run since being a canidate is not persistant
acsmars9475b1c2015-08-28 18:02:08 -07002829 # TODO: add check for "Command not found:" in the driver, this
2830 # means the election test app isn't loaded
2831
2832 oldLeaders = [] # leaders by node before withdrawl from candidates
2833 newLeaders = [] # leaders by node after withdrawl from candidates
2834 oldAllCandidates = [] # list of lists of each nodes' candidates before
2835 newAllCandidates = [] # list of lists of each nodes' candidates after
2836 oldCandidates = [] # list of candidates from node 0 before withdrawl
2837 newCandidates = [] # list of candidates from node 0 after withdrawl
2838 oldLeader = '' # the old leader from oldLeaders, None if not same
2839 newLeader = '' # the new leaders fron newLoeaders, None if not same
2840 oldLeaderCLI = None # the CLI of the old leader used for re-electing
acsmars71adceb2015-08-31 15:09:26 -07002841 expectNoLeader = False # True when there is only one leader
2842 if main.numCtrls == 1:
2843 expectNoLeader = True
acsmars9475b1c2015-08-28 18:02:08 -07002844
Jon Hall5cf14d52015-07-16 12:15:19 -07002845 main.step( "Run for election on each node" )
acsmars9475b1c2015-08-28 18:02:08 -07002846 electionResult = main.TRUE
2847
2848 for cli in main.CLIs: # run test election on each node
2849 if cli.electionTestRun() == main.FALSE:
2850 electionResult = main.FALSE
2851
Jon Hall5cf14d52015-07-16 12:15:19 -07002852 utilities.assert_equals(
2853 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07002854 actual=electionResult,
2855 onpass="All nodes successfully ran for leadership",
2856 onfail="At least one node failed to run for leadership" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002857
acsmars3a72bde2015-09-02 14:16:22 -07002858 if electionResult == main.FALSE:
2859 main.log.error(
2860 "Skipping Test Case because Election Test App isn't loaded" )
2861 main.skipCase()
2862
acsmars9475b1c2015-08-28 18:02:08 -07002863 main.step( "Check that each node shows the same leader and candidates" )
2864 sameResult = main.TRUE
2865 failMessage = "Nodes have different leaders"
2866 for cli in main.CLIs:
2867 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2868 oldAllCandidates.append( node )
2869 oldLeaders.append( node[ 0 ] )
2870 oldCandidates = oldAllCandidates[ 0 ]
2871
2872 # Check that each node has the same leader. Defines oldLeader
2873 if len( set( oldLeaders ) ) != 1:
2874 sameResult = main.FALSE
acsmars71adceb2015-08-31 15:09:26 -07002875 main.log.error( "More than one leader present:" + str( oldLeaders ) )
acsmars9475b1c2015-08-28 18:02:08 -07002876 oldLeader = None
2877 else:
2878 oldLeader = oldLeaders[ 0 ]
2879
2880 # Check that each node's candidate list is the same
acsmars29233db2015-11-04 11:15:00 -08002881 candidateDiscrepancy = False # Boolean of candidate mismatches
acsmars9475b1c2015-08-28 18:02:08 -07002882 for candidates in oldAllCandidates:
2883 if set( candidates ) != set( oldCandidates ):
2884 sameResult = main.FALSE
acsmars29233db2015-11-04 11:15:00 -08002885 candidateDiscrepancy = True
2886
2887 if candidateDiscrepancy:
2888 failMessage += " and candidates"
acsmars9475b1c2015-08-28 18:02:08 -07002889
Jon Hall5cf14d52015-07-16 12:15:19 -07002890 utilities.assert_equals(
2891 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002892 actual=sameResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002893 onpass="Leadership is consistent for the election topic",
acsmars9475b1c2015-08-28 18:02:08 -07002894 onfail=failMessage )
Jon Hall5cf14d52015-07-16 12:15:19 -07002895
2896 main.step( "Find current leader and withdraw" )
acsmars9475b1c2015-08-28 18:02:08 -07002897 withdrawResult = main.TRUE
Jon Hall5cf14d52015-07-16 12:15:19 -07002898 # do some sanity checking on leader before using it
acsmars9475b1c2015-08-28 18:02:08 -07002899 if oldLeader is None:
2900 main.log.error( "Leadership isn't consistent." )
2901 withdrawResult = main.FALSE
2902 # Get the CLI of the oldLeader
Jon Halle1a3b752015-07-22 13:02:46 -07002903 for i in range( len( main.CLIs ) ):
acsmars9475b1c2015-08-28 18:02:08 -07002904 if oldLeader == main.nodes[ i ].ip_address:
2905 oldLeaderCLI = main.CLIs[ i ]
Jon Hall5cf14d52015-07-16 12:15:19 -07002906 break
2907 else: # FOR/ELSE statement
2908 main.log.error( "Leader election, could not find current leader" )
2909 if oldLeader:
acsmars9475b1c2015-08-28 18:02:08 -07002910 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall5cf14d52015-07-16 12:15:19 -07002911 utilities.assert_equals(
2912 expect=main.TRUE,
2913 actual=withdrawResult,
2914 onpass="Node was withdrawn from election",
2915 onfail="Node was not withdrawn from election" )
2916
acsmars9475b1c2015-08-28 18:02:08 -07002917 main.step( "Check that a new node was elected leader" )
acsmars71adceb2015-08-31 15:09:26 -07002918
Jon Hall5cf14d52015-07-16 12:15:19 -07002919 # FIXME: use threads
acsmars9475b1c2015-08-28 18:02:08 -07002920 newLeaderResult = main.TRUE
2921 failMessage = "Nodes have different leaders"
2922
2923 # Get new leaders and candidates
Jon Halle1a3b752015-07-22 13:02:46 -07002924 for cli in main.CLIs:
acsmars9475b1c2015-08-28 18:02:08 -07002925 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
acsmars71adceb2015-08-31 15:09:26 -07002926 # elections might no have finished yet
2927 if node[ 0 ] == 'none' and not expectNoLeader:
acsmars9475b1c2015-08-28 18:02:08 -07002928 main.log.info( "Node has no leader, waiting 5 seconds to be " +
2929 "sure elections are complete." )
2930 time.sleep(5)
2931 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
acsmars71adceb2015-08-31 15:09:26 -07002932 # election still isn't done or there is a problem
2933 if node[ 0 ] == 'none':
2934 main.log.error( "No leader was elected on at least 1 node" )
2935 newLeaderResult = main.FALSE
acsmars9475b1c2015-08-28 18:02:08 -07002936 newAllCandidates.append( node )
2937 newLeaders.append( node[ 0 ] )
2938 newCandidates = newAllCandidates[ 0 ]
2939
2940 # Check that each node has the same leader. Defines newLeader
2941 if len( set( newLeaders ) ) != 1:
2942 newLeaderResult = main.FALSE
2943 main.log.error( "Nodes have different leaders: " +
2944 str( newLeaders ) )
2945 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07002946 else:
acsmars9475b1c2015-08-28 18:02:08 -07002947 newLeader = newLeaders[ 0 ]
2948
acsmars71adceb2015-08-31 15:09:26 -07002949 # Check that each node's candidate list is the same
2950 for candidates in newAllCandidates:
2951 if set( candidates ) != set( newCandidates ):
2952 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07002953 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07002954
acsmars9475b1c2015-08-28 18:02:08 -07002955 # Check that the new leader is not the older leader, which was withdrawn
2956 if newLeader == oldLeader:
2957 newLeaderResult = main.FALSE
2958 main.log.error( "All nodes still see old leader: " + oldLeader +
2959 " as the current leader" )
2960
Jon Hall5cf14d52015-07-16 12:15:19 -07002961 utilities.assert_equals(
2962 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07002963 actual=newLeaderResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07002964 onpass="Leadership election passed",
2965 onfail="Something went wrong with Leadership election" )
2966
acsmars9475b1c2015-08-28 18:02:08 -07002967 main.step( "Check that that new leader was the candidate of old leader")
2968 # candidates[ 2 ] should be come the top candidate after withdrawl
2969 correctCandidateResult = main.TRUE
acsmars71adceb2015-08-31 15:09:26 -07002970 if expectNoLeader:
2971 if newLeader == 'none':
2972 main.log.info( "No leader expected. None found. Pass" )
2973 correctCandidateResult = main.TRUE
2974 else:
2975 main.log.info( "Expected no leader, got: " + str( newLeader ) )
2976 correctCandidateResult = main.FALSE
2977 elif newLeader != oldCandidates[ 2 ]:
acsmars9475b1c2015-08-28 18:02:08 -07002978 correctCandidateResult = main.FALSE
2979 main.log.error( "Candidate " + newLeader + " was elected. " +
2980 oldCandidates[ 2 ] + " should have had priority." )
2981
2982 utilities.assert_equals(
2983 expect=main.TRUE,
2984 actual=correctCandidateResult,
2985 onpass="Correct Candidate Elected",
2986 onfail="Incorrect Candidate Elected" )
2987
Jon Hall5cf14d52015-07-16 12:15:19 -07002988 main.step( "Run for election on old leader( just so everyone " +
2989 "is in the hat )" )
acsmars9475b1c2015-08-28 18:02:08 -07002990 if oldLeaderCLI is not None:
2991 runResult = oldLeaderCLI.electionTestRun()
Jon Hall5cf14d52015-07-16 12:15:19 -07002992 else:
acsmars9475b1c2015-08-28 18:02:08 -07002993 main.log.error( "No old leader to re-elect" )
Jon Hall5cf14d52015-07-16 12:15:19 -07002994 runResult = main.FALSE
2995 utilities.assert_equals(
2996 expect=main.TRUE,
2997 actual=runResult,
2998 onpass="App re-ran for election",
2999 onfail="App failed to run for election" )
acsmars9475b1c2015-08-28 18:02:08 -07003000 main.step(
3001 "Check that oldLeader is a candidate, and leader if only 1 node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003002 # verify leader didn't just change
acsmars9475b1c2015-08-28 18:02:08 -07003003 positionResult = main.TRUE
3004 # Get new leaders and candidates, wait if oldLeader is not a candidate yet
3005
3006 # Reset and reuse the new candidate and leaders lists
3007 newAllCandidates = []
3008 newCandidates = []
3009 newLeaders = []
3010 for cli in main.CLIs:
3011 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
3012 if oldLeader not in node: # election might no have finished yet
3013 main.log.info( "Old Leader not elected, waiting 5 seconds to " +
3014 "be sure elections are complete" )
3015 time.sleep(5)
3016 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
3017 if oldLeader not in node: # election still isn't done, errors
3018 main.log.error(
3019 "Old leader was not elected on at least one node" )
3020 positionResult = main.FALSE
3021 newAllCandidates.append( node )
3022 newLeaders.append( node[ 0 ] )
3023 newCandidates = newAllCandidates[ 0 ]
3024
3025 # Check that each node has the same leader. Defines newLeader
3026 if len( set( newLeaders ) ) != 1:
3027 positionResult = main.FALSE
3028 main.log.error( "Nodes have different leaders: " +
3029 str( newLeaders ) )
3030 newLeader = None
Jon Hall5cf14d52015-07-16 12:15:19 -07003031 else:
acsmars9475b1c2015-08-28 18:02:08 -07003032 newLeader = newLeaders[ 0 ]
3033
acsmars71adceb2015-08-31 15:09:26 -07003034 # Check that each node's candidate list is the same
3035 for candidates in newAllCandidates:
3036 if set( candidates ) != set( newCandidates ):
3037 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07003038 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07003039
acsmars9475b1c2015-08-28 18:02:08 -07003040 # Check that the re-elected node is last on the candidate List
3041 if oldLeader != newCandidates[ -1 ]:
3042 main.log.error( "Old Leader (" + oldLeader + ") not in the proper position " +
3043 str( newCandidates ) )
3044 positionResult = main.FALSE
Jon Hall5cf14d52015-07-16 12:15:19 -07003045
3046 utilities.assert_equals(
3047 expect=main.TRUE,
acsmars9475b1c2015-08-28 18:02:08 -07003048 actual=positionResult,
Jon Hall5cf14d52015-07-16 12:15:19 -07003049 onpass="Old leader successfully re-ran for election",
3050 onfail="Something went wrong with Leadership election after " +
3051 "the old leader re-ran for election" )
3052
3053 def CASE16( self, main ):
3054 """
3055 Install Distributed Primitives app
3056 """
3057 import time
Jon Halle1a3b752015-07-22 13:02:46 -07003058 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003059 assert main, "main not defined"
3060 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003061 assert main.CLIs, "main.CLIs not defined"
3062 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003063
3064 # Variables for the distributed primitives tests
3065 global pCounterName
3066 global iCounterName
3067 global pCounterValue
3068 global iCounterValue
3069 global onosSet
3070 global onosSetName
3071 pCounterName = "TestON-Partitions"
3072 iCounterName = "TestON-inMemory"
3073 pCounterValue = 0
3074 iCounterValue = 0
3075 onosSet = set([])
3076 onosSetName = "TestON-set"
3077
3078 description = "Install Primitives app"
3079 main.case( description )
3080 main.step( "Install Primitives app" )
3081 appName = "org.onosproject.distributedprimitives"
Jon Halle1a3b752015-07-22 13:02:46 -07003082 appResults = main.CLIs[0].activateApp( appName )
Jon Hall5cf14d52015-07-16 12:15:19 -07003083 utilities.assert_equals( expect=main.TRUE,
3084 actual=appResults,
3085 onpass="Primitives app activated",
3086 onfail="Primitives app not activated" )
3087 time.sleep( 5 ) # To allow all nodes to activate
3088
3089 def CASE17( self, main ):
3090 """
3091 Check for basic functionality with distributed primitives
3092 """
Jon Hall5cf14d52015-07-16 12:15:19 -07003093 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07003094 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003095 assert main, "main not defined"
3096 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07003097 assert main.CLIs, "main.CLIs not defined"
3098 assert main.nodes, "main.nodes not defined"
Jon Hall5cf14d52015-07-16 12:15:19 -07003099 assert pCounterName, "pCounterName not defined"
3100 assert iCounterName, "iCounterName not defined"
3101 assert onosSetName, "onosSetName not defined"
3102 # NOTE: assert fails if value is 0/None/Empty/False
3103 try:
3104 pCounterValue
3105 except NameError:
3106 main.log.error( "pCounterValue not defined, setting to 0" )
3107 pCounterValue = 0
3108 try:
3109 iCounterValue
3110 except NameError:
3111 main.log.error( "iCounterValue not defined, setting to 0" )
3112 iCounterValue = 0
3113 try:
3114 onosSet
3115 except NameError:
3116 main.log.error( "onosSet not defined, setting to empty Set" )
3117 onosSet = set([])
3118 # Variables for the distributed primitives tests. These are local only
3119 addValue = "a"
3120 addAllValue = "a b c d e f"
3121 retainValue = "c d e f"
3122
3123 description = "Check for basic functionality with distributed " +\
3124 "primitives"
3125 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07003126 main.caseExplanation = "Test the methods of the distributed " +\
3127 "primitives (counters and sets) throught the cli"
Jon Hall5cf14d52015-07-16 12:15:19 -07003128 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07003129 # Partitioned counters
3130 main.step( "Increment then get a default counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003131 pCounters = []
3132 threads = []
3133 addedPValues = []
Jon Halle1a3b752015-07-22 13:02:46 -07003134 for i in range( main.numCtrls ):
3135 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3136 name="counterAddAndGet-" + str( i ),
Jon Hall5cf14d52015-07-16 12:15:19 -07003137 args=[ pCounterName ] )
3138 pCounterValue += 1
3139 addedPValues.append( pCounterValue )
3140 threads.append( t )
3141 t.start()
3142
3143 for t in threads:
3144 t.join()
3145 pCounters.append( t.result )
3146 # Check that counter incremented numController times
3147 pCounterResults = True
3148 for i in addedPValues:
3149 tmpResult = i in pCounters
3150 pCounterResults = pCounterResults and tmpResult
3151 if not tmpResult:
3152 main.log.error( str( i ) + " is not in partitioned "
3153 "counter incremented results" )
3154 utilities.assert_equals( expect=True,
3155 actual=pCounterResults,
3156 onpass="Default counter incremented",
3157 onfail="Error incrementing default" +
3158 " counter" )
3159
Jon Halle1a3b752015-07-22 13:02:46 -07003160 main.step( "Get then Increment a default counter on each node" )
3161 pCounters = []
3162 threads = []
3163 addedPValues = []
3164 for i in range( main.numCtrls ):
3165 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3166 name="counterGetAndAdd-" + str( i ),
3167 args=[ pCounterName ] )
3168 addedPValues.append( pCounterValue )
3169 pCounterValue += 1
3170 threads.append( t )
3171 t.start()
3172
3173 for t in threads:
3174 t.join()
3175 pCounters.append( t.result )
3176 # Check that counter incremented numController times
3177 pCounterResults = True
3178 for i in addedPValues:
3179 tmpResult = i in pCounters
3180 pCounterResults = pCounterResults and tmpResult
3181 if not tmpResult:
3182 main.log.error( str( i ) + " is not in partitioned "
3183 "counter incremented results" )
3184 utilities.assert_equals( expect=True,
3185 actual=pCounterResults,
3186 onpass="Default counter incremented",
3187 onfail="Error incrementing default" +
3188 " counter" )
3189
3190 main.step( "Counters we added have the correct values" )
3191 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3192 utilities.assert_equals( expect=main.TRUE,
3193 actual=incrementCheck,
3194 onpass="Added counters are correct",
3195 onfail="Added counters are incorrect" )
3196
3197 main.step( "Add -8 to then get a default counter on each node" )
3198 pCounters = []
3199 threads = []
3200 addedPValues = []
3201 for i in range( main.numCtrls ):
3202 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3203 name="counterIncrement-" + str( i ),
3204 args=[ pCounterName ],
3205 kwargs={ "delta": -8 } )
3206 pCounterValue += -8
3207 addedPValues.append( pCounterValue )
3208 threads.append( t )
3209 t.start()
3210
3211 for t in threads:
3212 t.join()
3213 pCounters.append( t.result )
3214 # Check that counter incremented numController times
3215 pCounterResults = True
3216 for i in addedPValues:
3217 tmpResult = i in pCounters
3218 pCounterResults = pCounterResults and tmpResult
3219 if not tmpResult:
3220 main.log.error( str( i ) + " is not in partitioned "
3221 "counter incremented results" )
3222 utilities.assert_equals( expect=True,
3223 actual=pCounterResults,
3224 onpass="Default counter incremented",
3225 onfail="Error incrementing default" +
3226 " counter" )
3227
3228 main.step( "Add 5 to then get a default counter on each node" )
3229 pCounters = []
3230 threads = []
3231 addedPValues = []
3232 for i in range( main.numCtrls ):
3233 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3234 name="counterIncrement-" + str( i ),
3235 args=[ pCounterName ],
3236 kwargs={ "delta": 5 } )
3237 pCounterValue += 5
3238 addedPValues.append( pCounterValue )
3239 threads.append( t )
3240 t.start()
3241
3242 for t in threads:
3243 t.join()
3244 pCounters.append( t.result )
3245 # Check that counter incremented numController times
3246 pCounterResults = True
3247 for i in addedPValues:
3248 tmpResult = i in pCounters
3249 pCounterResults = pCounterResults and tmpResult
3250 if not tmpResult:
3251 main.log.error( str( i ) + " is not in partitioned "
3252 "counter incremented results" )
3253 utilities.assert_equals( expect=True,
3254 actual=pCounterResults,
3255 onpass="Default counter incremented",
3256 onfail="Error incrementing default" +
3257 " counter" )
3258
3259 main.step( "Get then add 5 to a default counter on each node" )
3260 pCounters = []
3261 threads = []
3262 addedPValues = []
3263 for i in range( main.numCtrls ):
3264 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3265 name="counterIncrement-" + str( i ),
3266 args=[ pCounterName ],
3267 kwargs={ "delta": 5 } )
3268 addedPValues.append( pCounterValue )
3269 pCounterValue += 5
3270 threads.append( t )
3271 t.start()
3272
3273 for t in threads:
3274 t.join()
3275 pCounters.append( t.result )
3276 # Check that counter incremented numController times
3277 pCounterResults = True
3278 for i in addedPValues:
3279 tmpResult = i in pCounters
3280 pCounterResults = pCounterResults and tmpResult
3281 if not tmpResult:
3282 main.log.error( str( i ) + " is not in partitioned "
3283 "counter incremented results" )
3284 utilities.assert_equals( expect=True,
3285 actual=pCounterResults,
3286 onpass="Default counter incremented",
3287 onfail="Error incrementing default" +
3288 " counter" )
3289
3290 main.step( "Counters we added have the correct values" )
3291 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
3292 utilities.assert_equals( expect=main.TRUE,
3293 actual=incrementCheck,
3294 onpass="Added counters are correct",
3295 onfail="Added counters are incorrect" )
3296
3297 # In-Memory counters
3298 main.step( "Increment and get an in-memory counter on each node" )
Jon Hall5cf14d52015-07-16 12:15:19 -07003299 iCounters = []
3300 addedIValues = []
3301 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003302 for i in range( main.numCtrls ):
3303 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003304 name="icounterIncrement-" + str( i ),
3305 args=[ iCounterName ],
3306 kwargs={ "inMemory": True } )
3307 iCounterValue += 1
3308 addedIValues.append( iCounterValue )
3309 threads.append( t )
3310 t.start()
3311
3312 for t in threads:
3313 t.join()
3314 iCounters.append( t.result )
3315 # Check that counter incremented numController times
3316 iCounterResults = True
3317 for i in addedIValues:
3318 tmpResult = i in iCounters
3319 iCounterResults = iCounterResults and tmpResult
3320 if not tmpResult:
3321 main.log.error( str( i ) + " is not in the in-memory "
3322 "counter incremented results" )
3323 utilities.assert_equals( expect=True,
3324 actual=iCounterResults,
Jon Halle1a3b752015-07-22 13:02:46 -07003325 onpass="In-memory counter incremented",
3326 onfail="Error incrementing in-memory" +
Jon Hall5cf14d52015-07-16 12:15:19 -07003327 " counter" )
3328
Jon Halle1a3b752015-07-22 13:02:46 -07003329 main.step( "Get then Increment a in-memory counter on each node" )
3330 iCounters = []
3331 threads = []
3332 addedIValues = []
3333 for i in range( main.numCtrls ):
3334 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3335 name="counterGetAndAdd-" + str( i ),
3336 args=[ iCounterName ],
3337 kwargs={ "inMemory": True } )
3338 addedIValues.append( iCounterValue )
3339 iCounterValue += 1
3340 threads.append( t )
3341 t.start()
3342
3343 for t in threads:
3344 t.join()
3345 iCounters.append( t.result )
3346 # Check that counter incremented numController times
3347 iCounterResults = True
3348 for i in addedIValues:
3349 tmpResult = i in iCounters
3350 iCounterResults = iCounterResults and tmpResult
3351 if not tmpResult:
3352 main.log.error( str( i ) + " is not in in-memory "
3353 "counter incremented results" )
3354 utilities.assert_equals( expect=True,
3355 actual=iCounterResults,
3356 onpass="In-memory counter incremented",
3357 onfail="Error incrementing in-memory" +
3358 " counter" )
3359
3360 main.step( "Counters we added have the correct values" )
3361 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3362 utilities.assert_equals( expect=main.TRUE,
3363 actual=incrementCheck,
3364 onpass="Added counters are correct",
3365 onfail="Added counters are incorrect" )
3366
3367 main.step( "Add -8 to then get a in-memory counter on each node" )
3368 iCounters = []
3369 threads = []
3370 addedIValues = []
3371 for i in range( main.numCtrls ):
3372 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3373 name="counterIncrement-" + str( i ),
3374 args=[ iCounterName ],
3375 kwargs={ "delta": -8, "inMemory": True } )
3376 iCounterValue += -8
3377 addedIValues.append( iCounterValue )
3378 threads.append( t )
3379 t.start()
3380
3381 for t in threads:
3382 t.join()
3383 iCounters.append( t.result )
3384 # Check that counter incremented numController times
3385 iCounterResults = True
3386 for i in addedIValues:
3387 tmpResult = i in iCounters
3388 iCounterResults = iCounterResults and tmpResult
3389 if not tmpResult:
3390 main.log.error( str( i ) + " is not in in-memory "
3391 "counter incremented results" )
3392 utilities.assert_equals( expect=True,
3393 actual=pCounterResults,
3394 onpass="In-memory counter incremented",
3395 onfail="Error incrementing in-memory" +
3396 " counter" )
3397
3398 main.step( "Add 5 to then get a in-memory counter on each node" )
3399 iCounters = []
3400 threads = []
3401 addedIValues = []
3402 for i in range( main.numCtrls ):
3403 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
3404 name="counterIncrement-" + str( i ),
3405 args=[ iCounterName ],
3406 kwargs={ "delta": 5, "inMemory": True } )
3407 iCounterValue += 5
3408 addedIValues.append( iCounterValue )
3409 threads.append( t )
3410 t.start()
3411
3412 for t in threads:
3413 t.join()
3414 iCounters.append( t.result )
3415 # Check that counter incremented numController times
3416 iCounterResults = True
3417 for i in addedIValues:
3418 tmpResult = i in iCounters
3419 iCounterResults = iCounterResults and tmpResult
3420 if not tmpResult:
3421 main.log.error( str( i ) + " is not in in-memory "
3422 "counter incremented results" )
3423 utilities.assert_equals( expect=True,
3424 actual=pCounterResults,
3425 onpass="In-memory counter incremented",
3426 onfail="Error incrementing in-memory" +
3427 " counter" )
3428
3429 main.step( "Get then add 5 to a in-memory counter on each node" )
3430 iCounters = []
3431 threads = []
3432 addedIValues = []
3433 for i in range( main.numCtrls ):
3434 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
3435 name="counterIncrement-" + str( i ),
3436 args=[ iCounterName ],
3437 kwargs={ "delta": 5, "inMemory": True } )
3438 addedIValues.append( iCounterValue )
3439 iCounterValue += 5
3440 threads.append( t )
3441 t.start()
3442
3443 for t in threads:
3444 t.join()
3445 iCounters.append( t.result )
3446 # Check that counter incremented numController times
3447 iCounterResults = True
3448 for i in addedIValues:
3449 tmpResult = i in iCounters
3450 iCounterResults = iCounterResults and tmpResult
3451 if not tmpResult:
3452 main.log.error( str( i ) + " is not in in-memory "
3453 "counter incremented results" )
3454 utilities.assert_equals( expect=True,
3455 actual=iCounterResults,
3456 onpass="In-memory counter incremented",
3457 onfail="Error incrementing in-memory" +
3458 " counter" )
3459
3460 main.step( "Counters we added have the correct values" )
3461 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3462 utilities.assert_equals( expect=main.TRUE,
3463 actual=incrementCheck,
3464 onpass="Added counters are correct",
3465 onfail="Added counters are incorrect" )
3466
Jon Hall5cf14d52015-07-16 12:15:19 -07003467 main.step( "Check counters are consistant across nodes" )
Jon Hall57b50432015-10-22 10:20:10 -07003468 onosCounters, consistentCounterResults = main.Counters.consistentCheck()
Jon Hall5cf14d52015-07-16 12:15:19 -07003469 utilities.assert_equals( expect=main.TRUE,
3470 actual=consistentCounterResults,
3471 onpass="ONOS counters are consistent " +
3472 "across nodes",
3473 onfail="ONOS Counters are inconsistent " +
3474 "across nodes" )
3475
3476 main.step( "Counters we added have the correct values" )
Jon Halle1a3b752015-07-22 13:02:46 -07003477 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
3478 incrementCheck = incrementCheck and \
3479 main.Counters.counterCheck( iCounterName, iCounterValue )
Jon Hall5cf14d52015-07-16 12:15:19 -07003480 utilities.assert_equals( expect=main.TRUE,
Jon Halle1a3b752015-07-22 13:02:46 -07003481 actual=incrementCheck,
Jon Hall5cf14d52015-07-16 12:15:19 -07003482 onpass="Added counters are correct",
3483 onfail="Added counters are incorrect" )
3484 # DISTRIBUTED SETS
3485 main.step( "Distributed Set get" )
3486 size = len( onosSet )
3487 getResponses = []
3488 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003489 for i in range( main.numCtrls ):
3490 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003491 name="setTestGet-" + str( i ),
3492 args=[ onosSetName ] )
3493 threads.append( t )
3494 t.start()
3495 for t in threads:
3496 t.join()
3497 getResponses.append( t.result )
3498
3499 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003500 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003501 if isinstance( getResponses[ i ], list):
3502 current = set( getResponses[ i ] )
3503 if len( current ) == len( getResponses[ i ] ):
3504 # no repeats
3505 if onosSet != current:
3506 main.log.error( "ONOS" + str( i + 1 ) +
3507 " has incorrect view" +
3508 " of set " + onosSetName + ":\n" +
3509 str( getResponses[ i ] ) )
3510 main.log.debug( "Expected: " + str( onosSet ) )
3511 main.log.debug( "Actual: " + str( current ) )
3512 getResults = main.FALSE
3513 else:
3514 # error, set is not a set
3515 main.log.error( "ONOS" + str( i + 1 ) +
3516 " has repeat elements in" +
3517 " set " + onosSetName + ":\n" +
3518 str( getResponses[ i ] ) )
3519 getResults = main.FALSE
3520 elif getResponses[ i ] == main.ERROR:
3521 getResults = main.FALSE
3522 utilities.assert_equals( expect=main.TRUE,
3523 actual=getResults,
3524 onpass="Set elements are correct",
3525 onfail="Set elements are incorrect" )
3526
3527 main.step( "Distributed Set size" )
3528 sizeResponses = []
3529 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003530 for i in range( main.numCtrls ):
3531 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003532 name="setTestSize-" + str( i ),
3533 args=[ onosSetName ] )
3534 threads.append( t )
3535 t.start()
3536 for t in threads:
3537 t.join()
3538 sizeResponses.append( t.result )
3539
3540 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003541 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003542 if size != sizeResponses[ i ]:
3543 sizeResults = main.FALSE
3544 main.log.error( "ONOS" + str( i + 1 ) +
3545 " expected a size of " + str( size ) +
3546 " for set " + onosSetName +
3547 " but got " + str( sizeResponses[ i ] ) )
3548 utilities.assert_equals( expect=main.TRUE,
3549 actual=sizeResults,
3550 onpass="Set sizes are correct",
3551 onfail="Set sizes are incorrect" )
3552
3553 main.step( "Distributed Set add()" )
3554 onosSet.add( addValue )
3555 addResponses = []
3556 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003557 for i in range( main.numCtrls ):
3558 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003559 name="setTestAdd-" + str( i ),
3560 args=[ onosSetName, addValue ] )
3561 threads.append( t )
3562 t.start()
3563 for t in threads:
3564 t.join()
3565 addResponses.append( t.result )
3566
3567 # main.TRUE = successfully changed the set
3568 # main.FALSE = action resulted in no change in set
3569 # main.ERROR - Some error in executing the function
3570 addResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003571 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003572 if addResponses[ i ] == main.TRUE:
3573 # All is well
3574 pass
3575 elif addResponses[ i ] == main.FALSE:
3576 # Already in set, probably fine
3577 pass
3578 elif addResponses[ i ] == main.ERROR:
3579 # Error in execution
3580 addResults = main.FALSE
3581 else:
3582 # unexpected result
3583 addResults = main.FALSE
3584 if addResults != main.TRUE:
3585 main.log.error( "Error executing set add" )
3586
3587 # Check if set is still correct
3588 size = len( onosSet )
3589 getResponses = []
3590 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003591 for i in range( main.numCtrls ):
3592 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003593 name="setTestGet-" + str( i ),
3594 args=[ onosSetName ] )
3595 threads.append( t )
3596 t.start()
3597 for t in threads:
3598 t.join()
3599 getResponses.append( t.result )
3600 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003601 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003602 if isinstance( getResponses[ i ], list):
3603 current = set( getResponses[ i ] )
3604 if len( current ) == len( getResponses[ i ] ):
3605 # no repeats
3606 if onosSet != current:
3607 main.log.error( "ONOS" + str( i + 1 ) +
3608 " has incorrect view" +
3609 " of set " + onosSetName + ":\n" +
3610 str( getResponses[ i ] ) )
3611 main.log.debug( "Expected: " + str( onosSet ) )
3612 main.log.debug( "Actual: " + str( current ) )
3613 getResults = main.FALSE
3614 else:
3615 # error, set is not a set
3616 main.log.error( "ONOS" + str( i + 1 ) +
3617 " has repeat elements in" +
3618 " set " + onosSetName + ":\n" +
3619 str( getResponses[ i ] ) )
3620 getResults = main.FALSE
3621 elif getResponses[ i ] == main.ERROR:
3622 getResults = main.FALSE
3623 sizeResponses = []
3624 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003625 for i in range( main.numCtrls ):
3626 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003627 name="setTestSize-" + str( i ),
3628 args=[ onosSetName ] )
3629 threads.append( t )
3630 t.start()
3631 for t in threads:
3632 t.join()
3633 sizeResponses.append( t.result )
3634 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003635 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003636 if size != sizeResponses[ i ]:
3637 sizeResults = main.FALSE
3638 main.log.error( "ONOS" + str( i + 1 ) +
3639 " expected a size of " + str( size ) +
3640 " for set " + onosSetName +
3641 " but got " + str( sizeResponses[ i ] ) )
3642 addResults = addResults and getResults and sizeResults
3643 utilities.assert_equals( expect=main.TRUE,
3644 actual=addResults,
3645 onpass="Set add correct",
3646 onfail="Set add was incorrect" )
3647
3648 main.step( "Distributed Set addAll()" )
3649 onosSet.update( addAllValue.split() )
3650 addResponses = []
3651 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003652 for i in range( main.numCtrls ):
3653 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003654 name="setTestAddAll-" + str( i ),
3655 args=[ onosSetName, addAllValue ] )
3656 threads.append( t )
3657 t.start()
3658 for t in threads:
3659 t.join()
3660 addResponses.append( t.result )
3661
3662 # main.TRUE = successfully changed the set
3663 # main.FALSE = action resulted in no change in set
3664 # main.ERROR - Some error in executing the function
3665 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003666 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003667 if addResponses[ i ] == main.TRUE:
3668 # All is well
3669 pass
3670 elif addResponses[ i ] == main.FALSE:
3671 # Already in set, probably fine
3672 pass
3673 elif addResponses[ i ] == main.ERROR:
3674 # Error in execution
3675 addAllResults = main.FALSE
3676 else:
3677 # unexpected result
3678 addAllResults = main.FALSE
3679 if addAllResults != main.TRUE:
3680 main.log.error( "Error executing set addAll" )
3681
3682 # Check if set is still correct
3683 size = len( onosSet )
3684 getResponses = []
3685 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003686 for i in range( main.numCtrls ):
3687 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003688 name="setTestGet-" + str( i ),
3689 args=[ onosSetName ] )
3690 threads.append( t )
3691 t.start()
3692 for t in threads:
3693 t.join()
3694 getResponses.append( t.result )
3695 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003696 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003697 if isinstance( getResponses[ i ], list):
3698 current = set( getResponses[ i ] )
3699 if len( current ) == len( getResponses[ i ] ):
3700 # no repeats
3701 if onosSet != current:
3702 main.log.error( "ONOS" + str( i + 1 ) +
3703 " has incorrect view" +
3704 " of set " + onosSetName + ":\n" +
3705 str( getResponses[ i ] ) )
3706 main.log.debug( "Expected: " + str( onosSet ) )
3707 main.log.debug( "Actual: " + str( current ) )
3708 getResults = main.FALSE
3709 else:
3710 # error, set is not a set
3711 main.log.error( "ONOS" + str( i + 1 ) +
3712 " has repeat elements in" +
3713 " set " + onosSetName + ":\n" +
3714 str( getResponses[ i ] ) )
3715 getResults = main.FALSE
3716 elif getResponses[ i ] == main.ERROR:
3717 getResults = main.FALSE
3718 sizeResponses = []
3719 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003720 for i in range( main.numCtrls ):
3721 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003722 name="setTestSize-" + str( i ),
3723 args=[ onosSetName ] )
3724 threads.append( t )
3725 t.start()
3726 for t in threads:
3727 t.join()
3728 sizeResponses.append( t.result )
3729 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003730 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003731 if size != sizeResponses[ i ]:
3732 sizeResults = main.FALSE
3733 main.log.error( "ONOS" + str( i + 1 ) +
3734 " expected a size of " + str( size ) +
3735 " for set " + onosSetName +
3736 " but got " + str( sizeResponses[ i ] ) )
3737 addAllResults = addAllResults and getResults and sizeResults
3738 utilities.assert_equals( expect=main.TRUE,
3739 actual=addAllResults,
3740 onpass="Set addAll correct",
3741 onfail="Set addAll was incorrect" )
3742
3743 main.step( "Distributed Set contains()" )
3744 containsResponses = []
3745 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003746 for i in range( main.numCtrls ):
3747 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003748 name="setContains-" + str( i ),
3749 args=[ onosSetName ],
3750 kwargs={ "values": addValue } )
3751 threads.append( t )
3752 t.start()
3753 for t in threads:
3754 t.join()
3755 # NOTE: This is the tuple
3756 containsResponses.append( t.result )
3757
3758 containsResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003759 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003760 if containsResponses[ i ] == main.ERROR:
3761 containsResults = main.FALSE
3762 else:
3763 containsResults = containsResults and\
3764 containsResponses[ i ][ 1 ]
3765 utilities.assert_equals( expect=main.TRUE,
3766 actual=containsResults,
3767 onpass="Set contains is functional",
3768 onfail="Set contains failed" )
3769
3770 main.step( "Distributed Set containsAll()" )
3771 containsAllResponses = []
3772 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003773 for i in range( main.numCtrls ):
3774 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003775 name="setContainsAll-" + str( i ),
3776 args=[ onosSetName ],
3777 kwargs={ "values": addAllValue } )
3778 threads.append( t )
3779 t.start()
3780 for t in threads:
3781 t.join()
3782 # NOTE: This is the tuple
3783 containsAllResponses.append( t.result )
3784
3785 containsAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003786 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003787 if containsResponses[ i ] == main.ERROR:
3788 containsResults = main.FALSE
3789 else:
3790 containsResults = containsResults and\
3791 containsResponses[ i ][ 1 ]
3792 utilities.assert_equals( expect=main.TRUE,
3793 actual=containsAllResults,
3794 onpass="Set containsAll is functional",
3795 onfail="Set containsAll failed" )
3796
3797 main.step( "Distributed Set remove()" )
3798 onosSet.remove( addValue )
3799 removeResponses = []
3800 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003801 for i in range( main.numCtrls ):
3802 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003803 name="setTestRemove-" + str( i ),
3804 args=[ onosSetName, addValue ] )
3805 threads.append( t )
3806 t.start()
3807 for t in threads:
3808 t.join()
3809 removeResponses.append( t.result )
3810
3811 # main.TRUE = successfully changed the set
3812 # main.FALSE = action resulted in no change in set
3813 # main.ERROR - Some error in executing the function
3814 removeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003815 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003816 if removeResponses[ i ] == main.TRUE:
3817 # All is well
3818 pass
3819 elif removeResponses[ i ] == main.FALSE:
3820 # not in set, probably fine
3821 pass
3822 elif removeResponses[ i ] == main.ERROR:
3823 # Error in execution
3824 removeResults = main.FALSE
3825 else:
3826 # unexpected result
3827 removeResults = main.FALSE
3828 if removeResults != main.TRUE:
3829 main.log.error( "Error executing set remove" )
3830
3831 # Check if set is still correct
3832 size = len( onosSet )
3833 getResponses = []
3834 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003835 for i in range( main.numCtrls ):
3836 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003837 name="setTestGet-" + str( i ),
3838 args=[ onosSetName ] )
3839 threads.append( t )
3840 t.start()
3841 for t in threads:
3842 t.join()
3843 getResponses.append( t.result )
3844 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003845 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003846 if isinstance( getResponses[ i ], list):
3847 current = set( getResponses[ i ] )
3848 if len( current ) == len( getResponses[ i ] ):
3849 # no repeats
3850 if onosSet != current:
3851 main.log.error( "ONOS" + str( i + 1 ) +
3852 " has incorrect view" +
3853 " of set " + onosSetName + ":\n" +
3854 str( getResponses[ i ] ) )
3855 main.log.debug( "Expected: " + str( onosSet ) )
3856 main.log.debug( "Actual: " + str( current ) )
3857 getResults = main.FALSE
3858 else:
3859 # error, set is not a set
3860 main.log.error( "ONOS" + str( i + 1 ) +
3861 " has repeat elements in" +
3862 " set " + onosSetName + ":\n" +
3863 str( getResponses[ i ] ) )
3864 getResults = main.FALSE
3865 elif getResponses[ i ] == main.ERROR:
3866 getResults = main.FALSE
3867 sizeResponses = []
3868 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003869 for i in range( main.numCtrls ):
3870 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003871 name="setTestSize-" + str( i ),
3872 args=[ onosSetName ] )
3873 threads.append( t )
3874 t.start()
3875 for t in threads:
3876 t.join()
3877 sizeResponses.append( t.result )
3878 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003879 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003880 if size != sizeResponses[ i ]:
3881 sizeResults = main.FALSE
3882 main.log.error( "ONOS" + str( i + 1 ) +
3883 " expected a size of " + str( size ) +
3884 " for set " + onosSetName +
3885 " but got " + str( sizeResponses[ i ] ) )
3886 removeResults = removeResults and getResults and sizeResults
3887 utilities.assert_equals( expect=main.TRUE,
3888 actual=removeResults,
3889 onpass="Set remove correct",
3890 onfail="Set remove was incorrect" )
3891
3892 main.step( "Distributed Set removeAll()" )
3893 onosSet.difference_update( addAllValue.split() )
3894 removeAllResponses = []
3895 threads = []
3896 try:
Jon Halle1a3b752015-07-22 13:02:46 -07003897 for i in range( main.numCtrls ):
3898 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07003899 name="setTestRemoveAll-" + str( i ),
3900 args=[ onosSetName, addAllValue ] )
3901 threads.append( t )
3902 t.start()
3903 for t in threads:
3904 t.join()
3905 removeAllResponses.append( t.result )
3906 except Exception, e:
3907 main.log.exception(e)
3908
3909 # main.TRUE = successfully changed the set
3910 # main.FALSE = action resulted in no change in set
3911 # main.ERROR - Some error in executing the function
3912 removeAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003913 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003914 if removeAllResponses[ i ] == main.TRUE:
3915 # All is well
3916 pass
3917 elif removeAllResponses[ i ] == main.FALSE:
3918 # not in set, probably fine
3919 pass
3920 elif removeAllResponses[ i ] == main.ERROR:
3921 # Error in execution
3922 removeAllResults = main.FALSE
3923 else:
3924 # unexpected result
3925 removeAllResults = main.FALSE
3926 if removeAllResults != main.TRUE:
3927 main.log.error( "Error executing set removeAll" )
3928
3929 # Check if set is still correct
3930 size = len( onosSet )
3931 getResponses = []
3932 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003933 for i in range( main.numCtrls ):
3934 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07003935 name="setTestGet-" + str( i ),
3936 args=[ onosSetName ] )
3937 threads.append( t )
3938 t.start()
3939 for t in threads:
3940 t.join()
3941 getResponses.append( t.result )
3942 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003943 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003944 if isinstance( getResponses[ i ], list):
3945 current = set( getResponses[ i ] )
3946 if len( current ) == len( getResponses[ i ] ):
3947 # no repeats
3948 if onosSet != current:
3949 main.log.error( "ONOS" + str( i + 1 ) +
3950 " has incorrect view" +
3951 " of set " + onosSetName + ":\n" +
3952 str( getResponses[ i ] ) )
3953 main.log.debug( "Expected: " + str( onosSet ) )
3954 main.log.debug( "Actual: " + str( current ) )
3955 getResults = main.FALSE
3956 else:
3957 # error, set is not a set
3958 main.log.error( "ONOS" + str( i + 1 ) +
3959 " has repeat elements in" +
3960 " set " + onosSetName + ":\n" +
3961 str( getResponses[ i ] ) )
3962 getResults = main.FALSE
3963 elif getResponses[ i ] == main.ERROR:
3964 getResults = main.FALSE
3965 sizeResponses = []
3966 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003967 for i in range( main.numCtrls ):
3968 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07003969 name="setTestSize-" + str( i ),
3970 args=[ onosSetName ] )
3971 threads.append( t )
3972 t.start()
3973 for t in threads:
3974 t.join()
3975 sizeResponses.append( t.result )
3976 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003977 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07003978 if size != sizeResponses[ i ]:
3979 sizeResults = main.FALSE
3980 main.log.error( "ONOS" + str( i + 1 ) +
3981 " expected a size of " + str( size ) +
3982 " for set " + onosSetName +
3983 " but got " + str( sizeResponses[ i ] ) )
3984 removeAllResults = removeAllResults and getResults and sizeResults
3985 utilities.assert_equals( expect=main.TRUE,
3986 actual=removeAllResults,
3987 onpass="Set removeAll correct",
3988 onfail="Set removeAll was incorrect" )
3989
3990 main.step( "Distributed Set addAll()" )
3991 onosSet.update( addAllValue.split() )
3992 addResponses = []
3993 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003994 for i in range( main.numCtrls ):
3995 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07003996 name="setTestAddAll-" + str( i ),
3997 args=[ onosSetName, addAllValue ] )
3998 threads.append( t )
3999 t.start()
4000 for t in threads:
4001 t.join()
4002 addResponses.append( t.result )
4003
4004 # main.TRUE = successfully changed the set
4005 # main.FALSE = action resulted in no change in set
4006 # main.ERROR - Some error in executing the function
4007 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004008 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004009 if addResponses[ i ] == main.TRUE:
4010 # All is well
4011 pass
4012 elif addResponses[ i ] == main.FALSE:
4013 # Already in set, probably fine
4014 pass
4015 elif addResponses[ i ] == main.ERROR:
4016 # Error in execution
4017 addAllResults = main.FALSE
4018 else:
4019 # unexpected result
4020 addAllResults = main.FALSE
4021 if addAllResults != main.TRUE:
4022 main.log.error( "Error executing set addAll" )
4023
4024 # Check if set is still correct
4025 size = len( onosSet )
4026 getResponses = []
4027 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004028 for i in range( main.numCtrls ):
4029 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004030 name="setTestGet-" + str( i ),
4031 args=[ onosSetName ] )
4032 threads.append( t )
4033 t.start()
4034 for t in threads:
4035 t.join()
4036 getResponses.append( t.result )
4037 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004038 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004039 if isinstance( getResponses[ i ], list):
4040 current = set( getResponses[ i ] )
4041 if len( current ) == len( getResponses[ i ] ):
4042 # no repeats
4043 if onosSet != current:
4044 main.log.error( "ONOS" + str( i + 1 ) +
4045 " has incorrect view" +
4046 " of set " + onosSetName + ":\n" +
4047 str( getResponses[ i ] ) )
4048 main.log.debug( "Expected: " + str( onosSet ) )
4049 main.log.debug( "Actual: " + str( current ) )
4050 getResults = main.FALSE
4051 else:
4052 # error, set is not a set
4053 main.log.error( "ONOS" + str( i + 1 ) +
4054 " has repeat elements in" +
4055 " set " + onosSetName + ":\n" +
4056 str( getResponses[ i ] ) )
4057 getResults = main.FALSE
4058 elif getResponses[ i ] == main.ERROR:
4059 getResults = main.FALSE
4060 sizeResponses = []
4061 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004062 for i in range( main.numCtrls ):
4063 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004064 name="setTestSize-" + str( i ),
4065 args=[ onosSetName ] )
4066 threads.append( t )
4067 t.start()
4068 for t in threads:
4069 t.join()
4070 sizeResponses.append( t.result )
4071 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004072 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004073 if size != sizeResponses[ i ]:
4074 sizeResults = main.FALSE
4075 main.log.error( "ONOS" + str( i + 1 ) +
4076 " expected a size of " + str( size ) +
4077 " for set " + onosSetName +
4078 " but got " + str( sizeResponses[ i ] ) )
4079 addAllResults = addAllResults and getResults and sizeResults
4080 utilities.assert_equals( expect=main.TRUE,
4081 actual=addAllResults,
4082 onpass="Set addAll correct",
4083 onfail="Set addAll was incorrect" )
4084
4085 main.step( "Distributed Set clear()" )
4086 onosSet.clear()
4087 clearResponses = []
4088 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004089 for i in range( main.numCtrls ):
4090 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004091 name="setTestClear-" + str( i ),
4092 args=[ onosSetName, " "], # Values doesn't matter
4093 kwargs={ "clear": True } )
4094 threads.append( t )
4095 t.start()
4096 for t in threads:
4097 t.join()
4098 clearResponses.append( t.result )
4099
4100 # main.TRUE = successfully changed the set
4101 # main.FALSE = action resulted in no change in set
4102 # main.ERROR - Some error in executing the function
4103 clearResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004104 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004105 if clearResponses[ i ] == main.TRUE:
4106 # All is well
4107 pass
4108 elif clearResponses[ i ] == main.FALSE:
4109 # Nothing set, probably fine
4110 pass
4111 elif clearResponses[ i ] == main.ERROR:
4112 # Error in execution
4113 clearResults = main.FALSE
4114 else:
4115 # unexpected result
4116 clearResults = main.FALSE
4117 if clearResults != main.TRUE:
4118 main.log.error( "Error executing set clear" )
4119
4120 # Check if set is still correct
4121 size = len( onosSet )
4122 getResponses = []
4123 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004124 for i in range( main.numCtrls ):
4125 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004126 name="setTestGet-" + str( i ),
4127 args=[ onosSetName ] )
4128 threads.append( t )
4129 t.start()
4130 for t in threads:
4131 t.join()
4132 getResponses.append( t.result )
4133 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004134 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004135 if isinstance( getResponses[ i ], list):
4136 current = set( getResponses[ i ] )
4137 if len( current ) == len( getResponses[ i ] ):
4138 # no repeats
4139 if onosSet != current:
4140 main.log.error( "ONOS" + str( i + 1 ) +
4141 " has incorrect view" +
4142 " of set " + onosSetName + ":\n" +
4143 str( getResponses[ i ] ) )
4144 main.log.debug( "Expected: " + str( onosSet ) )
4145 main.log.debug( "Actual: " + str( current ) )
4146 getResults = main.FALSE
4147 else:
4148 # error, set is not a set
4149 main.log.error( "ONOS" + str( i + 1 ) +
4150 " has repeat elements in" +
4151 " set " + onosSetName + ":\n" +
4152 str( getResponses[ i ] ) )
4153 getResults = main.FALSE
4154 elif getResponses[ i ] == main.ERROR:
4155 getResults = main.FALSE
4156 sizeResponses = []
4157 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004158 for i in range( main.numCtrls ):
4159 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004160 name="setTestSize-" + str( i ),
4161 args=[ onosSetName ] )
4162 threads.append( t )
4163 t.start()
4164 for t in threads:
4165 t.join()
4166 sizeResponses.append( t.result )
4167 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004168 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004169 if size != sizeResponses[ i ]:
4170 sizeResults = main.FALSE
4171 main.log.error( "ONOS" + str( i + 1 ) +
4172 " expected a size of " + str( size ) +
4173 " for set " + onosSetName +
4174 " but got " + str( sizeResponses[ i ] ) )
4175 clearResults = clearResults and getResults and sizeResults
4176 utilities.assert_equals( expect=main.TRUE,
4177 actual=clearResults,
4178 onpass="Set clear correct",
4179 onfail="Set clear was incorrect" )
4180
4181 main.step( "Distributed Set addAll()" )
4182 onosSet.update( addAllValue.split() )
4183 addResponses = []
4184 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004185 for i in range( main.numCtrls ):
4186 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall5cf14d52015-07-16 12:15:19 -07004187 name="setTestAddAll-" + str( i ),
4188 args=[ onosSetName, addAllValue ] )
4189 threads.append( t )
4190 t.start()
4191 for t in threads:
4192 t.join()
4193 addResponses.append( t.result )
4194
4195 # main.TRUE = successfully changed the set
4196 # main.FALSE = action resulted in no change in set
4197 # main.ERROR - Some error in executing the function
4198 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004199 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004200 if addResponses[ i ] == main.TRUE:
4201 # All is well
4202 pass
4203 elif addResponses[ i ] == main.FALSE:
4204 # Already in set, probably fine
4205 pass
4206 elif addResponses[ i ] == main.ERROR:
4207 # Error in execution
4208 addAllResults = main.FALSE
4209 else:
4210 # unexpected result
4211 addAllResults = main.FALSE
4212 if addAllResults != main.TRUE:
4213 main.log.error( "Error executing set addAll" )
4214
4215 # Check if set is still correct
4216 size = len( onosSet )
4217 getResponses = []
4218 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004219 for i in range( main.numCtrls ):
4220 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004221 name="setTestGet-" + str( i ),
4222 args=[ onosSetName ] )
4223 threads.append( t )
4224 t.start()
4225 for t in threads:
4226 t.join()
4227 getResponses.append( t.result )
4228 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004229 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004230 if isinstance( getResponses[ i ], list):
4231 current = set( getResponses[ i ] )
4232 if len( current ) == len( getResponses[ i ] ):
4233 # no repeats
4234 if onosSet != current:
4235 main.log.error( "ONOS" + str( i + 1 ) +
4236 " has incorrect view" +
4237 " of set " + onosSetName + ":\n" +
4238 str( getResponses[ i ] ) )
4239 main.log.debug( "Expected: " + str( onosSet ) )
4240 main.log.debug( "Actual: " + str( current ) )
4241 getResults = main.FALSE
4242 else:
4243 # error, set is not a set
4244 main.log.error( "ONOS" + str( i + 1 ) +
4245 " has repeat elements in" +
4246 " set " + onosSetName + ":\n" +
4247 str( getResponses[ i ] ) )
4248 getResults = main.FALSE
4249 elif getResponses[ i ] == main.ERROR:
4250 getResults = main.FALSE
4251 sizeResponses = []
4252 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004253 for i in range( main.numCtrls ):
4254 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004255 name="setTestSize-" + str( i ),
4256 args=[ onosSetName ] )
4257 threads.append( t )
4258 t.start()
4259 for t in threads:
4260 t.join()
4261 sizeResponses.append( t.result )
4262 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004263 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004264 if size != sizeResponses[ i ]:
4265 sizeResults = main.FALSE
4266 main.log.error( "ONOS" + str( i + 1 ) +
4267 " expected a size of " + str( size ) +
4268 " for set " + onosSetName +
4269 " but got " + str( sizeResponses[ i ] ) )
4270 addAllResults = addAllResults and getResults and sizeResults
4271 utilities.assert_equals( expect=main.TRUE,
4272 actual=addAllResults,
4273 onpass="Set addAll correct",
4274 onfail="Set addAll was incorrect" )
4275
4276 main.step( "Distributed Set retain()" )
4277 onosSet.intersection_update( retainValue.split() )
4278 retainResponses = []
4279 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004280 for i in range( main.numCtrls ):
4281 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall5cf14d52015-07-16 12:15:19 -07004282 name="setTestRetain-" + str( i ),
4283 args=[ onosSetName, retainValue ],
4284 kwargs={ "retain": True } )
4285 threads.append( t )
4286 t.start()
4287 for t in threads:
4288 t.join()
4289 retainResponses.append( t.result )
4290
4291 # main.TRUE = successfully changed the set
4292 # main.FALSE = action resulted in no change in set
4293 # main.ERROR - Some error in executing the function
4294 retainResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004295 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004296 if retainResponses[ i ] == main.TRUE:
4297 # All is well
4298 pass
4299 elif retainResponses[ i ] == main.FALSE:
4300 # Already in set, probably fine
4301 pass
4302 elif retainResponses[ i ] == main.ERROR:
4303 # Error in execution
4304 retainResults = main.FALSE
4305 else:
4306 # unexpected result
4307 retainResults = main.FALSE
4308 if retainResults != main.TRUE:
4309 main.log.error( "Error executing set retain" )
4310
4311 # Check if set is still correct
4312 size = len( onosSet )
4313 getResponses = []
4314 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004315 for i in range( main.numCtrls ):
4316 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall5cf14d52015-07-16 12:15:19 -07004317 name="setTestGet-" + str( i ),
4318 args=[ onosSetName ] )
4319 threads.append( t )
4320 t.start()
4321 for t in threads:
4322 t.join()
4323 getResponses.append( t.result )
4324 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004325 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004326 if isinstance( getResponses[ i ], list):
4327 current = set( getResponses[ i ] )
4328 if len( current ) == len( getResponses[ i ] ):
4329 # no repeats
4330 if onosSet != current:
4331 main.log.error( "ONOS" + str( i + 1 ) +
4332 " has incorrect view" +
4333 " of set " + onosSetName + ":\n" +
4334 str( getResponses[ i ] ) )
4335 main.log.debug( "Expected: " + str( onosSet ) )
4336 main.log.debug( "Actual: " + str( current ) )
4337 getResults = main.FALSE
4338 else:
4339 # error, set is not a set
4340 main.log.error( "ONOS" + str( i + 1 ) +
4341 " has repeat elements in" +
4342 " set " + onosSetName + ":\n" +
4343 str( getResponses[ i ] ) )
4344 getResults = main.FALSE
4345 elif getResponses[ i ] == main.ERROR:
4346 getResults = main.FALSE
4347 sizeResponses = []
4348 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07004349 for i in range( main.numCtrls ):
4350 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall5cf14d52015-07-16 12:15:19 -07004351 name="setTestSize-" + str( i ),
4352 args=[ onosSetName ] )
4353 threads.append( t )
4354 t.start()
4355 for t in threads:
4356 t.join()
4357 sizeResponses.append( t.result )
4358 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07004359 for i in range( main.numCtrls ):
Jon Hall5cf14d52015-07-16 12:15:19 -07004360 if size != sizeResponses[ i ]:
4361 sizeResults = main.FALSE
4362 main.log.error( "ONOS" + str( i + 1 ) +
4363 " expected a size of " +
4364 str( size ) + " for set " + onosSetName +
4365 " but got " + str( sizeResponses[ i ] ) )
4366 retainResults = retainResults and getResults and sizeResults
4367 utilities.assert_equals( expect=main.TRUE,
4368 actual=retainResults,
4369 onpass="Set retain correct",
4370 onfail="Set retain was incorrect" )
4371
Jon Hall2a5002c2015-08-21 16:49:11 -07004372 # Transactional maps
4373 main.step( "Partitioned Transactional maps put" )
4374 tMapValue = "Testing"
4375 numKeys = 100
4376 putResult = True
4377 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue )
4378 if len( putResponses ) == 100:
4379 for i in putResponses:
4380 if putResponses[ i ][ 'value' ] != tMapValue:
4381 putResult = False
4382 else:
4383 putResult = False
4384 if not putResult:
4385 main.log.debug( "Put response values: " + str( putResponses ) )
4386 utilities.assert_equals( expect=True,
4387 actual=putResult,
4388 onpass="Partitioned Transactional Map put successful",
4389 onfail="Partitioned Transactional Map put values are incorrect" )
4390
4391 main.step( "Partitioned Transactional maps get" )
4392 getCheck = True
4393 for n in range( 1, numKeys + 1 ):
4394 getResponses = []
4395 threads = []
4396 valueCheck = True
4397 for i in range( main.numCtrls ):
4398 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4399 name="TMap-get-" + str( i ),
4400 args=[ "Key" + str ( n ) ] )
4401 threads.append( t )
4402 t.start()
4403 for t in threads:
4404 t.join()
4405 getResponses.append( t.result )
4406 for node in getResponses:
4407 if node != tMapValue:
4408 valueCheck = False
4409 if not valueCheck:
4410 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4411 main.log.warn( getResponses )
4412 getCheck = getCheck and valueCheck
4413 utilities.assert_equals( expect=True,
4414 actual=getCheck,
4415 onpass="Partitioned Transactional Map get values were correct",
4416 onfail="Partitioned Transactional Map values incorrect" )
4417
4418 main.step( "In-memory Transactional maps put" )
4419 tMapValue = "Testing"
4420 numKeys = 100
4421 putResult = True
4422 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue, inMemory=True )
4423 if len( putResponses ) == 100:
4424 for i in putResponses:
4425 if putResponses[ i ][ 'value' ] != tMapValue:
4426 putResult = False
4427 else:
4428 putResult = False
4429 if not putResult:
4430 main.log.debug( "Put response values: " + str( putResponses ) )
4431 utilities.assert_equals( expect=True,
4432 actual=putResult,
4433 onpass="In-Memory Transactional Map put successful",
4434 onfail="In-Memory Transactional Map put values are incorrect" )
4435
4436 main.step( "In-Memory Transactional maps get" )
4437 getCheck = True
4438 for n in range( 1, numKeys + 1 ):
4439 getResponses = []
4440 threads = []
4441 valueCheck = True
4442 for i in range( main.numCtrls ):
4443 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
4444 name="TMap-get-" + str( i ),
4445 args=[ "Key" + str ( n ) ],
4446 kwargs={ "inMemory": True } )
4447 threads.append( t )
4448 t.start()
4449 for t in threads:
4450 t.join()
4451 getResponses.append( t.result )
4452 for node in getResponses:
4453 if node != tMapValue:
4454 valueCheck = False
4455 if not valueCheck:
4456 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
4457 main.log.warn( getResponses )
4458 getCheck = getCheck and valueCheck
4459 utilities.assert_equals( expect=True,
4460 actual=getCheck,
4461 onpass="In-Memory Transactional Map get values were correct",
4462 onfail="In-Memory Transactional Map values incorrect" )