blob: a6b4592d80f97ac4ded22e2abbcfec7635125fbb [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 Hallf3d16e72015-12-16 17:45:08 -080051 import time
Jon Hall85794ff2015-07-08 14:12:30 -070052 main.log.info( "ONOS Single node cluster restart " +
53 "HA test - initialization" )
54 main.case( "Setting up test environment" )
Jon Hall783bbf92015-07-23 14:33:19 -070055 main.caseExplanation = "Setup the test environment including " +\
Jon Hall85794ff2015-07-08 14:12:30 -070056 "installing ONOS, starting Mininet and ONOS" +\
57 "cli sessions."
58 # TODO: save all the timers and output them for plotting
59
60 # load some variables from the params file
61 PULLCODE = False
62 if main.params[ 'Git' ] == 'True':
63 PULLCODE = True
64 gitBranch = main.params[ 'branch' ]
65 cellName = main.params[ 'ENV' ][ 'cellName' ]
66
Jon Halle1a3b752015-07-22 13:02:46 -070067 main.numCtrls = int( main.params[ 'num_controllers' ] )
Jon Hall5cf14d52015-07-16 12:15:19 -070068 if main.ONOSbench.maxNodes:
Jon Halle1a3b752015-07-22 13:02:46 -070069 if main.ONOSbench.maxNodes < main.numCtrls:
70 main.numCtrls = int( main.ONOSbench.maxNodes )
Jon Hall85794ff2015-07-08 14:12:30 -070071
Jon Halle1a3b752015-07-22 13:02:46 -070072 try:
73 fileName = "Counters"
74 path = main.params[ 'imports' ][ 'path' ]
75 main.Counters = imp.load_source( fileName,
76 path + fileName + ".py" )
77 except Exception as e:
78 main.log.exception( e )
79 main.cleanup()
80 main.exit()
81
82 main.CLIs = []
83 main.nodes = []
Jon Hall5cf14d52015-07-16 12:15:19 -070084 ipList = []
85 for i in range( 1, int( main.ONOSbench.maxNodes ) + 1 ):
86 try:
Jon Halle1a3b752015-07-22 13:02:46 -070087 main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
88 main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
89 ipList.append( main.nodes[ -1 ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -070090 except AttributeError:
91 break
Jon Hall85794ff2015-07-08 14:12:30 -070092
Jon Hall5cf14d52015-07-16 12:15:19 -070093 main.step( "Create cell file" )
94 cellAppString = main.params[ 'ENV' ][ 'appString' ]
95 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
96 main.Mininet1.ip_address,
97 cellAppString, ipList )
Jon Hall85794ff2015-07-08 14:12:30 -070098 main.step( "Applying cell variable to environment" )
99 cellResult = main.ONOSbench.setCell( cellName )
100 verifyResult = main.ONOSbench.verifyCell()
101
102 # FIXME:this is short term fix
103 main.log.info( "Removing raft logs" )
104 main.ONOSbench.onosRemoveRaftLogs()
105
106 main.log.info( "Uninstalling ONOS" )
Jon Halle1a3b752015-07-22 13:02:46 -0700107 for node in main.nodes:
Jon Hall85794ff2015-07-08 14:12:30 -0700108 main.ONOSbench.onosUninstall( node.ip_address )
109
110 # Make sure ONOS is DEAD
111 main.log.info( "Killing any ONOS processes" )
112 killResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -0700113 for node in main.nodes:
Jon Hall85794ff2015-07-08 14:12:30 -0700114 killed = main.ONOSbench.onosKill( node.ip_address )
115 killResults = killResults and killed
116
117 cleanInstallResult = main.TRUE
118 gitPullResult = main.TRUE
119
120 main.step( "Starting Mininet" )
121 # scp topo file to mininet
122 # TODO: move to params?
123 topoName = "obelisk.py"
124 filePath = main.ONOSbench.home + "/tools/test/topos/"
kelvin-onlabd9e23de2015-08-06 10:34:44 -0700125 main.ONOSbench.scp( main.Mininet1,
126 filePath + topoName,
127 main.Mininet1.home,
128 direction="to" )
Jon Hall85794ff2015-07-08 14:12:30 -0700129 mnResult = main.Mininet1.startNet( )
130 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
131 onpass="Mininet Started",
132 onfail="Error starting Mininet" )
133
134 main.step( "Git checkout and pull " + gitBranch )
135 if PULLCODE:
136 main.ONOSbench.gitCheckout( gitBranch )
137 gitPullResult = main.ONOSbench.gitPull()
138 # values of 1 or 3 are good
139 utilities.assert_lesser( expect=0, actual=gitPullResult,
140 onpass="Git pull successful",
141 onfail="Git pull failed" )
142 main.ONOSbench.getVersion( report=True )
143
144 main.step( "Using mvn clean install" )
145 cleanInstallResult = main.TRUE
146 if PULLCODE and gitPullResult == main.TRUE:
147 cleanInstallResult = main.ONOSbench.cleanInstall()
148 else:
149 main.log.warn( "Did not pull new code so skipping mvn " +
150 "clean install" )
151 utilities.assert_equals( expect=main.TRUE,
152 actual=cleanInstallResult,
153 onpass="MCI successful",
154 onfail="MCI failed" )
155 # GRAPHS
156 # NOTE: important params here:
157 # job = name of Jenkins job
158 # Plot Name = Plot-HA, only can be used if multiple plots
159 # index = The number of the graph under plot name
Jon Hall5cf14d52015-07-16 12:15:19 -0700160 job = "HAsingleInstanceRestart"
Jon Hall85794ff2015-07-08 14:12:30 -0700161 plotName = "Plot-HA"
Jon Halla9845df2016-01-15 14:55:58 -0800162 index = "0"
Jon Hall85794ff2015-07-08 14:12:30 -0700163 graphs = '<ac:structured-macro ac:name="html">\n'
164 graphs += '<ac:plain-text-body><![CDATA[\n'
165 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
Jon Halla9845df2016-01-15 14:55:58 -0800166 '/plot/' + plotName + '/getPlot?index=' + index +\
Jon Hall85794ff2015-07-08 14:12:30 -0700167 '&width=500&height=300"' +\
168 'noborder="0" width="500" height="300" scrolling="yes" ' +\
169 'seamless="seamless"></iframe>\n'
170 graphs += ']]></ac:plain-text-body>\n'
171 graphs += '</ac:structured-macro>\n'
172 main.log.wiki(graphs)
173
Jon Halle1a3b752015-07-22 13:02:46 -0700174 main.CLIs = []
175 main.nodes = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700176 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700177 for i in range( 1, main.numCtrls + 1 ):
178 main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
179 main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
180 ipList.append( main.nodes[ -1 ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -0700181
182 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, "SingleHA",
183 main.Mininet1.ip_address,
184 cellAppString, ipList[ 0 ] )
Jon Hall85794ff2015-07-08 14:12:30 -0700185 cellResult = main.ONOSbench.setCell( "SingleHA" )
186 verifyResult = main.ONOSbench.verifyCell()
187 main.step( "Creating ONOS package" )
188 packageResult = main.ONOSbench.onosPackage()
189 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
190 onpass="ONOS package successful",
191 onfail="ONOS package failed" )
192
193 main.step( "Installing ONOS package" )
194 onosInstallResult = main.ONOSbench.onosInstall(
Jon Halle1a3b752015-07-22 13:02:46 -0700195 options="-f", node=main.nodes[0].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -0700196 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
197 onpass="ONOS install successful",
198 onfail="ONOS install failed" )
199
200 main.step( "Checking if ONOS is up yet" )
201 for i in range( 2 ):
Jon Halle1a3b752015-07-22 13:02:46 -0700202 onos1Isup = main.ONOSbench.isup( main.nodes[0].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -0700203 if onos1Isup:
204 break
205 utilities.assert_equals( expect=main.TRUE, actual=onos1Isup,
206 onpass="ONOS startup successful",
207 onfail="ONOS startup failed" )
208
209 main.log.step( "Starting ONOS CLI sessions" )
Jon Halle1a3b752015-07-22 13:02:46 -0700210 cliResults = main.ONOScli1.startOnosCli( main.nodes[0].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -0700211 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
212 onpass="ONOS cli startup successful",
213 onfail="ONOS cli startup failed" )
214
215 if main.params[ 'tcpdump' ].lower() == "true":
216 main.step( "Start Packet Capture MN" )
217 main.Mininet2.startTcpdump(
218 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
219 + "-MN.pcap",
220 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
221 port=main.params[ 'MNtcpdump' ][ 'port' ] )
222
223 main.step( "App Ids check" )
Jon Hallf3d16e72015-12-16 17:45:08 -0800224 time.sleep(60)
Jon Hall85794ff2015-07-08 14:12:30 -0700225 appCheck = main.ONOScli1.appToIDCheck()
226 if appCheck != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700227 main.log.warn( main.CLIs[0].apps() )
228 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall85794ff2015-07-08 14:12:30 -0700229 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
230 onpass="App Ids seem to be correct",
231 onfail="Something is wrong with app Ids" )
232
233 if cliResults == main.FALSE:
234 main.log.error( "Failed to start ONOS, stopping test" )
235 main.cleanup()
236 main.exit()
237
238 def CASE2( self, main ):
239 """
240 Assign devices to controllers
241 """
242 import re
Jon Halle1a3b752015-07-22 13:02:46 -0700243 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700244 assert main, "main not defined"
245 assert utilities.assert_equals, "utilities.assert_equals not defined"
246
247 main.case( "Assigning devices to controllers" )
Jon Hall783bbf92015-07-23 14:33:19 -0700248 main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700249 "and check that an ONOS node becomes the " +\
250 "master of the device."
251 main.step( "Assign switches to controllers" )
252
253 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700254 for i in range( main.numCtrls ):
255 ipList.append( main.nodes[ i ].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -0700256 swList = []
257 for i in range( 1, 29 ):
258 swList.append( "s" + str( i ) )
259 main.Mininet1.assignSwController( sw=swList, ip=ipList )
260
261 mastershipCheck = main.TRUE
262 for i in range( 1, 29 ):
263 response = main.Mininet1.getSwController( "s" + str( i ) )
264 try:
265 main.log.info( str( response ) )
266 except Exception:
267 main.log.info( repr( response ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700268 if re.search( "tcp:" + main.nodes[0].ip_address, response ):
Jon Hall85794ff2015-07-08 14:12:30 -0700269 mastershipCheck = mastershipCheck and main.TRUE
270 else:
271 mastershipCheck = main.FALSE
272 if mastershipCheck == main.TRUE:
273 main.log.info( "Switch mastership assigned correctly" )
274 utilities.assert_equals(
275 expect=main.TRUE,
276 actual=mastershipCheck,
277 onpass="Switch mastership assigned correctly",
278 onfail="Switches not assigned correctly to controllers" )
279
280 def CASE21( self, main ):
281 """
282 Assign mastership to controllers
283 """
Jon Halle1a3b752015-07-22 13:02:46 -0700284 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700285 assert main, "main not defined"
286 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700287 assert main.CLIs, "main.CLIs not defined"
288 assert main.nodes, "main.nodes not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700289
290 main.case( "Assigning Controller roles for switches" )
Jon Hall783bbf92015-07-23 14:33:19 -0700291 main.caseExplanation = "Check that ONOS is connected to each " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700292 "device. Then manually assign" +\
293 " mastership to specific ONOS nodes using" +\
294 " 'device-role'"
295 main.step( "Assign mastership of switches to specific controllers" )
296 roleCall = main.TRUE
297 roleCheck = main.TRUE
298 try:
299 for i in range( 1, 29 ): # switches 1 through 28
Jon Halle1a3b752015-07-22 13:02:46 -0700300 ip = main.nodes[ 0 ].ip_address # ONOS1
Jon Hall85794ff2015-07-08 14:12:30 -0700301 # set up correct variables:
302 if i == 1:
303 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
304 elif i == 2:
305 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
306 elif i == 3:
307 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
308 elif i == 4:
309 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
310 elif i == 5:
311 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
312 elif i == 6:
313 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
314 elif i == 7:
315 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
316 elif i >= 8 and i <= 17:
317 dpid = '3' + str( i ).zfill( 3 )
318 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
319 elif i >= 18 and i <= 27:
320 dpid = '6' + str( i ).zfill( 3 )
321 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
322 elif i == 28:
323 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
324 else:
325 main.log.error( "You didn't write an else statement for " +
326 "switch s" + str( i ) )
327 # Assign switch
328 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
329 # TODO: make this controller dynamic
330 roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
331 ip )
332 # Check assignment
333 master = main.ONOScli1.getRole( deviceId ).get( 'master' )
334 if ip in master:
335 roleCheck = roleCheck and main.TRUE
336 else:
337 roleCheck = roleCheck and main.FALSE
338 main.log.error( "Error, controller " + ip + " is not" +
339 " master " + "of device " +
340 str( deviceId ) + ". Master is " +
341 repr( master ) + "." )
342 except ( AttributeError, AssertionError ):
343 main.log.exception( "Something is wrong with ONOS device view" )
344 main.log.info( main.ONOScli1.devices() )
345 utilities.assert_equals(
346 expect=main.TRUE,
347 actual=roleCall,
348 onpass="Re-assigned switch mastership to designated controller",
349 onfail="Something wrong with deviceRole calls" )
350
351 main.step( "Check mastership was correctly assigned" )
352 utilities.assert_equals(
353 expect=main.TRUE,
354 actual=roleCheck,
355 onpass="Switches were successfully reassigned to designated " +
356 "controller",
357 onfail="Switches were not successfully reassigned" )
358
359 def CASE3( self, main ):
360 """
361 Assign intents
362 """
363 import time
364 import json
Jon Halle1a3b752015-07-22 13:02:46 -0700365 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700366 assert main, "main not defined"
367 assert utilities.assert_equals, "utilities.assert_equals not defined"
368 # NOTE: we must reinstall intents until we have a persistant intent
369 # datastore!
370 main.case( "Adding host Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700371 main.caseExplanation = "Discover hosts by using pingall then " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700372 "assign predetermined host-to-host intents." +\
373 " After installation, check that the intent" +\
374 " is distributed to all nodes and the state" +\
375 " is INSTALLED"
376
377 # install onos-app-fwd
378 main.step( "Install reactive forwarding app" )
Jon Halle1a3b752015-07-22 13:02:46 -0700379 installResults = main.CLIs[0].activateApp( "org.onosproject.fwd" )
Jon Hall85794ff2015-07-08 14:12:30 -0700380 utilities.assert_equals( expect=main.TRUE, actual=installResults,
381 onpass="Install fwd successful",
382 onfail="Install fwd failed" )
383
384 main.step( "Check app ids" )
385 appCheck = main.ONOScli1.appToIDCheck()
386 if appCheck != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700387 main.log.warn( main.CLIs[0].apps() )
388 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall85794ff2015-07-08 14:12:30 -0700389 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
390 onpass="App Ids seem to be correct",
391 onfail="Something is wrong with app Ids" )
392
393 main.step( "Discovering Hosts( Via pingall for now )" )
394 # FIXME: Once we have a host discovery mechanism, use that instead
395 # REACTIVE FWD test
396 pingResult = main.FALSE
Jon Hall96091e62015-09-21 17:34:17 -0700397 passMsg = "Reactive Pingall test passed"
398 time1 = time.time()
399 pingResult = main.Mininet1.pingall()
400 time2 = time.time()
401 if not pingResult:
402 main.log.warn("First pingall failed. Trying again...")
Jon Hall85794ff2015-07-08 14:12:30 -0700403 pingResult = main.Mininet1.pingall()
Jon Hall96091e62015-09-21 17:34:17 -0700404 passMsg += " on the second try"
405 utilities.assert_equals(
406 expect=main.TRUE,
407 actual=pingResult,
408 onpass= passMsg,
409 onfail="Reactive Pingall failed, " +
410 "one or more ping pairs failed" )
411 main.log.info( "Time for pingall: %2f seconds" %
412 ( time2 - time1 ) )
Jon Hall85794ff2015-07-08 14:12:30 -0700413 # timeout for fwd flows
414 time.sleep( 11 )
415 # uninstall onos-app-fwd
416 main.step( "Uninstall reactive forwarding app" )
Jon Halle1a3b752015-07-22 13:02:46 -0700417 uninstallResult = main.CLIs[0].deactivateApp( "org.onosproject.fwd" )
Jon Hall85794ff2015-07-08 14:12:30 -0700418 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
419 onpass="Uninstall fwd successful",
420 onfail="Uninstall fwd failed" )
421
422 main.step( "Check app ids" )
423 appCheck2 = main.ONOScli1.appToIDCheck()
424 if appCheck2 != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700425 main.log.warn( main.CLIs[0].apps() )
426 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall85794ff2015-07-08 14:12:30 -0700427 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
428 onpass="App Ids seem to be correct",
429 onfail="Something is wrong with app Ids" )
430
431 main.step( "Add host intents via cli" )
432 intentIds = []
433 # TODO: move the host numbers to params
434 # Maybe look at all the paths we ping?
435 intentAddResult = True
436 hostResult = main.TRUE
437 for i in range( 8, 18 ):
438 main.log.info( "Adding host intent between h" + str( i ) +
439 " and h" + str( i + 10 ) )
440 host1 = "00:00:00:00:00:" + \
441 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
442 host2 = "00:00:00:00:00:" + \
443 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
444 # NOTE: getHost can return None
445 host1Dict = main.ONOScli1.getHost( host1 )
446 host2Dict = main.ONOScli1.getHost( host2 )
447 host1Id = None
448 host2Id = None
449 if host1Dict and host2Dict:
450 host1Id = host1Dict.get( 'id', None )
451 host2Id = host2Dict.get( 'id', None )
452 if host1Id and host2Id:
453 tmpId = main.ONOScli1.addHostIntent( host1Id, host2Id )
454 if tmpId:
455 main.log.info( "Added intent with id: " + tmpId )
456 intentIds.append( tmpId )
457 else:
458 main.log.error( "addHostIntent returned: " +
459 repr( tmpId ) )
460 else:
461 main.log.error( "Error, getHost() failed for h" + str( i ) +
462 " and/or h" + str( i + 10 ) )
463 hosts = main.ONOScli1.hosts()
464 main.log.warn( "Hosts output: " )
465 try:
466 main.log.warn( json.dumps( json.loads( hosts ),
467 sort_keys=True,
468 indent=4,
469 separators=( ',', ': ' ) ) )
470 except ( ValueError, TypeError ):
471 main.log.warn( repr( hosts ) )
472 hostResult = main.FALSE
473 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
474 onpass="Found a host id for each host",
475 onfail="Error looking up host ids" )
476
477 intentStart = time.time()
478 onosIds = main.ONOScli1.getAllIntentsId()
479 main.log.info( "Submitted intents: " + str( intentIds ) )
480 main.log.info( "Intents in ONOS: " + str( onosIds ) )
481 for intent in intentIds:
482 if intent in onosIds:
483 pass # intent submitted is in onos
484 else:
485 intentAddResult = False
486 if intentAddResult:
487 intentStop = time.time()
488 else:
489 intentStop = None
490 # Print the intent states
491 intents = main.ONOScli1.intents()
492 intentStates = []
493 installedCheck = True
494 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
495 count = 0
496 try:
497 for intent in json.loads( intents ):
498 state = intent.get( 'state', None )
499 if "INSTALLED" not in state:
500 installedCheck = False
501 intentId = intent.get( 'id', None )
502 intentStates.append( ( intentId, state ) )
503 except ( ValueError, TypeError ):
504 main.log.exception( "Error parsing intents" )
505 # add submitted intents not in the store
506 tmplist = [ i for i, s in intentStates ]
507 missingIntents = False
508 for i in intentIds:
509 if i not in tmplist:
510 intentStates.append( ( i, " - " ) )
511 missingIntents = True
512 intentStates.sort()
513 for i, s in intentStates:
514 count += 1
515 main.log.info( "%-6s%-15s%-15s" %
516 ( str( count ), str( i ), str( s ) ) )
517 leaders = main.ONOScli1.leaders()
518 try:
519 missing = False
520 if leaders:
521 parsedLeaders = json.loads( leaders )
522 main.log.warn( json.dumps( parsedLeaders,
523 sort_keys=True,
524 indent=4,
525 separators=( ',', ': ' ) ) )
526 # check for all intent partitions
527 topics = []
528 for i in range( 14 ):
529 topics.append( "intent-partition-" + str( i ) )
530 main.log.debug( topics )
531 ONOStopics = [ j['topic'] for j in parsedLeaders ]
532 for topic in topics:
533 if topic not in ONOStopics:
534 main.log.error( "Error: " + topic +
535 " not in leaders" )
536 missing = True
537 else:
538 main.log.error( "leaders() returned None" )
539 except ( ValueError, TypeError ):
540 main.log.exception( "Error parsing leaders" )
541 main.log.error( repr( leaders ) )
542 # Check all nodes
543 if missing:
544 response = main.ONOScli1.leaders( jsonFormat=False)
545 main.log.warn( "ONOS1 leaders output: \n" +
546 str( response ) )
547
548 partitions = main.ONOScli1.partitions()
549 try:
550 if partitions :
551 parsedPartitions = json.loads( partitions )
552 main.log.warn( json.dumps( parsedPartitions,
553 sort_keys=True,
554 indent=4,
555 separators=( ',', ': ' ) ) )
556 # TODO check for a leader in all paritions
557 # TODO check for consistency among nodes
558 else:
559 main.log.error( "partitions() returned None" )
560 except ( ValueError, TypeError ):
561 main.log.exception( "Error parsing partitions" )
562 main.log.error( repr( partitions ) )
563 pendingMap = main.ONOScli1.pendingMap()
564 try:
565 if pendingMap :
566 parsedPending = json.loads( pendingMap )
567 main.log.warn( json.dumps( parsedPending,
568 sort_keys=True,
569 indent=4,
570 separators=( ',', ': ' ) ) )
571 # TODO check something here?
572 else:
573 main.log.error( "pendingMap() returned None" )
574 except ( ValueError, TypeError ):
575 main.log.exception( "Error parsing pending map" )
576 main.log.error( repr( pendingMap ) )
577
578 intentAddResult = bool( intentAddResult and not missingIntents and
579 installedCheck )
580 if not intentAddResult:
581 main.log.error( "Error in pushing host intents to ONOS" )
582
583 main.step( "Intent Anti-Entropy dispersion" )
584 for i in range(100):
585 correct = True
586 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700587 for cli in main.CLIs:
Jon Hall85794ff2015-07-08 14:12:30 -0700588 onosIds = []
589 ids = cli.getAllIntentsId()
590 onosIds.append( ids )
591 main.log.debug( "Intents in " + cli.name + ": " +
592 str( sorted( onosIds ) ) )
593 if sorted( ids ) != sorted( intentIds ):
594 main.log.warn( "Set of intent IDs doesn't match" )
595 correct = False
596 break
597 else:
598 intents = json.loads( cli.intents() )
599 for intent in intents:
600 if intent[ 'state' ] != "INSTALLED":
601 main.log.warn( "Intent " + intent[ 'id' ] +
602 " is " + intent[ 'state' ] )
603 correct = False
604 break
605 if correct:
606 break
607 else:
608 time.sleep(1)
609 if not intentStop:
610 intentStop = time.time()
611 global gossipTime
612 gossipTime = intentStop - intentStart
613 main.log.info( "It took about " + str( gossipTime ) +
614 " seconds for all intents to appear in each node" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700615 gossipPeriod = int( main.params['timers']['gossip'] )
616 maxGossipTime = gossipPeriod * len( main.nodes )
Jon Hall85794ff2015-07-08 14:12:30 -0700617 utilities.assert_greater_equals(
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700618 expect=maxGossipTime, actual=gossipTime,
Jon Hall85794ff2015-07-08 14:12:30 -0700619 onpass="ECM anti-entropy for intents worked within " +
620 "expected time",
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700621 onfail="Intent ECM anti-entropy took too long. " +
622 "Expected time:{}, Actual time:{}".format( maxGossipTime,
623 gossipTime ) )
624 if gossipTime <= maxGossipTime:
Jon Hall85794ff2015-07-08 14:12:30 -0700625 intentAddResult = True
626
627 if not intentAddResult or "key" in pendingMap:
628 import time
629 installedCheck = True
630 main.log.info( "Sleeping 60 seconds to see if intents are found" )
631 time.sleep( 60 )
632 onosIds = main.ONOScli1.getAllIntentsId()
633 main.log.info( "Submitted intents: " + str( intentIds ) )
634 main.log.info( "Intents in ONOS: " + str( onosIds ) )
635 # Print the intent states
636 intents = main.ONOScli1.intents()
637 intentStates = []
638 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
639 count = 0
640 try:
641 for intent in json.loads( intents ):
642 # Iter through intents of a node
643 state = intent.get( 'state', None )
644 if "INSTALLED" not in state:
645 installedCheck = False
646 intentId = intent.get( 'id', None )
647 intentStates.append( ( intentId, state ) )
648 except ( ValueError, TypeError ):
649 main.log.exception( "Error parsing intents" )
650 # add submitted intents not in the store
651 tmplist = [ i for i, s in intentStates ]
652 for i in intentIds:
653 if i not in tmplist:
654 intentStates.append( ( i, " - " ) )
655 intentStates.sort()
656 for i, s in intentStates:
657 count += 1
658 main.log.info( "%-6s%-15s%-15s" %
659 ( str( count ), str( i ), str( s ) ) )
660 leaders = main.ONOScli1.leaders()
661 try:
662 missing = False
663 if leaders:
664 parsedLeaders = json.loads( leaders )
665 main.log.warn( json.dumps( parsedLeaders,
666 sort_keys=True,
667 indent=4,
668 separators=( ',', ': ' ) ) )
669 # check for all intent partitions
670 # check for election
671 topics = []
672 for i in range( 14 ):
673 topics.append( "intent-partition-" + str( i ) )
674 # FIXME: this should only be after we start the app
675 topics.append( "org.onosproject.election" )
676 main.log.debug( topics )
677 ONOStopics = [ j['topic'] for j in parsedLeaders ]
678 for topic in topics:
679 if topic not in ONOStopics:
680 main.log.error( "Error: " + topic +
681 " not in leaders" )
682 missing = True
683 else:
684 main.log.error( "leaders() returned None" )
685 except ( ValueError, TypeError ):
686 main.log.exception( "Error parsing leaders" )
687 main.log.error( repr( leaders ) )
688 # Check all nodes
689 if missing:
690 response = main.ONOScli1.leaders( jsonFormat=False)
691 main.log.warn( "ONOS1 leaders output: \n" +
692 str( response ) )
693 partitions = main.ONOScli1.partitions()
694 try:
695 if partitions :
696 parsedPartitions = json.loads( partitions )
697 main.log.warn( json.dumps( parsedPartitions,
698 sort_keys=True,
699 indent=4,
700 separators=( ',', ': ' ) ) )
701 # TODO check for a leader in all paritions
702 # TODO check for consistency among nodes
703 else:
704 main.log.error( "partitions() returned None" )
705 except ( ValueError, TypeError ):
706 main.log.exception( "Error parsing partitions" )
707 main.log.error( repr( partitions ) )
708 pendingMap = main.ONOScli1.pendingMap()
709 try:
710 if pendingMap :
711 parsedPending = json.loads( pendingMap )
712 main.log.warn( json.dumps( parsedPending,
713 sort_keys=True,
714 indent=4,
715 separators=( ',', ': ' ) ) )
716 # TODO check something here?
717 else:
718 main.log.error( "pendingMap() returned None" )
719 except ( ValueError, TypeError ):
720 main.log.exception( "Error parsing pending map" )
721 main.log.error( repr( pendingMap ) )
722
723 def CASE4( self, main ):
724 """
725 Ping across added host intents
726 """
727 import json
728 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700729 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700730 assert main, "main not defined"
731 assert utilities.assert_equals, "utilities.assert_equals not defined"
732 main.case( "Verify connectivity by sendind traffic across Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700733 main.caseExplanation = "Ping across added host intents to check " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700734 "functionality and check the state of " +\
735 "the intent"
736 main.step( "Ping across added host intents" )
737 PingResult = main.TRUE
738 for i in range( 8, 18 ):
739 ping = main.Mininet1.pingHost( src="h" + str( i ),
740 target="h" + str( i + 10 ) )
741 PingResult = PingResult and ping
742 if ping == main.FALSE:
743 main.log.warn( "Ping failed between h" + str( i ) +
744 " and h" + str( i + 10 ) )
745 elif ping == main.TRUE:
746 main.log.info( "Ping test passed!" )
747 # Don't set PingResult or you'd override failures
748 if PingResult == main.FALSE:
749 main.log.error(
750 "Intents have not been installed correctly, pings failed." )
751 # TODO: pretty print
752 main.log.warn( "ONOS1 intents: " )
753 try:
754 tmpIntents = main.ONOScli1.intents()
755 main.log.warn( json.dumps( json.loads( tmpIntents ),
756 sort_keys=True,
757 indent=4,
758 separators=( ',', ': ' ) ) )
759 except ( ValueError, TypeError ):
760 main.log.warn( repr( tmpIntents ) )
761 utilities.assert_equals(
762 expect=main.TRUE,
763 actual=PingResult,
764 onpass="Intents have been installed correctly and pings work",
765 onfail="Intents have not been installed correctly, pings failed." )
766
767 main.step( "Check Intent state" )
768 installedCheck = True
769 # Print the intent states
770 intents = main.ONOScli1.intents()
771 intentStates = []
772 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
773 count = 0
774 # Iter through intents of a node
775 try:
776 for intent in json.loads( intents ):
777 state = intent.get( 'state', None )
778 if "INSTALLED" not in state:
779 installedCheck = False
780 intentId = intent.get( 'id', None )
781 intentStates.append( ( intentId, state ) )
782 except ( ValueError, TypeError ):
783 main.log.exception( "Error parsing intents." )
784 # Print states
785 intentStates.sort()
786 for i, s in intentStates:
787 count += 1
788 main.log.info( "%-6s%-15s%-15s" %
789 ( str( count ), str( i ), str( s ) ) )
790 utilities.assert_equals( expect=True, actual=installedCheck,
791 onpass="Intents are all INSTALLED",
792 onfail="Intents are not all in " +
793 "INSTALLED state" )
794
795 main.step( "Check leadership of topics" )
796 leaders = main.ONOScli1.leaders()
797 topicCheck = main.TRUE
798 try:
799 if leaders:
800 parsedLeaders = json.loads( leaders )
801 main.log.warn( json.dumps( parsedLeaders,
802 sort_keys=True,
803 indent=4,
804 separators=( ',', ': ' ) ) )
805 # check for all intent partitions
806 # check for election
807 # TODO: Look at Devices as topics now that it uses this system
808 topics = []
809 for i in range( 14 ):
810 topics.append( "intent-partition-" + str( i ) )
811 # FIXME: this should only be after we start the app
812 # FIXME: topics.append( "org.onosproject.election" )
813 # Print leaders output
814 main.log.debug( topics )
815 ONOStopics = [ j['topic'] for j in parsedLeaders ]
816 for topic in topics:
817 if topic not in ONOStopics:
818 main.log.error( "Error: " + topic +
819 " not in leaders" )
820 topicCheck = main.FALSE
821 else:
822 main.log.error( "leaders() returned None" )
823 topicCheck = main.FALSE
824 except ( ValueError, TypeError ):
825 topicCheck = main.FALSE
826 main.log.exception( "Error parsing leaders" )
827 main.log.error( repr( leaders ) )
828 # TODO: Check for a leader of these topics
829 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
830 onpass="intent Partitions is in leaders",
831 onfail="Some topics were lost " )
832 # Print partitions
833 partitions = main.ONOScli1.partitions()
834 try:
835 if partitions :
836 parsedPartitions = json.loads( partitions )
837 main.log.warn( json.dumps( parsedPartitions,
838 sort_keys=True,
839 indent=4,
840 separators=( ',', ': ' ) ) )
841 # TODO check for a leader in all paritions
842 # TODO check for consistency among nodes
843 else:
844 main.log.error( "partitions() returned None" )
845 except ( ValueError, TypeError ):
846 main.log.exception( "Error parsing partitions" )
847 main.log.error( repr( partitions ) )
848 # Print Pending Map
849 pendingMap = main.ONOScli1.pendingMap()
850 try:
851 if pendingMap :
852 parsedPending = json.loads( pendingMap )
853 main.log.warn( json.dumps( parsedPending,
854 sort_keys=True,
855 indent=4,
856 separators=( ',', ': ' ) ) )
857 # TODO check something here?
858 else:
859 main.log.error( "pendingMap() returned None" )
860 except ( ValueError, TypeError ):
861 main.log.exception( "Error parsing pending map" )
862 main.log.error( repr( pendingMap ) )
863
864 if not installedCheck:
865 main.log.info( "Waiting 60 seconds to see if the state of " +
866 "intents change" )
867 time.sleep( 60 )
868 # Print the intent states
869 intents = main.ONOScli1.intents()
870 intentStates = []
871 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
872 count = 0
873 # Iter through intents of a node
874 try:
875 for intent in json.loads( intents ):
876 state = intent.get( 'state', None )
877 if "INSTALLED" not in state:
878 installedCheck = False
879 intentId = intent.get( 'id', None )
880 intentStates.append( ( intentId, state ) )
881 except ( ValueError, TypeError ):
882 main.log.exception( "Error parsing intents." )
883 intentStates.sort()
884 for i, s in intentStates:
885 count += 1
886 main.log.info( "%-6s%-15s%-15s" %
887 ( str( count ), str( i ), str( s ) ) )
888 leaders = main.ONOScli1.leaders()
889 try:
890 missing = False
891 if leaders:
892 parsedLeaders = json.loads( leaders )
893 main.log.warn( json.dumps( parsedLeaders,
894 sort_keys=True,
895 indent=4,
896 separators=( ',', ': ' ) ) )
897 # check for all intent partitions
898 # check for election
899 topics = []
900 for i in range( 14 ):
901 topics.append( "intent-partition-" + str( i ) )
902 # FIXME: this should only be after we start the app
903 topics.append( "org.onosproject.election" )
904 main.log.debug( topics )
905 ONOStopics = [ j['topic'] for j in parsedLeaders ]
906 for topic in topics:
907 if topic not in ONOStopics:
908 main.log.error( "Error: " + topic +
909 " not in leaders" )
910 missing = True
911 else:
912 main.log.error( "leaders() returned None" )
913 except ( ValueError, TypeError ):
914 main.log.exception( "Error parsing leaders" )
915 main.log.error( repr( leaders ) )
916 if missing:
917 response = main.ONOScli1.leaders( jsonFormat=False)
918 main.log.warn( "ONOS1 leaders output: \n" +
919 str( response ) )
920 partitions = main.ONOScli1.partitions()
921 try:
922 if partitions :
923 parsedPartitions = json.loads( partitions )
924 main.log.warn( json.dumps( parsedPartitions,
925 sort_keys=True,
926 indent=4,
927 separators=( ',', ': ' ) ) )
928 # TODO check for a leader in all paritions
929 # TODO check for consistency among nodes
930 else:
931 main.log.error( "partitions() returned None" )
932 except ( ValueError, TypeError ):
933 main.log.exception( "Error parsing partitions" )
934 main.log.error( repr( partitions ) )
935 pendingMap = main.ONOScli1.pendingMap()
936 try:
937 if pendingMap :
938 parsedPending = json.loads( pendingMap )
939 main.log.warn( json.dumps( parsedPending,
940 sort_keys=True,
941 indent=4,
942 separators=( ',', ': ' ) ) )
943 # TODO check something here?
944 else:
945 main.log.error( "pendingMap() returned None" )
946 except ( ValueError, TypeError ):
947 main.log.exception( "Error parsing pending map" )
948 main.log.error( repr( pendingMap ) )
949 # Print flowrules
Jon Halle1a3b752015-07-22 13:02:46 -0700950 main.log.debug( main.CLIs[0].flows( jsonFormat=False ) )
Jon Hall85794ff2015-07-08 14:12:30 -0700951 main.step( "Wait a minute then ping again" )
952 # the wait is above
953 PingResult = main.TRUE
954 for i in range( 8, 18 ):
955 ping = main.Mininet1.pingHost( src="h" + str( i ),
956 target="h" + str( i + 10 ) )
957 PingResult = PingResult and ping
958 if ping == main.FALSE:
959 main.log.warn( "Ping failed between h" + str( i ) +
960 " and h" + str( i + 10 ) )
961 elif ping == main.TRUE:
962 main.log.info( "Ping test passed!" )
963 # Don't set PingResult or you'd override failures
964 if PingResult == main.FALSE:
965 main.log.error(
966 "Intents have not been installed correctly, pings failed." )
967 # TODO: pretty print
968 main.log.warn( "ONOS1 intents: " )
969 try:
970 tmpIntents = main.ONOScli1.intents()
971 main.log.warn( json.dumps( json.loads( tmpIntents ),
972 sort_keys=True,
973 indent=4,
974 separators=( ',', ': ' ) ) )
975 except ( ValueError, TypeError ):
976 main.log.warn( repr( tmpIntents ) )
977 utilities.assert_equals(
978 expect=main.TRUE,
979 actual=PingResult,
980 onpass="Intents have been installed correctly and pings work",
981 onfail="Intents have not been installed correctly, pings failed." )
982
983 def CASE5( self, main ):
984 """
985 Reading state of ONOS
986 """
987 import json
Jon Halle1a3b752015-07-22 13:02:46 -0700988 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700989 assert main, "main not defined"
990 assert utilities.assert_equals, "utilities.assert_equals not defined"
991
992 main.case( "Setting up and gathering data for current state" )
993 # The general idea for this test case is to pull the state of
994 # ( intents,flows, topology,... ) from each ONOS node
995 # We can then compare them with each other and also with past states
996
997 main.step( "Check that each switch has a master" )
998 global mastershipState
999 mastershipState = '[]'
1000
1001 # Assert that each device has a master
1002 rolesNotNull = main.ONOScli1.rolesNotNull()
1003 utilities.assert_equals(
1004 expect=main.TRUE,
1005 actual=rolesNotNull,
1006 onpass="Each device has a master",
1007 onfail="Some devices don't have a master assigned" )
1008
1009 main.step( "Get the Mastership of each switch" )
1010 ONOS1Mastership = main.ONOScli1.roles()
1011 # TODO: Make this a meaningful check
1012 if "Error" in ONOS1Mastership or not ONOS1Mastership:
1013 main.log.error( "Error in getting ONOS roles" )
1014 main.log.warn(
1015 "ONOS1 mastership response: " +
1016 repr( ONOS1Mastership ) )
1017 consistentMastership = main.FALSE
1018 else:
1019 mastershipState = ONOS1Mastership
1020 consistentMastership = main.TRUE
1021
1022 main.step( "Get the intents from each controller" )
1023 global intentState
1024 intentState = []
1025 ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
1026 intentCheck = main.FALSE
1027 if "Error" in ONOS1Intents or not ONOS1Intents:
1028 main.log.error( "Error in getting ONOS intents" )
1029 main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
1030 else:
1031 intentCheck = main.TRUE
1032
1033 main.step( "Get the flows from each controller" )
1034 global flowState
1035 flowState = []
1036 flowCheck = main.FALSE
1037 ONOS1Flows = main.ONOScli1.flows( jsonFormat=True )
1038 if "Error" in ONOS1Flows or not ONOS1Flows:
1039 main.log.error( "Error in getting ONOS flows" )
1040 main.log.warn( "ONOS1 flows repsponse: " + ONOS1Flows )
1041 else:
1042 # TODO: Do a better check, maybe compare flows on switches?
1043 flowState = ONOS1Flows
1044 flowCheck = main.TRUE
1045
1046 main.step( "Get the OF Table entries" )
1047 global flows
1048 flows = []
1049 for i in range( 1, 29 ):
GlennRC68467eb2015-11-16 18:01:01 -08001050 flows.append( main.Mininet1.getFlowTable( "s" + str( i ), version="1.3", debug=False ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001051 if flowCheck == main.FALSE:
1052 for table in flows:
1053 main.log.warn( table )
1054 # TODO: Compare switch flow tables with ONOS flow tables
1055
1056 main.step( "Collecting topology information from ONOS" )
1057 devices = []
1058 devices.append( main.ONOScli1.devices() )
1059 hosts = []
1060 hosts.append( json.loads( main.ONOScli1.hosts() ) )
1061 ports = []
1062 ports.append( main.ONOScli1.ports() )
1063 links = []
1064 links.append( main.ONOScli1.links() )
1065 clusters = []
1066 clusters.append( main.ONOScli1.clusters() )
1067
1068 main.step( "Each host has an IP address" )
1069 ipResult = main.TRUE
1070 for controller in range( 0, len( hosts ) ):
1071 controllerStr = str( controller + 1 )
1072 for host in hosts[ controller ]:
1073 if host is None or host.get( 'ipAddresses', [] ) == []:
1074 main.log.error(
1075 "DEBUG:Error with host ips on controller" +
1076 controllerStr + ": " + str( host ) )
1077 ipResult = main.FALSE
1078 utilities.assert_equals(
1079 expect=main.TRUE,
1080 actual=ipResult,
1081 onpass="The ips of the hosts aren't empty",
1082 onfail="The ip of at least one host is missing" )
1083
1084 # there should always only be one cluster
1085 main.step( "There is only one dataplane cluster" )
1086 try:
1087 numClusters = len( json.loads( clusters[ 0 ] ) )
1088 except ( ValueError, TypeError ):
1089 main.log.exception( "Error parsing clusters[0]: " +
1090 repr( clusters[ 0 ] ) )
1091 clusterResults = main.FALSE
1092 if numClusters == 1:
1093 clusterResults = main.TRUE
1094 utilities.assert_equals(
1095 expect=1,
1096 actual=numClusters,
1097 onpass="ONOS shows 1 SCC",
1098 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1099
1100 main.step( "Comparing ONOS topology to MN" )
1101 devicesResults = main.TRUE
1102 linksResults = main.TRUE
1103 hostsResults = main.TRUE
1104 mnSwitches = main.Mininet1.getSwitches()
1105 mnLinks = main.Mininet1.getLinks()
1106 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07001107 for controller in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07001108 controllerStr = str( controller + 1 )
1109 if devices[ controller ] and ports[ controller ] and\
1110 "Error" not in devices[ controller ] and\
1111 "Error" not in ports[ controller ]:
1112
1113 currentDevicesResult = main.Mininet1.compareSwitches(
1114 mnSwitches,
1115 json.loads( devices[ controller ] ),
1116 json.loads( ports[ controller ] ) )
1117 else:
1118 currentDevicesResult = main.FALSE
1119 utilities.assert_equals( expect=main.TRUE,
1120 actual=currentDevicesResult,
1121 onpass="ONOS" + controllerStr +
1122 " Switches view is correct",
1123 onfail="ONOS" + controllerStr +
1124 " Switches view is incorrect" )
1125 if links[ controller ] and "Error" not in links[ controller ]:
1126 currentLinksResult = main.Mininet1.compareLinks(
1127 mnSwitches, mnLinks,
1128 json.loads( links[ controller ] ) )
1129 else:
1130 currentLinksResult = main.FALSE
1131 utilities.assert_equals( expect=main.TRUE,
1132 actual=currentLinksResult,
1133 onpass="ONOS" + controllerStr +
1134 " links view is correct",
1135 onfail="ONOS" + controllerStr +
1136 " links view is incorrect" )
1137
1138 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1139 currentHostsResult = main.Mininet1.compareHosts(
1140 mnHosts,
1141 hosts[ controller ] )
1142 else:
1143 currentHostsResult = main.FALSE
1144 utilities.assert_equals( expect=main.TRUE,
1145 actual=currentHostsResult,
1146 onpass="ONOS" + controllerStr +
1147 " hosts exist in Mininet",
1148 onfail="ONOS" + controllerStr +
1149 " hosts don't match Mininet" )
1150
1151 devicesResults = devicesResults and currentDevicesResult
1152 linksResults = linksResults and currentLinksResult
1153 hostsResults = hostsResults and currentHostsResult
1154
1155 main.step( "Device information is correct" )
1156 utilities.assert_equals(
1157 expect=main.TRUE,
1158 actual=devicesResults,
1159 onpass="Device information is correct",
1160 onfail="Device information is incorrect" )
1161
1162 main.step( "Links are correct" )
1163 utilities.assert_equals(
1164 expect=main.TRUE,
1165 actual=linksResults,
1166 onpass="Link are correct",
1167 onfail="Links are incorrect" )
1168
1169 main.step( "Hosts are correct" )
1170 utilities.assert_equals(
1171 expect=main.TRUE,
1172 actual=hostsResults,
1173 onpass="Hosts are correct",
1174 onfail="Hosts are incorrect" )
1175
1176 def CASE6( self, main ):
1177 """
1178 The Failure case.
1179 """
1180 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001181 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001182 assert main, "main not defined"
1183 assert utilities.assert_equals, "utilities.assert_equals not defined"
1184
1185 # Reset non-persistent variables
1186 try:
1187 iCounterValue = 0
1188 except NameError:
1189 main.log.error( "iCounterValue not defined, setting to 0" )
1190 iCounterValue = 0
1191
1192 main.case( "Restart ONOS node" )
Jon Hall783bbf92015-07-23 14:33:19 -07001193 main.caseExplanation = "Killing ONOS process and restart cli " +\
Jon Hall85794ff2015-07-08 14:12:30 -07001194 "sessions once onos is up."
Jon Hall96091e62015-09-21 17:34:17 -07001195
1196 main.step( "Checking ONOS Logs for errors" )
1197 for node in main.nodes:
1198 main.log.debug( "Checking logs for errors on " + node.name + ":" )
1199 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
1200
Jon Hall85794ff2015-07-08 14:12:30 -07001201 main.step( "Killing ONOS processes" )
Jon Halle1a3b752015-07-22 13:02:46 -07001202 killResult = main.ONOSbench.onosKill( main.nodes[0].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -07001203 start = time.time()
1204 utilities.assert_equals( expect=main.TRUE, actual=killResult,
1205 onpass="ONOS Killed",
1206 onfail="Error killing ONOS" )
1207
1208 main.step( "Checking if ONOS is up yet" )
1209 count = 0
1210 while count < 10:
Jon Halle1a3b752015-07-22 13:02:46 -07001211 onos1Isup = main.ONOSbench.isup( main.nodes[0].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -07001212 if onos1Isup == main.TRUE:
1213 elapsed = time.time() - start
1214 break
1215 else:
1216 count = count + 1
1217 utilities.assert_equals( expect=main.TRUE, actual=onos1Isup,
1218 onpass="ONOS is back up",
1219 onfail="ONOS failed to start" )
1220
1221 main.log.step( "Starting ONOS CLI sessions" )
Jon Halle1a3b752015-07-22 13:02:46 -07001222 cliResults = main.ONOScli1.startOnosCli( main.nodes[0].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -07001223 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1224 onpass="ONOS cli startup successful",
1225 onfail="ONOS cli startup failed" )
1226
1227 if elapsed:
1228 main.log.info( "ESTIMATE: ONOS took %s seconds to restart" %
1229 str( elapsed ) )
1230 main.restartTime = elapsed
1231 else:
1232 main.restartTime = -1
1233 time.sleep( 5 )
1234 # rerun on election apps
1235 main.ONOScli1.electionTestRun()
1236
1237 def CASE7( self, main ):
1238 """
1239 Check state after ONOS failure
1240 """
1241 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001242 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001243 assert main, "main not defined"
1244 assert utilities.assert_equals, "utilities.assert_equals not defined"
1245 main.case( "Running ONOS Constant State Tests" )
1246 main.step( "Check that each switch has a master" )
1247 # Assert that each device has a master
1248 rolesNotNull = main.ONOScli1.rolesNotNull()
1249 utilities.assert_equals(
1250 expect=main.TRUE,
1251 actual=rolesNotNull,
1252 onpass="Each device has a master",
1253 onfail="Some devices don't have a master assigned" )
1254
1255 main.step( "Check if switch roles are consistent across all nodes" )
1256 ONOS1Mastership = main.ONOScli1.roles()
1257 # FIXME: Refactor this whole case for single instance
1258 if "Error" in ONOS1Mastership or not ONOS1Mastership:
1259 main.log.error( "Error in getting ONOS mastership" )
1260 main.log.warn( "ONOS1 mastership response: " +
1261 repr( ONOS1Mastership ) )
1262 consistentMastership = main.FALSE
1263 else:
1264 consistentMastership = main.TRUE
1265 utilities.assert_equals(
1266 expect=main.TRUE,
1267 actual=consistentMastership,
1268 onpass="Switch roles are consistent across all ONOS nodes",
1269 onfail="ONOS nodes have different views of switch roles" )
1270
1271 description2 = "Compare switch roles from before failure"
1272 main.step( description2 )
1273
1274 currentJson = json.loads( ONOS1Mastership )
1275 oldJson = json.loads( mastershipState )
1276 mastershipCheck = main.TRUE
1277 for i in range( 1, 29 ):
1278 switchDPID = str(
1279 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
1280
1281 current = [ switch[ 'master' ] for switch in currentJson
1282 if switchDPID in switch[ 'id' ] ]
1283 old = [ switch[ 'master' ] for switch in oldJson
1284 if switchDPID in switch[ 'id' ] ]
1285 if current == old:
1286 mastershipCheck = mastershipCheck and main.TRUE
1287 else:
1288 main.log.warn( "Mastership of switch %s changed" % switchDPID )
1289 mastershipCheck = main.FALSE
1290 utilities.assert_equals(
1291 expect=main.TRUE,
1292 actual=mastershipCheck,
1293 onpass="Mastership of Switches was not changed",
1294 onfail="Mastership of some switches changed" )
1295 mastershipCheck = mastershipCheck and consistentMastership
1296
1297 main.step( "Get the intents and compare across all nodes" )
1298 ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
1299 intentCheck = main.FALSE
1300 if "Error" in ONOS1Intents or not ONOS1Intents:
1301 main.log.error( "Error in getting ONOS intents" )
1302 main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
1303 else:
1304 intentCheck = main.TRUE
1305 utilities.assert_equals(
1306 expect=main.TRUE,
1307 actual=intentCheck,
1308 onpass="Intents are consistent across all ONOS nodes",
1309 onfail="ONOS nodes have different views of intents" )
1310 # Print the intent states
1311 intents = []
1312 intents.append( ONOS1Intents )
1313 intentStates = []
1314 for node in intents: # Iter through ONOS nodes
1315 nodeStates = []
1316 # Iter through intents of a node
1317 for intent in json.loads( node ):
1318 nodeStates.append( intent[ 'state' ] )
1319 intentStates.append( nodeStates )
1320 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1321 main.log.info( dict( out ) )
1322
1323 # NOTE: Store has no durability, so intents are lost across system
1324 # restarts
1325 """
1326 main.step( "Compare current intents with intents before the failure" )
1327 # NOTE: this requires case 5 to pass for intentState to be set.
1328 # maybe we should stop the test if that fails?
1329 sameIntents = main.FALSE
1330 if intentState and intentState == ONOSIntents[ 0 ]:
1331 sameIntents = main.TRUE
1332 main.log.info( "Intents are consistent with before failure" )
1333 # TODO: possibly the states have changed? we may need to figure out
1334 # what the acceptable states are
1335 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
1336 sameIntents = main.TRUE
1337 try:
1338 before = json.loads( intentState )
1339 after = json.loads( ONOSIntents[ 0 ] )
1340 for intent in before:
1341 if intent not in after:
1342 sameIntents = main.FALSE
1343 main.log.debug( "Intent is not currently in ONOS " +
1344 "(at least in the same form):" )
1345 main.log.debug( json.dumps( intent ) )
1346 except ( ValueError, TypeError ):
1347 main.log.exception( "Exception printing intents" )
1348 main.log.debug( repr( ONOSIntents[0] ) )
1349 main.log.debug( repr( intentState ) )
1350 if sameIntents == main.FALSE:
1351 try:
1352 main.log.debug( "ONOS intents before: " )
1353 main.log.debug( json.dumps( json.loads( intentState ),
1354 sort_keys=True, indent=4,
1355 separators=( ',', ': ' ) ) )
1356 main.log.debug( "Current ONOS intents: " )
1357 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1358 sort_keys=True, indent=4,
1359 separators=( ',', ': ' ) ) )
1360 except ( ValueError, TypeError ):
1361 main.log.exception( "Exception printing intents" )
1362 main.log.debug( repr( ONOSIntents[0] ) )
1363 main.log.debug( repr( intentState ) )
1364 utilities.assert_equals(
1365 expect=main.TRUE,
1366 actual=sameIntents,
1367 onpass="Intents are consistent with before failure",
1368 onfail="The Intents changed during failure" )
1369 intentCheck = intentCheck and sameIntents
1370 """
1371 main.step( "Get the OF Table entries and compare to before " +
1372 "component failure" )
1373 FlowTables = main.TRUE
Jon Hall85794ff2015-07-08 14:12:30 -07001374 for i in range( 28 ):
1375 main.log.info( "Checking flow table on s" + str( i + 1 ) )
GlennRC68467eb2015-11-16 18:01:01 -08001376 tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
1377 FlowTables = FlowTables and main.Mininet1.flowTableComp( flows[i], tmpFlows )
Jon Hall85794ff2015-07-08 14:12:30 -07001378 if FlowTables == main.FALSE:
GlennRC68467eb2015-11-16 18:01:01 -08001379 main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
1380
Jon Hall85794ff2015-07-08 14:12:30 -07001381 utilities.assert_equals(
1382 expect=main.TRUE,
1383 actual=FlowTables,
1384 onpass="No changes were found in the flow tables",
1385 onfail="Changes were found in the flow tables" )
1386
1387 main.step( "Leadership Election is still functional" )
1388 # Test of LeadershipElection
1389
Jon Halle1a3b752015-07-22 13:02:46 -07001390 leader = main.nodes[0].ip_address
Jon Hall85794ff2015-07-08 14:12:30 -07001391 leaderResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001392 for controller in range( 1, main.numCtrls + 1 ):
Jon Hall85794ff2015-07-08 14:12:30 -07001393 # loop through ONOScli handlers
1394 node = getattr( main, ( 'ONOScli' + str( controller ) ) )
1395 leaderN = node.electionTestLeader()
1396 # verify leader is ONOS1
1397 # NOTE even though we restarted ONOS, it is the only one so onos 1
1398 # must be leader
1399 if leaderN == leader:
1400 # all is well
1401 pass
1402 elif leaderN == main.FALSE:
1403 # error in response
1404 main.log.error( "Something is wrong with " +
1405 "electionTestLeader function, check the" +
1406 " error logs" )
1407 leaderResult = main.FALSE
1408 elif leader != leaderN:
1409 leaderResult = main.FALSE
1410 main.log.error( "ONOS" + str( controller ) + " sees " +
1411 str( leaderN ) +
1412 " as the leader of the election app. " +
1413 "Leader should be " + str( leader ) )
1414 utilities.assert_equals(
1415 expect=main.TRUE,
1416 actual=leaderResult,
1417 onpass="Leadership election passed",
1418 onfail="Something went wrong with Leadership election" )
1419
1420 def CASE8( self, main ):
1421 """
1422 Compare topo
1423 """
1424 import json
1425 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001426 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001427 assert main, "main not defined"
1428 assert utilities.assert_equals, "utilities.assert_equals not defined"
1429
1430 main.case( "Compare ONOS Topology view to Mininet topology" )
Jon Hall783bbf92015-07-23 14:33:19 -07001431 main.caseExplanation = "Compare topology objects between Mininet" +\
Jon Hall85794ff2015-07-08 14:12:30 -07001432 " and ONOS"
Jon Hall85794ff2015-07-08 14:12:30 -07001433 topoResult = main.FALSE
1434 elapsed = 0
1435 count = 0
Jon Halle9b1fa32015-12-08 15:32:21 -08001436 main.step( "Comparing ONOS topology to MN topology" )
Jon Hall85794ff2015-07-08 14:12:30 -07001437 startTime = time.time()
1438 # Give time for Gossip to work
Jon Halle9b1fa32015-12-08 15:32:21 -08001439 while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
Jon Hall96091e62015-09-21 17:34:17 -07001440 devicesResults = main.TRUE
1441 linksResults = main.TRUE
1442 hostsResults = main.TRUE
1443 hostAttachmentResults = True
Jon Hall85794ff2015-07-08 14:12:30 -07001444 count += 1
1445 cliStart = time.time()
1446 devices = []
1447 devices.append( main.ONOScli1.devices() )
1448 hosts = []
1449 hosts.append( json.loads( main.ONOScli1.hosts() ) )
1450 ipResult = main.TRUE
1451 for controller in range( 0, len( hosts ) ):
1452 controllerStr = str( controller + 1 )
1453 for host in hosts[ controller ]:
1454 if host is None or host.get( 'ipAddresses', [] ) == []:
1455 main.log.error(
1456 "DEBUG:Error with host ips on controller" +
1457 controllerStr + ": " + str( host ) )
1458 ipResult = main.FALSE
1459 ports = []
1460 ports.append( main.ONOScli1.ports() )
1461 links = []
1462 links.append( main.ONOScli1.links() )
1463 clusters = []
1464 clusters.append( main.ONOScli1.clusters() )
1465
1466 elapsed = time.time() - startTime
1467 cliTime = time.time() - cliStart
1468 print "CLI time: " + str( cliTime )
1469
1470 mnSwitches = main.Mininet1.getSwitches()
1471 mnLinks = main.Mininet1.getLinks()
1472 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07001473 for controller in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07001474 controllerStr = str( controller + 1 )
1475 if devices[ controller ] and ports[ controller ] and\
1476 "Error" not in devices[ controller ] and\
1477 "Error" not in ports[ controller ]:
1478
1479 currentDevicesResult = main.Mininet1.compareSwitches(
1480 mnSwitches,
1481 json.loads( devices[ controller ] ),
1482 json.loads( ports[ controller ] ) )
1483 else:
1484 currentDevicesResult = main.FALSE
1485 utilities.assert_equals( expect=main.TRUE,
1486 actual=currentDevicesResult,
1487 onpass="ONOS" + controllerStr +
1488 " Switches view is correct",
1489 onfail="ONOS" + controllerStr +
1490 " Switches view is incorrect" )
1491
1492 if links[ controller ] and "Error" not in links[ controller ]:
1493 currentLinksResult = main.Mininet1.compareLinks(
1494 mnSwitches, mnLinks,
1495 json.loads( links[ controller ] ) )
1496 else:
1497 currentLinksResult = main.FALSE
1498 utilities.assert_equals( expect=main.TRUE,
1499 actual=currentLinksResult,
1500 onpass="ONOS" + controllerStr +
1501 " links view is correct",
1502 onfail="ONOS" + controllerStr +
1503 " links view is incorrect" )
1504
1505 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1506 currentHostsResult = main.Mininet1.compareHosts(
1507 mnHosts,
1508 hosts[ controller ] )
1509 else:
1510 currentHostsResult = main.FALSE
1511 utilities.assert_equals( expect=main.TRUE,
1512 actual=currentHostsResult,
1513 onpass="ONOS" + controllerStr +
1514 " hosts exist in Mininet",
1515 onfail="ONOS" + controllerStr +
1516 " hosts don't match Mininet" )
1517 # CHECKING HOST ATTACHMENT POINTS
1518 hostAttachment = True
1519 zeroHosts = False
1520 # FIXME: topo-HA/obelisk specific mappings:
1521 # key is mac and value is dpid
1522 mappings = {}
1523 for i in range( 1, 29 ): # hosts 1 through 28
1524 # set up correct variables:
1525 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
1526 if i == 1:
1527 deviceId = "1000".zfill(16)
1528 elif i == 2:
1529 deviceId = "2000".zfill(16)
1530 elif i == 3:
1531 deviceId = "3000".zfill(16)
1532 elif i == 4:
1533 deviceId = "3004".zfill(16)
1534 elif i == 5:
1535 deviceId = "5000".zfill(16)
1536 elif i == 6:
1537 deviceId = "6000".zfill(16)
1538 elif i == 7:
1539 deviceId = "6007".zfill(16)
1540 elif i >= 8 and i <= 17:
1541 dpid = '3' + str( i ).zfill( 3 )
1542 deviceId = dpid.zfill(16)
1543 elif i >= 18 and i <= 27:
1544 dpid = '6' + str( i ).zfill( 3 )
1545 deviceId = dpid.zfill(16)
1546 elif i == 28:
1547 deviceId = "2800".zfill(16)
1548 mappings[ macId ] = deviceId
1549 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1550 if hosts[ controller ] == []:
1551 main.log.warn( "There are no hosts discovered" )
1552 zeroHosts = True
1553 else:
1554 for host in hosts[ controller ]:
1555 mac = None
1556 location = None
1557 device = None
1558 port = None
1559 try:
1560 mac = host.get( 'mac' )
1561 assert mac, "mac field could not be found for this host object"
1562
1563 location = host.get( 'location' )
1564 assert location, "location field could not be found for this host object"
1565
1566 # Trim the protocol identifier off deviceId
1567 device = str( location.get( 'elementId' ) ).split(':')[1]
1568 assert device, "elementId field could not be found for this host location object"
1569
1570 port = location.get( 'port' )
1571 assert port, "port field could not be found for this host location object"
1572
1573 # Now check if this matches where they should be
1574 if mac and device and port:
1575 if str( port ) != "1":
1576 main.log.error( "The attachment port is incorrect for " +
1577 "host " + str( mac ) +
1578 ". Expected: 1 Actual: " + str( port) )
1579 hostAttachment = False
1580 if device != mappings[ str( mac ) ]:
1581 main.log.error( "The attachment device is incorrect for " +
1582 "host " + str( mac ) +
1583 ". Expected: " + mappings[ str( mac ) ] +
1584 " Actual: " + device )
1585 hostAttachment = False
1586 else:
1587 hostAttachment = False
1588 except AssertionError:
1589 main.log.exception( "Json object not as expected" )
1590 main.log.error( repr( host ) )
1591 hostAttachment = False
1592 else:
1593 main.log.error( "No hosts json output or \"Error\"" +
1594 " in output. hosts = " +
1595 repr( hosts[ controller ] ) )
1596 if zeroHosts is False:
1597 hostAttachment = True
1598
Jon Hall85794ff2015-07-08 14:12:30 -07001599 devicesResults = devicesResults and currentDevicesResult
1600 linksResults = linksResults and currentLinksResult
1601 hostsResults = hostsResults and currentHostsResult
1602 hostAttachmentResults = hostAttachmentResults and\
1603 hostAttachment
1604
1605 # "consistent" results don't make sense for single instance
1606 # there should always only be one cluster
1607 numClusters = len( json.loads( clusters[ 0 ] ) )
1608 clusterResults = main.FALSE
1609 if numClusters == 1:
1610 clusterResults = main.TRUE
1611 utilities.assert_equals(
1612 expect=1,
1613 actual=numClusters,
1614 onpass="ONOS shows 1 SCC",
1615 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1616
1617 topoResult = ( devicesResults and linksResults
1618 and hostsResults and ipResult and clusterResults and
1619 hostAttachmentResults )
1620
1621 topoResult = topoResult and int( count <= 2 )
1622 note = "note it takes about " + str( int( cliTime ) ) + \
1623 " seconds for the test to make all the cli calls to fetch " +\
1624 "the topology from each ONOS instance"
1625 main.log.info(
1626 "Very crass estimate for topology discovery/convergence( " +
1627 str( note ) + " ): " + str( elapsed ) + " seconds, " +
1628 str( count ) + " tries" )
1629 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
1630 onpass="Topology Check Test successful",
1631 onfail="Topology Check Test NOT successful" )
1632
1633 def CASE9( self, main ):
1634 """
1635 Link s3-s28 down
1636 """
1637 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001638 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001639 assert main, "main not defined"
1640 assert utilities.assert_equals, "utilities.assert_equals not defined"
1641 # NOTE: You should probably run a topology check after this
1642
1643 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
1644
1645 description = "Turn off a link to ensure that Link Discovery " +\
1646 "is working properly"
1647 main.case( description )
1648
1649 main.step( "Kill Link between s3 and s28" )
1650 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
1651 main.log.info( "Waiting " + str( linkSleep ) +
1652 " seconds for link down to be discovered" )
1653 time.sleep( linkSleep )
1654 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
1655 onpass="Link down successful",
1656 onfail="Failed to bring link down" )
1657 # TODO do some sort of check here
1658
1659 def CASE10( self, main ):
1660 """
1661 Link s3-s28 up
1662 """
1663 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001664 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001665 assert main, "main not defined"
1666 assert utilities.assert_equals, "utilities.assert_equals not defined"
1667 # NOTE: You should probably run a topology check after this
1668
1669 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
1670
1671 description = "Restore a link to ensure that Link Discovery is " + \
1672 "working properly"
1673 main.case( description )
1674
1675 main.step( "Bring link between s3 and s28 back up" )
1676 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
1677 main.log.info( "Waiting " + str( linkSleep ) +
1678 " seconds for link up to be discovered" )
1679 time.sleep( linkSleep )
1680 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
1681 onpass="Link up successful",
1682 onfail="Failed to bring link up" )
1683 # TODO do some sort of check here
1684
1685 def CASE11( self, main ):
1686 """
1687 Switch Down
1688 """
1689 # NOTE: You should probably run a topology check after this
1690 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001691 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001692 assert main, "main not defined"
1693 assert utilities.assert_equals, "utilities.assert_equals not defined"
1694
1695 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
1696
1697 description = "Killing a switch to ensure it is discovered correctly"
1698 main.case( description )
1699 switch = main.params[ 'kill' ][ 'switch' ]
1700 switchDPID = main.params[ 'kill' ][ 'dpid' ]
1701
1702 # TODO: Make this switch parameterizable
1703 main.step( "Kill " + switch )
1704 main.log.info( "Deleting " + switch )
1705 main.Mininet1.delSwitch( switch )
1706 main.log.info( "Waiting " + str( switchSleep ) +
1707 " seconds for switch down to be discovered" )
1708 time.sleep( switchSleep )
1709 device = main.ONOScli1.getDevice( dpid=switchDPID )
1710 # Peek at the deleted switch
1711 main.log.warn( str( device ) )
1712 result = main.FALSE
1713 if device and device[ 'available' ] is False:
1714 result = main.TRUE
1715 utilities.assert_equals( expect=main.TRUE, actual=result,
1716 onpass="Kill switch successful",
1717 onfail="Failed to kill switch?" )
1718
1719 def CASE12( self, main ):
1720 """
1721 Switch Up
1722 """
1723 # NOTE: You should probably run a topology check after this
1724 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001725 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001726 assert main, "main not defined"
1727 assert utilities.assert_equals, "utilities.assert_equals not defined"
1728
1729 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
1730 switch = main.params[ 'kill' ][ 'switch' ]
1731 switchDPID = main.params[ 'kill' ][ 'dpid' ]
1732 links = main.params[ 'kill' ][ 'links' ].split()
1733 description = "Adding a switch to ensure it is discovered correctly"
1734 main.case( description )
1735
1736 main.step( "Add back " + switch )
1737 main.Mininet1.addSwitch( switch, dpid=switchDPID )
1738 for peer in links:
1739 main.Mininet1.addLink( switch, peer )
1740 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -07001741 for i in range( main.numCtrls ):
1742 ipList.append( main.nodes[ i ].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -07001743 main.Mininet1.assignSwController( sw=switch, ip=ipList )
1744 main.log.info( "Waiting " + str( switchSleep ) +
1745 " seconds for switch up to be discovered" )
1746 time.sleep( switchSleep )
1747 device = main.ONOScli1.getDevice( dpid=switchDPID )
1748 # Peek at the deleted switch
1749 main.log.warn( str( device ) )
1750 result = main.FALSE
1751 if device and device[ 'available' ]:
1752 result = main.TRUE
1753 utilities.assert_equals( expect=main.TRUE, actual=result,
1754 onpass="add switch successful",
1755 onfail="Failed to add switch?" )
1756
1757 def CASE13( self, main ):
1758 """
1759 Clean up
1760 """
1761 import os
1762 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001763 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001764 assert main, "main not defined"
1765 assert utilities.assert_equals, "utilities.assert_equals not defined"
1766 # printing colors to terminal
1767 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
1768 'blue': '\033[94m', 'green': '\033[92m',
1769 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
1770 main.case( "Test Cleanup" )
1771 main.step( "Killing tcpdumps" )
1772 main.Mininet2.stopTcpdump()
1773
1774 testname = main.TEST
Jon Hall96091e62015-09-21 17:34:17 -07001775 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall85794ff2015-07-08 14:12:30 -07001776 main.step( "Copying MN pcap and ONOS log files to test station" )
1777 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
1778 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
Jon Hall96091e62015-09-21 17:34:17 -07001779 # NOTE: MN Pcap file is being saved to logdir.
1780 # We scp this file as MN and TestON aren't necessarily the same vm
1781
1782 # FIXME: To be replaced with a Jenkin's post script
Jon Hall85794ff2015-07-08 14:12:30 -07001783 # TODO: Load these from params
1784 # NOTE: must end in /
1785 logFolder = "/opt/onos/log/"
1786 logFiles = [ "karaf.log", "karaf.log.1" ]
1787 # NOTE: must end in /
Jon Hall85794ff2015-07-08 14:12:30 -07001788 for f in logFiles:
Jon Hall96091e62015-09-21 17:34:17 -07001789 for node in main.nodes:
1790 dstName = main.logdir + "/" + node.name + "-" + f
1791 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
1792 logFolder + f, dstName )
Jon Hall85794ff2015-07-08 14:12:30 -07001793 # std*.log's
1794 # NOTE: must end in /
1795 logFolder = "/opt/onos/var/"
1796 logFiles = [ "stderr.log", "stdout.log" ]
1797 # NOTE: must end in /
Jon Hall85794ff2015-07-08 14:12:30 -07001798 for f in logFiles:
Jon Hall96091e62015-09-21 17:34:17 -07001799 for node in main.nodes:
1800 dstName = main.logdir + "/" + node.name + "-" + f
1801 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
1802 logFolder + f, dstName )
1803 else:
1804 main.log.debug( "skipping saving log files" )
Jon Hall85794ff2015-07-08 14:12:30 -07001805
Jon Hall85794ff2015-07-08 14:12:30 -07001806 main.step( "Stopping Mininet" )
1807 mnResult = main.Mininet1.stopNet()
1808 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
1809 onpass="Mininet stopped",
1810 onfail="MN cleanup NOT successful" )
1811
1812 main.step( "Checking ONOS Logs for errors" )
Jon Hall96091e62015-09-21 17:34:17 -07001813 for node in main.nodes:
1814 main.log.debug( "Checking logs for errors on " + node.name + ":" )
1815 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001816
1817 try:
1818 timerLog = open( main.logdir + "/Timers.csv", 'w')
1819 # Overwrite with empty line and close
1820 labels = "Gossip Intents, Restart"
1821 data = str( gossipTime ) + ", " + str( main.restartTime )
1822 timerLog.write( labels + "\n" + data )
1823 timerLog.close()
1824 except NameError, e:
1825 main.log.exception(e)
1826
1827 def CASE14( self, main ):
1828 """
1829 start election app on all onos nodes
1830 """
Jon Halle1a3b752015-07-22 13:02:46 -07001831 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001832 assert main, "main not defined"
1833 assert utilities.assert_equals, "utilities.assert_equals not defined"
1834
1835 main.case("Start Leadership Election app")
1836 main.step( "Install leadership election app" )
1837 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
1838 utilities.assert_equals(
1839 expect=main.TRUE,
1840 actual=appResult,
1841 onpass="Election app installed",
1842 onfail="Something went wrong with installing Leadership election" )
1843
1844 main.step( "Run for election on each node" )
1845 leaderResult = main.ONOScli1.electionTestRun()
1846 # check for leader
1847 leader = main.ONOScli1.electionTestLeader()
1848 # verify leader is ONOS1
Jon Halle1a3b752015-07-22 13:02:46 -07001849 if leader == main.nodes[0].ip_address:
Jon Hall85794ff2015-07-08 14:12:30 -07001850 # all is well
1851 pass
1852 elif leader is None:
1853 # No leader elected
1854 main.log.error( "No leader was elected" )
1855 leaderResult = main.FALSE
1856 elif leader == main.FALSE:
1857 # error in response
1858 # TODO: add check for "Command not found:" in the driver, this
1859 # means the app isn't loaded
1860 main.log.error( "Something is wrong with electionTestLeader" +
1861 " function, check the error logs" )
1862 leaderResult = main.FALSE
1863 else:
1864 # error in response
1865 main.log.error(
1866 "Unexpected response from electionTestLeader function:'" +
1867 str( leader ) +
1868 "'" )
1869 leaderResult = main.FALSE
1870 utilities.assert_equals(
1871 expect=main.TRUE,
1872 actual=leaderResult,
1873 onpass="Successfully ran for leadership",
1874 onfail="Failed to run for leadership" )
1875
1876 def CASE15( self, main ):
1877 """
1878 Check that Leadership Election is still functional
acsmars71adceb2015-08-31 15:09:26 -07001879 15.1 Run election on each node
1880 15.2 Check that each node has the same leaders and candidates
1881 15.3 Find current leader and withdraw
1882 15.4 Check that a new node was elected leader
1883 15.5 Check that that new leader was the candidate of old leader
1884 15.6 Run for election on old leader
1885 15.7 Check that oldLeader is a candidate, and leader if only 1 node
1886 15.8 Make sure that the old leader was added to the candidate list
1887
1888 old and new variable prefixes refer to data from before vs after
1889 withdrawl and later before withdrawl vs after re-election
Jon Hall85794ff2015-07-08 14:12:30 -07001890 """
acsmars71adceb2015-08-31 15:09:26 -07001891 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001892 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001893 assert main, "main not defined"
1894 assert utilities.assert_equals, "utilities.assert_equals not defined"
acsmars71adceb2015-08-31 15:09:26 -07001895 assert main.CLIs, "main.CLIs not defined"
1896 assert main.nodes, "main.nodes not defined"
1897
Jon Hall85794ff2015-07-08 14:12:30 -07001898 description = "Check that Leadership Election is still functional"
1899 main.case( description )
acsmars71adceb2015-08-31 15:09:26 -07001900 # NOTE: Need to re-run since being a canidate is not persistant
1901 # TODO: add check for "Command not found:" in the driver, this
1902 # means the election test app isn't loaded
acsmars2c2fcdd2015-08-25 17:14:13 -07001903
acsmars71adceb2015-08-31 15:09:26 -07001904 oldLeaders = [] # leaders by node before withdrawl from candidates
1905 newLeaders = [] # leaders by node after withdrawl from candidates
1906 oldAllCandidates = [] # list of lists of each nodes' candidates before
1907 newAllCandidates = [] # list of lists of each nodes' candidates after
1908 oldCandidates = [] # list of candidates from node 0 before withdrawl
1909 newCandidates = [] # list of candidates from node 0 after withdrawl
1910 oldLeader = '' # the old leader from oldLeaders, None if not same
1911 newLeader = '' # the new leaders fron newLoeaders, None if not same
1912 oldLeaderCLI = None # the CLI of the old leader used for re-electing
1913 expectNoLeader = False # True when there is only one leader
1914 if main.numCtrls == 1:
1915 expectNoLeader = True
acsmars2c2fcdd2015-08-25 17:14:13 -07001916
acsmars71adceb2015-08-31 15:09:26 -07001917 main.step( "Run for election on each node" )
1918 electionResult = main.TRUE
1919
1920 for cli in main.CLIs: # run test election on each node
1921 if cli.electionTestRun() == main.FALSE:
1922 electionResult = main.FALSE
1923
1924 utilities.assert_equals(
1925 expect=main.TRUE,
1926 actual=electionResult,
1927 onpass="All nodes successfully ran for leadership",
1928 onfail="At least one node failed to run for leadership" )
1929
acsmars3a72bde2015-09-02 14:16:22 -07001930 if electionResult == main.FALSE:
1931 main.log.error(
1932 "Skipping Test Case because Election Test App isn't loaded" )
1933 main.skipCase()
1934
acsmars71adceb2015-08-31 15:09:26 -07001935 main.step( "Check that each node shows the same leader and candidates" )
1936 sameResult = main.TRUE
1937 failMessage = "Nodes have different leaders"
1938 for cli in main.CLIs:
1939 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
1940 oldAllCandidates.append( node )
1941 oldLeaders.append( node[ 0 ] )
1942 oldCandidates = oldAllCandidates[ 0 ]
1943
1944 # Check that each node has the same leader. Defines oldLeader
1945 if len( set( oldLeaders ) ) != 1:
1946 sameResult = main.FALSE
1947 main.log.error( "More than one leader present:" + str( oldLeaders ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001948 oldLeader = None
1949 else:
acsmars71adceb2015-08-31 15:09:26 -07001950 oldLeader = oldLeaders[ 0 ]
1951
1952 # Check that each node's candidate list is the same
acsmars29233db2015-11-04 11:15:00 -08001953 candidateDiscrepancy = False # Boolean of candidate mismatches
acsmars71adceb2015-08-31 15:09:26 -07001954 for candidates in oldAllCandidates:
1955 if set( candidates ) != set( oldCandidates ):
1956 sameResult = main.FALSE
acsmars29233db2015-11-04 11:15:00 -08001957 candidateDiscrepancy = True
1958
1959 if candidateDiscrepancy:
1960 failMessage += " and candidates"
acsmars71adceb2015-08-31 15:09:26 -07001961
1962 utilities.assert_equals(
1963 expect=main.TRUE,
1964 actual=sameResult,
1965 onpass="Leadership is consistent for the election topic",
1966 onfail=failMessage )
1967
1968 main.step( "Find current leader and withdraw" )
1969 withdrawResult = main.TRUE
1970 # do some sanity checking on leader before using it
1971 if oldLeader is None:
1972 main.log.error( "Leadership isn't consistent." )
1973 withdrawResult = main.FALSE
1974 # Get the CLI of the oldLeader
1975 for i in range( len( main.CLIs ) ):
1976 if oldLeader == main.nodes[ i ].ip_address:
1977 oldLeaderCLI = main.CLIs[ i ]
1978 break
1979 else: # FOR/ELSE statement
1980 main.log.error( "Leader election, could not find current leader" )
Jon Hall85794ff2015-07-08 14:12:30 -07001981 if oldLeader:
acsmars71adceb2015-08-31 15:09:26 -07001982 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall85794ff2015-07-08 14:12:30 -07001983 utilities.assert_equals(
1984 expect=main.TRUE,
1985 actual=withdrawResult,
1986 onpass="Node was withdrawn from election",
1987 onfail="Node was not withdrawn from election" )
1988
acsmars71adceb2015-08-31 15:09:26 -07001989 main.step( "Check that a new node was elected leader" )
1990
1991 # FIXME: use threads
1992 newLeaderResult = main.TRUE
1993 failMessage = "Nodes have different leaders"
1994
1995 # Get new leaders and candidates
1996 for cli in main.CLIs:
1997 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
1998 # elections might no have finished yet
1999 if node[ 0 ] == 'none' and not expectNoLeader:
2000 main.log.info( "Node has no leader, waiting 5 seconds to be " +
2001 "sure elections are complete." )
2002 time.sleep(5)
2003 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2004 # election still isn't done or there is a problem
2005 if node[ 0 ] == 'none':
2006 main.log.error( "No leader was elected on at least 1 node" )
2007 newLeaderResult = main.FALSE
2008 newAllCandidates.append( node )
2009 newLeaders.append( node[ 0 ] )
2010 newCandidates = newAllCandidates[ 0 ]
2011
2012 # Check that each node has the same leader. Defines newLeader
2013 if len( set( newLeaders ) ) != 1:
2014 newLeaderResult = main.FALSE
2015 main.log.error( "Nodes have different leaders: " +
2016 str( newLeaders ) )
2017 newLeader = None
2018 else:
2019 newLeader = newLeaders[ 0 ]
2020
2021 # Check that each node's candidate list is the same
2022 for candidates in newAllCandidates:
2023 if set( candidates ) != set( newCandidates ):
2024 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07002025 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07002026
2027 # Check that the new leader is not the older leader, which was withdrawn
2028 if newLeader == oldLeader:
2029 newLeaderResult = main.FALSE
2030 main.log.error( "All nodes still see old leader: " + oldLeader +
2031 " as the current leader" )
2032
Jon Hall85794ff2015-07-08 14:12:30 -07002033 utilities.assert_equals(
2034 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002035 actual=newLeaderResult,
2036 onpass="Leadership election passed",
2037 onfail="Something went wrong with Leadership election" )
Jon Hall85794ff2015-07-08 14:12:30 -07002038
acsmars71adceb2015-08-31 15:09:26 -07002039 main.step( "Check that that new leader was the candidate of old leader")
2040 # candidates[ 2 ] should be come the top candidate after withdrawl
2041 correctCandidateResult = main.TRUE
2042 if expectNoLeader:
2043 if newLeader == 'none':
2044 main.log.info( "No leader expected. None found. Pass" )
2045 correctCandidateResult = main.TRUE
2046 else:
2047 main.log.info( "Expected no leader, got: " + str( newLeader ) )
2048 correctCandidateResult = main.FALSE
2049 elif newLeader != oldCandidates[ 2 ]:
2050 correctCandidateResult = main.FALSE
2051 main.log.error( "Candidate " + newLeader + " was elected. " +
2052 oldCandidates[ 2 ] + " should have had priority." )
2053
2054 utilities.assert_equals(
2055 expect=main.TRUE,
2056 actual=correctCandidateResult,
2057 onpass="Correct Candidate Elected",
2058 onfail="Incorrect Candidate Elected" )
2059
Jon Hall85794ff2015-07-08 14:12:30 -07002060 main.step( "Run for election on old leader( just so everyone " +
2061 "is in the hat )" )
acsmars71adceb2015-08-31 15:09:26 -07002062 if oldLeaderCLI is not None:
2063 runResult = oldLeaderCLI.electionTestRun()
Jon Hall85794ff2015-07-08 14:12:30 -07002064 else:
acsmars71adceb2015-08-31 15:09:26 -07002065 main.log.error( "No old leader to re-elect" )
Jon Hall85794ff2015-07-08 14:12:30 -07002066 runResult = main.FALSE
2067 utilities.assert_equals(
2068 expect=main.TRUE,
2069 actual=runResult,
2070 onpass="App re-ran for election",
2071 onfail="App failed to run for election" )
acsmars71adceb2015-08-31 15:09:26 -07002072 main.step(
2073 "Check that oldLeader is a candidate, and leader if only 1 node" )
2074 # verify leader didn't just change
2075 positionResult = main.TRUE
2076 # Get new leaders and candidates, wait if oldLeader is not a candidate yet
Jon Hall85794ff2015-07-08 14:12:30 -07002077
acsmars71adceb2015-08-31 15:09:26 -07002078 # Reset and reuse the new candidate and leaders lists
2079 newAllCandidates = []
2080 newCandidates = []
2081 newLeaders = []
2082 for cli in main.CLIs:
2083 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2084 if oldLeader not in node: # election might no have finished yet
2085 main.log.info( "Old Leader not elected, waiting 5 seconds to " +
2086 "be sure elections are complete" )
2087 time.sleep(5)
2088 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2089 if oldLeader not in node: # election still isn't done, errors
2090 main.log.error(
2091 "Old leader was not elected on at least one node" )
2092 positionResult = main.FALSE
2093 newAllCandidates.append( node )
2094 newLeaders.append( node[ 0 ] )
2095 newCandidates = newAllCandidates[ 0 ]
2096
2097 # Check that each node has the same leader. Defines newLeader
2098 if len( set( newLeaders ) ) != 1:
2099 positionResult = main.FALSE
2100 main.log.error( "Nodes have different leaders: " +
2101 str( newLeaders ) )
2102 newLeader = None
Jon Hall85794ff2015-07-08 14:12:30 -07002103 else:
acsmars71adceb2015-08-31 15:09:26 -07002104 newLeader = newLeaders[ 0 ]
2105
2106 # Check that each node's candidate list is the same
2107 for candidates in newAllCandidates:
2108 if set( candidates ) != set( newCandidates ):
2109 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07002110 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07002111
2112 # Check that the re-elected node is last on the candidate List
2113 if oldLeader != newCandidates[ -1 ]:
2114 main.log.error( "Old Leader (" + oldLeader + ") not in the proper position " +
2115 str( newCandidates ) )
2116 positionResult = main.FALSE
Jon Hall85794ff2015-07-08 14:12:30 -07002117
2118 utilities.assert_equals(
2119 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002120 actual=positionResult,
Jon Hall85794ff2015-07-08 14:12:30 -07002121 onpass="Old leader successfully re-ran for election",
2122 onfail="Something went wrong with Leadership election after " +
2123 "the old leader re-ran for election" )
2124
2125 def CASE16( self, main ):
2126 """
2127 Install Distributed Primitives app
2128 """
Jon Halle1a3b752015-07-22 13:02:46 -07002129 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002130 assert main, "main not defined"
2131 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002132 assert main.CLIs, "main.CLIs not defined"
2133 assert main.nodes, "main.nodes not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002134
2135 # Variables for the distributed primitives tests
2136 global pCounterName
2137 global iCounterName
2138 global pCounterValue
2139 global iCounterValue
2140 global onosSet
2141 global onosSetName
2142 pCounterName = "TestON-Partitions"
2143 iCounterName = "TestON-inMemory"
2144 pCounterValue = 0
2145 iCounterValue = 0
2146 onosSet = set([])
2147 onosSetName = "TestON-set"
2148
2149 description = "Install Primitives app"
2150 main.case( description )
2151 main.step( "Install Primitives app" )
2152 appName = "org.onosproject.distributedprimitives"
Jon Halle1a3b752015-07-22 13:02:46 -07002153 appResults = main.CLIs[0].activateApp( appName )
Jon Hall85794ff2015-07-08 14:12:30 -07002154 utilities.assert_equals( expect=main.TRUE,
2155 actual=appResults,
2156 onpass="Primitives app activated",
2157 onfail="Primitives app not activated" )
2158
2159 def CASE17( self, main ):
2160 """
2161 Check for basic functionality with distributed primitives
2162 """
Jon Hall85794ff2015-07-08 14:12:30 -07002163 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07002164 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002165 assert main, "main not defined"
2166 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002167 assert main.CLIs, "main.CLIs not defined"
2168 assert main.nodes, "main.nodes not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002169 assert pCounterName, "pCounterName not defined"
2170 assert iCounterName, "iCounterName not defined"
2171 assert onosSetName, "onosSetName not defined"
2172 # NOTE: assert fails if value is 0/None/Empty/False
2173 try:
2174 pCounterValue
2175 except NameError:
2176 main.log.error( "pCounterValue not defined, setting to 0" )
2177 pCounterValue = 0
2178 try:
2179 iCounterValue
2180 except NameError:
2181 main.log.error( "iCounterValue not defined, setting to 0" )
2182 iCounterValue = 0
2183 try:
2184 onosSet
2185 except NameError:
2186 main.log.error( "onosSet not defined, setting to empty Set" )
2187 onosSet = set([])
2188 # Variables for the distributed primitives tests. These are local only
2189 addValue = "a"
2190 addAllValue = "a b c d e f"
2191 retainValue = "c d e f"
2192
2193 description = "Check for basic functionality with distributed " +\
2194 "primitives"
2195 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07002196 main.caseExplanation = "Test the methods of the distributed " +\
2197 "primitives (counters and sets) throught the cli"
Jon Hall85794ff2015-07-08 14:12:30 -07002198 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07002199 # Partitioned counters
2200 main.step( "Increment then get a default counter on each node" )
Jon Hall85794ff2015-07-08 14:12:30 -07002201 pCounters = []
2202 threads = []
2203 addedPValues = []
Jon Halle1a3b752015-07-22 13:02:46 -07002204 for i in range( main.numCtrls ):
2205 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2206 name="counterAddAndGet-" + str( i ),
Jon Hall85794ff2015-07-08 14:12:30 -07002207 args=[ pCounterName ] )
2208 pCounterValue += 1
2209 addedPValues.append( pCounterValue )
2210 threads.append( t )
2211 t.start()
2212
2213 for t in threads:
2214 t.join()
2215 pCounters.append( t.result )
2216 # Check that counter incremented numController times
2217 pCounterResults = True
2218 for i in addedPValues:
2219 tmpResult = i in pCounters
2220 pCounterResults = pCounterResults and tmpResult
2221 if not tmpResult:
2222 main.log.error( str( i ) + " is not in partitioned "
2223 "counter incremented results" )
2224 utilities.assert_equals( expect=True,
2225 actual=pCounterResults,
2226 onpass="Default counter incremented",
2227 onfail="Error incrementing default" +
2228 " counter" )
2229
Jon Halle1a3b752015-07-22 13:02:46 -07002230 main.step( "Get then Increment a default counter on each node" )
2231 pCounters = []
2232 threads = []
2233 addedPValues = []
2234 for i in range( main.numCtrls ):
2235 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
2236 name="counterGetAndAdd-" + str( i ),
2237 args=[ pCounterName ] )
2238 addedPValues.append( pCounterValue )
2239 pCounterValue += 1
2240 threads.append( t )
2241 t.start()
2242
2243 for t in threads:
2244 t.join()
2245 pCounters.append( t.result )
2246 # Check that counter incremented numController times
2247 pCounterResults = True
2248 for i in addedPValues:
2249 tmpResult = i in pCounters
2250 pCounterResults = pCounterResults and tmpResult
2251 if not tmpResult:
2252 main.log.error( str( i ) + " is not in partitioned "
2253 "counter incremented results" )
2254 utilities.assert_equals( expect=True,
2255 actual=pCounterResults,
2256 onpass="Default counter incremented",
2257 onfail="Error incrementing default" +
2258 " counter" )
2259
2260 main.step( "Counters we added have the correct values" )
2261 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
2262 utilities.assert_equals( expect=main.TRUE,
2263 actual=incrementCheck,
2264 onpass="Added counters are correct",
2265 onfail="Added counters are incorrect" )
2266
2267 main.step( "Add -8 to then get a default counter on each node" )
2268 pCounters = []
2269 threads = []
2270 addedPValues = []
2271 for i in range( main.numCtrls ):
2272 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2273 name="counterIncrement-" + str( i ),
2274 args=[ pCounterName ],
2275 kwargs={ "delta": -8 } )
2276 pCounterValue += -8
2277 addedPValues.append( pCounterValue )
2278 threads.append( t )
2279 t.start()
2280
2281 for t in threads:
2282 t.join()
2283 pCounters.append( t.result )
2284 # Check that counter incremented numController times
2285 pCounterResults = True
2286 for i in addedPValues:
2287 tmpResult = i in pCounters
2288 pCounterResults = pCounterResults and tmpResult
2289 if not tmpResult:
2290 main.log.error( str( i ) + " is not in partitioned "
2291 "counter incremented results" )
2292 utilities.assert_equals( expect=True,
2293 actual=pCounterResults,
2294 onpass="Default counter incremented",
2295 onfail="Error incrementing default" +
2296 " counter" )
2297
2298 main.step( "Add 5 to then get a default counter on each node" )
2299 pCounters = []
2300 threads = []
2301 addedPValues = []
2302 for i in range( main.numCtrls ):
2303 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2304 name="counterIncrement-" + str( i ),
2305 args=[ pCounterName ],
2306 kwargs={ "delta": 5 } )
2307 pCounterValue += 5
2308 addedPValues.append( pCounterValue )
2309 threads.append( t )
2310 t.start()
2311
2312 for t in threads:
2313 t.join()
2314 pCounters.append( t.result )
2315 # Check that counter incremented numController times
2316 pCounterResults = True
2317 for i in addedPValues:
2318 tmpResult = i in pCounters
2319 pCounterResults = pCounterResults and tmpResult
2320 if not tmpResult:
2321 main.log.error( str( i ) + " is not in partitioned "
2322 "counter incremented results" )
2323 utilities.assert_equals( expect=True,
2324 actual=pCounterResults,
2325 onpass="Default counter incremented",
2326 onfail="Error incrementing default" +
2327 " counter" )
2328
2329 main.step( "Get then add 5 to a default counter on each node" )
2330 pCounters = []
2331 threads = []
2332 addedPValues = []
2333 for i in range( main.numCtrls ):
2334 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
2335 name="counterIncrement-" + str( i ),
2336 args=[ pCounterName ],
2337 kwargs={ "delta": 5 } )
2338 addedPValues.append( pCounterValue )
2339 pCounterValue += 5
2340 threads.append( t )
2341 t.start()
2342
2343 for t in threads:
2344 t.join()
2345 pCounters.append( t.result )
2346 # Check that counter incremented numController times
2347 pCounterResults = True
2348 for i in addedPValues:
2349 tmpResult = i in pCounters
2350 pCounterResults = pCounterResults and tmpResult
2351 if not tmpResult:
2352 main.log.error( str( i ) + " is not in partitioned "
2353 "counter incremented results" )
2354 utilities.assert_equals( expect=True,
2355 actual=pCounterResults,
2356 onpass="Default counter incremented",
2357 onfail="Error incrementing default" +
2358 " counter" )
2359
2360 main.step( "Counters we added have the correct values" )
2361 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
2362 utilities.assert_equals( expect=main.TRUE,
2363 actual=incrementCheck,
2364 onpass="Added counters are correct",
2365 onfail="Added counters are incorrect" )
2366
2367 # In-Memory counters
2368 main.step( "Increment and get an in-memory counter on each node" )
Jon Hall85794ff2015-07-08 14:12:30 -07002369 iCounters = []
2370 addedIValues = []
2371 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002372 for i in range( main.numCtrls ):
2373 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002374 name="icounterIncrement-" + str( i ),
2375 args=[ iCounterName ],
2376 kwargs={ "inMemory": True } )
2377 iCounterValue += 1
2378 addedIValues.append( iCounterValue )
2379 threads.append( t )
2380 t.start()
2381
2382 for t in threads:
2383 t.join()
2384 iCounters.append( t.result )
2385 # Check that counter incremented numController times
2386 iCounterResults = True
2387 for i in addedIValues:
2388 tmpResult = i in iCounters
2389 iCounterResults = iCounterResults and tmpResult
2390 if not tmpResult:
2391 main.log.error( str( i ) + " is not in the in-memory "
2392 "counter incremented results" )
2393 utilities.assert_equals( expect=True,
2394 actual=iCounterResults,
Jon Halle1a3b752015-07-22 13:02:46 -07002395 onpass="In-memory counter incremented",
2396 onfail="Error incrementing in-memory" +
Jon Hall85794ff2015-07-08 14:12:30 -07002397 " counter" )
2398
Jon Halle1a3b752015-07-22 13:02:46 -07002399 main.step( "Get then Increment a in-memory counter on each node" )
2400 iCounters = []
2401 threads = []
2402 addedIValues = []
2403 for i in range( main.numCtrls ):
2404 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
2405 name="counterGetAndAdd-" + str( i ),
2406 args=[ iCounterName ],
2407 kwargs={ "inMemory": True } )
2408 addedIValues.append( iCounterValue )
2409 iCounterValue += 1
2410 threads.append( t )
2411 t.start()
2412
2413 for t in threads:
2414 t.join()
2415 iCounters.append( t.result )
2416 # Check that counter incremented numController times
2417 iCounterResults = True
2418 for i in addedIValues:
2419 tmpResult = i in iCounters
2420 iCounterResults = iCounterResults and tmpResult
2421 if not tmpResult:
2422 main.log.error( str( i ) + " is not in in-memory "
2423 "counter incremented results" )
2424 utilities.assert_equals( expect=True,
2425 actual=iCounterResults,
2426 onpass="In-memory counter incremented",
2427 onfail="Error incrementing in-memory" +
2428 " counter" )
2429
2430 main.step( "Counters we added have the correct values" )
2431 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
2432 utilities.assert_equals( expect=main.TRUE,
2433 actual=incrementCheck,
2434 onpass="Added counters are correct",
2435 onfail="Added counters are incorrect" )
2436
2437 main.step( "Add -8 to then get a in-memory counter on each node" )
2438 iCounters = []
2439 threads = []
2440 addedIValues = []
2441 for i in range( main.numCtrls ):
2442 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2443 name="counterIncrement-" + str( i ),
2444 args=[ iCounterName ],
2445 kwargs={ "delta": -8, "inMemory": True } )
2446 iCounterValue += -8
2447 addedIValues.append( iCounterValue )
2448 threads.append( t )
2449 t.start()
2450
2451 for t in threads:
2452 t.join()
2453 iCounters.append( t.result )
2454 # Check that counter incremented numController times
2455 iCounterResults = True
2456 for i in addedIValues:
2457 tmpResult = i in iCounters
2458 iCounterResults = iCounterResults and tmpResult
2459 if not tmpResult:
2460 main.log.error( str( i ) + " is not in in-memory "
2461 "counter incremented results" )
2462 utilities.assert_equals( expect=True,
2463 actual=pCounterResults,
2464 onpass="In-memory counter incremented",
2465 onfail="Error incrementing in-memory" +
2466 " counter" )
2467
2468 main.step( "Add 5 to then get a in-memory counter on each node" )
2469 iCounters = []
2470 threads = []
2471 addedIValues = []
2472 for i in range( main.numCtrls ):
2473 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2474 name="counterIncrement-" + str( i ),
2475 args=[ iCounterName ],
2476 kwargs={ "delta": 5, "inMemory": True } )
2477 iCounterValue += 5
2478 addedIValues.append( iCounterValue )
2479 threads.append( t )
2480 t.start()
2481
2482 for t in threads:
2483 t.join()
2484 iCounters.append( t.result )
2485 # Check that counter incremented numController times
2486 iCounterResults = True
2487 for i in addedIValues:
2488 tmpResult = i in iCounters
2489 iCounterResults = iCounterResults and tmpResult
2490 if not tmpResult:
2491 main.log.error( str( i ) + " is not in in-memory "
2492 "counter incremented results" )
2493 utilities.assert_equals( expect=True,
2494 actual=pCounterResults,
2495 onpass="In-memory counter incremented",
2496 onfail="Error incrementing in-memory" +
2497 " counter" )
2498
2499 main.step( "Get then add 5 to a in-memory counter on each node" )
2500 iCounters = []
2501 threads = []
2502 addedIValues = []
2503 for i in range( main.numCtrls ):
2504 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
2505 name="counterIncrement-" + str( i ),
2506 args=[ iCounterName ],
2507 kwargs={ "delta": 5, "inMemory": True } )
2508 addedIValues.append( iCounterValue )
2509 iCounterValue += 5
2510 threads.append( t )
2511 t.start()
2512
2513 for t in threads:
2514 t.join()
2515 iCounters.append( t.result )
2516 # Check that counter incremented numController times
2517 iCounterResults = True
2518 for i in addedIValues:
2519 tmpResult = i in iCounters
2520 iCounterResults = iCounterResults and tmpResult
2521 if not tmpResult:
2522 main.log.error( str( i ) + " is not in in-memory "
2523 "counter incremented results" )
2524 utilities.assert_equals( expect=True,
2525 actual=iCounterResults,
2526 onpass="In-memory counter incremented",
2527 onfail="Error incrementing in-memory" +
2528 " counter" )
2529
2530 main.step( "Counters we added have the correct values" )
2531 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
2532 utilities.assert_equals( expect=main.TRUE,
2533 actual=incrementCheck,
2534 onpass="Added counters are correct",
2535 onfail="Added counters are incorrect" )
2536
Jon Hall85794ff2015-07-08 14:12:30 -07002537 main.step( "Check counters are consistant across nodes" )
Jon Hall57b50432015-10-22 10:20:10 -07002538 onosCounters, consistentCounterResults = main.Counters.consistentCheck()
Jon Hall85794ff2015-07-08 14:12:30 -07002539 utilities.assert_equals( expect=main.TRUE,
2540 actual=consistentCounterResults,
2541 onpass="ONOS counters are consistent " +
2542 "across nodes",
2543 onfail="ONOS Counters are inconsistent " +
2544 "across nodes" )
2545
2546 main.step( "Counters we added have the correct values" )
Jon Halle1a3b752015-07-22 13:02:46 -07002547 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
2548 incrementCheck = incrementCheck and \
2549 main.Counters.counterCheck( iCounterName, iCounterValue )
Jon Hall85794ff2015-07-08 14:12:30 -07002550 utilities.assert_equals( expect=main.TRUE,
Jon Halle1a3b752015-07-22 13:02:46 -07002551 actual=incrementCheck,
Jon Hall85794ff2015-07-08 14:12:30 -07002552 onpass="Added counters are correct",
2553 onfail="Added counters are incorrect" )
2554 # DISTRIBUTED SETS
2555 main.step( "Distributed Set get" )
2556 size = len( onosSet )
2557 getResponses = []
2558 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002559 for i in range( main.numCtrls ):
2560 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002561 name="setTestGet-" + str( i ),
2562 args=[ onosSetName ] )
2563 threads.append( t )
2564 t.start()
2565 for t in threads:
2566 t.join()
2567 getResponses.append( t.result )
2568
2569 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002570 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002571 if isinstance( getResponses[ i ], list):
2572 current = set( getResponses[ i ] )
2573 if len( current ) == len( getResponses[ i ] ):
2574 # no repeats
2575 if onosSet != current:
2576 main.log.error( "ONOS" + str( i + 1 ) +
2577 " has incorrect view" +
2578 " of set " + onosSetName + ":\n" +
2579 str( getResponses[ i ] ) )
2580 main.log.debug( "Expected: " + str( onosSet ) )
2581 main.log.debug( "Actual: " + str( current ) )
2582 getResults = main.FALSE
2583 else:
2584 # error, set is not a set
2585 main.log.error( "ONOS" + str( i + 1 ) +
2586 " has repeat elements in" +
2587 " set " + onosSetName + ":\n" +
2588 str( getResponses[ i ] ) )
2589 getResults = main.FALSE
2590 elif getResponses[ i ] == main.ERROR:
2591 getResults = main.FALSE
2592 utilities.assert_equals( expect=main.TRUE,
2593 actual=getResults,
2594 onpass="Set elements are correct",
2595 onfail="Set elements are incorrect" )
2596
2597 main.step( "Distributed Set size" )
2598 sizeResponses = []
2599 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002600 for i in range( main.numCtrls ):
2601 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002602 name="setTestSize-" + str( i ),
2603 args=[ onosSetName ] )
2604 threads.append( t )
2605 t.start()
2606 for t in threads:
2607 t.join()
2608 sizeResponses.append( t.result )
2609
2610 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002611 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002612 if size != sizeResponses[ i ]:
2613 sizeResults = main.FALSE
2614 main.log.error( "ONOS" + str( i + 1 ) +
2615 " expected a size of " + str( size ) +
2616 " for set " + onosSetName +
2617 " but got " + str( sizeResponses[ i ] ) )
2618 utilities.assert_equals( expect=main.TRUE,
2619 actual=sizeResults,
2620 onpass="Set sizes are correct",
2621 onfail="Set sizes are incorrect" )
2622
2623 main.step( "Distributed Set add()" )
2624 onosSet.add( addValue )
2625 addResponses = []
2626 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002627 for i in range( main.numCtrls ):
2628 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07002629 name="setTestAdd-" + str( i ),
2630 args=[ onosSetName, addValue ] )
2631 threads.append( t )
2632 t.start()
2633 for t in threads:
2634 t.join()
2635 addResponses.append( t.result )
2636
2637 # main.TRUE = successfully changed the set
2638 # main.FALSE = action resulted in no change in set
2639 # main.ERROR - Some error in executing the function
2640 addResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002641 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002642 if addResponses[ i ] == main.TRUE:
2643 # All is well
2644 pass
2645 elif addResponses[ i ] == main.FALSE:
2646 # Already in set, probably fine
2647 pass
2648 elif addResponses[ i ] == main.ERROR:
2649 # Error in execution
2650 addResults = main.FALSE
2651 else:
2652 # unexpected result
2653 addResults = main.FALSE
2654 if addResults != main.TRUE:
2655 main.log.error( "Error executing set add" )
2656
2657 # Check if set is still correct
2658 size = len( onosSet )
2659 getResponses = []
2660 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002661 for i in range( main.numCtrls ):
2662 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002663 name="setTestGet-" + str( i ),
2664 args=[ onosSetName ] )
2665 threads.append( t )
2666 t.start()
2667 for t in threads:
2668 t.join()
2669 getResponses.append( t.result )
2670 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002671 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002672 if isinstance( getResponses[ i ], list):
2673 current = set( getResponses[ i ] )
2674 if len( current ) == len( getResponses[ i ] ):
2675 # no repeats
2676 if onosSet != current:
2677 main.log.error( "ONOS" + str( i + 1 ) +
2678 " has incorrect view" +
2679 " of set " + onosSetName + ":\n" +
2680 str( getResponses[ i ] ) )
2681 main.log.debug( "Expected: " + str( onosSet ) )
2682 main.log.debug( "Actual: " + str( current ) )
2683 getResults = main.FALSE
2684 else:
2685 # error, set is not a set
2686 main.log.error( "ONOS" + str( i + 1 ) +
2687 " has repeat elements in" +
2688 " set " + onosSetName + ":\n" +
2689 str( getResponses[ i ] ) )
2690 getResults = main.FALSE
2691 elif getResponses[ i ] == main.ERROR:
2692 getResults = main.FALSE
2693 sizeResponses = []
2694 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002695 for i in range( main.numCtrls ):
2696 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002697 name="setTestSize-" + str( i ),
2698 args=[ onosSetName ] )
2699 threads.append( t )
2700 t.start()
2701 for t in threads:
2702 t.join()
2703 sizeResponses.append( t.result )
2704 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002705 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002706 if size != sizeResponses[ i ]:
2707 sizeResults = main.FALSE
2708 main.log.error( "ONOS" + str( i + 1 ) +
2709 " expected a size of " + str( size ) +
2710 " for set " + onosSetName +
2711 " but got " + str( sizeResponses[ i ] ) )
2712 addResults = addResults and getResults and sizeResults
2713 utilities.assert_equals( expect=main.TRUE,
2714 actual=addResults,
2715 onpass="Set add correct",
2716 onfail="Set add was incorrect" )
2717
2718 main.step( "Distributed Set addAll()" )
2719 onosSet.update( addAllValue.split() )
2720 addResponses = []
2721 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002722 for i in range( main.numCtrls ):
2723 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07002724 name="setTestAddAll-" + str( i ),
2725 args=[ onosSetName, addAllValue ] )
2726 threads.append( t )
2727 t.start()
2728 for t in threads:
2729 t.join()
2730 addResponses.append( t.result )
2731
2732 # main.TRUE = successfully changed the set
2733 # main.FALSE = action resulted in no change in set
2734 # main.ERROR - Some error in executing the function
2735 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002736 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002737 if addResponses[ i ] == main.TRUE:
2738 # All is well
2739 pass
2740 elif addResponses[ i ] == main.FALSE:
2741 # Already in set, probably fine
2742 pass
2743 elif addResponses[ i ] == main.ERROR:
2744 # Error in execution
2745 addAllResults = main.FALSE
2746 else:
2747 # unexpected result
2748 addAllResults = main.FALSE
2749 if addAllResults != main.TRUE:
2750 main.log.error( "Error executing set addAll" )
2751
2752 # Check if set is still correct
2753 size = len( onosSet )
2754 getResponses = []
2755 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002756 for i in range( main.numCtrls ):
2757 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002758 name="setTestGet-" + str( i ),
2759 args=[ onosSetName ] )
2760 threads.append( t )
2761 t.start()
2762 for t in threads:
2763 t.join()
2764 getResponses.append( t.result )
2765 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002766 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002767 if isinstance( getResponses[ i ], list):
2768 current = set( getResponses[ i ] )
2769 if len( current ) == len( getResponses[ i ] ):
2770 # no repeats
2771 if onosSet != current:
2772 main.log.error( "ONOS" + str( i + 1 ) +
2773 " has incorrect view" +
2774 " of set " + onosSetName + ":\n" +
2775 str( getResponses[ i ] ) )
2776 main.log.debug( "Expected: " + str( onosSet ) )
2777 main.log.debug( "Actual: " + str( current ) )
2778 getResults = main.FALSE
2779 else:
2780 # error, set is not a set
2781 main.log.error( "ONOS" + str( i + 1 ) +
2782 " has repeat elements in" +
2783 " set " + onosSetName + ":\n" +
2784 str( getResponses[ i ] ) )
2785 getResults = main.FALSE
2786 elif getResponses[ i ] == main.ERROR:
2787 getResults = main.FALSE
2788 sizeResponses = []
2789 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002790 for i in range( main.numCtrls ):
2791 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002792 name="setTestSize-" + str( i ),
2793 args=[ onosSetName ] )
2794 threads.append( t )
2795 t.start()
2796 for t in threads:
2797 t.join()
2798 sizeResponses.append( t.result )
2799 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002800 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002801 if size != sizeResponses[ i ]:
2802 sizeResults = main.FALSE
2803 main.log.error( "ONOS" + str( i + 1 ) +
2804 " expected a size of " + str( size ) +
2805 " for set " + onosSetName +
2806 " but got " + str( sizeResponses[ i ] ) )
2807 addAllResults = addAllResults and getResults and sizeResults
2808 utilities.assert_equals( expect=main.TRUE,
2809 actual=addAllResults,
2810 onpass="Set addAll correct",
2811 onfail="Set addAll was incorrect" )
2812
2813 main.step( "Distributed Set contains()" )
2814 containsResponses = []
2815 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002816 for i in range( main.numCtrls ):
2817 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002818 name="setContains-" + str( i ),
2819 args=[ onosSetName ],
2820 kwargs={ "values": addValue } )
2821 threads.append( t )
2822 t.start()
2823 for t in threads:
2824 t.join()
2825 # NOTE: This is the tuple
2826 containsResponses.append( t.result )
2827
2828 containsResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002829 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002830 if containsResponses[ i ] == main.ERROR:
2831 containsResults = main.FALSE
2832 else:
2833 containsResults = containsResults and\
2834 containsResponses[ i ][ 1 ]
2835 utilities.assert_equals( expect=main.TRUE,
2836 actual=containsResults,
2837 onpass="Set contains is functional",
2838 onfail="Set contains failed" )
2839
2840 main.step( "Distributed Set containsAll()" )
2841 containsAllResponses = []
2842 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002843 for i in range( main.numCtrls ):
2844 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002845 name="setContainsAll-" + str( i ),
2846 args=[ onosSetName ],
2847 kwargs={ "values": addAllValue } )
2848 threads.append( t )
2849 t.start()
2850 for t in threads:
2851 t.join()
2852 # NOTE: This is the tuple
2853 containsAllResponses.append( t.result )
2854
2855 containsAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002856 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002857 if containsResponses[ i ] == main.ERROR:
2858 containsResults = main.FALSE
2859 else:
2860 containsResults = containsResults and\
2861 containsResponses[ i ][ 1 ]
2862 utilities.assert_equals( expect=main.TRUE,
2863 actual=containsAllResults,
2864 onpass="Set containsAll is functional",
2865 onfail="Set containsAll failed" )
2866
2867 main.step( "Distributed Set remove()" )
2868 onosSet.remove( addValue )
2869 removeResponses = []
2870 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002871 for i in range( main.numCtrls ):
2872 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07002873 name="setTestRemove-" + str( i ),
2874 args=[ onosSetName, addValue ] )
2875 threads.append( t )
2876 t.start()
2877 for t in threads:
2878 t.join()
2879 removeResponses.append( t.result )
2880
2881 # main.TRUE = successfully changed the set
2882 # main.FALSE = action resulted in no change in set
2883 # main.ERROR - Some error in executing the function
2884 removeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002885 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002886 if removeResponses[ i ] == main.TRUE:
2887 # All is well
2888 pass
2889 elif removeResponses[ i ] == main.FALSE:
2890 # not in set, probably fine
2891 pass
2892 elif removeResponses[ i ] == main.ERROR:
2893 # Error in execution
2894 removeResults = main.FALSE
2895 else:
2896 # unexpected result
2897 removeResults = main.FALSE
2898 if removeResults != main.TRUE:
2899 main.log.error( "Error executing set remove" )
2900
2901 # Check if set is still correct
2902 size = len( onosSet )
2903 getResponses = []
2904 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002905 for i in range( main.numCtrls ):
2906 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002907 name="setTestGet-" + str( i ),
2908 args=[ onosSetName ] )
2909 threads.append( t )
2910 t.start()
2911 for t in threads:
2912 t.join()
2913 getResponses.append( t.result )
2914 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002915 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002916 if isinstance( getResponses[ i ], list):
2917 current = set( getResponses[ i ] )
2918 if len( current ) == len( getResponses[ i ] ):
2919 # no repeats
2920 if onosSet != current:
2921 main.log.error( "ONOS" + str( i + 1 ) +
2922 " has incorrect view" +
2923 " of set " + onosSetName + ":\n" +
2924 str( getResponses[ i ] ) )
2925 main.log.debug( "Expected: " + str( onosSet ) )
2926 main.log.debug( "Actual: " + str( current ) )
2927 getResults = main.FALSE
2928 else:
2929 # error, set is not a set
2930 main.log.error( "ONOS" + str( i + 1 ) +
2931 " has repeat elements in" +
2932 " set " + onosSetName + ":\n" +
2933 str( getResponses[ i ] ) )
2934 getResults = main.FALSE
2935 elif getResponses[ i ] == main.ERROR:
2936 getResults = main.FALSE
2937 sizeResponses = []
2938 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002939 for i in range( main.numCtrls ):
2940 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002941 name="setTestSize-" + str( i ),
2942 args=[ onosSetName ] )
2943 threads.append( t )
2944 t.start()
2945 for t in threads:
2946 t.join()
2947 sizeResponses.append( t.result )
2948 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002949 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002950 if size != sizeResponses[ i ]:
2951 sizeResults = main.FALSE
2952 main.log.error( "ONOS" + str( i + 1 ) +
2953 " expected a size of " + str( size ) +
2954 " for set " + onosSetName +
2955 " but got " + str( sizeResponses[ i ] ) )
2956 removeResults = removeResults and getResults and sizeResults
2957 utilities.assert_equals( expect=main.TRUE,
2958 actual=removeResults,
2959 onpass="Set remove correct",
2960 onfail="Set remove was incorrect" )
2961
2962 main.step( "Distributed Set removeAll()" )
2963 onosSet.difference_update( addAllValue.split() )
2964 removeAllResponses = []
2965 threads = []
2966 try:
Jon Halle1a3b752015-07-22 13:02:46 -07002967 for i in range( main.numCtrls ):
2968 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07002969 name="setTestRemoveAll-" + str( i ),
2970 args=[ onosSetName, addAllValue ] )
2971 threads.append( t )
2972 t.start()
2973 for t in threads:
2974 t.join()
2975 removeAllResponses.append( t.result )
2976 except Exception, e:
2977 main.log.exception(e)
2978
2979 # main.TRUE = successfully changed the set
2980 # main.FALSE = action resulted in no change in set
2981 # main.ERROR - Some error in executing the function
2982 removeAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002983 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002984 if removeAllResponses[ i ] == main.TRUE:
2985 # All is well
2986 pass
2987 elif removeAllResponses[ i ] == main.FALSE:
2988 # not in set, probably fine
2989 pass
2990 elif removeAllResponses[ i ] == main.ERROR:
2991 # Error in execution
2992 removeAllResults = main.FALSE
2993 else:
2994 # unexpected result
2995 removeAllResults = main.FALSE
2996 if removeAllResults != main.TRUE:
2997 main.log.error( "Error executing set removeAll" )
2998
2999 # Check if set is still correct
3000 size = len( onosSet )
3001 getResponses = []
3002 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003003 for i in range( main.numCtrls ):
3004 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003005 name="setTestGet-" + str( i ),
3006 args=[ onosSetName ] )
3007 threads.append( t )
3008 t.start()
3009 for t in threads:
3010 t.join()
3011 getResponses.append( t.result )
3012 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003013 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003014 if isinstance( getResponses[ i ], list):
3015 current = set( getResponses[ i ] )
3016 if len( current ) == len( getResponses[ i ] ):
3017 # no repeats
3018 if onosSet != current:
3019 main.log.error( "ONOS" + str( i + 1 ) +
3020 " has incorrect view" +
3021 " of set " + onosSetName + ":\n" +
3022 str( getResponses[ i ] ) )
3023 main.log.debug( "Expected: " + str( onosSet ) )
3024 main.log.debug( "Actual: " + str( current ) )
3025 getResults = main.FALSE
3026 else:
3027 # error, set is not a set
3028 main.log.error( "ONOS" + str( i + 1 ) +
3029 " has repeat elements in" +
3030 " set " + onosSetName + ":\n" +
3031 str( getResponses[ i ] ) )
3032 getResults = main.FALSE
3033 elif getResponses[ i ] == main.ERROR:
3034 getResults = main.FALSE
3035 sizeResponses = []
3036 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003037 for i in range( main.numCtrls ):
3038 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003039 name="setTestSize-" + str( i ),
3040 args=[ onosSetName ] )
3041 threads.append( t )
3042 t.start()
3043 for t in threads:
3044 t.join()
3045 sizeResponses.append( t.result )
3046 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003047 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003048 if size != sizeResponses[ i ]:
3049 sizeResults = main.FALSE
3050 main.log.error( "ONOS" + str( i + 1 ) +
3051 " expected a size of " + str( size ) +
3052 " for set " + onosSetName +
3053 " but got " + str( sizeResponses[ i ] ) )
3054 removeAllResults = removeAllResults and getResults and sizeResults
3055 utilities.assert_equals( expect=main.TRUE,
3056 actual=removeAllResults,
3057 onpass="Set removeAll correct",
3058 onfail="Set removeAll was incorrect" )
3059
3060 main.step( "Distributed Set addAll()" )
3061 onosSet.update( addAllValue.split() )
3062 addResponses = []
3063 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003064 for i in range( main.numCtrls ):
3065 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07003066 name="setTestAddAll-" + str( i ),
3067 args=[ onosSetName, addAllValue ] )
3068 threads.append( t )
3069 t.start()
3070 for t in threads:
3071 t.join()
3072 addResponses.append( t.result )
3073
3074 # main.TRUE = successfully changed the set
3075 # main.FALSE = action resulted in no change in set
3076 # main.ERROR - Some error in executing the function
3077 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003078 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003079 if addResponses[ i ] == main.TRUE:
3080 # All is well
3081 pass
3082 elif addResponses[ i ] == main.FALSE:
3083 # Already in set, probably fine
3084 pass
3085 elif addResponses[ i ] == main.ERROR:
3086 # Error in execution
3087 addAllResults = main.FALSE
3088 else:
3089 # unexpected result
3090 addAllResults = main.FALSE
3091 if addAllResults != main.TRUE:
3092 main.log.error( "Error executing set addAll" )
3093
3094 # Check if set is still correct
3095 size = len( onosSet )
3096 getResponses = []
3097 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003098 for i in range( main.numCtrls ):
3099 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003100 name="setTestGet-" + str( i ),
3101 args=[ onosSetName ] )
3102 threads.append( t )
3103 t.start()
3104 for t in threads:
3105 t.join()
3106 getResponses.append( t.result )
3107 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003108 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003109 if isinstance( getResponses[ i ], list):
3110 current = set( getResponses[ i ] )
3111 if len( current ) == len( getResponses[ i ] ):
3112 # no repeats
3113 if onosSet != current:
3114 main.log.error( "ONOS" + str( i + 1 ) +
3115 " has incorrect view" +
3116 " of set " + onosSetName + ":\n" +
3117 str( getResponses[ i ] ) )
3118 main.log.debug( "Expected: " + str( onosSet ) )
3119 main.log.debug( "Actual: " + str( current ) )
3120 getResults = main.FALSE
3121 else:
3122 # error, set is not a set
3123 main.log.error( "ONOS" + str( i + 1 ) +
3124 " has repeat elements in" +
3125 " set " + onosSetName + ":\n" +
3126 str( getResponses[ i ] ) )
3127 getResults = main.FALSE
3128 elif getResponses[ i ] == main.ERROR:
3129 getResults = main.FALSE
3130 sizeResponses = []
3131 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003132 for i in range( main.numCtrls ):
3133 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003134 name="setTestSize-" + str( i ),
3135 args=[ onosSetName ] )
3136 threads.append( t )
3137 t.start()
3138 for t in threads:
3139 t.join()
3140 sizeResponses.append( t.result )
3141 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003142 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003143 if size != sizeResponses[ i ]:
3144 sizeResults = main.FALSE
3145 main.log.error( "ONOS" + str( i + 1 ) +
3146 " expected a size of " + str( size ) +
3147 " for set " + onosSetName +
3148 " but got " + str( sizeResponses[ i ] ) )
3149 addAllResults = addAllResults and getResults and sizeResults
3150 utilities.assert_equals( expect=main.TRUE,
3151 actual=addAllResults,
3152 onpass="Set addAll correct",
3153 onfail="Set addAll was incorrect" )
3154
3155 main.step( "Distributed Set clear()" )
3156 onosSet.clear()
3157 clearResponses = []
3158 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003159 for i in range( main.numCtrls ):
3160 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07003161 name="setTestClear-" + str( i ),
3162 args=[ onosSetName, " "], # Values doesn't matter
3163 kwargs={ "clear": True } )
3164 threads.append( t )
3165 t.start()
3166 for t in threads:
3167 t.join()
3168 clearResponses.append( t.result )
3169
3170 # main.TRUE = successfully changed the set
3171 # main.FALSE = action resulted in no change in set
3172 # main.ERROR - Some error in executing the function
3173 clearResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003174 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003175 if clearResponses[ i ] == main.TRUE:
3176 # All is well
3177 pass
3178 elif clearResponses[ i ] == main.FALSE:
3179 # Nothing set, probably fine
3180 pass
3181 elif clearResponses[ i ] == main.ERROR:
3182 # Error in execution
3183 clearResults = main.FALSE
3184 else:
3185 # unexpected result
3186 clearResults = main.FALSE
3187 if clearResults != main.TRUE:
3188 main.log.error( "Error executing set clear" )
3189
3190 # Check if set is still correct
3191 size = len( onosSet )
3192 getResponses = []
3193 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003194 for i in range( main.numCtrls ):
3195 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003196 name="setTestGet-" + str( i ),
3197 args=[ onosSetName ] )
3198 threads.append( t )
3199 t.start()
3200 for t in threads:
3201 t.join()
3202 getResponses.append( t.result )
3203 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003204 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003205 if isinstance( getResponses[ i ], list):
3206 current = set( getResponses[ i ] )
3207 if len( current ) == len( getResponses[ i ] ):
3208 # no repeats
3209 if onosSet != current:
3210 main.log.error( "ONOS" + str( i + 1 ) +
3211 " has incorrect view" +
3212 " of set " + onosSetName + ":\n" +
3213 str( getResponses[ i ] ) )
3214 main.log.debug( "Expected: " + str( onosSet ) )
3215 main.log.debug( "Actual: " + str( current ) )
3216 getResults = main.FALSE
3217 else:
3218 # error, set is not a set
3219 main.log.error( "ONOS" + str( i + 1 ) +
3220 " has repeat elements in" +
3221 " set " + onosSetName + ":\n" +
3222 str( getResponses[ i ] ) )
3223 getResults = main.FALSE
3224 elif getResponses[ i ] == main.ERROR:
3225 getResults = main.FALSE
3226 sizeResponses = []
3227 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003228 for i in range( main.numCtrls ):
3229 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003230 name="setTestSize-" + str( i ),
3231 args=[ onosSetName ] )
3232 threads.append( t )
3233 t.start()
3234 for t in threads:
3235 t.join()
3236 sizeResponses.append( t.result )
3237 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003238 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003239 if size != sizeResponses[ i ]:
3240 sizeResults = main.FALSE
3241 main.log.error( "ONOS" + str( i + 1 ) +
3242 " expected a size of " + str( size ) +
3243 " for set " + onosSetName +
3244 " but got " + str( sizeResponses[ i ] ) )
3245 clearResults = clearResults and getResults and sizeResults
3246 utilities.assert_equals( expect=main.TRUE,
3247 actual=clearResults,
3248 onpass="Set clear correct",
3249 onfail="Set clear was incorrect" )
3250
3251 main.step( "Distributed Set addAll()" )
3252 onosSet.update( addAllValue.split() )
3253 addResponses = []
3254 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003255 for i in range( main.numCtrls ):
3256 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07003257 name="setTestAddAll-" + str( i ),
3258 args=[ onosSetName, addAllValue ] )
3259 threads.append( t )
3260 t.start()
3261 for t in threads:
3262 t.join()
3263 addResponses.append( t.result )
3264
3265 # main.TRUE = successfully changed the set
3266 # main.FALSE = action resulted in no change in set
3267 # main.ERROR - Some error in executing the function
3268 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003269 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003270 if addResponses[ i ] == main.TRUE:
3271 # All is well
3272 pass
3273 elif addResponses[ i ] == main.FALSE:
3274 # Already in set, probably fine
3275 pass
3276 elif addResponses[ i ] == main.ERROR:
3277 # Error in execution
3278 addAllResults = main.FALSE
3279 else:
3280 # unexpected result
3281 addAllResults = main.FALSE
3282 if addAllResults != main.TRUE:
3283 main.log.error( "Error executing set addAll" )
3284
3285 # Check if set is still correct
3286 size = len( onosSet )
3287 getResponses = []
3288 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003289 for i in range( main.numCtrls ):
3290 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003291 name="setTestGet-" + str( i ),
3292 args=[ onosSetName ] )
3293 threads.append( t )
3294 t.start()
3295 for t in threads:
3296 t.join()
3297 getResponses.append( t.result )
3298 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003299 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003300 if isinstance( getResponses[ i ], list):
3301 current = set( getResponses[ i ] )
3302 if len( current ) == len( getResponses[ i ] ):
3303 # no repeats
3304 if onosSet != current:
3305 main.log.error( "ONOS" + str( i + 1 ) +
3306 " has incorrect view" +
3307 " of set " + onosSetName + ":\n" +
3308 str( getResponses[ i ] ) )
3309 main.log.debug( "Expected: " + str( onosSet ) )
3310 main.log.debug( "Actual: " + str( current ) )
3311 getResults = main.FALSE
3312 else:
3313 # error, set is not a set
3314 main.log.error( "ONOS" + str( i + 1 ) +
3315 " has repeat elements in" +
3316 " set " + onosSetName + ":\n" +
3317 str( getResponses[ i ] ) )
3318 getResults = main.FALSE
3319 elif getResponses[ i ] == main.ERROR:
3320 getResults = main.FALSE
3321 sizeResponses = []
3322 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003323 for i in range( main.numCtrls ):
3324 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003325 name="setTestSize-" + str( i ),
3326 args=[ onosSetName ] )
3327 threads.append( t )
3328 t.start()
3329 for t in threads:
3330 t.join()
3331 sizeResponses.append( t.result )
3332 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003333 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003334 if size != sizeResponses[ i ]:
3335 sizeResults = main.FALSE
3336 main.log.error( "ONOS" + str( i + 1 ) +
3337 " expected a size of " + str( size ) +
3338 " for set " + onosSetName +
3339 " but got " + str( sizeResponses[ i ] ) )
3340 addAllResults = addAllResults and getResults and sizeResults
3341 utilities.assert_equals( expect=main.TRUE,
3342 actual=addAllResults,
3343 onpass="Set addAll correct",
3344 onfail="Set addAll was incorrect" )
3345
3346 main.step( "Distributed Set retain()" )
3347 onosSet.intersection_update( retainValue.split() )
3348 retainResponses = []
3349 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003350 for i in range( main.numCtrls ):
3351 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07003352 name="setTestRetain-" + str( i ),
3353 args=[ onosSetName, retainValue ],
3354 kwargs={ "retain": True } )
3355 threads.append( t )
3356 t.start()
3357 for t in threads:
3358 t.join()
3359 retainResponses.append( t.result )
3360
3361 # main.TRUE = successfully changed the set
3362 # main.FALSE = action resulted in no change in set
3363 # main.ERROR - Some error in executing the function
3364 retainResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003365 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003366 if retainResponses[ i ] == main.TRUE:
3367 # All is well
3368 pass
3369 elif retainResponses[ i ] == main.FALSE:
3370 # Already in set, probably fine
3371 pass
3372 elif retainResponses[ i ] == main.ERROR:
3373 # Error in execution
3374 retainResults = main.FALSE
3375 else:
3376 # unexpected result
3377 retainResults = main.FALSE
3378 if retainResults != main.TRUE:
3379 main.log.error( "Error executing set retain" )
3380
3381 # Check if set is still correct
3382 size = len( onosSet )
3383 getResponses = []
3384 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003385 for i in range( main.numCtrls ):
3386 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003387 name="setTestGet-" + str( i ),
3388 args=[ onosSetName ] )
3389 threads.append( t )
3390 t.start()
3391 for t in threads:
3392 t.join()
3393 getResponses.append( t.result )
3394 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003395 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003396 if isinstance( getResponses[ i ], list):
3397 current = set( getResponses[ i ] )
3398 if len( current ) == len( getResponses[ i ] ):
3399 # no repeats
3400 if onosSet != current:
3401 main.log.error( "ONOS" + str( i + 1 ) +
3402 " has incorrect view" +
3403 " of set " + onosSetName + ":\n" +
3404 str( getResponses[ i ] ) )
3405 main.log.debug( "Expected: " + str( onosSet ) )
3406 main.log.debug( "Actual: " + str( current ) )
3407 getResults = main.FALSE
3408 else:
3409 # error, set is not a set
3410 main.log.error( "ONOS" + str( i + 1 ) +
3411 " has repeat elements in" +
3412 " set " + onosSetName + ":\n" +
3413 str( getResponses[ i ] ) )
3414 getResults = main.FALSE
3415 elif getResponses[ i ] == main.ERROR:
3416 getResults = main.FALSE
3417 sizeResponses = []
3418 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003419 for i in range( main.numCtrls ):
3420 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003421 name="setTestSize-" + str( i ),
3422 args=[ onosSetName ] )
3423 threads.append( t )
3424 t.start()
3425 for t in threads:
3426 t.join()
3427 sizeResponses.append( t.result )
3428 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003429 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003430 if size != sizeResponses[ i ]:
3431 sizeResults = main.FALSE
3432 main.log.error( "ONOS" + str( i + 1 ) +
3433 " expected a size of " +
3434 str( size ) + " for set " + onosSetName +
3435 " but got " + str( sizeResponses[ i ] ) )
3436 retainResults = retainResults and getResults and sizeResults
3437 utilities.assert_equals( expect=main.TRUE,
3438 actual=retainResults,
3439 onpass="Set retain correct",
3440 onfail="Set retain was incorrect" )
3441
Jon Hall2a5002c2015-08-21 16:49:11 -07003442 # Transactional maps
3443 main.step( "Partitioned Transactional maps put" )
3444 tMapValue = "Testing"
3445 numKeys = 100
3446 putResult = True
3447 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue )
3448 if len( putResponses ) == 100:
3449 for i in putResponses:
3450 if putResponses[ i ][ 'value' ] != tMapValue:
3451 putResult = False
3452 else:
3453 putResult = False
3454 if not putResult:
3455 main.log.debug( "Put response values: " + str( putResponses ) )
3456 utilities.assert_equals( expect=True,
3457 actual=putResult,
3458 onpass="Partitioned Transactional Map put successful",
3459 onfail="Partitioned Transactional Map put values are incorrect" )
3460
3461 main.step( "Partitioned Transactional maps get" )
3462 getCheck = True
3463 for n in range( 1, numKeys + 1 ):
3464 getResponses = []
3465 threads = []
3466 valueCheck = True
3467 for i in range( main.numCtrls ):
3468 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
3469 name="TMap-get-" + str( i ),
3470 args=[ "Key" + str ( n ) ] )
3471 threads.append( t )
3472 t.start()
3473 for t in threads:
3474 t.join()
3475 getResponses.append( t.result )
3476 for node in getResponses:
3477 if node != tMapValue:
3478 valueCheck = False
3479 if not valueCheck:
3480 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
3481 main.log.warn( getResponses )
3482 getCheck = getCheck and valueCheck
3483 utilities.assert_equals( expect=True,
3484 actual=getCheck,
3485 onpass="Partitioned Transactional Map get values were correct",
3486 onfail="Partitioned Transactional Map values incorrect" )
3487
3488 main.step( "In-memory Transactional maps put" )
3489 tMapValue = "Testing"
3490 numKeys = 100
3491 putResult = True
3492 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue, inMemory=True )
3493 if len( putResponses ) == 100:
3494 for i in putResponses:
3495 if putResponses[ i ][ 'value' ] != tMapValue:
3496 putResult = False
3497 else:
3498 putResult = False
3499 if not putResult:
3500 main.log.debug( "Put response values: " + str( putResponses ) )
3501 utilities.assert_equals( expect=True,
3502 actual=putResult,
3503 onpass="In-Memory Transactional Map put successful",
3504 onfail="In-Memory Transactional Map put values are incorrect" )
3505
3506 main.step( "In-Memory Transactional maps get" )
3507 getCheck = True
3508 for n in range( 1, numKeys + 1 ):
3509 getResponses = []
3510 threads = []
3511 valueCheck = True
3512 for i in range( main.numCtrls ):
3513 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
3514 name="TMap-get-" + str( i ),
3515 args=[ "Key" + str ( n ) ],
3516 kwargs={ "inMemory": True } )
3517 threads.append( t )
3518 t.start()
3519 for t in threads:
3520 t.join()
3521 getResponses.append( t.result )
3522 for node in getResponses:
3523 if node != tMapValue:
3524 valueCheck = False
3525 if not valueCheck:
3526 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
3527 main.log.warn( getResponses )
3528 getCheck = getCheck and valueCheck
3529 utilities.assert_equals( expect=True,
3530 actual=getCheck,
3531 onpass="In-Memory Transactional Map get values were correct",
3532 onfail="In-Memory Transactional Map values incorrect" )