blob: 728b9ab3fd5b261b989fc997624d26f8c0bf8021 [file] [log] [blame]
Jon Hall85794ff2015-07-08 14:12:30 -07001"""
2Description: This test is to determine if a single
3 instance ONOS 'cluster' can handle a restart
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 HAsingleInstanceRestart:
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 Hall85794ff2015-07-08 14:12:30 -070051 main.log.info( "ONOS Single node cluster restart " +
52 "HA test - initialization" )
53 main.case( "Setting up test environment" )
Jon Hall783bbf92015-07-23 14:33:19 -070054 main.caseExplanation = "Setup the test environment including " +\
Jon Hall85794ff2015-07-08 14:12:30 -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 )
Jon Hall85794ff2015-07-08 14:12:30 -070070
Jon Halle1a3b752015-07-22 13:02:46 -070071 try:
72 fileName = "Counters"
73 path = main.params[ 'imports' ][ 'path' ]
74 main.Counters = imp.load_source( fileName,
75 path + fileName + ".py" )
76 except Exception as e:
77 main.log.exception( e )
78 main.cleanup()
79 main.exit()
80
81 main.CLIs = []
82 main.nodes = []
Jon Hall5cf14d52015-07-16 12:15:19 -070083 ipList = []
84 for i in range( 1, int( main.ONOSbench.maxNodes ) + 1 ):
85 try:
Jon Halle1a3b752015-07-22 13:02:46 -070086 main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
87 main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
88 ipList.append( main.nodes[ -1 ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -070089 except AttributeError:
90 break
Jon Hall85794ff2015-07-08 14:12:30 -070091
Jon Hall5cf14d52015-07-16 12:15:19 -070092 main.step( "Create cell file" )
93 cellAppString = main.params[ 'ENV' ][ 'appString' ]
94 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
95 main.Mininet1.ip_address,
96 cellAppString, ipList )
Jon Hall85794ff2015-07-08 14:12:30 -070097 main.step( "Applying cell variable to environment" )
98 cellResult = main.ONOSbench.setCell( cellName )
99 verifyResult = main.ONOSbench.verifyCell()
100
101 # FIXME:this is short term fix
102 main.log.info( "Removing raft logs" )
103 main.ONOSbench.onosRemoveRaftLogs()
104
105 main.log.info( "Uninstalling ONOS" )
Jon Halle1a3b752015-07-22 13:02:46 -0700106 for node in main.nodes:
Jon Hall85794ff2015-07-08 14:12:30 -0700107 main.ONOSbench.onosUninstall( node.ip_address )
108
109 # Make sure ONOS is DEAD
110 main.log.info( "Killing any ONOS processes" )
111 killResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700112 for node in main.nodes:
Jon Hall85794ff2015-07-08 14:12:30 -0700113 killed = main.ONOSbench.onosKill( node.ip_address )
114 killResults = killResults and killed
115
116 cleanInstallResult = main.TRUE
117 gitPullResult = main.TRUE
118
119 main.step( "Starting Mininet" )
120 # scp topo file to mininet
121 # TODO: move to params?
122 topoName = "obelisk.py"
123 filePath = main.ONOSbench.home + "/tools/test/topos/"
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700124 main.ONOSbench.scp( main.Mininet1,
125 filePath + topoName,
126 main.Mininet1.home,
127 direction="to" )
Jon Hall85794ff2015-07-08 14:12:30 -0700128 mnResult = main.Mininet1.startNet( )
129 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
130 onpass="Mininet Started",
131 onfail="Error starting Mininet" )
132
133 main.step( "Git checkout and pull " + gitBranch )
134 if PULLCODE:
135 main.ONOSbench.gitCheckout( gitBranch )
136 gitPullResult = main.ONOSbench.gitPull()
137 # values of 1 or 3 are good
138 utilities.assert_lesser( expect=0, actual=gitPullResult,
139 onpass="Git pull successful",
140 onfail="Git pull failed" )
141 main.ONOSbench.getVersion( report=True )
142
143 main.step( "Using mvn clean install" )
144 cleanInstallResult = main.TRUE
145 if PULLCODE and gitPullResult == main.TRUE:
146 cleanInstallResult = main.ONOSbench.cleanInstall()
147 else:
148 main.log.warn( "Did not pull new code so skipping mvn " +
149 "clean install" )
150 utilities.assert_equals( expect=main.TRUE,
151 actual=cleanInstallResult,
152 onpass="MCI successful",
153 onfail="MCI failed" )
154 # GRAPHS
155 # NOTE: important params here:
156 # job = name of Jenkins job
157 # Plot Name = Plot-HA, only can be used if multiple plots
158 # index = The number of the graph under plot name
Jon Hall5cf14d52015-07-16 12:15:19 -0700159 job = "HAsingleInstanceRestart"
Jon Hall85794ff2015-07-08 14:12:30 -0700160 plotName = "Plot-HA"
161 graphs = '<ac:structured-macro ac:name="html">\n'
162 graphs += '<ac:plain-text-body><![CDATA[\n'
163 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
164 '/plot/' + plotName + '/getPlot?index=0' +\
165 '&width=500&height=300"' +\
166 'noborder="0" width="500" height="300" scrolling="yes" ' +\
167 'seamless="seamless"></iframe>\n'
168 graphs += ']]></ac:plain-text-body>\n'
169 graphs += '</ac:structured-macro>\n'
170 main.log.wiki(graphs)
171
Jon Halle1a3b752015-07-22 13:02:46 -0700172 main.CLIs = []
173 main.nodes = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700174 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700175 for i in range( 1, main.numCtrls + 1 ):
176 main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
177 main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
178 ipList.append( main.nodes[ -1 ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -0700179
180 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, "SingleHA",
181 main.Mininet1.ip_address,
182 cellAppString, ipList[ 0 ] )
Jon Hall85794ff2015-07-08 14:12:30 -0700183 cellResult = main.ONOSbench.setCell( "SingleHA" )
184 verifyResult = main.ONOSbench.verifyCell()
185 main.step( "Creating ONOS package" )
186 packageResult = main.ONOSbench.onosPackage()
187 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
188 onpass="ONOS package successful",
189 onfail="ONOS package failed" )
190
191 main.step( "Installing ONOS package" )
192 onosInstallResult = main.ONOSbench.onosInstall(
Jon Halle1a3b752015-07-22 13:02:46 -0700193 options="-f", node=main.nodes[0].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -0700194 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
195 onpass="ONOS install successful",
196 onfail="ONOS install failed" )
197
198 main.step( "Checking if ONOS is up yet" )
199 for i in range( 2 ):
Jon Halle1a3b752015-07-22 13:02:46 -0700200 onos1Isup = main.ONOSbench.isup( main.nodes[0].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -0700201 if onos1Isup:
202 break
203 utilities.assert_equals( expect=main.TRUE, actual=onos1Isup,
204 onpass="ONOS startup successful",
205 onfail="ONOS startup failed" )
206
207 main.log.step( "Starting ONOS CLI sessions" )
Jon Halle1a3b752015-07-22 13:02:46 -0700208 cliResults = main.ONOScli1.startOnosCli( main.nodes[0].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -0700209 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
210 onpass="ONOS cli startup successful",
211 onfail="ONOS cli startup failed" )
212
213 if main.params[ 'tcpdump' ].lower() == "true":
214 main.step( "Start Packet Capture MN" )
215 main.Mininet2.startTcpdump(
216 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
217 + "-MN.pcap",
218 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
219 port=main.params[ 'MNtcpdump' ][ 'port' ] )
220
221 main.step( "App Ids check" )
222 appCheck = main.ONOScli1.appToIDCheck()
223 if appCheck != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700224 main.log.warn( main.CLIs[0].apps() )
225 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall85794ff2015-07-08 14:12:30 -0700226 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
227 onpass="App Ids seem to be correct",
228 onfail="Something is wrong with app Ids" )
229
230 if cliResults == main.FALSE:
231 main.log.error( "Failed to start ONOS, stopping test" )
232 main.cleanup()
233 main.exit()
234
235 def CASE2( self, main ):
236 """
237 Assign devices to controllers
238 """
239 import re
Jon Halle1a3b752015-07-22 13:02:46 -0700240 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700241 assert main, "main not defined"
242 assert utilities.assert_equals, "utilities.assert_equals not defined"
243
244 main.case( "Assigning devices to controllers" )
Jon Hall783bbf92015-07-23 14:33:19 -0700245 main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700246 "and check that an ONOS node becomes the " +\
247 "master of the device."
248 main.step( "Assign switches to controllers" )
249
250 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700251 for i in range( main.numCtrls ):
252 ipList.append( main.nodes[ i ].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -0700253 swList = []
254 for i in range( 1, 29 ):
255 swList.append( "s" + str( i ) )
256 main.Mininet1.assignSwController( sw=swList, ip=ipList )
257
258 mastershipCheck = main.TRUE
259 for i in range( 1, 29 ):
260 response = main.Mininet1.getSwController( "s" + str( i ) )
261 try:
262 main.log.info( str( response ) )
263 except Exception:
264 main.log.info( repr( response ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700265 if re.search( "tcp:" + main.nodes[0].ip_address, response ):
Jon Hall85794ff2015-07-08 14:12:30 -0700266 mastershipCheck = mastershipCheck and main.TRUE
267 else:
268 mastershipCheck = main.FALSE
269 if mastershipCheck == main.TRUE:
270 main.log.info( "Switch mastership assigned correctly" )
271 utilities.assert_equals(
272 expect=main.TRUE,
273 actual=mastershipCheck,
274 onpass="Switch mastership assigned correctly",
275 onfail="Switches not assigned correctly to controllers" )
276
277 def CASE21( self, main ):
278 """
279 Assign mastership to controllers
280 """
Jon Halle1a3b752015-07-22 13:02:46 -0700281 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700282 assert main, "main not defined"
283 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700284 assert main.CLIs, "main.CLIs not defined"
285 assert main.nodes, "main.nodes not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700286
287 main.case( "Assigning Controller roles for switches" )
Jon Hall783bbf92015-07-23 14:33:19 -0700288 main.caseExplanation = "Check that ONOS is connected to each " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700289 "device. Then manually assign" +\
290 " mastership to specific ONOS nodes using" +\
291 " 'device-role'"
292 main.step( "Assign mastership of switches to specific controllers" )
293 roleCall = main.TRUE
294 roleCheck = main.TRUE
295 try:
296 for i in range( 1, 29 ): # switches 1 through 28
Jon Halle1a3b752015-07-22 13:02:46 -0700297 ip = main.nodes[ 0 ].ip_address # ONOS1
Jon Hall85794ff2015-07-08 14:12:30 -0700298 # set up correct variables:
299 if i == 1:
300 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
301 elif i == 2:
302 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
303 elif i == 3:
304 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
305 elif i == 4:
306 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
307 elif i == 5:
308 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
309 elif i == 6:
310 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
311 elif i == 7:
312 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
313 elif i >= 8 and i <= 17:
314 dpid = '3' + str( i ).zfill( 3 )
315 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
316 elif i >= 18 and i <= 27:
317 dpid = '6' + str( i ).zfill( 3 )
318 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
319 elif i == 28:
320 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
321 else:
322 main.log.error( "You didn't write an else statement for " +
323 "switch s" + str( i ) )
324 # Assign switch
325 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
326 # TODO: make this controller dynamic
327 roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
328 ip )
329 # Check assignment
330 master = main.ONOScli1.getRole( deviceId ).get( 'master' )
331 if ip in master:
332 roleCheck = roleCheck and main.TRUE
333 else:
334 roleCheck = roleCheck and main.FALSE
335 main.log.error( "Error, controller " + ip + " is not" +
336 " master " + "of device " +
337 str( deviceId ) + ". Master is " +
338 repr( master ) + "." )
339 except ( AttributeError, AssertionError ):
340 main.log.exception( "Something is wrong with ONOS device view" )
341 main.log.info( main.ONOScli1.devices() )
342 utilities.assert_equals(
343 expect=main.TRUE,
344 actual=roleCall,
345 onpass="Re-assigned switch mastership to designated controller",
346 onfail="Something wrong with deviceRole calls" )
347
348 main.step( "Check mastership was correctly assigned" )
349 utilities.assert_equals(
350 expect=main.TRUE,
351 actual=roleCheck,
352 onpass="Switches were successfully reassigned to designated " +
353 "controller",
354 onfail="Switches were not successfully reassigned" )
355
356 def CASE3( self, main ):
357 """
358 Assign intents
359 """
360 import time
361 import json
Jon Halle1a3b752015-07-22 13:02:46 -0700362 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700363 assert main, "main not defined"
364 assert utilities.assert_equals, "utilities.assert_equals not defined"
365 # NOTE: we must reinstall intents until we have a persistant intent
366 # datastore!
367 main.case( "Adding host Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700368 main.caseExplanation = "Discover hosts by using pingall then " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700369 "assign predetermined host-to-host intents." +\
370 " After installation, check that the intent" +\
371 " is distributed to all nodes and the state" +\
372 " is INSTALLED"
373
374 # install onos-app-fwd
375 main.step( "Install reactive forwarding app" )
Jon Halle1a3b752015-07-22 13:02:46 -0700376 installResults = main.CLIs[0].activateApp( "org.onosproject.fwd" )
Jon Hall85794ff2015-07-08 14:12:30 -0700377 utilities.assert_equals( expect=main.TRUE, actual=installResults,
378 onpass="Install fwd successful",
379 onfail="Install fwd failed" )
380
381 main.step( "Check app ids" )
382 appCheck = main.ONOScli1.appToIDCheck()
383 if appCheck != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700384 main.log.warn( main.CLIs[0].apps() )
385 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall85794ff2015-07-08 14:12:30 -0700386 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
387 onpass="App Ids seem to be correct",
388 onfail="Something is wrong with app Ids" )
389
390 main.step( "Discovering Hosts( Via pingall for now )" )
391 # FIXME: Once we have a host discovery mechanism, use that instead
392 # REACTIVE FWD test
393 pingResult = main.FALSE
Jon Hall96091e62015-09-21 17:34:17 -0700394 passMsg = "Reactive Pingall test passed"
395 time1 = time.time()
396 pingResult = main.Mininet1.pingall()
397 time2 = time.time()
398 if not pingResult:
399 main.log.warn("First pingall failed. Trying again...")
Jon Hall85794ff2015-07-08 14:12:30 -0700400 pingResult = main.Mininet1.pingall()
Jon Hall96091e62015-09-21 17:34:17 -0700401 passMsg += " on the second try"
402 utilities.assert_equals(
403 expect=main.TRUE,
404 actual=pingResult,
405 onpass= passMsg,
406 onfail="Reactive Pingall failed, " +
407 "one or more ping pairs failed" )
408 main.log.info( "Time for pingall: %2f seconds" %
409 ( time2 - time1 ) )
Jon Hall85794ff2015-07-08 14:12:30 -0700410 # timeout for fwd flows
411 time.sleep( 11 )
412 # uninstall onos-app-fwd
413 main.step( "Uninstall reactive forwarding app" )
Jon Halle1a3b752015-07-22 13:02:46 -0700414 uninstallResult = main.CLIs[0].deactivateApp( "org.onosproject.fwd" )
Jon Hall85794ff2015-07-08 14:12:30 -0700415 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
416 onpass="Uninstall fwd successful",
417 onfail="Uninstall fwd failed" )
418
419 main.step( "Check app ids" )
420 appCheck2 = main.ONOScli1.appToIDCheck()
421 if appCheck2 != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700422 main.log.warn( main.CLIs[0].apps() )
423 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall85794ff2015-07-08 14:12:30 -0700424 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
425 onpass="App Ids seem to be correct",
426 onfail="Something is wrong with app Ids" )
427
428 main.step( "Add host intents via cli" )
429 intentIds = []
430 # TODO: move the host numbers to params
431 # Maybe look at all the paths we ping?
432 intentAddResult = True
433 hostResult = main.TRUE
434 for i in range( 8, 18 ):
435 main.log.info( "Adding host intent between h" + str( i ) +
436 " and h" + str( i + 10 ) )
437 host1 = "00:00:00:00:00:" + \
438 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
439 host2 = "00:00:00:00:00:" + \
440 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
441 # NOTE: getHost can return None
442 host1Dict = main.ONOScli1.getHost( host1 )
443 host2Dict = main.ONOScli1.getHost( host2 )
444 host1Id = None
445 host2Id = None
446 if host1Dict and host2Dict:
447 host1Id = host1Dict.get( 'id', None )
448 host2Id = host2Dict.get( 'id', None )
449 if host1Id and host2Id:
450 tmpId = main.ONOScli1.addHostIntent( host1Id, host2Id )
451 if tmpId:
452 main.log.info( "Added intent with id: " + tmpId )
453 intentIds.append( tmpId )
454 else:
455 main.log.error( "addHostIntent returned: " +
456 repr( tmpId ) )
457 else:
458 main.log.error( "Error, getHost() failed for h" + str( i ) +
459 " and/or h" + str( i + 10 ) )
460 hosts = main.ONOScli1.hosts()
461 main.log.warn( "Hosts output: " )
462 try:
463 main.log.warn( json.dumps( json.loads( hosts ),
464 sort_keys=True,
465 indent=4,
466 separators=( ',', ': ' ) ) )
467 except ( ValueError, TypeError ):
468 main.log.warn( repr( hosts ) )
469 hostResult = main.FALSE
470 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
471 onpass="Found a host id for each host",
472 onfail="Error looking up host ids" )
473
474 intentStart = time.time()
475 onosIds = main.ONOScli1.getAllIntentsId()
476 main.log.info( "Submitted intents: " + str( intentIds ) )
477 main.log.info( "Intents in ONOS: " + str( onosIds ) )
478 for intent in intentIds:
479 if intent in onosIds:
480 pass # intent submitted is in onos
481 else:
482 intentAddResult = False
483 if intentAddResult:
484 intentStop = time.time()
485 else:
486 intentStop = None
487 # Print the intent states
488 intents = main.ONOScli1.intents()
489 intentStates = []
490 installedCheck = True
491 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
492 count = 0
493 try:
494 for intent in json.loads( intents ):
495 state = intent.get( 'state', None )
496 if "INSTALLED" not in state:
497 installedCheck = False
498 intentId = intent.get( 'id', None )
499 intentStates.append( ( intentId, state ) )
500 except ( ValueError, TypeError ):
501 main.log.exception( "Error parsing intents" )
502 # add submitted intents not in the store
503 tmplist = [ i for i, s in intentStates ]
504 missingIntents = False
505 for i in intentIds:
506 if i not in tmplist:
507 intentStates.append( ( i, " - " ) )
508 missingIntents = True
509 intentStates.sort()
510 for i, s in intentStates:
511 count += 1
512 main.log.info( "%-6s%-15s%-15s" %
513 ( str( count ), str( i ), str( s ) ) )
514 leaders = main.ONOScli1.leaders()
515 try:
516 missing = False
517 if leaders:
518 parsedLeaders = json.loads( leaders )
519 main.log.warn( json.dumps( parsedLeaders,
520 sort_keys=True,
521 indent=4,
522 separators=( ',', ': ' ) ) )
523 # check for all intent partitions
524 topics = []
525 for i in range( 14 ):
526 topics.append( "intent-partition-" + str( i ) )
527 main.log.debug( topics )
528 ONOStopics = [ j['topic'] for j in parsedLeaders ]
529 for topic in topics:
530 if topic not in ONOStopics:
531 main.log.error( "Error: " + topic +
532 " not in leaders" )
533 missing = True
534 else:
535 main.log.error( "leaders() returned None" )
536 except ( ValueError, TypeError ):
537 main.log.exception( "Error parsing leaders" )
538 main.log.error( repr( leaders ) )
539 # Check all nodes
540 if missing:
541 response = main.ONOScli1.leaders( jsonFormat=False)
542 main.log.warn( "ONOS1 leaders output: \n" +
543 str( response ) )
544
545 partitions = main.ONOScli1.partitions()
546 try:
547 if partitions :
548 parsedPartitions = json.loads( partitions )
549 main.log.warn( json.dumps( parsedPartitions,
550 sort_keys=True,
551 indent=4,
552 separators=( ',', ': ' ) ) )
553 # TODO check for a leader in all paritions
554 # TODO check for consistency among nodes
555 else:
556 main.log.error( "partitions() returned None" )
557 except ( ValueError, TypeError ):
558 main.log.exception( "Error parsing partitions" )
559 main.log.error( repr( partitions ) )
560 pendingMap = main.ONOScli1.pendingMap()
561 try:
562 if pendingMap :
563 parsedPending = json.loads( pendingMap )
564 main.log.warn( json.dumps( parsedPending,
565 sort_keys=True,
566 indent=4,
567 separators=( ',', ': ' ) ) )
568 # TODO check something here?
569 else:
570 main.log.error( "pendingMap() returned None" )
571 except ( ValueError, TypeError ):
572 main.log.exception( "Error parsing pending map" )
573 main.log.error( repr( pendingMap ) )
574
575 intentAddResult = bool( intentAddResult and not missingIntents and
576 installedCheck )
577 if not intentAddResult:
578 main.log.error( "Error in pushing host intents to ONOS" )
579
580 main.step( "Intent Anti-Entropy dispersion" )
581 for i in range(100):
582 correct = True
583 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700584 for cli in main.CLIs:
Jon Hall85794ff2015-07-08 14:12:30 -0700585 onosIds = []
586 ids = cli.getAllIntentsId()
587 onosIds.append( ids )
588 main.log.debug( "Intents in " + cli.name + ": " +
589 str( sorted( onosIds ) ) )
590 if sorted( ids ) != sorted( intentIds ):
591 main.log.warn( "Set of intent IDs doesn't match" )
592 correct = False
593 break
594 else:
595 intents = json.loads( cli.intents() )
596 for intent in intents:
597 if intent[ 'state' ] != "INSTALLED":
598 main.log.warn( "Intent " + intent[ 'id' ] +
599 " is " + intent[ 'state' ] )
600 correct = False
601 break
602 if correct:
603 break
604 else:
605 time.sleep(1)
606 if not intentStop:
607 intentStop = time.time()
608 global gossipTime
609 gossipTime = intentStop - intentStart
610 main.log.info( "It took about " + str( gossipTime ) +
611 " seconds for all intents to appear in each node" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700612 gossipPeriod = int( main.params['timers']['gossip'] )
613 maxGossipTime = gossipPeriod * len( main.nodes )
Jon Hall85794ff2015-07-08 14:12:30 -0700614 utilities.assert_greater_equals(
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700615 expect=maxGossipTime, actual=gossipTime,
Jon Hall85794ff2015-07-08 14:12:30 -0700616 onpass="ECM anti-entropy for intents worked within " +
617 "expected time",
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700618 onfail="Intent ECM anti-entropy took too long. " +
619 "Expected time:{}, Actual time:{}".format( maxGossipTime,
620 gossipTime ) )
621 if gossipTime <= maxGossipTime:
Jon Hall85794ff2015-07-08 14:12:30 -0700622 intentAddResult = True
623
624 if not intentAddResult or "key" in pendingMap:
625 import time
626 installedCheck = True
627 main.log.info( "Sleeping 60 seconds to see if intents are found" )
628 time.sleep( 60 )
629 onosIds = main.ONOScli1.getAllIntentsId()
630 main.log.info( "Submitted intents: " + str( intentIds ) )
631 main.log.info( "Intents in ONOS: " + str( onosIds ) )
632 # Print the intent states
633 intents = main.ONOScli1.intents()
634 intentStates = []
635 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
636 count = 0
637 try:
638 for intent in json.loads( intents ):
639 # Iter through intents of a node
640 state = intent.get( 'state', None )
641 if "INSTALLED" not in state:
642 installedCheck = False
643 intentId = intent.get( 'id', None )
644 intentStates.append( ( intentId, state ) )
645 except ( ValueError, TypeError ):
646 main.log.exception( "Error parsing intents" )
647 # add submitted intents not in the store
648 tmplist = [ i for i, s in intentStates ]
649 for i in intentIds:
650 if i not in tmplist:
651 intentStates.append( ( i, " - " ) )
652 intentStates.sort()
653 for i, s in intentStates:
654 count += 1
655 main.log.info( "%-6s%-15s%-15s" %
656 ( str( count ), str( i ), str( s ) ) )
657 leaders = main.ONOScli1.leaders()
658 try:
659 missing = False
660 if leaders:
661 parsedLeaders = json.loads( leaders )
662 main.log.warn( json.dumps( parsedLeaders,
663 sort_keys=True,
664 indent=4,
665 separators=( ',', ': ' ) ) )
666 # check for all intent partitions
667 # check for election
668 topics = []
669 for i in range( 14 ):
670 topics.append( "intent-partition-" + str( i ) )
671 # FIXME: this should only be after we start the app
672 topics.append( "org.onosproject.election" )
673 main.log.debug( topics )
674 ONOStopics = [ j['topic'] for j in parsedLeaders ]
675 for topic in topics:
676 if topic not in ONOStopics:
677 main.log.error( "Error: " + topic +
678 " not in leaders" )
679 missing = True
680 else:
681 main.log.error( "leaders() returned None" )
682 except ( ValueError, TypeError ):
683 main.log.exception( "Error parsing leaders" )
684 main.log.error( repr( leaders ) )
685 # Check all nodes
686 if missing:
687 response = main.ONOScli1.leaders( jsonFormat=False)
688 main.log.warn( "ONOS1 leaders output: \n" +
689 str( response ) )
690 partitions = main.ONOScli1.partitions()
691 try:
692 if partitions :
693 parsedPartitions = json.loads( partitions )
694 main.log.warn( json.dumps( parsedPartitions,
695 sort_keys=True,
696 indent=4,
697 separators=( ',', ': ' ) ) )
698 # TODO check for a leader in all paritions
699 # TODO check for consistency among nodes
700 else:
701 main.log.error( "partitions() returned None" )
702 except ( ValueError, TypeError ):
703 main.log.exception( "Error parsing partitions" )
704 main.log.error( repr( partitions ) )
705 pendingMap = main.ONOScli1.pendingMap()
706 try:
707 if pendingMap :
708 parsedPending = json.loads( pendingMap )
709 main.log.warn( json.dumps( parsedPending,
710 sort_keys=True,
711 indent=4,
712 separators=( ',', ': ' ) ) )
713 # TODO check something here?
714 else:
715 main.log.error( "pendingMap() returned None" )
716 except ( ValueError, TypeError ):
717 main.log.exception( "Error parsing pending map" )
718 main.log.error( repr( pendingMap ) )
719
720 def CASE4( self, main ):
721 """
722 Ping across added host intents
723 """
724 import json
725 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700726 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700727 assert main, "main not defined"
728 assert utilities.assert_equals, "utilities.assert_equals not defined"
729 main.case( "Verify connectivity by sendind traffic across Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700730 main.caseExplanation = "Ping across added host intents to check " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700731 "functionality and check the state of " +\
732 "the intent"
733 main.step( "Ping across added host intents" )
734 PingResult = main.TRUE
735 for i in range( 8, 18 ):
736 ping = main.Mininet1.pingHost( src="h" + str( i ),
737 target="h" + str( i + 10 ) )
738 PingResult = PingResult and ping
739 if ping == main.FALSE:
740 main.log.warn( "Ping failed between h" + str( i ) +
741 " and h" + str( i + 10 ) )
742 elif ping == main.TRUE:
743 main.log.info( "Ping test passed!" )
744 # Don't set PingResult or you'd override failures
745 if PingResult == main.FALSE:
746 main.log.error(
747 "Intents have not been installed correctly, pings failed." )
748 # TODO: pretty print
749 main.log.warn( "ONOS1 intents: " )
750 try:
751 tmpIntents = main.ONOScli1.intents()
752 main.log.warn( json.dumps( json.loads( tmpIntents ),
753 sort_keys=True,
754 indent=4,
755 separators=( ',', ': ' ) ) )
756 except ( ValueError, TypeError ):
757 main.log.warn( repr( tmpIntents ) )
758 utilities.assert_equals(
759 expect=main.TRUE,
760 actual=PingResult,
761 onpass="Intents have been installed correctly and pings work",
762 onfail="Intents have not been installed correctly, pings failed." )
763
764 main.step( "Check Intent state" )
765 installedCheck = True
766 # Print the intent states
767 intents = main.ONOScli1.intents()
768 intentStates = []
769 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
770 count = 0
771 # Iter through intents of a node
772 try:
773 for intent in json.loads( intents ):
774 state = intent.get( 'state', None )
775 if "INSTALLED" not in state:
776 installedCheck = False
777 intentId = intent.get( 'id', None )
778 intentStates.append( ( intentId, state ) )
779 except ( ValueError, TypeError ):
780 main.log.exception( "Error parsing intents." )
781 # Print states
782 intentStates.sort()
783 for i, s in intentStates:
784 count += 1
785 main.log.info( "%-6s%-15s%-15s" %
786 ( str( count ), str( i ), str( s ) ) )
787 utilities.assert_equals( expect=True, actual=installedCheck,
788 onpass="Intents are all INSTALLED",
789 onfail="Intents are not all in " +
790 "INSTALLED state" )
791
792 main.step( "Check leadership of topics" )
793 leaders = main.ONOScli1.leaders()
794 topicCheck = main.TRUE
795 try:
796 if leaders:
797 parsedLeaders = json.loads( leaders )
798 main.log.warn( json.dumps( parsedLeaders,
799 sort_keys=True,
800 indent=4,
801 separators=( ',', ': ' ) ) )
802 # check for all intent partitions
803 # check for election
804 # TODO: Look at Devices as topics now that it uses this system
805 topics = []
806 for i in range( 14 ):
807 topics.append( "intent-partition-" + str( i ) )
808 # FIXME: this should only be after we start the app
809 # FIXME: topics.append( "org.onosproject.election" )
810 # Print leaders output
811 main.log.debug( topics )
812 ONOStopics = [ j['topic'] for j in parsedLeaders ]
813 for topic in topics:
814 if topic not in ONOStopics:
815 main.log.error( "Error: " + topic +
816 " not in leaders" )
817 topicCheck = main.FALSE
818 else:
819 main.log.error( "leaders() returned None" )
820 topicCheck = main.FALSE
821 except ( ValueError, TypeError ):
822 topicCheck = main.FALSE
823 main.log.exception( "Error parsing leaders" )
824 main.log.error( repr( leaders ) )
825 # TODO: Check for a leader of these topics
826 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
827 onpass="intent Partitions is in leaders",
828 onfail="Some topics were lost " )
829 # Print partitions
830 partitions = main.ONOScli1.partitions()
831 try:
832 if partitions :
833 parsedPartitions = json.loads( partitions )
834 main.log.warn( json.dumps( parsedPartitions,
835 sort_keys=True,
836 indent=4,
837 separators=( ',', ': ' ) ) )
838 # TODO check for a leader in all paritions
839 # TODO check for consistency among nodes
840 else:
841 main.log.error( "partitions() returned None" )
842 except ( ValueError, TypeError ):
843 main.log.exception( "Error parsing partitions" )
844 main.log.error( repr( partitions ) )
845 # Print Pending Map
846 pendingMap = main.ONOScli1.pendingMap()
847 try:
848 if pendingMap :
849 parsedPending = json.loads( pendingMap )
850 main.log.warn( json.dumps( parsedPending,
851 sort_keys=True,
852 indent=4,
853 separators=( ',', ': ' ) ) )
854 # TODO check something here?
855 else:
856 main.log.error( "pendingMap() returned None" )
857 except ( ValueError, TypeError ):
858 main.log.exception( "Error parsing pending map" )
859 main.log.error( repr( pendingMap ) )
860
861 if not installedCheck:
862 main.log.info( "Waiting 60 seconds to see if the state of " +
863 "intents change" )
864 time.sleep( 60 )
865 # Print the intent states
866 intents = main.ONOScli1.intents()
867 intentStates = []
868 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
869 count = 0
870 # Iter through intents of a node
871 try:
872 for intent in json.loads( intents ):
873 state = intent.get( 'state', None )
874 if "INSTALLED" not in state:
875 installedCheck = False
876 intentId = intent.get( 'id', None )
877 intentStates.append( ( intentId, state ) )
878 except ( ValueError, TypeError ):
879 main.log.exception( "Error parsing intents." )
880 intentStates.sort()
881 for i, s in intentStates:
882 count += 1
883 main.log.info( "%-6s%-15s%-15s" %
884 ( str( count ), str( i ), str( s ) ) )
885 leaders = main.ONOScli1.leaders()
886 try:
887 missing = False
888 if leaders:
889 parsedLeaders = json.loads( leaders )
890 main.log.warn( json.dumps( parsedLeaders,
891 sort_keys=True,
892 indent=4,
893 separators=( ',', ': ' ) ) )
894 # check for all intent partitions
895 # check for election
896 topics = []
897 for i in range( 14 ):
898 topics.append( "intent-partition-" + str( i ) )
899 # FIXME: this should only be after we start the app
900 topics.append( "org.onosproject.election" )
901 main.log.debug( topics )
902 ONOStopics = [ j['topic'] for j in parsedLeaders ]
903 for topic in topics:
904 if topic not in ONOStopics:
905 main.log.error( "Error: " + topic +
906 " not in leaders" )
907 missing = True
908 else:
909 main.log.error( "leaders() returned None" )
910 except ( ValueError, TypeError ):
911 main.log.exception( "Error parsing leaders" )
912 main.log.error( repr( leaders ) )
913 if missing:
914 response = main.ONOScli1.leaders( jsonFormat=False)
915 main.log.warn( "ONOS1 leaders output: \n" +
916 str( response ) )
917 partitions = main.ONOScli1.partitions()
918 try:
919 if partitions :
920 parsedPartitions = json.loads( partitions )
921 main.log.warn( json.dumps( parsedPartitions,
922 sort_keys=True,
923 indent=4,
924 separators=( ',', ': ' ) ) )
925 # TODO check for a leader in all paritions
926 # TODO check for consistency among nodes
927 else:
928 main.log.error( "partitions() returned None" )
929 except ( ValueError, TypeError ):
930 main.log.exception( "Error parsing partitions" )
931 main.log.error( repr( partitions ) )
932 pendingMap = main.ONOScli1.pendingMap()
933 try:
934 if pendingMap :
935 parsedPending = json.loads( pendingMap )
936 main.log.warn( json.dumps( parsedPending,
937 sort_keys=True,
938 indent=4,
939 separators=( ',', ': ' ) ) )
940 # TODO check something here?
941 else:
942 main.log.error( "pendingMap() returned None" )
943 except ( ValueError, TypeError ):
944 main.log.exception( "Error parsing pending map" )
945 main.log.error( repr( pendingMap ) )
946 # Print flowrules
Jon Halle1a3b752015-07-22 13:02:46 -0700947 main.log.debug( main.CLIs[0].flows( jsonFormat=False ) )
Jon Hall85794ff2015-07-08 14:12:30 -0700948 main.step( "Wait a minute then ping again" )
949 # the wait is above
950 PingResult = main.TRUE
951 for i in range( 8, 18 ):
952 ping = main.Mininet1.pingHost( src="h" + str( i ),
953 target="h" + str( i + 10 ) )
954 PingResult = PingResult and ping
955 if ping == main.FALSE:
956 main.log.warn( "Ping failed between h" + str( i ) +
957 " and h" + str( i + 10 ) )
958 elif ping == main.TRUE:
959 main.log.info( "Ping test passed!" )
960 # Don't set PingResult or you'd override failures
961 if PingResult == main.FALSE:
962 main.log.error(
963 "Intents have not been installed correctly, pings failed." )
964 # TODO: pretty print
965 main.log.warn( "ONOS1 intents: " )
966 try:
967 tmpIntents = main.ONOScli1.intents()
968 main.log.warn( json.dumps( json.loads( tmpIntents ),
969 sort_keys=True,
970 indent=4,
971 separators=( ',', ': ' ) ) )
972 except ( ValueError, TypeError ):
973 main.log.warn( repr( tmpIntents ) )
974 utilities.assert_equals(
975 expect=main.TRUE,
976 actual=PingResult,
977 onpass="Intents have been installed correctly and pings work",
978 onfail="Intents have not been installed correctly, pings failed." )
979
980 def CASE5( self, main ):
981 """
982 Reading state of ONOS
983 """
984 import json
Jon Halle1a3b752015-07-22 13:02:46 -0700985 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700986 assert main, "main not defined"
987 assert utilities.assert_equals, "utilities.assert_equals not defined"
988
989 main.case( "Setting up and gathering data for current state" )
990 # The general idea for this test case is to pull the state of
991 # ( intents,flows, topology,... ) from each ONOS node
992 # We can then compare them with each other and also with past states
993
994 main.step( "Check that each switch has a master" )
995 global mastershipState
996 mastershipState = '[]'
997
998 # Assert that each device has a master
999 rolesNotNull = main.ONOScli1.rolesNotNull()
1000 utilities.assert_equals(
1001 expect=main.TRUE,
1002 actual=rolesNotNull,
1003 onpass="Each device has a master",
1004 onfail="Some devices don't have a master assigned" )
1005
1006 main.step( "Get the Mastership of each switch" )
1007 ONOS1Mastership = main.ONOScli1.roles()
1008 # TODO: Make this a meaningful check
1009 if "Error" in ONOS1Mastership or not ONOS1Mastership:
1010 main.log.error( "Error in getting ONOS roles" )
1011 main.log.warn(
1012 "ONOS1 mastership response: " +
1013 repr( ONOS1Mastership ) )
1014 consistentMastership = main.FALSE
1015 else:
1016 mastershipState = ONOS1Mastership
1017 consistentMastership = main.TRUE
1018
1019 main.step( "Get the intents from each controller" )
1020 global intentState
1021 intentState = []
1022 ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
1023 intentCheck = main.FALSE
1024 if "Error" in ONOS1Intents or not ONOS1Intents:
1025 main.log.error( "Error in getting ONOS intents" )
1026 main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
1027 else:
1028 intentCheck = main.TRUE
1029
1030 main.step( "Get the flows from each controller" )
1031 global flowState
1032 flowState = []
1033 flowCheck = main.FALSE
1034 ONOS1Flows = main.ONOScli1.flows( jsonFormat=True )
1035 if "Error" in ONOS1Flows or not ONOS1Flows:
1036 main.log.error( "Error in getting ONOS flows" )
1037 main.log.warn( "ONOS1 flows repsponse: " + ONOS1Flows )
1038 else:
1039 # TODO: Do a better check, maybe compare flows on switches?
1040 flowState = ONOS1Flows
1041 flowCheck = main.TRUE
1042
1043 main.step( "Get the OF Table entries" )
1044 global flows
1045 flows = []
1046 for i in range( 1, 29 ):
GlennRC68467eb2015-11-16 18:01:01 -08001047 flows.append( main.Mininet1.getFlowTable( "s" + str( i ), version="1.3", debug=False ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001048 if flowCheck == main.FALSE:
1049 for table in flows:
1050 main.log.warn( table )
1051 # TODO: Compare switch flow tables with ONOS flow tables
1052
1053 main.step( "Collecting topology information from ONOS" )
1054 devices = []
1055 devices.append( main.ONOScli1.devices() )
1056 hosts = []
1057 hosts.append( json.loads( main.ONOScli1.hosts() ) )
1058 ports = []
1059 ports.append( main.ONOScli1.ports() )
1060 links = []
1061 links.append( main.ONOScli1.links() )
1062 clusters = []
1063 clusters.append( main.ONOScli1.clusters() )
1064
1065 main.step( "Each host has an IP address" )
1066 ipResult = main.TRUE
1067 for controller in range( 0, len( hosts ) ):
1068 controllerStr = str( controller + 1 )
1069 for host in hosts[ controller ]:
1070 if host is None or host.get( 'ipAddresses', [] ) == []:
1071 main.log.error(
1072 "DEBUG:Error with host ips on controller" +
1073 controllerStr + ": " + str( host ) )
1074 ipResult = main.FALSE
1075 utilities.assert_equals(
1076 expect=main.TRUE,
1077 actual=ipResult,
1078 onpass="The ips of the hosts aren't empty",
1079 onfail="The ip of at least one host is missing" )
1080
1081 # there should always only be one cluster
1082 main.step( "There is only one dataplane cluster" )
1083 try:
1084 numClusters = len( json.loads( clusters[ 0 ] ) )
1085 except ( ValueError, TypeError ):
1086 main.log.exception( "Error parsing clusters[0]: " +
1087 repr( clusters[ 0 ] ) )
1088 clusterResults = main.FALSE
1089 if numClusters == 1:
1090 clusterResults = main.TRUE
1091 utilities.assert_equals(
1092 expect=1,
1093 actual=numClusters,
1094 onpass="ONOS shows 1 SCC",
1095 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1096
1097 main.step( "Comparing ONOS topology to MN" )
1098 devicesResults = main.TRUE
1099 linksResults = main.TRUE
1100 hostsResults = main.TRUE
1101 mnSwitches = main.Mininet1.getSwitches()
1102 mnLinks = main.Mininet1.getLinks()
1103 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07001104 for controller in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07001105 controllerStr = str( controller + 1 )
1106 if devices[ controller ] and ports[ controller ] and\
1107 "Error" not in devices[ controller ] and\
1108 "Error" not in ports[ controller ]:
1109
1110 currentDevicesResult = main.Mininet1.compareSwitches(
1111 mnSwitches,
1112 json.loads( devices[ controller ] ),
1113 json.loads( ports[ controller ] ) )
1114 else:
1115 currentDevicesResult = main.FALSE
1116 utilities.assert_equals( expect=main.TRUE,
1117 actual=currentDevicesResult,
1118 onpass="ONOS" + controllerStr +
1119 " Switches view is correct",
1120 onfail="ONOS" + controllerStr +
1121 " Switches view is incorrect" )
1122 if links[ controller ] and "Error" not in links[ controller ]:
1123 currentLinksResult = main.Mininet1.compareLinks(
1124 mnSwitches, mnLinks,
1125 json.loads( links[ controller ] ) )
1126 else:
1127 currentLinksResult = main.FALSE
1128 utilities.assert_equals( expect=main.TRUE,
1129 actual=currentLinksResult,
1130 onpass="ONOS" + controllerStr +
1131 " links view is correct",
1132 onfail="ONOS" + controllerStr +
1133 " links view is incorrect" )
1134
1135 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1136 currentHostsResult = main.Mininet1.compareHosts(
1137 mnHosts,
1138 hosts[ controller ] )
1139 else:
1140 currentHostsResult = main.FALSE
1141 utilities.assert_equals( expect=main.TRUE,
1142 actual=currentHostsResult,
1143 onpass="ONOS" + controllerStr +
1144 " hosts exist in Mininet",
1145 onfail="ONOS" + controllerStr +
1146 " hosts don't match Mininet" )
1147
1148 devicesResults = devicesResults and currentDevicesResult
1149 linksResults = linksResults and currentLinksResult
1150 hostsResults = hostsResults and currentHostsResult
1151
1152 main.step( "Device information is correct" )
1153 utilities.assert_equals(
1154 expect=main.TRUE,
1155 actual=devicesResults,
1156 onpass="Device information is correct",
1157 onfail="Device information is incorrect" )
1158
1159 main.step( "Links are correct" )
1160 utilities.assert_equals(
1161 expect=main.TRUE,
1162 actual=linksResults,
1163 onpass="Link are correct",
1164 onfail="Links are incorrect" )
1165
1166 main.step( "Hosts are correct" )
1167 utilities.assert_equals(
1168 expect=main.TRUE,
1169 actual=hostsResults,
1170 onpass="Hosts are correct",
1171 onfail="Hosts are incorrect" )
1172
1173 def CASE6( self, main ):
1174 """
1175 The Failure case.
1176 """
1177 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001178 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001179 assert main, "main not defined"
1180 assert utilities.assert_equals, "utilities.assert_equals not defined"
1181
1182 # Reset non-persistent variables
1183 try:
1184 iCounterValue = 0
1185 except NameError:
1186 main.log.error( "iCounterValue not defined, setting to 0" )
1187 iCounterValue = 0
1188
1189 main.case( "Restart ONOS node" )
Jon Hall783bbf92015-07-23 14:33:19 -07001190 main.caseExplanation = "Killing ONOS process and restart cli " +\
Jon Hall85794ff2015-07-08 14:12:30 -07001191 "sessions once onos is up."
Jon Hall96091e62015-09-21 17:34:17 -07001192
1193 main.step( "Checking ONOS Logs for errors" )
1194 for node in main.nodes:
1195 main.log.debug( "Checking logs for errors on " + node.name + ":" )
1196 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
1197
Jon Hall85794ff2015-07-08 14:12:30 -07001198 main.step( "Killing ONOS processes" )
Jon Halle1a3b752015-07-22 13:02:46 -07001199 killResult = main.ONOSbench.onosKill( main.nodes[0].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -07001200 start = time.time()
1201 utilities.assert_equals( expect=main.TRUE, actual=killResult,
1202 onpass="ONOS Killed",
1203 onfail="Error killing ONOS" )
1204
1205 main.step( "Checking if ONOS is up yet" )
1206 count = 0
1207 while count < 10:
Jon Halle1a3b752015-07-22 13:02:46 -07001208 onos1Isup = main.ONOSbench.isup( main.nodes[0].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -07001209 if onos1Isup == main.TRUE:
1210 elapsed = time.time() - start
1211 break
1212 else:
1213 count = count + 1
1214 utilities.assert_equals( expect=main.TRUE, actual=onos1Isup,
1215 onpass="ONOS is back up",
1216 onfail="ONOS failed to start" )
1217
1218 main.log.step( "Starting ONOS CLI sessions" )
Jon Halle1a3b752015-07-22 13:02:46 -07001219 cliResults = main.ONOScli1.startOnosCli( main.nodes[0].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -07001220 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1221 onpass="ONOS cli startup successful",
1222 onfail="ONOS cli startup failed" )
1223
1224 if elapsed:
1225 main.log.info( "ESTIMATE: ONOS took %s seconds to restart" %
1226 str( elapsed ) )
1227 main.restartTime = elapsed
1228 else:
1229 main.restartTime = -1
1230 time.sleep( 5 )
1231 # rerun on election apps
1232 main.ONOScli1.electionTestRun()
1233
1234 def CASE7( self, main ):
1235 """
1236 Check state after ONOS failure
1237 """
1238 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001239 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001240 assert main, "main not defined"
1241 assert utilities.assert_equals, "utilities.assert_equals not defined"
1242 main.case( "Running ONOS Constant State Tests" )
1243 main.step( "Check that each switch has a master" )
1244 # Assert that each device has a master
1245 rolesNotNull = main.ONOScli1.rolesNotNull()
1246 utilities.assert_equals(
1247 expect=main.TRUE,
1248 actual=rolesNotNull,
1249 onpass="Each device has a master",
1250 onfail="Some devices don't have a master assigned" )
1251
1252 main.step( "Check if switch roles are consistent across all nodes" )
1253 ONOS1Mastership = main.ONOScli1.roles()
1254 # FIXME: Refactor this whole case for single instance
1255 if "Error" in ONOS1Mastership or not ONOS1Mastership:
1256 main.log.error( "Error in getting ONOS mastership" )
1257 main.log.warn( "ONOS1 mastership response: " +
1258 repr( ONOS1Mastership ) )
1259 consistentMastership = main.FALSE
1260 else:
1261 consistentMastership = main.TRUE
1262 utilities.assert_equals(
1263 expect=main.TRUE,
1264 actual=consistentMastership,
1265 onpass="Switch roles are consistent across all ONOS nodes",
1266 onfail="ONOS nodes have different views of switch roles" )
1267
1268 description2 = "Compare switch roles from before failure"
1269 main.step( description2 )
1270
1271 currentJson = json.loads( ONOS1Mastership )
1272 oldJson = json.loads( mastershipState )
1273 mastershipCheck = main.TRUE
1274 for i in range( 1, 29 ):
1275 switchDPID = str(
1276 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
1277
1278 current = [ switch[ 'master' ] for switch in currentJson
1279 if switchDPID in switch[ 'id' ] ]
1280 old = [ switch[ 'master' ] for switch in oldJson
1281 if switchDPID in switch[ 'id' ] ]
1282 if current == old:
1283 mastershipCheck = mastershipCheck and main.TRUE
1284 else:
1285 main.log.warn( "Mastership of switch %s changed" % switchDPID )
1286 mastershipCheck = main.FALSE
1287 utilities.assert_equals(
1288 expect=main.TRUE,
1289 actual=mastershipCheck,
1290 onpass="Mastership of Switches was not changed",
1291 onfail="Mastership of some switches changed" )
1292 mastershipCheck = mastershipCheck and consistentMastership
1293
1294 main.step( "Get the intents and compare across all nodes" )
1295 ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
1296 intentCheck = main.FALSE
1297 if "Error" in ONOS1Intents or not ONOS1Intents:
1298 main.log.error( "Error in getting ONOS intents" )
1299 main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
1300 else:
1301 intentCheck = main.TRUE
1302 utilities.assert_equals(
1303 expect=main.TRUE,
1304 actual=intentCheck,
1305 onpass="Intents are consistent across all ONOS nodes",
1306 onfail="ONOS nodes have different views of intents" )
1307 # Print the intent states
1308 intents = []
1309 intents.append( ONOS1Intents )
1310 intentStates = []
1311 for node in intents: # Iter through ONOS nodes
1312 nodeStates = []
1313 # Iter through intents of a node
1314 for intent in json.loads( node ):
1315 nodeStates.append( intent[ 'state' ] )
1316 intentStates.append( nodeStates )
1317 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1318 main.log.info( dict( out ) )
1319
1320 # NOTE: Store has no durability, so intents are lost across system
1321 # restarts
1322 """
1323 main.step( "Compare current intents with intents before the failure" )
1324 # NOTE: this requires case 5 to pass for intentState to be set.
1325 # maybe we should stop the test if that fails?
1326 sameIntents = main.FALSE
1327 if intentState and intentState == ONOSIntents[ 0 ]:
1328 sameIntents = main.TRUE
1329 main.log.info( "Intents are consistent with before failure" )
1330 # TODO: possibly the states have changed? we may need to figure out
1331 # what the acceptable states are
1332 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
1333 sameIntents = main.TRUE
1334 try:
1335 before = json.loads( intentState )
1336 after = json.loads( ONOSIntents[ 0 ] )
1337 for intent in before:
1338 if intent not in after:
1339 sameIntents = main.FALSE
1340 main.log.debug( "Intent is not currently in ONOS " +
1341 "(at least in the same form):" )
1342 main.log.debug( json.dumps( intent ) )
1343 except ( ValueError, TypeError ):
1344 main.log.exception( "Exception printing intents" )
1345 main.log.debug( repr( ONOSIntents[0] ) )
1346 main.log.debug( repr( intentState ) )
1347 if sameIntents == main.FALSE:
1348 try:
1349 main.log.debug( "ONOS intents before: " )
1350 main.log.debug( json.dumps( json.loads( intentState ),
1351 sort_keys=True, indent=4,
1352 separators=( ',', ': ' ) ) )
1353 main.log.debug( "Current ONOS intents: " )
1354 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1355 sort_keys=True, indent=4,
1356 separators=( ',', ': ' ) ) )
1357 except ( ValueError, TypeError ):
1358 main.log.exception( "Exception printing intents" )
1359 main.log.debug( repr( ONOSIntents[0] ) )
1360 main.log.debug( repr( intentState ) )
1361 utilities.assert_equals(
1362 expect=main.TRUE,
1363 actual=sameIntents,
1364 onpass="Intents are consistent with before failure",
1365 onfail="The Intents changed during failure" )
1366 intentCheck = intentCheck and sameIntents
1367 """
1368 main.step( "Get the OF Table entries and compare to before " +
1369 "component failure" )
1370 FlowTables = main.TRUE
Jon Hall85794ff2015-07-08 14:12:30 -07001371 for i in range( 28 ):
1372 main.log.info( "Checking flow table on s" + str( i + 1 ) )
GlennRC68467eb2015-11-16 18:01:01 -08001373 tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
1374 FlowTables = FlowTables and main.Mininet1.flowTableComp( flows[i], tmpFlows )
Jon Hall85794ff2015-07-08 14:12:30 -07001375 if FlowTables == main.FALSE:
GlennRC68467eb2015-11-16 18:01:01 -08001376 main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
1377
Jon Hall85794ff2015-07-08 14:12:30 -07001378 utilities.assert_equals(
1379 expect=main.TRUE,
1380 actual=FlowTables,
1381 onpass="No changes were found in the flow tables",
1382 onfail="Changes were found in the flow tables" )
1383
1384 main.step( "Leadership Election is still functional" )
1385 # Test of LeadershipElection
1386
Jon Halle1a3b752015-07-22 13:02:46 -07001387 leader = main.nodes[0].ip_address
Jon Hall85794ff2015-07-08 14:12:30 -07001388 leaderResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001389 for controller in range( 1, main.numCtrls + 1 ):
Jon Hall85794ff2015-07-08 14:12:30 -07001390 # loop through ONOScli handlers
1391 node = getattr( main, ( 'ONOScli' + str( controller ) ) )
1392 leaderN = node.electionTestLeader()
1393 # verify leader is ONOS1
1394 # NOTE even though we restarted ONOS, it is the only one so onos 1
1395 # must be leader
1396 if leaderN == leader:
1397 # all is well
1398 pass
1399 elif leaderN == main.FALSE:
1400 # error in response
1401 main.log.error( "Something is wrong with " +
1402 "electionTestLeader function, check the" +
1403 " error logs" )
1404 leaderResult = main.FALSE
1405 elif leader != leaderN:
1406 leaderResult = main.FALSE
1407 main.log.error( "ONOS" + str( controller ) + " sees " +
1408 str( leaderN ) +
1409 " as the leader of the election app. " +
1410 "Leader should be " + str( leader ) )
1411 utilities.assert_equals(
1412 expect=main.TRUE,
1413 actual=leaderResult,
1414 onpass="Leadership election passed",
1415 onfail="Something went wrong with Leadership election" )
1416
1417 def CASE8( self, main ):
1418 """
1419 Compare topo
1420 """
1421 import json
1422 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001423 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001424 assert main, "main not defined"
1425 assert utilities.assert_equals, "utilities.assert_equals not defined"
1426
1427 main.case( "Compare ONOS Topology view to Mininet topology" )
Jon Hall783bbf92015-07-23 14:33:19 -07001428 main.caseExplanation = "Compare topology objects between Mininet" +\
Jon Hall85794ff2015-07-08 14:12:30 -07001429 " and ONOS"
Jon Hall85794ff2015-07-08 14:12:30 -07001430 topoResult = main.FALSE
1431 elapsed = 0
1432 count = 0
Jon Halle9b1fa32015-12-08 15:32:21 -08001433 main.step( "Comparing ONOS topology to MN topology" )
Jon Hall85794ff2015-07-08 14:12:30 -07001434 startTime = time.time()
1435 # Give time for Gossip to work
Jon Halle9b1fa32015-12-08 15:32:21 -08001436 while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
Jon Hall96091e62015-09-21 17:34:17 -07001437 devicesResults = main.TRUE
1438 linksResults = main.TRUE
1439 hostsResults = main.TRUE
1440 hostAttachmentResults = True
Jon Hall85794ff2015-07-08 14:12:30 -07001441 count += 1
1442 cliStart = time.time()
1443 devices = []
1444 devices.append( main.ONOScli1.devices() )
1445 hosts = []
1446 hosts.append( json.loads( main.ONOScli1.hosts() ) )
1447 ipResult = main.TRUE
1448 for controller in range( 0, len( hosts ) ):
1449 controllerStr = str( controller + 1 )
1450 for host in hosts[ controller ]:
1451 if host is None or host.get( 'ipAddresses', [] ) == []:
1452 main.log.error(
1453 "DEBUG:Error with host ips on controller" +
1454 controllerStr + ": " + str( host ) )
1455 ipResult = main.FALSE
1456 ports = []
1457 ports.append( main.ONOScli1.ports() )
1458 links = []
1459 links.append( main.ONOScli1.links() )
1460 clusters = []
1461 clusters.append( main.ONOScli1.clusters() )
1462
1463 elapsed = time.time() - startTime
1464 cliTime = time.time() - cliStart
1465 print "CLI time: " + str( cliTime )
1466
1467 mnSwitches = main.Mininet1.getSwitches()
1468 mnLinks = main.Mininet1.getLinks()
1469 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07001470 for controller in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07001471 controllerStr = str( controller + 1 )
1472 if devices[ controller ] and ports[ controller ] and\
1473 "Error" not in devices[ controller ] and\
1474 "Error" not in ports[ controller ]:
1475
1476 currentDevicesResult = main.Mininet1.compareSwitches(
1477 mnSwitches,
1478 json.loads( devices[ controller ] ),
1479 json.loads( ports[ controller ] ) )
1480 else:
1481 currentDevicesResult = main.FALSE
1482 utilities.assert_equals( expect=main.TRUE,
1483 actual=currentDevicesResult,
1484 onpass="ONOS" + controllerStr +
1485 " Switches view is correct",
1486 onfail="ONOS" + controllerStr +
1487 " Switches view is incorrect" )
1488
1489 if links[ controller ] and "Error" not in links[ controller ]:
1490 currentLinksResult = main.Mininet1.compareLinks(
1491 mnSwitches, mnLinks,
1492 json.loads( links[ controller ] ) )
1493 else:
1494 currentLinksResult = main.FALSE
1495 utilities.assert_equals( expect=main.TRUE,
1496 actual=currentLinksResult,
1497 onpass="ONOS" + controllerStr +
1498 " links view is correct",
1499 onfail="ONOS" + controllerStr +
1500 " links view is incorrect" )
1501
1502 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1503 currentHostsResult = main.Mininet1.compareHosts(
1504 mnHosts,
1505 hosts[ controller ] )
1506 else:
1507 currentHostsResult = main.FALSE
1508 utilities.assert_equals( expect=main.TRUE,
1509 actual=currentHostsResult,
1510 onpass="ONOS" + controllerStr +
1511 " hosts exist in Mininet",
1512 onfail="ONOS" + controllerStr +
1513 " hosts don't match Mininet" )
1514 # CHECKING HOST ATTACHMENT POINTS
1515 hostAttachment = True
1516 zeroHosts = False
1517 # FIXME: topo-HA/obelisk specific mappings:
1518 # key is mac and value is dpid
1519 mappings = {}
1520 for i in range( 1, 29 ): # hosts 1 through 28
1521 # set up correct variables:
1522 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
1523 if i == 1:
1524 deviceId = "1000".zfill(16)
1525 elif i == 2:
1526 deviceId = "2000".zfill(16)
1527 elif i == 3:
1528 deviceId = "3000".zfill(16)
1529 elif i == 4:
1530 deviceId = "3004".zfill(16)
1531 elif i == 5:
1532 deviceId = "5000".zfill(16)
1533 elif i == 6:
1534 deviceId = "6000".zfill(16)
1535 elif i == 7:
1536 deviceId = "6007".zfill(16)
1537 elif i >= 8 and i <= 17:
1538 dpid = '3' + str( i ).zfill( 3 )
1539 deviceId = dpid.zfill(16)
1540 elif i >= 18 and i <= 27:
1541 dpid = '6' + str( i ).zfill( 3 )
1542 deviceId = dpid.zfill(16)
1543 elif i == 28:
1544 deviceId = "2800".zfill(16)
1545 mappings[ macId ] = deviceId
1546 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1547 if hosts[ controller ] == []:
1548 main.log.warn( "There are no hosts discovered" )
1549 zeroHosts = True
1550 else:
1551 for host in hosts[ controller ]:
1552 mac = None
1553 location = None
1554 device = None
1555 port = None
1556 try:
1557 mac = host.get( 'mac' )
1558 assert mac, "mac field could not be found for this host object"
1559
1560 location = host.get( 'location' )
1561 assert location, "location field could not be found for this host object"
1562
1563 # Trim the protocol identifier off deviceId
1564 device = str( location.get( 'elementId' ) ).split(':')[1]
1565 assert device, "elementId field could not be found for this host location object"
1566
1567 port = location.get( 'port' )
1568 assert port, "port field could not be found for this host location object"
1569
1570 # Now check if this matches where they should be
1571 if mac and device and port:
1572 if str( port ) != "1":
1573 main.log.error( "The attachment port is incorrect for " +
1574 "host " + str( mac ) +
1575 ". Expected: 1 Actual: " + str( port) )
1576 hostAttachment = False
1577 if device != mappings[ str( mac ) ]:
1578 main.log.error( "The attachment device is incorrect for " +
1579 "host " + str( mac ) +
1580 ". Expected: " + mappings[ str( mac ) ] +
1581 " Actual: " + device )
1582 hostAttachment = False
1583 else:
1584 hostAttachment = False
1585 except AssertionError:
1586 main.log.exception( "Json object not as expected" )
1587 main.log.error( repr( host ) )
1588 hostAttachment = False
1589 else:
1590 main.log.error( "No hosts json output or \"Error\"" +
1591 " in output. hosts = " +
1592 repr( hosts[ controller ] ) )
1593 if zeroHosts is False:
1594 hostAttachment = True
1595
Jon Hall85794ff2015-07-08 14:12:30 -07001596 devicesResults = devicesResults and currentDevicesResult
1597 linksResults = linksResults and currentLinksResult
1598 hostsResults = hostsResults and currentHostsResult
1599 hostAttachmentResults = hostAttachmentResults and\
1600 hostAttachment
1601
1602 # "consistent" results don't make sense for single instance
1603 # there should always only be one cluster
1604 numClusters = len( json.loads( clusters[ 0 ] ) )
1605 clusterResults = main.FALSE
1606 if numClusters == 1:
1607 clusterResults = main.TRUE
1608 utilities.assert_equals(
1609 expect=1,
1610 actual=numClusters,
1611 onpass="ONOS shows 1 SCC",
1612 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1613
1614 topoResult = ( devicesResults and linksResults
1615 and hostsResults and ipResult and clusterResults and
1616 hostAttachmentResults )
1617
1618 topoResult = topoResult and int( count <= 2 )
1619 note = "note it takes about " + str( int( cliTime ) ) + \
1620 " seconds for the test to make all the cli calls to fetch " +\
1621 "the topology from each ONOS instance"
1622 main.log.info(
1623 "Very crass estimate for topology discovery/convergence( " +
1624 str( note ) + " ): " + str( elapsed ) + " seconds, " +
1625 str( count ) + " tries" )
1626 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
1627 onpass="Topology Check Test successful",
1628 onfail="Topology Check Test NOT successful" )
1629
1630 def CASE9( self, main ):
1631 """
1632 Link s3-s28 down
1633 """
1634 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001635 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001636 assert main, "main not defined"
1637 assert utilities.assert_equals, "utilities.assert_equals not defined"
1638 # NOTE: You should probably run a topology check after this
1639
1640 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
1641
1642 description = "Turn off a link to ensure that Link Discovery " +\
1643 "is working properly"
1644 main.case( description )
1645
1646 main.step( "Kill Link between s3 and s28" )
1647 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
1648 main.log.info( "Waiting " + str( linkSleep ) +
1649 " seconds for link down to be discovered" )
1650 time.sleep( linkSleep )
1651 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
1652 onpass="Link down successful",
1653 onfail="Failed to bring link down" )
1654 # TODO do some sort of check here
1655
1656 def CASE10( self, main ):
1657 """
1658 Link s3-s28 up
1659 """
1660 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001661 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001662 assert main, "main not defined"
1663 assert utilities.assert_equals, "utilities.assert_equals not defined"
1664 # NOTE: You should probably run a topology check after this
1665
1666 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
1667
1668 description = "Restore a link to ensure that Link Discovery is " + \
1669 "working properly"
1670 main.case( description )
1671
1672 main.step( "Bring link between s3 and s28 back up" )
1673 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
1674 main.log.info( "Waiting " + str( linkSleep ) +
1675 " seconds for link up to be discovered" )
1676 time.sleep( linkSleep )
1677 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
1678 onpass="Link up successful",
1679 onfail="Failed to bring link up" )
1680 # TODO do some sort of check here
1681
1682 def CASE11( self, main ):
1683 """
1684 Switch Down
1685 """
1686 # NOTE: You should probably run a topology check after this
1687 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001688 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001689 assert main, "main not defined"
1690 assert utilities.assert_equals, "utilities.assert_equals not defined"
1691
1692 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
1693
1694 description = "Killing a switch to ensure it is discovered correctly"
1695 main.case( description )
1696 switch = main.params[ 'kill' ][ 'switch' ]
1697 switchDPID = main.params[ 'kill' ][ 'dpid' ]
1698
1699 # TODO: Make this switch parameterizable
1700 main.step( "Kill " + switch )
1701 main.log.info( "Deleting " + switch )
1702 main.Mininet1.delSwitch( switch )
1703 main.log.info( "Waiting " + str( switchSleep ) +
1704 " seconds for switch down to be discovered" )
1705 time.sleep( switchSleep )
1706 device = main.ONOScli1.getDevice( dpid=switchDPID )
1707 # Peek at the deleted switch
1708 main.log.warn( str( device ) )
1709 result = main.FALSE
1710 if device and device[ 'available' ] is False:
1711 result = main.TRUE
1712 utilities.assert_equals( expect=main.TRUE, actual=result,
1713 onpass="Kill switch successful",
1714 onfail="Failed to kill switch?" )
1715
1716 def CASE12( self, main ):
1717 """
1718 Switch Up
1719 """
1720 # NOTE: You should probably run a topology check after this
1721 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001722 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001723 assert main, "main not defined"
1724 assert utilities.assert_equals, "utilities.assert_equals not defined"
1725
1726 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
1727 switch = main.params[ 'kill' ][ 'switch' ]
1728 switchDPID = main.params[ 'kill' ][ 'dpid' ]
1729 links = main.params[ 'kill' ][ 'links' ].split()
1730 description = "Adding a switch to ensure it is discovered correctly"
1731 main.case( description )
1732
1733 main.step( "Add back " + switch )
1734 main.Mininet1.addSwitch( switch, dpid=switchDPID )
1735 for peer in links:
1736 main.Mininet1.addLink( switch, peer )
1737 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -07001738 for i in range( main.numCtrls ):
1739 ipList.append( main.nodes[ i ].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -07001740 main.Mininet1.assignSwController( sw=switch, ip=ipList )
1741 main.log.info( "Waiting " + str( switchSleep ) +
1742 " seconds for switch up to be discovered" )
1743 time.sleep( switchSleep )
1744 device = main.ONOScli1.getDevice( dpid=switchDPID )
1745 # Peek at the deleted switch
1746 main.log.warn( str( device ) )
1747 result = main.FALSE
1748 if device and device[ 'available' ]:
1749 result = main.TRUE
1750 utilities.assert_equals( expect=main.TRUE, actual=result,
1751 onpass="add switch successful",
1752 onfail="Failed to add switch?" )
1753
1754 def CASE13( self, main ):
1755 """
1756 Clean up
1757 """
1758 import os
1759 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001760 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001761 assert main, "main not defined"
1762 assert utilities.assert_equals, "utilities.assert_equals not defined"
1763 # printing colors to terminal
1764 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
1765 'blue': '\033[94m', 'green': '\033[92m',
1766 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
1767 main.case( "Test Cleanup" )
1768 main.step( "Killing tcpdumps" )
1769 main.Mininet2.stopTcpdump()
1770
1771 testname = main.TEST
Jon Hall96091e62015-09-21 17:34:17 -07001772 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall85794ff2015-07-08 14:12:30 -07001773 main.step( "Copying MN pcap and ONOS log files to test station" )
1774 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
1775 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
Jon Hall96091e62015-09-21 17:34:17 -07001776 # NOTE: MN Pcap file is being saved to logdir.
1777 # We scp this file as MN and TestON aren't necessarily the same vm
1778
1779 # FIXME: To be replaced with a Jenkin's post script
Jon Hall85794ff2015-07-08 14:12:30 -07001780 # TODO: Load these from params
1781 # NOTE: must end in /
1782 logFolder = "/opt/onos/log/"
1783 logFiles = [ "karaf.log", "karaf.log.1" ]
1784 # NOTE: must end in /
Jon Hall85794ff2015-07-08 14:12:30 -07001785 for f in logFiles:
Jon Hall96091e62015-09-21 17:34:17 -07001786 for node in main.nodes:
1787 dstName = main.logdir + "/" + node.name + "-" + f
1788 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
1789 logFolder + f, dstName )
Jon Hall85794ff2015-07-08 14:12:30 -07001790 # std*.log's
1791 # NOTE: must end in /
1792 logFolder = "/opt/onos/var/"
1793 logFiles = [ "stderr.log", "stdout.log" ]
1794 # NOTE: must end in /
Jon Hall85794ff2015-07-08 14:12:30 -07001795 for f in logFiles:
Jon Hall96091e62015-09-21 17:34:17 -07001796 for node in main.nodes:
1797 dstName = main.logdir + "/" + node.name + "-" + f
1798 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
1799 logFolder + f, dstName )
1800 else:
1801 main.log.debug( "skipping saving log files" )
Jon Hall85794ff2015-07-08 14:12:30 -07001802
Jon Hall85794ff2015-07-08 14:12:30 -07001803 main.step( "Stopping Mininet" )
1804 mnResult = main.Mininet1.stopNet()
1805 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
1806 onpass="Mininet stopped",
1807 onfail="MN cleanup NOT successful" )
1808
1809 main.step( "Checking ONOS Logs for errors" )
Jon Hall96091e62015-09-21 17:34:17 -07001810 for node in main.nodes:
1811 main.log.debug( "Checking logs for errors on " + node.name + ":" )
1812 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001813
1814 try:
1815 timerLog = open( main.logdir + "/Timers.csv", 'w')
1816 # Overwrite with empty line and close
1817 labels = "Gossip Intents, Restart"
1818 data = str( gossipTime ) + ", " + str( main.restartTime )
1819 timerLog.write( labels + "\n" + data )
1820 timerLog.close()
1821 except NameError, e:
1822 main.log.exception(e)
1823
1824 def CASE14( self, main ):
1825 """
1826 start election app on all onos nodes
1827 """
Jon Halle1a3b752015-07-22 13:02:46 -07001828 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001829 assert main, "main not defined"
1830 assert utilities.assert_equals, "utilities.assert_equals not defined"
1831
1832 main.case("Start Leadership Election app")
1833 main.step( "Install leadership election app" )
1834 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
1835 utilities.assert_equals(
1836 expect=main.TRUE,
1837 actual=appResult,
1838 onpass="Election app installed",
1839 onfail="Something went wrong with installing Leadership election" )
1840
1841 main.step( "Run for election on each node" )
1842 leaderResult = main.ONOScli1.electionTestRun()
1843 # check for leader
1844 leader = main.ONOScli1.electionTestLeader()
1845 # verify leader is ONOS1
Jon Halle1a3b752015-07-22 13:02:46 -07001846 if leader == main.nodes[0].ip_address:
Jon Hall85794ff2015-07-08 14:12:30 -07001847 # all is well
1848 pass
1849 elif leader is None:
1850 # No leader elected
1851 main.log.error( "No leader was elected" )
1852 leaderResult = main.FALSE
1853 elif leader == main.FALSE:
1854 # error in response
1855 # TODO: add check for "Command not found:" in the driver, this
1856 # means the app isn't loaded
1857 main.log.error( "Something is wrong with electionTestLeader" +
1858 " function, check the error logs" )
1859 leaderResult = main.FALSE
1860 else:
1861 # error in response
1862 main.log.error(
1863 "Unexpected response from electionTestLeader function:'" +
1864 str( leader ) +
1865 "'" )
1866 leaderResult = main.FALSE
1867 utilities.assert_equals(
1868 expect=main.TRUE,
1869 actual=leaderResult,
1870 onpass="Successfully ran for leadership",
1871 onfail="Failed to run for leadership" )
1872
1873 def CASE15( self, main ):
1874 """
1875 Check that Leadership Election is still functional
acsmars71adceb2015-08-31 15:09:26 -07001876 15.1 Run election on each node
1877 15.2 Check that each node has the same leaders and candidates
1878 15.3 Find current leader and withdraw
1879 15.4 Check that a new node was elected leader
1880 15.5 Check that that new leader was the candidate of old leader
1881 15.6 Run for election on old leader
1882 15.7 Check that oldLeader is a candidate, and leader if only 1 node
1883 15.8 Make sure that the old leader was added to the candidate list
1884
1885 old and new variable prefixes refer to data from before vs after
1886 withdrawl and later before withdrawl vs after re-election
Jon Hall85794ff2015-07-08 14:12:30 -07001887 """
acsmars71adceb2015-08-31 15:09:26 -07001888 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001889 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001890 assert main, "main not defined"
1891 assert utilities.assert_equals, "utilities.assert_equals not defined"
acsmars71adceb2015-08-31 15:09:26 -07001892 assert main.CLIs, "main.CLIs not defined"
1893 assert main.nodes, "main.nodes not defined"
1894
Jon Hall85794ff2015-07-08 14:12:30 -07001895 description = "Check that Leadership Election is still functional"
1896 main.case( description )
acsmars71adceb2015-08-31 15:09:26 -07001897 # NOTE: Need to re-run since being a canidate is not persistant
1898 # TODO: add check for "Command not found:" in the driver, this
1899 # means the election test app isn't loaded
acsmars2c2fcdd2015-08-25 17:14:13 -07001900
acsmars71adceb2015-08-31 15:09:26 -07001901 oldLeaders = [] # leaders by node before withdrawl from candidates
1902 newLeaders = [] # leaders by node after withdrawl from candidates
1903 oldAllCandidates = [] # list of lists of each nodes' candidates before
1904 newAllCandidates = [] # list of lists of each nodes' candidates after
1905 oldCandidates = [] # list of candidates from node 0 before withdrawl
1906 newCandidates = [] # list of candidates from node 0 after withdrawl
1907 oldLeader = '' # the old leader from oldLeaders, None if not same
1908 newLeader = '' # the new leaders fron newLoeaders, None if not same
1909 oldLeaderCLI = None # the CLI of the old leader used for re-electing
1910 expectNoLeader = False # True when there is only one leader
1911 if main.numCtrls == 1:
1912 expectNoLeader = True
acsmars2c2fcdd2015-08-25 17:14:13 -07001913
acsmars71adceb2015-08-31 15:09:26 -07001914 main.step( "Run for election on each node" )
1915 electionResult = main.TRUE
1916
1917 for cli in main.CLIs: # run test election on each node
1918 if cli.electionTestRun() == main.FALSE:
1919 electionResult = main.FALSE
1920
1921 utilities.assert_equals(
1922 expect=main.TRUE,
1923 actual=electionResult,
1924 onpass="All nodes successfully ran for leadership",
1925 onfail="At least one node failed to run for leadership" )
1926
acsmars3a72bde2015-09-02 14:16:22 -07001927 if electionResult == main.FALSE:
1928 main.log.error(
1929 "Skipping Test Case because Election Test App isn't loaded" )
1930 main.skipCase()
1931
acsmars71adceb2015-08-31 15:09:26 -07001932 main.step( "Check that each node shows the same leader and candidates" )
1933 sameResult = main.TRUE
1934 failMessage = "Nodes have different leaders"
1935 for cli in main.CLIs:
1936 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
1937 oldAllCandidates.append( node )
1938 oldLeaders.append( node[ 0 ] )
1939 oldCandidates = oldAllCandidates[ 0 ]
1940
1941 # Check that each node has the same leader. Defines oldLeader
1942 if len( set( oldLeaders ) ) != 1:
1943 sameResult = main.FALSE
1944 main.log.error( "More than one leader present:" + str( oldLeaders ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001945 oldLeader = None
1946 else:
acsmars71adceb2015-08-31 15:09:26 -07001947 oldLeader = oldLeaders[ 0 ]
1948
1949 # Check that each node's candidate list is the same
acsmars29233db2015-11-04 11:15:00 -08001950 candidateDiscrepancy = False # Boolean of candidate mismatches
acsmars71adceb2015-08-31 15:09:26 -07001951 for candidates in oldAllCandidates:
1952 if set( candidates ) != set( oldCandidates ):
1953 sameResult = main.FALSE
acsmars29233db2015-11-04 11:15:00 -08001954 candidateDiscrepancy = True
1955
1956 if candidateDiscrepancy:
1957 failMessage += " and candidates"
acsmars71adceb2015-08-31 15:09:26 -07001958
1959 utilities.assert_equals(
1960 expect=main.TRUE,
1961 actual=sameResult,
1962 onpass="Leadership is consistent for the election topic",
1963 onfail=failMessage )
1964
1965 main.step( "Find current leader and withdraw" )
1966 withdrawResult = main.TRUE
1967 # do some sanity checking on leader before using it
1968 if oldLeader is None:
1969 main.log.error( "Leadership isn't consistent." )
1970 withdrawResult = main.FALSE
1971 # Get the CLI of the oldLeader
1972 for i in range( len( main.CLIs ) ):
1973 if oldLeader == main.nodes[ i ].ip_address:
1974 oldLeaderCLI = main.CLIs[ i ]
1975 break
1976 else: # FOR/ELSE statement
1977 main.log.error( "Leader election, could not find current leader" )
Jon Hall85794ff2015-07-08 14:12:30 -07001978 if oldLeader:
acsmars71adceb2015-08-31 15:09:26 -07001979 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall85794ff2015-07-08 14:12:30 -07001980 utilities.assert_equals(
1981 expect=main.TRUE,
1982 actual=withdrawResult,
1983 onpass="Node was withdrawn from election",
1984 onfail="Node was not withdrawn from election" )
1985
acsmars71adceb2015-08-31 15:09:26 -07001986 main.step( "Check that a new node was elected leader" )
1987
1988 # FIXME: use threads
1989 newLeaderResult = main.TRUE
1990 failMessage = "Nodes have different leaders"
1991
1992 # Get new leaders and candidates
1993 for cli in main.CLIs:
1994 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
1995 # elections might no have finished yet
1996 if node[ 0 ] == 'none' and not expectNoLeader:
1997 main.log.info( "Node has no leader, waiting 5 seconds to be " +
1998 "sure elections are complete." )
1999 time.sleep(5)
2000 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2001 # election still isn't done or there is a problem
2002 if node[ 0 ] == 'none':
2003 main.log.error( "No leader was elected on at least 1 node" )
2004 newLeaderResult = main.FALSE
2005 newAllCandidates.append( node )
2006 newLeaders.append( node[ 0 ] )
2007 newCandidates = newAllCandidates[ 0 ]
2008
2009 # Check that each node has the same leader. Defines newLeader
2010 if len( set( newLeaders ) ) != 1:
2011 newLeaderResult = main.FALSE
2012 main.log.error( "Nodes have different leaders: " +
2013 str( newLeaders ) )
2014 newLeader = None
2015 else:
2016 newLeader = newLeaders[ 0 ]
2017
2018 # Check that each node's candidate list is the same
2019 for candidates in newAllCandidates:
2020 if set( candidates ) != set( newCandidates ):
2021 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07002022 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07002023
2024 # Check that the new leader is not the older leader, which was withdrawn
2025 if newLeader == oldLeader:
2026 newLeaderResult = main.FALSE
2027 main.log.error( "All nodes still see old leader: " + oldLeader +
2028 " as the current leader" )
2029
Jon Hall85794ff2015-07-08 14:12:30 -07002030 utilities.assert_equals(
2031 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002032 actual=newLeaderResult,
2033 onpass="Leadership election passed",
2034 onfail="Something went wrong with Leadership election" )
Jon Hall85794ff2015-07-08 14:12:30 -07002035
acsmars71adceb2015-08-31 15:09:26 -07002036 main.step( "Check that that new leader was the candidate of old leader")
2037 # candidates[ 2 ] should be come the top candidate after withdrawl
2038 correctCandidateResult = main.TRUE
2039 if expectNoLeader:
2040 if newLeader == 'none':
2041 main.log.info( "No leader expected. None found. Pass" )
2042 correctCandidateResult = main.TRUE
2043 else:
2044 main.log.info( "Expected no leader, got: " + str( newLeader ) )
2045 correctCandidateResult = main.FALSE
2046 elif newLeader != oldCandidates[ 2 ]:
2047 correctCandidateResult = main.FALSE
2048 main.log.error( "Candidate " + newLeader + " was elected. " +
2049 oldCandidates[ 2 ] + " should have had priority." )
2050
2051 utilities.assert_equals(
2052 expect=main.TRUE,
2053 actual=correctCandidateResult,
2054 onpass="Correct Candidate Elected",
2055 onfail="Incorrect Candidate Elected" )
2056
Jon Hall85794ff2015-07-08 14:12:30 -07002057 main.step( "Run for election on old leader( just so everyone " +
2058 "is in the hat )" )
acsmars71adceb2015-08-31 15:09:26 -07002059 if oldLeaderCLI is not None:
2060 runResult = oldLeaderCLI.electionTestRun()
Jon Hall85794ff2015-07-08 14:12:30 -07002061 else:
acsmars71adceb2015-08-31 15:09:26 -07002062 main.log.error( "No old leader to re-elect" )
Jon Hall85794ff2015-07-08 14:12:30 -07002063 runResult = main.FALSE
2064 utilities.assert_equals(
2065 expect=main.TRUE,
2066 actual=runResult,
2067 onpass="App re-ran for election",
2068 onfail="App failed to run for election" )
acsmars71adceb2015-08-31 15:09:26 -07002069 main.step(
2070 "Check that oldLeader is a candidate, and leader if only 1 node" )
2071 # verify leader didn't just change
2072 positionResult = main.TRUE
2073 # Get new leaders and candidates, wait if oldLeader is not a candidate yet
Jon Hall85794ff2015-07-08 14:12:30 -07002074
acsmars71adceb2015-08-31 15:09:26 -07002075 # Reset and reuse the new candidate and leaders lists
2076 newAllCandidates = []
2077 newCandidates = []
2078 newLeaders = []
2079 for cli in main.CLIs:
2080 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2081 if oldLeader not in node: # election might no have finished yet
2082 main.log.info( "Old Leader not elected, waiting 5 seconds to " +
2083 "be sure elections are complete" )
2084 time.sleep(5)
2085 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2086 if oldLeader not in node: # election still isn't done, errors
2087 main.log.error(
2088 "Old leader was not elected on at least one node" )
2089 positionResult = main.FALSE
2090 newAllCandidates.append( node )
2091 newLeaders.append( node[ 0 ] )
2092 newCandidates = newAllCandidates[ 0 ]
2093
2094 # Check that each node has the same leader. Defines newLeader
2095 if len( set( newLeaders ) ) != 1:
2096 positionResult = main.FALSE
2097 main.log.error( "Nodes have different leaders: " +
2098 str( newLeaders ) )
2099 newLeader = None
Jon Hall85794ff2015-07-08 14:12:30 -07002100 else:
acsmars71adceb2015-08-31 15:09:26 -07002101 newLeader = newLeaders[ 0 ]
2102
2103 # Check that each node's candidate list is the same
2104 for candidates in newAllCandidates:
2105 if set( candidates ) != set( newCandidates ):
2106 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07002107 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07002108
2109 # Check that the re-elected node is last on the candidate List
2110 if oldLeader != newCandidates[ -1 ]:
2111 main.log.error( "Old Leader (" + oldLeader + ") not in the proper position " +
2112 str( newCandidates ) )
2113 positionResult = main.FALSE
Jon Hall85794ff2015-07-08 14:12:30 -07002114
2115 utilities.assert_equals(
2116 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002117 actual=positionResult,
Jon Hall85794ff2015-07-08 14:12:30 -07002118 onpass="Old leader successfully re-ran for election",
2119 onfail="Something went wrong with Leadership election after " +
2120 "the old leader re-ran for election" )
2121
2122 def CASE16( self, main ):
2123 """
2124 Install Distributed Primitives app
2125 """
Jon Halle1a3b752015-07-22 13:02:46 -07002126 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002127 assert main, "main not defined"
2128 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002129 assert main.CLIs, "main.CLIs not defined"
2130 assert main.nodes, "main.nodes not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002131
2132 # Variables for the distributed primitives tests
2133 global pCounterName
2134 global iCounterName
2135 global pCounterValue
2136 global iCounterValue
2137 global onosSet
2138 global onosSetName
2139 pCounterName = "TestON-Partitions"
2140 iCounterName = "TestON-inMemory"
2141 pCounterValue = 0
2142 iCounterValue = 0
2143 onosSet = set([])
2144 onosSetName = "TestON-set"
2145
2146 description = "Install Primitives app"
2147 main.case( description )
2148 main.step( "Install Primitives app" )
2149 appName = "org.onosproject.distributedprimitives"
Jon Halle1a3b752015-07-22 13:02:46 -07002150 appResults = main.CLIs[0].activateApp( appName )
Jon Hall85794ff2015-07-08 14:12:30 -07002151 utilities.assert_equals( expect=main.TRUE,
2152 actual=appResults,
2153 onpass="Primitives app activated",
2154 onfail="Primitives app not activated" )
2155
2156 def CASE17( self, main ):
2157 """
2158 Check for basic functionality with distributed primitives
2159 """
Jon Hall85794ff2015-07-08 14:12:30 -07002160 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07002161 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002162 assert main, "main not defined"
2163 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002164 assert main.CLIs, "main.CLIs not defined"
2165 assert main.nodes, "main.nodes not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002166 assert pCounterName, "pCounterName not defined"
2167 assert iCounterName, "iCounterName not defined"
2168 assert onosSetName, "onosSetName not defined"
2169 # NOTE: assert fails if value is 0/None/Empty/False
2170 try:
2171 pCounterValue
2172 except NameError:
2173 main.log.error( "pCounterValue not defined, setting to 0" )
2174 pCounterValue = 0
2175 try:
2176 iCounterValue
2177 except NameError:
2178 main.log.error( "iCounterValue not defined, setting to 0" )
2179 iCounterValue = 0
2180 try:
2181 onosSet
2182 except NameError:
2183 main.log.error( "onosSet not defined, setting to empty Set" )
2184 onosSet = set([])
2185 # Variables for the distributed primitives tests. These are local only
2186 addValue = "a"
2187 addAllValue = "a b c d e f"
2188 retainValue = "c d e f"
2189
2190 description = "Check for basic functionality with distributed " +\
2191 "primitives"
2192 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07002193 main.caseExplanation = "Test the methods of the distributed " +\
2194 "primitives (counters and sets) throught the cli"
Jon Hall85794ff2015-07-08 14:12:30 -07002195 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07002196 # Partitioned counters
2197 main.step( "Increment then get a default counter on each node" )
Jon Hall85794ff2015-07-08 14:12:30 -07002198 pCounters = []
2199 threads = []
2200 addedPValues = []
Jon Halle1a3b752015-07-22 13:02:46 -07002201 for i in range( main.numCtrls ):
2202 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2203 name="counterAddAndGet-" + str( i ),
Jon Hall85794ff2015-07-08 14:12:30 -07002204 args=[ pCounterName ] )
2205 pCounterValue += 1
2206 addedPValues.append( pCounterValue )
2207 threads.append( t )
2208 t.start()
2209
2210 for t in threads:
2211 t.join()
2212 pCounters.append( t.result )
2213 # Check that counter incremented numController times
2214 pCounterResults = True
2215 for i in addedPValues:
2216 tmpResult = i in pCounters
2217 pCounterResults = pCounterResults and tmpResult
2218 if not tmpResult:
2219 main.log.error( str( i ) + " is not in partitioned "
2220 "counter incremented results" )
2221 utilities.assert_equals( expect=True,
2222 actual=pCounterResults,
2223 onpass="Default counter incremented",
2224 onfail="Error incrementing default" +
2225 " counter" )
2226
Jon Halle1a3b752015-07-22 13:02:46 -07002227 main.step( "Get then Increment a default counter on each node" )
2228 pCounters = []
2229 threads = []
2230 addedPValues = []
2231 for i in range( main.numCtrls ):
2232 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
2233 name="counterGetAndAdd-" + str( i ),
2234 args=[ pCounterName ] )
2235 addedPValues.append( pCounterValue )
2236 pCounterValue += 1
2237 threads.append( t )
2238 t.start()
2239
2240 for t in threads:
2241 t.join()
2242 pCounters.append( t.result )
2243 # Check that counter incremented numController times
2244 pCounterResults = True
2245 for i in addedPValues:
2246 tmpResult = i in pCounters
2247 pCounterResults = pCounterResults and tmpResult
2248 if not tmpResult:
2249 main.log.error( str( i ) + " is not in partitioned "
2250 "counter incremented results" )
2251 utilities.assert_equals( expect=True,
2252 actual=pCounterResults,
2253 onpass="Default counter incremented",
2254 onfail="Error incrementing default" +
2255 " counter" )
2256
2257 main.step( "Counters we added have the correct values" )
2258 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
2259 utilities.assert_equals( expect=main.TRUE,
2260 actual=incrementCheck,
2261 onpass="Added counters are correct",
2262 onfail="Added counters are incorrect" )
2263
2264 main.step( "Add -8 to then get a default counter on each node" )
2265 pCounters = []
2266 threads = []
2267 addedPValues = []
2268 for i in range( main.numCtrls ):
2269 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2270 name="counterIncrement-" + str( i ),
2271 args=[ pCounterName ],
2272 kwargs={ "delta": -8 } )
2273 pCounterValue += -8
2274 addedPValues.append( pCounterValue )
2275 threads.append( t )
2276 t.start()
2277
2278 for t in threads:
2279 t.join()
2280 pCounters.append( t.result )
2281 # Check that counter incremented numController times
2282 pCounterResults = True
2283 for i in addedPValues:
2284 tmpResult = i in pCounters
2285 pCounterResults = pCounterResults and tmpResult
2286 if not tmpResult:
2287 main.log.error( str( i ) + " is not in partitioned "
2288 "counter incremented results" )
2289 utilities.assert_equals( expect=True,
2290 actual=pCounterResults,
2291 onpass="Default counter incremented",
2292 onfail="Error incrementing default" +
2293 " counter" )
2294
2295 main.step( "Add 5 to then get a default counter on each node" )
2296 pCounters = []
2297 threads = []
2298 addedPValues = []
2299 for i in range( main.numCtrls ):
2300 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2301 name="counterIncrement-" + str( i ),
2302 args=[ pCounterName ],
2303 kwargs={ "delta": 5 } )
2304 pCounterValue += 5
2305 addedPValues.append( pCounterValue )
2306 threads.append( t )
2307 t.start()
2308
2309 for t in threads:
2310 t.join()
2311 pCounters.append( t.result )
2312 # Check that counter incremented numController times
2313 pCounterResults = True
2314 for i in addedPValues:
2315 tmpResult = i in pCounters
2316 pCounterResults = pCounterResults and tmpResult
2317 if not tmpResult:
2318 main.log.error( str( i ) + " is not in partitioned "
2319 "counter incremented results" )
2320 utilities.assert_equals( expect=True,
2321 actual=pCounterResults,
2322 onpass="Default counter incremented",
2323 onfail="Error incrementing default" +
2324 " counter" )
2325
2326 main.step( "Get then add 5 to a default counter on each node" )
2327 pCounters = []
2328 threads = []
2329 addedPValues = []
2330 for i in range( main.numCtrls ):
2331 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
2332 name="counterIncrement-" + str( i ),
2333 args=[ pCounterName ],
2334 kwargs={ "delta": 5 } )
2335 addedPValues.append( pCounterValue )
2336 pCounterValue += 5
2337 threads.append( t )
2338 t.start()
2339
2340 for t in threads:
2341 t.join()
2342 pCounters.append( t.result )
2343 # Check that counter incremented numController times
2344 pCounterResults = True
2345 for i in addedPValues:
2346 tmpResult = i in pCounters
2347 pCounterResults = pCounterResults and tmpResult
2348 if not tmpResult:
2349 main.log.error( str( i ) + " is not in partitioned "
2350 "counter incremented results" )
2351 utilities.assert_equals( expect=True,
2352 actual=pCounterResults,
2353 onpass="Default counter incremented",
2354 onfail="Error incrementing default" +
2355 " counter" )
2356
2357 main.step( "Counters we added have the correct values" )
2358 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
2359 utilities.assert_equals( expect=main.TRUE,
2360 actual=incrementCheck,
2361 onpass="Added counters are correct",
2362 onfail="Added counters are incorrect" )
2363
2364 # In-Memory counters
2365 main.step( "Increment and get an in-memory counter on each node" )
Jon Hall85794ff2015-07-08 14:12:30 -07002366 iCounters = []
2367 addedIValues = []
2368 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002369 for i in range( main.numCtrls ):
2370 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002371 name="icounterIncrement-" + str( i ),
2372 args=[ iCounterName ],
2373 kwargs={ "inMemory": True } )
2374 iCounterValue += 1
2375 addedIValues.append( iCounterValue )
2376 threads.append( t )
2377 t.start()
2378
2379 for t in threads:
2380 t.join()
2381 iCounters.append( t.result )
2382 # Check that counter incremented numController times
2383 iCounterResults = True
2384 for i in addedIValues:
2385 tmpResult = i in iCounters
2386 iCounterResults = iCounterResults and tmpResult
2387 if not tmpResult:
2388 main.log.error( str( i ) + " is not in the in-memory "
2389 "counter incremented results" )
2390 utilities.assert_equals( expect=True,
2391 actual=iCounterResults,
Jon Halle1a3b752015-07-22 13:02:46 -07002392 onpass="In-memory counter incremented",
2393 onfail="Error incrementing in-memory" +
Jon Hall85794ff2015-07-08 14:12:30 -07002394 " counter" )
2395
Jon Halle1a3b752015-07-22 13:02:46 -07002396 main.step( "Get then Increment a in-memory counter on each node" )
2397 iCounters = []
2398 threads = []
2399 addedIValues = []
2400 for i in range( main.numCtrls ):
2401 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
2402 name="counterGetAndAdd-" + str( i ),
2403 args=[ iCounterName ],
2404 kwargs={ "inMemory": True } )
2405 addedIValues.append( iCounterValue )
2406 iCounterValue += 1
2407 threads.append( t )
2408 t.start()
2409
2410 for t in threads:
2411 t.join()
2412 iCounters.append( t.result )
2413 # Check that counter incremented numController times
2414 iCounterResults = True
2415 for i in addedIValues:
2416 tmpResult = i in iCounters
2417 iCounterResults = iCounterResults and tmpResult
2418 if not tmpResult:
2419 main.log.error( str( i ) + " is not in in-memory "
2420 "counter incremented results" )
2421 utilities.assert_equals( expect=True,
2422 actual=iCounterResults,
2423 onpass="In-memory counter incremented",
2424 onfail="Error incrementing in-memory" +
2425 " counter" )
2426
2427 main.step( "Counters we added have the correct values" )
2428 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
2429 utilities.assert_equals( expect=main.TRUE,
2430 actual=incrementCheck,
2431 onpass="Added counters are correct",
2432 onfail="Added counters are incorrect" )
2433
2434 main.step( "Add -8 to then get a in-memory counter on each node" )
2435 iCounters = []
2436 threads = []
2437 addedIValues = []
2438 for i in range( main.numCtrls ):
2439 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2440 name="counterIncrement-" + str( i ),
2441 args=[ iCounterName ],
2442 kwargs={ "delta": -8, "inMemory": True } )
2443 iCounterValue += -8
2444 addedIValues.append( iCounterValue )
2445 threads.append( t )
2446 t.start()
2447
2448 for t in threads:
2449 t.join()
2450 iCounters.append( t.result )
2451 # Check that counter incremented numController times
2452 iCounterResults = True
2453 for i in addedIValues:
2454 tmpResult = i in iCounters
2455 iCounterResults = iCounterResults and tmpResult
2456 if not tmpResult:
2457 main.log.error( str( i ) + " is not in in-memory "
2458 "counter incremented results" )
2459 utilities.assert_equals( expect=True,
2460 actual=pCounterResults,
2461 onpass="In-memory counter incremented",
2462 onfail="Error incrementing in-memory" +
2463 " counter" )
2464
2465 main.step( "Add 5 to then get a in-memory counter on each node" )
2466 iCounters = []
2467 threads = []
2468 addedIValues = []
2469 for i in range( main.numCtrls ):
2470 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2471 name="counterIncrement-" + str( i ),
2472 args=[ iCounterName ],
2473 kwargs={ "delta": 5, "inMemory": True } )
2474 iCounterValue += 5
2475 addedIValues.append( iCounterValue )
2476 threads.append( t )
2477 t.start()
2478
2479 for t in threads:
2480 t.join()
2481 iCounters.append( t.result )
2482 # Check that counter incremented numController times
2483 iCounterResults = True
2484 for i in addedIValues:
2485 tmpResult = i in iCounters
2486 iCounterResults = iCounterResults and tmpResult
2487 if not tmpResult:
2488 main.log.error( str( i ) + " is not in in-memory "
2489 "counter incremented results" )
2490 utilities.assert_equals( expect=True,
2491 actual=pCounterResults,
2492 onpass="In-memory counter incremented",
2493 onfail="Error incrementing in-memory" +
2494 " counter" )
2495
2496 main.step( "Get then add 5 to a in-memory counter on each node" )
2497 iCounters = []
2498 threads = []
2499 addedIValues = []
2500 for i in range( main.numCtrls ):
2501 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
2502 name="counterIncrement-" + str( i ),
2503 args=[ iCounterName ],
2504 kwargs={ "delta": 5, "inMemory": True } )
2505 addedIValues.append( iCounterValue )
2506 iCounterValue += 5
2507 threads.append( t )
2508 t.start()
2509
2510 for t in threads:
2511 t.join()
2512 iCounters.append( t.result )
2513 # Check that counter incremented numController times
2514 iCounterResults = True
2515 for i in addedIValues:
2516 tmpResult = i in iCounters
2517 iCounterResults = iCounterResults and tmpResult
2518 if not tmpResult:
2519 main.log.error( str( i ) + " is not in in-memory "
2520 "counter incremented results" )
2521 utilities.assert_equals( expect=True,
2522 actual=iCounterResults,
2523 onpass="In-memory counter incremented",
2524 onfail="Error incrementing in-memory" +
2525 " counter" )
2526
2527 main.step( "Counters we added have the correct values" )
2528 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
2529 utilities.assert_equals( expect=main.TRUE,
2530 actual=incrementCheck,
2531 onpass="Added counters are correct",
2532 onfail="Added counters are incorrect" )
2533
Jon Hall85794ff2015-07-08 14:12:30 -07002534 main.step( "Check counters are consistant across nodes" )
Jon Hall57b50432015-10-22 10:20:10 -07002535 onosCounters, consistentCounterResults = main.Counters.consistentCheck()
Jon Hall85794ff2015-07-08 14:12:30 -07002536 utilities.assert_equals( expect=main.TRUE,
2537 actual=consistentCounterResults,
2538 onpass="ONOS counters are consistent " +
2539 "across nodes",
2540 onfail="ONOS Counters are inconsistent " +
2541 "across nodes" )
2542
2543 main.step( "Counters we added have the correct values" )
Jon Halle1a3b752015-07-22 13:02:46 -07002544 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
2545 incrementCheck = incrementCheck and \
2546 main.Counters.counterCheck( iCounterName, iCounterValue )
Jon Hall85794ff2015-07-08 14:12:30 -07002547 utilities.assert_equals( expect=main.TRUE,
Jon Halle1a3b752015-07-22 13:02:46 -07002548 actual=incrementCheck,
Jon Hall85794ff2015-07-08 14:12:30 -07002549 onpass="Added counters are correct",
2550 onfail="Added counters are incorrect" )
2551 # DISTRIBUTED SETS
2552 main.step( "Distributed Set get" )
2553 size = len( onosSet )
2554 getResponses = []
2555 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002556 for i in range( main.numCtrls ):
2557 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002558 name="setTestGet-" + str( i ),
2559 args=[ onosSetName ] )
2560 threads.append( t )
2561 t.start()
2562 for t in threads:
2563 t.join()
2564 getResponses.append( t.result )
2565
2566 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002567 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002568 if isinstance( getResponses[ i ], list):
2569 current = set( getResponses[ i ] )
2570 if len( current ) == len( getResponses[ i ] ):
2571 # no repeats
2572 if onosSet != current:
2573 main.log.error( "ONOS" + str( i + 1 ) +
2574 " has incorrect view" +
2575 " of set " + onosSetName + ":\n" +
2576 str( getResponses[ i ] ) )
2577 main.log.debug( "Expected: " + str( onosSet ) )
2578 main.log.debug( "Actual: " + str( current ) )
2579 getResults = main.FALSE
2580 else:
2581 # error, set is not a set
2582 main.log.error( "ONOS" + str( i + 1 ) +
2583 " has repeat elements in" +
2584 " set " + onosSetName + ":\n" +
2585 str( getResponses[ i ] ) )
2586 getResults = main.FALSE
2587 elif getResponses[ i ] == main.ERROR:
2588 getResults = main.FALSE
2589 utilities.assert_equals( expect=main.TRUE,
2590 actual=getResults,
2591 onpass="Set elements are correct",
2592 onfail="Set elements are incorrect" )
2593
2594 main.step( "Distributed Set size" )
2595 sizeResponses = []
2596 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002597 for i in range( main.numCtrls ):
2598 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002599 name="setTestSize-" + str( i ),
2600 args=[ onosSetName ] )
2601 threads.append( t )
2602 t.start()
2603 for t in threads:
2604 t.join()
2605 sizeResponses.append( t.result )
2606
2607 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002608 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002609 if size != sizeResponses[ i ]:
2610 sizeResults = main.FALSE
2611 main.log.error( "ONOS" + str( i + 1 ) +
2612 " expected a size of " + str( size ) +
2613 " for set " + onosSetName +
2614 " but got " + str( sizeResponses[ i ] ) )
2615 utilities.assert_equals( expect=main.TRUE,
2616 actual=sizeResults,
2617 onpass="Set sizes are correct",
2618 onfail="Set sizes are incorrect" )
2619
2620 main.step( "Distributed Set add()" )
2621 onosSet.add( addValue )
2622 addResponses = []
2623 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002624 for i in range( main.numCtrls ):
2625 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07002626 name="setTestAdd-" + str( i ),
2627 args=[ onosSetName, addValue ] )
2628 threads.append( t )
2629 t.start()
2630 for t in threads:
2631 t.join()
2632 addResponses.append( t.result )
2633
2634 # main.TRUE = successfully changed the set
2635 # main.FALSE = action resulted in no change in set
2636 # main.ERROR - Some error in executing the function
2637 addResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002638 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002639 if addResponses[ i ] == main.TRUE:
2640 # All is well
2641 pass
2642 elif addResponses[ i ] == main.FALSE:
2643 # Already in set, probably fine
2644 pass
2645 elif addResponses[ i ] == main.ERROR:
2646 # Error in execution
2647 addResults = main.FALSE
2648 else:
2649 # unexpected result
2650 addResults = main.FALSE
2651 if addResults != main.TRUE:
2652 main.log.error( "Error executing set add" )
2653
2654 # Check if set is still correct
2655 size = len( onosSet )
2656 getResponses = []
2657 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002658 for i in range( main.numCtrls ):
2659 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002660 name="setTestGet-" + str( i ),
2661 args=[ onosSetName ] )
2662 threads.append( t )
2663 t.start()
2664 for t in threads:
2665 t.join()
2666 getResponses.append( t.result )
2667 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002668 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002669 if isinstance( getResponses[ i ], list):
2670 current = set( getResponses[ i ] )
2671 if len( current ) == len( getResponses[ i ] ):
2672 # no repeats
2673 if onosSet != current:
2674 main.log.error( "ONOS" + str( i + 1 ) +
2675 " has incorrect view" +
2676 " of set " + onosSetName + ":\n" +
2677 str( getResponses[ i ] ) )
2678 main.log.debug( "Expected: " + str( onosSet ) )
2679 main.log.debug( "Actual: " + str( current ) )
2680 getResults = main.FALSE
2681 else:
2682 # error, set is not a set
2683 main.log.error( "ONOS" + str( i + 1 ) +
2684 " has repeat elements in" +
2685 " set " + onosSetName + ":\n" +
2686 str( getResponses[ i ] ) )
2687 getResults = main.FALSE
2688 elif getResponses[ i ] == main.ERROR:
2689 getResults = main.FALSE
2690 sizeResponses = []
2691 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002692 for i in range( main.numCtrls ):
2693 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002694 name="setTestSize-" + str( i ),
2695 args=[ onosSetName ] )
2696 threads.append( t )
2697 t.start()
2698 for t in threads:
2699 t.join()
2700 sizeResponses.append( t.result )
2701 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002702 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002703 if size != sizeResponses[ i ]:
2704 sizeResults = main.FALSE
2705 main.log.error( "ONOS" + str( i + 1 ) +
2706 " expected a size of " + str( size ) +
2707 " for set " + onosSetName +
2708 " but got " + str( sizeResponses[ i ] ) )
2709 addResults = addResults and getResults and sizeResults
2710 utilities.assert_equals( expect=main.TRUE,
2711 actual=addResults,
2712 onpass="Set add correct",
2713 onfail="Set add was incorrect" )
2714
2715 main.step( "Distributed Set addAll()" )
2716 onosSet.update( addAllValue.split() )
2717 addResponses = []
2718 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002719 for i in range( main.numCtrls ):
2720 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07002721 name="setTestAddAll-" + str( i ),
2722 args=[ onosSetName, addAllValue ] )
2723 threads.append( t )
2724 t.start()
2725 for t in threads:
2726 t.join()
2727 addResponses.append( t.result )
2728
2729 # main.TRUE = successfully changed the set
2730 # main.FALSE = action resulted in no change in set
2731 # main.ERROR - Some error in executing the function
2732 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002733 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002734 if addResponses[ i ] == main.TRUE:
2735 # All is well
2736 pass
2737 elif addResponses[ i ] == main.FALSE:
2738 # Already in set, probably fine
2739 pass
2740 elif addResponses[ i ] == main.ERROR:
2741 # Error in execution
2742 addAllResults = main.FALSE
2743 else:
2744 # unexpected result
2745 addAllResults = main.FALSE
2746 if addAllResults != main.TRUE:
2747 main.log.error( "Error executing set addAll" )
2748
2749 # Check if set is still correct
2750 size = len( onosSet )
2751 getResponses = []
2752 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002753 for i in range( main.numCtrls ):
2754 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002755 name="setTestGet-" + str( i ),
2756 args=[ onosSetName ] )
2757 threads.append( t )
2758 t.start()
2759 for t in threads:
2760 t.join()
2761 getResponses.append( t.result )
2762 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002763 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002764 if isinstance( getResponses[ i ], list):
2765 current = set( getResponses[ i ] )
2766 if len( current ) == len( getResponses[ i ] ):
2767 # no repeats
2768 if onosSet != current:
2769 main.log.error( "ONOS" + str( i + 1 ) +
2770 " has incorrect view" +
2771 " of set " + onosSetName + ":\n" +
2772 str( getResponses[ i ] ) )
2773 main.log.debug( "Expected: " + str( onosSet ) )
2774 main.log.debug( "Actual: " + str( current ) )
2775 getResults = main.FALSE
2776 else:
2777 # error, set is not a set
2778 main.log.error( "ONOS" + str( i + 1 ) +
2779 " has repeat elements in" +
2780 " set " + onosSetName + ":\n" +
2781 str( getResponses[ i ] ) )
2782 getResults = main.FALSE
2783 elif getResponses[ i ] == main.ERROR:
2784 getResults = main.FALSE
2785 sizeResponses = []
2786 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002787 for i in range( main.numCtrls ):
2788 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002789 name="setTestSize-" + str( i ),
2790 args=[ onosSetName ] )
2791 threads.append( t )
2792 t.start()
2793 for t in threads:
2794 t.join()
2795 sizeResponses.append( t.result )
2796 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002797 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002798 if size != sizeResponses[ i ]:
2799 sizeResults = main.FALSE
2800 main.log.error( "ONOS" + str( i + 1 ) +
2801 " expected a size of " + str( size ) +
2802 " for set " + onosSetName +
2803 " but got " + str( sizeResponses[ i ] ) )
2804 addAllResults = addAllResults and getResults and sizeResults
2805 utilities.assert_equals( expect=main.TRUE,
2806 actual=addAllResults,
2807 onpass="Set addAll correct",
2808 onfail="Set addAll was incorrect" )
2809
2810 main.step( "Distributed Set contains()" )
2811 containsResponses = []
2812 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002813 for i in range( main.numCtrls ):
2814 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002815 name="setContains-" + str( i ),
2816 args=[ onosSetName ],
2817 kwargs={ "values": addValue } )
2818 threads.append( t )
2819 t.start()
2820 for t in threads:
2821 t.join()
2822 # NOTE: This is the tuple
2823 containsResponses.append( t.result )
2824
2825 containsResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002826 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002827 if containsResponses[ i ] == main.ERROR:
2828 containsResults = main.FALSE
2829 else:
2830 containsResults = containsResults and\
2831 containsResponses[ i ][ 1 ]
2832 utilities.assert_equals( expect=main.TRUE,
2833 actual=containsResults,
2834 onpass="Set contains is functional",
2835 onfail="Set contains failed" )
2836
2837 main.step( "Distributed Set containsAll()" )
2838 containsAllResponses = []
2839 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002840 for i in range( main.numCtrls ):
2841 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002842 name="setContainsAll-" + str( i ),
2843 args=[ onosSetName ],
2844 kwargs={ "values": addAllValue } )
2845 threads.append( t )
2846 t.start()
2847 for t in threads:
2848 t.join()
2849 # NOTE: This is the tuple
2850 containsAllResponses.append( t.result )
2851
2852 containsAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002853 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002854 if containsResponses[ i ] == main.ERROR:
2855 containsResults = main.FALSE
2856 else:
2857 containsResults = containsResults and\
2858 containsResponses[ i ][ 1 ]
2859 utilities.assert_equals( expect=main.TRUE,
2860 actual=containsAllResults,
2861 onpass="Set containsAll is functional",
2862 onfail="Set containsAll failed" )
2863
2864 main.step( "Distributed Set remove()" )
2865 onosSet.remove( addValue )
2866 removeResponses = []
2867 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002868 for i in range( main.numCtrls ):
2869 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07002870 name="setTestRemove-" + str( i ),
2871 args=[ onosSetName, addValue ] )
2872 threads.append( t )
2873 t.start()
2874 for t in threads:
2875 t.join()
2876 removeResponses.append( t.result )
2877
2878 # main.TRUE = successfully changed the set
2879 # main.FALSE = action resulted in no change in set
2880 # main.ERROR - Some error in executing the function
2881 removeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002882 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002883 if removeResponses[ i ] == main.TRUE:
2884 # All is well
2885 pass
2886 elif removeResponses[ i ] == main.FALSE:
2887 # not in set, probably fine
2888 pass
2889 elif removeResponses[ i ] == main.ERROR:
2890 # Error in execution
2891 removeResults = main.FALSE
2892 else:
2893 # unexpected result
2894 removeResults = main.FALSE
2895 if removeResults != main.TRUE:
2896 main.log.error( "Error executing set remove" )
2897
2898 # Check if set is still correct
2899 size = len( onosSet )
2900 getResponses = []
2901 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002902 for i in range( main.numCtrls ):
2903 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002904 name="setTestGet-" + str( i ),
2905 args=[ onosSetName ] )
2906 threads.append( t )
2907 t.start()
2908 for t in threads:
2909 t.join()
2910 getResponses.append( t.result )
2911 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002912 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002913 if isinstance( getResponses[ i ], list):
2914 current = set( getResponses[ i ] )
2915 if len( current ) == len( getResponses[ i ] ):
2916 # no repeats
2917 if onosSet != current:
2918 main.log.error( "ONOS" + str( i + 1 ) +
2919 " has incorrect view" +
2920 " of set " + onosSetName + ":\n" +
2921 str( getResponses[ i ] ) )
2922 main.log.debug( "Expected: " + str( onosSet ) )
2923 main.log.debug( "Actual: " + str( current ) )
2924 getResults = main.FALSE
2925 else:
2926 # error, set is not a set
2927 main.log.error( "ONOS" + str( i + 1 ) +
2928 " has repeat elements in" +
2929 " set " + onosSetName + ":\n" +
2930 str( getResponses[ i ] ) )
2931 getResults = main.FALSE
2932 elif getResponses[ i ] == main.ERROR:
2933 getResults = main.FALSE
2934 sizeResponses = []
2935 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002936 for i in range( main.numCtrls ):
2937 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002938 name="setTestSize-" + str( i ),
2939 args=[ onosSetName ] )
2940 threads.append( t )
2941 t.start()
2942 for t in threads:
2943 t.join()
2944 sizeResponses.append( t.result )
2945 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002946 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002947 if size != sizeResponses[ i ]:
2948 sizeResults = main.FALSE
2949 main.log.error( "ONOS" + str( i + 1 ) +
2950 " expected a size of " + str( size ) +
2951 " for set " + onosSetName +
2952 " but got " + str( sizeResponses[ i ] ) )
2953 removeResults = removeResults and getResults and sizeResults
2954 utilities.assert_equals( expect=main.TRUE,
2955 actual=removeResults,
2956 onpass="Set remove correct",
2957 onfail="Set remove was incorrect" )
2958
2959 main.step( "Distributed Set removeAll()" )
2960 onosSet.difference_update( addAllValue.split() )
2961 removeAllResponses = []
2962 threads = []
2963 try:
Jon Halle1a3b752015-07-22 13:02:46 -07002964 for i in range( main.numCtrls ):
2965 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07002966 name="setTestRemoveAll-" + str( i ),
2967 args=[ onosSetName, addAllValue ] )
2968 threads.append( t )
2969 t.start()
2970 for t in threads:
2971 t.join()
2972 removeAllResponses.append( t.result )
2973 except Exception, e:
2974 main.log.exception(e)
2975
2976 # main.TRUE = successfully changed the set
2977 # main.FALSE = action resulted in no change in set
2978 # main.ERROR - Some error in executing the function
2979 removeAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002980 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002981 if removeAllResponses[ i ] == main.TRUE:
2982 # All is well
2983 pass
2984 elif removeAllResponses[ i ] == main.FALSE:
2985 # not in set, probably fine
2986 pass
2987 elif removeAllResponses[ i ] == main.ERROR:
2988 # Error in execution
2989 removeAllResults = main.FALSE
2990 else:
2991 # unexpected result
2992 removeAllResults = main.FALSE
2993 if removeAllResults != main.TRUE:
2994 main.log.error( "Error executing set removeAll" )
2995
2996 # Check if set is still correct
2997 size = len( onosSet )
2998 getResponses = []
2999 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003000 for i in range( main.numCtrls ):
3001 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003002 name="setTestGet-" + str( i ),
3003 args=[ onosSetName ] )
3004 threads.append( t )
3005 t.start()
3006 for t in threads:
3007 t.join()
3008 getResponses.append( t.result )
3009 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003010 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003011 if isinstance( getResponses[ i ], list):
3012 current = set( getResponses[ i ] )
3013 if len( current ) == len( getResponses[ i ] ):
3014 # no repeats
3015 if onosSet != current:
3016 main.log.error( "ONOS" + str( i + 1 ) +
3017 " has incorrect view" +
3018 " of set " + onosSetName + ":\n" +
3019 str( getResponses[ i ] ) )
3020 main.log.debug( "Expected: " + str( onosSet ) )
3021 main.log.debug( "Actual: " + str( current ) )
3022 getResults = main.FALSE
3023 else:
3024 # error, set is not a set
3025 main.log.error( "ONOS" + str( i + 1 ) +
3026 " has repeat elements in" +
3027 " set " + onosSetName + ":\n" +
3028 str( getResponses[ i ] ) )
3029 getResults = main.FALSE
3030 elif getResponses[ i ] == main.ERROR:
3031 getResults = main.FALSE
3032 sizeResponses = []
3033 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003034 for i in range( main.numCtrls ):
3035 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003036 name="setTestSize-" + str( i ),
3037 args=[ onosSetName ] )
3038 threads.append( t )
3039 t.start()
3040 for t in threads:
3041 t.join()
3042 sizeResponses.append( t.result )
3043 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003044 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003045 if size != sizeResponses[ i ]:
3046 sizeResults = main.FALSE
3047 main.log.error( "ONOS" + str( i + 1 ) +
3048 " expected a size of " + str( size ) +
3049 " for set " + onosSetName +
3050 " but got " + str( sizeResponses[ i ] ) )
3051 removeAllResults = removeAllResults and getResults and sizeResults
3052 utilities.assert_equals( expect=main.TRUE,
3053 actual=removeAllResults,
3054 onpass="Set removeAll correct",
3055 onfail="Set removeAll was incorrect" )
3056
3057 main.step( "Distributed Set addAll()" )
3058 onosSet.update( addAllValue.split() )
3059 addResponses = []
3060 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003061 for i in range( main.numCtrls ):
3062 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07003063 name="setTestAddAll-" + str( i ),
3064 args=[ onosSetName, addAllValue ] )
3065 threads.append( t )
3066 t.start()
3067 for t in threads:
3068 t.join()
3069 addResponses.append( t.result )
3070
3071 # main.TRUE = successfully changed the set
3072 # main.FALSE = action resulted in no change in set
3073 # main.ERROR - Some error in executing the function
3074 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003075 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003076 if addResponses[ i ] == main.TRUE:
3077 # All is well
3078 pass
3079 elif addResponses[ i ] == main.FALSE:
3080 # Already in set, probably fine
3081 pass
3082 elif addResponses[ i ] == main.ERROR:
3083 # Error in execution
3084 addAllResults = main.FALSE
3085 else:
3086 # unexpected result
3087 addAllResults = main.FALSE
3088 if addAllResults != main.TRUE:
3089 main.log.error( "Error executing set addAll" )
3090
3091 # Check if set is still correct
3092 size = len( onosSet )
3093 getResponses = []
3094 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003095 for i in range( main.numCtrls ):
3096 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003097 name="setTestGet-" + str( i ),
3098 args=[ onosSetName ] )
3099 threads.append( t )
3100 t.start()
3101 for t in threads:
3102 t.join()
3103 getResponses.append( t.result )
3104 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003105 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003106 if isinstance( getResponses[ i ], list):
3107 current = set( getResponses[ i ] )
3108 if len( current ) == len( getResponses[ i ] ):
3109 # no repeats
3110 if onosSet != current:
3111 main.log.error( "ONOS" + str( i + 1 ) +
3112 " has incorrect view" +
3113 " of set " + onosSetName + ":\n" +
3114 str( getResponses[ i ] ) )
3115 main.log.debug( "Expected: " + str( onosSet ) )
3116 main.log.debug( "Actual: " + str( current ) )
3117 getResults = main.FALSE
3118 else:
3119 # error, set is not a set
3120 main.log.error( "ONOS" + str( i + 1 ) +
3121 " has repeat elements in" +
3122 " set " + onosSetName + ":\n" +
3123 str( getResponses[ i ] ) )
3124 getResults = main.FALSE
3125 elif getResponses[ i ] == main.ERROR:
3126 getResults = main.FALSE
3127 sizeResponses = []
3128 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003129 for i in range( main.numCtrls ):
3130 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003131 name="setTestSize-" + str( i ),
3132 args=[ onosSetName ] )
3133 threads.append( t )
3134 t.start()
3135 for t in threads:
3136 t.join()
3137 sizeResponses.append( t.result )
3138 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003139 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003140 if size != sizeResponses[ i ]:
3141 sizeResults = main.FALSE
3142 main.log.error( "ONOS" + str( i + 1 ) +
3143 " expected a size of " + str( size ) +
3144 " for set " + onosSetName +
3145 " but got " + str( sizeResponses[ i ] ) )
3146 addAllResults = addAllResults and getResults and sizeResults
3147 utilities.assert_equals( expect=main.TRUE,
3148 actual=addAllResults,
3149 onpass="Set addAll correct",
3150 onfail="Set addAll was incorrect" )
3151
3152 main.step( "Distributed Set clear()" )
3153 onosSet.clear()
3154 clearResponses = []
3155 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003156 for i in range( main.numCtrls ):
3157 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07003158 name="setTestClear-" + str( i ),
3159 args=[ onosSetName, " "], # Values doesn't matter
3160 kwargs={ "clear": True } )
3161 threads.append( t )
3162 t.start()
3163 for t in threads:
3164 t.join()
3165 clearResponses.append( t.result )
3166
3167 # main.TRUE = successfully changed the set
3168 # main.FALSE = action resulted in no change in set
3169 # main.ERROR - Some error in executing the function
3170 clearResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003171 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003172 if clearResponses[ i ] == main.TRUE:
3173 # All is well
3174 pass
3175 elif clearResponses[ i ] == main.FALSE:
3176 # Nothing set, probably fine
3177 pass
3178 elif clearResponses[ i ] == main.ERROR:
3179 # Error in execution
3180 clearResults = main.FALSE
3181 else:
3182 # unexpected result
3183 clearResults = main.FALSE
3184 if clearResults != main.TRUE:
3185 main.log.error( "Error executing set clear" )
3186
3187 # Check if set is still correct
3188 size = len( onosSet )
3189 getResponses = []
3190 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003191 for i in range( main.numCtrls ):
3192 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003193 name="setTestGet-" + str( i ),
3194 args=[ onosSetName ] )
3195 threads.append( t )
3196 t.start()
3197 for t in threads:
3198 t.join()
3199 getResponses.append( t.result )
3200 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003201 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003202 if isinstance( getResponses[ i ], list):
3203 current = set( getResponses[ i ] )
3204 if len( current ) == len( getResponses[ i ] ):
3205 # no repeats
3206 if onosSet != current:
3207 main.log.error( "ONOS" + str( i + 1 ) +
3208 " has incorrect view" +
3209 " of set " + onosSetName + ":\n" +
3210 str( getResponses[ i ] ) )
3211 main.log.debug( "Expected: " + str( onosSet ) )
3212 main.log.debug( "Actual: " + str( current ) )
3213 getResults = main.FALSE
3214 else:
3215 # error, set is not a set
3216 main.log.error( "ONOS" + str( i + 1 ) +
3217 " has repeat elements in" +
3218 " set " + onosSetName + ":\n" +
3219 str( getResponses[ i ] ) )
3220 getResults = main.FALSE
3221 elif getResponses[ i ] == main.ERROR:
3222 getResults = main.FALSE
3223 sizeResponses = []
3224 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003225 for i in range( main.numCtrls ):
3226 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003227 name="setTestSize-" + str( i ),
3228 args=[ onosSetName ] )
3229 threads.append( t )
3230 t.start()
3231 for t in threads:
3232 t.join()
3233 sizeResponses.append( t.result )
3234 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003235 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003236 if size != sizeResponses[ i ]:
3237 sizeResults = main.FALSE
3238 main.log.error( "ONOS" + str( i + 1 ) +
3239 " expected a size of " + str( size ) +
3240 " for set " + onosSetName +
3241 " but got " + str( sizeResponses[ i ] ) )
3242 clearResults = clearResults and getResults and sizeResults
3243 utilities.assert_equals( expect=main.TRUE,
3244 actual=clearResults,
3245 onpass="Set clear correct",
3246 onfail="Set clear was incorrect" )
3247
3248 main.step( "Distributed Set addAll()" )
3249 onosSet.update( addAllValue.split() )
3250 addResponses = []
3251 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003252 for i in range( main.numCtrls ):
3253 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07003254 name="setTestAddAll-" + str( i ),
3255 args=[ onosSetName, addAllValue ] )
3256 threads.append( t )
3257 t.start()
3258 for t in threads:
3259 t.join()
3260 addResponses.append( t.result )
3261
3262 # main.TRUE = successfully changed the set
3263 # main.FALSE = action resulted in no change in set
3264 # main.ERROR - Some error in executing the function
3265 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003266 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003267 if addResponses[ i ] == main.TRUE:
3268 # All is well
3269 pass
3270 elif addResponses[ i ] == main.FALSE:
3271 # Already in set, probably fine
3272 pass
3273 elif addResponses[ i ] == main.ERROR:
3274 # Error in execution
3275 addAllResults = main.FALSE
3276 else:
3277 # unexpected result
3278 addAllResults = main.FALSE
3279 if addAllResults != main.TRUE:
3280 main.log.error( "Error executing set addAll" )
3281
3282 # Check if set is still correct
3283 size = len( onosSet )
3284 getResponses = []
3285 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003286 for i in range( main.numCtrls ):
3287 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003288 name="setTestGet-" + str( i ),
3289 args=[ onosSetName ] )
3290 threads.append( t )
3291 t.start()
3292 for t in threads:
3293 t.join()
3294 getResponses.append( t.result )
3295 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003296 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003297 if isinstance( getResponses[ i ], list):
3298 current = set( getResponses[ i ] )
3299 if len( current ) == len( getResponses[ i ] ):
3300 # no repeats
3301 if onosSet != current:
3302 main.log.error( "ONOS" + str( i + 1 ) +
3303 " has incorrect view" +
3304 " of set " + onosSetName + ":\n" +
3305 str( getResponses[ i ] ) )
3306 main.log.debug( "Expected: " + str( onosSet ) )
3307 main.log.debug( "Actual: " + str( current ) )
3308 getResults = main.FALSE
3309 else:
3310 # error, set is not a set
3311 main.log.error( "ONOS" + str( i + 1 ) +
3312 " has repeat elements in" +
3313 " set " + onosSetName + ":\n" +
3314 str( getResponses[ i ] ) )
3315 getResults = main.FALSE
3316 elif getResponses[ i ] == main.ERROR:
3317 getResults = main.FALSE
3318 sizeResponses = []
3319 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003320 for i in range( main.numCtrls ):
3321 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003322 name="setTestSize-" + str( i ),
3323 args=[ onosSetName ] )
3324 threads.append( t )
3325 t.start()
3326 for t in threads:
3327 t.join()
3328 sizeResponses.append( t.result )
3329 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003330 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003331 if size != sizeResponses[ i ]:
3332 sizeResults = main.FALSE
3333 main.log.error( "ONOS" + str( i + 1 ) +
3334 " expected a size of " + str( size ) +
3335 " for set " + onosSetName +
3336 " but got " + str( sizeResponses[ i ] ) )
3337 addAllResults = addAllResults and getResults and sizeResults
3338 utilities.assert_equals( expect=main.TRUE,
3339 actual=addAllResults,
3340 onpass="Set addAll correct",
3341 onfail="Set addAll was incorrect" )
3342
3343 main.step( "Distributed Set retain()" )
3344 onosSet.intersection_update( retainValue.split() )
3345 retainResponses = []
3346 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003347 for i in range( main.numCtrls ):
3348 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07003349 name="setTestRetain-" + str( i ),
3350 args=[ onosSetName, retainValue ],
3351 kwargs={ "retain": True } )
3352 threads.append( t )
3353 t.start()
3354 for t in threads:
3355 t.join()
3356 retainResponses.append( t.result )
3357
3358 # main.TRUE = successfully changed the set
3359 # main.FALSE = action resulted in no change in set
3360 # main.ERROR - Some error in executing the function
3361 retainResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003362 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003363 if retainResponses[ i ] == main.TRUE:
3364 # All is well
3365 pass
3366 elif retainResponses[ i ] == main.FALSE:
3367 # Already in set, probably fine
3368 pass
3369 elif retainResponses[ i ] == main.ERROR:
3370 # Error in execution
3371 retainResults = main.FALSE
3372 else:
3373 # unexpected result
3374 retainResults = main.FALSE
3375 if retainResults != main.TRUE:
3376 main.log.error( "Error executing set retain" )
3377
3378 # Check if set is still correct
3379 size = len( onosSet )
3380 getResponses = []
3381 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003382 for i in range( main.numCtrls ):
3383 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003384 name="setTestGet-" + str( i ),
3385 args=[ onosSetName ] )
3386 threads.append( t )
3387 t.start()
3388 for t in threads:
3389 t.join()
3390 getResponses.append( t.result )
3391 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003392 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003393 if isinstance( getResponses[ i ], list):
3394 current = set( getResponses[ i ] )
3395 if len( current ) == len( getResponses[ i ] ):
3396 # no repeats
3397 if onosSet != current:
3398 main.log.error( "ONOS" + str( i + 1 ) +
3399 " has incorrect view" +
3400 " of set " + onosSetName + ":\n" +
3401 str( getResponses[ i ] ) )
3402 main.log.debug( "Expected: " + str( onosSet ) )
3403 main.log.debug( "Actual: " + str( current ) )
3404 getResults = main.FALSE
3405 else:
3406 # error, set is not a set
3407 main.log.error( "ONOS" + str( i + 1 ) +
3408 " has repeat elements in" +
3409 " set " + onosSetName + ":\n" +
3410 str( getResponses[ i ] ) )
3411 getResults = main.FALSE
3412 elif getResponses[ i ] == main.ERROR:
3413 getResults = main.FALSE
3414 sizeResponses = []
3415 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003416 for i in range( main.numCtrls ):
3417 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003418 name="setTestSize-" + str( i ),
3419 args=[ onosSetName ] )
3420 threads.append( t )
3421 t.start()
3422 for t in threads:
3423 t.join()
3424 sizeResponses.append( t.result )
3425 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003426 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003427 if size != sizeResponses[ i ]:
3428 sizeResults = main.FALSE
3429 main.log.error( "ONOS" + str( i + 1 ) +
3430 " expected a size of " +
3431 str( size ) + " for set " + onosSetName +
3432 " but got " + str( sizeResponses[ i ] ) )
3433 retainResults = retainResults and getResults and sizeResults
3434 utilities.assert_equals( expect=main.TRUE,
3435 actual=retainResults,
3436 onpass="Set retain correct",
3437 onfail="Set retain was incorrect" )
3438
Jon Hall2a5002c2015-08-21 16:49:11 -07003439 # Transactional maps
3440 main.step( "Partitioned Transactional maps put" )
3441 tMapValue = "Testing"
3442 numKeys = 100
3443 putResult = True
3444 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue )
3445 if len( putResponses ) == 100:
3446 for i in putResponses:
3447 if putResponses[ i ][ 'value' ] != tMapValue:
3448 putResult = False
3449 else:
3450 putResult = False
3451 if not putResult:
3452 main.log.debug( "Put response values: " + str( putResponses ) )
3453 utilities.assert_equals( expect=True,
3454 actual=putResult,
3455 onpass="Partitioned Transactional Map put successful",
3456 onfail="Partitioned Transactional Map put values are incorrect" )
3457
3458 main.step( "Partitioned Transactional maps get" )
3459 getCheck = True
3460 for n in range( 1, numKeys + 1 ):
3461 getResponses = []
3462 threads = []
3463 valueCheck = True
3464 for i in range( main.numCtrls ):
3465 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
3466 name="TMap-get-" + str( i ),
3467 args=[ "Key" + str ( n ) ] )
3468 threads.append( t )
3469 t.start()
3470 for t in threads:
3471 t.join()
3472 getResponses.append( t.result )
3473 for node in getResponses:
3474 if node != tMapValue:
3475 valueCheck = False
3476 if not valueCheck:
3477 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
3478 main.log.warn( getResponses )
3479 getCheck = getCheck and valueCheck
3480 utilities.assert_equals( expect=True,
3481 actual=getCheck,
3482 onpass="Partitioned Transactional Map get values were correct",
3483 onfail="Partitioned Transactional Map values incorrect" )
3484
3485 main.step( "In-memory Transactional maps put" )
3486 tMapValue = "Testing"
3487 numKeys = 100
3488 putResult = True
3489 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue, inMemory=True )
3490 if len( putResponses ) == 100:
3491 for i in putResponses:
3492 if putResponses[ i ][ 'value' ] != tMapValue:
3493 putResult = False
3494 else:
3495 putResult = False
3496 if not putResult:
3497 main.log.debug( "Put response values: " + str( putResponses ) )
3498 utilities.assert_equals( expect=True,
3499 actual=putResult,
3500 onpass="In-Memory Transactional Map put successful",
3501 onfail="In-Memory Transactional Map put values are incorrect" )
3502
3503 main.step( "In-Memory Transactional maps get" )
3504 getCheck = True
3505 for n in range( 1, numKeys + 1 ):
3506 getResponses = []
3507 threads = []
3508 valueCheck = True
3509 for i in range( main.numCtrls ):
3510 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
3511 name="TMap-get-" + str( i ),
3512 args=[ "Key" + str ( n ) ],
3513 kwargs={ "inMemory": True } )
3514 threads.append( t )
3515 t.start()
3516 for t in threads:
3517 t.join()
3518 getResponses.append( t.result )
3519 for node in getResponses:
3520 if node != tMapValue:
3521 valueCheck = False
3522 if not valueCheck:
3523 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
3524 main.log.warn( getResponses )
3525 getCheck = getCheck and valueCheck
3526 utilities.assert_equals( expect=True,
3527 actual=getCheck,
3528 onpass="In-Memory Transactional Map get values were correct",
3529 onfail="In-Memory Transactional Map values incorrect" )