blob: 158756353d33ffca1a076cbc886092c2588bad3c [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 Hallff566d52016-01-15 14:45:36 -0800162 index = "1"
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
Jon Hallc6793552016-01-19 14:18:37 -08001479 try:
1480 currentDevicesResult = main.Mininet1.compareSwitches(
1481 mnSwitches,
1482 json.loads( devices[ controller ] ),
1483 json.loads( ports[ controller ] ) )
1484 except ( TypeError, ValueError ) as e:
1485 main.log.exception( "Object not as expected; devices={!r}\nports={!r}".format(
1486 devices[ controller ], ports[ controller ] ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001487 else:
1488 currentDevicesResult = main.FALSE
1489 utilities.assert_equals( expect=main.TRUE,
1490 actual=currentDevicesResult,
1491 onpass="ONOS" + controllerStr +
1492 " Switches view is correct",
1493 onfail="ONOS" + controllerStr +
1494 " Switches view is incorrect" )
1495
1496 if links[ controller ] and "Error" not in links[ controller ]:
1497 currentLinksResult = main.Mininet1.compareLinks(
1498 mnSwitches, mnLinks,
1499 json.loads( links[ controller ] ) )
1500 else:
1501 currentLinksResult = main.FALSE
1502 utilities.assert_equals( expect=main.TRUE,
1503 actual=currentLinksResult,
1504 onpass="ONOS" + controllerStr +
1505 " links view is correct",
1506 onfail="ONOS" + controllerStr +
1507 " links view is incorrect" )
1508
1509 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1510 currentHostsResult = main.Mininet1.compareHosts(
1511 mnHosts,
1512 hosts[ controller ] )
1513 else:
1514 currentHostsResult = main.FALSE
1515 utilities.assert_equals( expect=main.TRUE,
1516 actual=currentHostsResult,
1517 onpass="ONOS" + controllerStr +
1518 " hosts exist in Mininet",
1519 onfail="ONOS" + controllerStr +
1520 " hosts don't match Mininet" )
1521 # CHECKING HOST ATTACHMENT POINTS
1522 hostAttachment = True
1523 zeroHosts = False
1524 # FIXME: topo-HA/obelisk specific mappings:
1525 # key is mac and value is dpid
1526 mappings = {}
1527 for i in range( 1, 29 ): # hosts 1 through 28
1528 # set up correct variables:
1529 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
1530 if i == 1:
1531 deviceId = "1000".zfill(16)
1532 elif i == 2:
1533 deviceId = "2000".zfill(16)
1534 elif i == 3:
1535 deviceId = "3000".zfill(16)
1536 elif i == 4:
1537 deviceId = "3004".zfill(16)
1538 elif i == 5:
1539 deviceId = "5000".zfill(16)
1540 elif i == 6:
1541 deviceId = "6000".zfill(16)
1542 elif i == 7:
1543 deviceId = "6007".zfill(16)
1544 elif i >= 8 and i <= 17:
1545 dpid = '3' + str( i ).zfill( 3 )
1546 deviceId = dpid.zfill(16)
1547 elif i >= 18 and i <= 27:
1548 dpid = '6' + str( i ).zfill( 3 )
1549 deviceId = dpid.zfill(16)
1550 elif i == 28:
1551 deviceId = "2800".zfill(16)
1552 mappings[ macId ] = deviceId
1553 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1554 if hosts[ controller ] == []:
1555 main.log.warn( "There are no hosts discovered" )
1556 zeroHosts = True
1557 else:
1558 for host in hosts[ controller ]:
1559 mac = None
1560 location = None
1561 device = None
1562 port = None
1563 try:
1564 mac = host.get( 'mac' )
1565 assert mac, "mac field could not be found for this host object"
1566
1567 location = host.get( 'location' )
1568 assert location, "location field could not be found for this host object"
1569
1570 # Trim the protocol identifier off deviceId
1571 device = str( location.get( 'elementId' ) ).split(':')[1]
1572 assert device, "elementId field could not be found for this host location object"
1573
1574 port = location.get( 'port' )
1575 assert port, "port field could not be found for this host location object"
1576
1577 # Now check if this matches where they should be
1578 if mac and device and port:
1579 if str( port ) != "1":
1580 main.log.error( "The attachment port is incorrect for " +
1581 "host " + str( mac ) +
1582 ". Expected: 1 Actual: " + str( port) )
1583 hostAttachment = False
1584 if device != mappings[ str( mac ) ]:
1585 main.log.error( "The attachment device is incorrect for " +
1586 "host " + str( mac ) +
1587 ". Expected: " + mappings[ str( mac ) ] +
1588 " Actual: " + device )
1589 hostAttachment = False
1590 else:
1591 hostAttachment = False
1592 except AssertionError:
1593 main.log.exception( "Json object not as expected" )
1594 main.log.error( repr( host ) )
1595 hostAttachment = False
1596 else:
1597 main.log.error( "No hosts json output or \"Error\"" +
1598 " in output. hosts = " +
1599 repr( hosts[ controller ] ) )
1600 if zeroHosts is False:
1601 hostAttachment = True
1602
Jon Hall85794ff2015-07-08 14:12:30 -07001603 devicesResults = devicesResults and currentDevicesResult
1604 linksResults = linksResults and currentLinksResult
1605 hostsResults = hostsResults and currentHostsResult
1606 hostAttachmentResults = hostAttachmentResults and\
1607 hostAttachment
1608
1609 # "consistent" results don't make sense for single instance
1610 # there should always only be one cluster
1611 numClusters = len( json.loads( clusters[ 0 ] ) )
1612 clusterResults = main.FALSE
1613 if numClusters == 1:
1614 clusterResults = main.TRUE
1615 utilities.assert_equals(
1616 expect=1,
1617 actual=numClusters,
1618 onpass="ONOS shows 1 SCC",
1619 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1620
1621 topoResult = ( devicesResults and linksResults
1622 and hostsResults and ipResult and clusterResults and
1623 hostAttachmentResults )
1624
1625 topoResult = topoResult and int( count <= 2 )
1626 note = "note it takes about " + str( int( cliTime ) ) + \
1627 " seconds for the test to make all the cli calls to fetch " +\
1628 "the topology from each ONOS instance"
1629 main.log.info(
1630 "Very crass estimate for topology discovery/convergence( " +
1631 str( note ) + " ): " + str( elapsed ) + " seconds, " +
1632 str( count ) + " tries" )
1633 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
1634 onpass="Topology Check Test successful",
1635 onfail="Topology Check Test NOT successful" )
1636
1637 def CASE9( self, main ):
1638 """
1639 Link s3-s28 down
1640 """
1641 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001642 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001643 assert main, "main not defined"
1644 assert utilities.assert_equals, "utilities.assert_equals not defined"
1645 # NOTE: You should probably run a topology check after this
1646
1647 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
1648
1649 description = "Turn off a link to ensure that Link Discovery " +\
1650 "is working properly"
1651 main.case( description )
1652
1653 main.step( "Kill Link between s3 and s28" )
1654 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
1655 main.log.info( "Waiting " + str( linkSleep ) +
1656 " seconds for link down to be discovered" )
1657 time.sleep( linkSleep )
1658 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
1659 onpass="Link down successful",
1660 onfail="Failed to bring link down" )
1661 # TODO do some sort of check here
1662
1663 def CASE10( self, main ):
1664 """
1665 Link s3-s28 up
1666 """
1667 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001668 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001669 assert main, "main not defined"
1670 assert utilities.assert_equals, "utilities.assert_equals not defined"
1671 # NOTE: You should probably run a topology check after this
1672
1673 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
1674
1675 description = "Restore a link to ensure that Link Discovery is " + \
1676 "working properly"
1677 main.case( description )
1678
1679 main.step( "Bring link between s3 and s28 back up" )
1680 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
1681 main.log.info( "Waiting " + str( linkSleep ) +
1682 " seconds for link up to be discovered" )
1683 time.sleep( linkSleep )
1684 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
1685 onpass="Link up successful",
1686 onfail="Failed to bring link up" )
1687 # TODO do some sort of check here
1688
1689 def CASE11( self, main ):
1690 """
1691 Switch Down
1692 """
1693 # NOTE: You should probably run a topology check after this
1694 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001695 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001696 assert main, "main not defined"
1697 assert utilities.assert_equals, "utilities.assert_equals not defined"
1698
1699 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
1700
1701 description = "Killing a switch to ensure it is discovered correctly"
1702 main.case( description )
1703 switch = main.params[ 'kill' ][ 'switch' ]
1704 switchDPID = main.params[ 'kill' ][ 'dpid' ]
1705
1706 # TODO: Make this switch parameterizable
1707 main.step( "Kill " + switch )
1708 main.log.info( "Deleting " + switch )
1709 main.Mininet1.delSwitch( switch )
1710 main.log.info( "Waiting " + str( switchSleep ) +
1711 " seconds for switch down to be discovered" )
1712 time.sleep( switchSleep )
1713 device = main.ONOScli1.getDevice( dpid=switchDPID )
1714 # Peek at the deleted switch
1715 main.log.warn( str( device ) )
1716 result = main.FALSE
1717 if device and device[ 'available' ] is False:
1718 result = main.TRUE
1719 utilities.assert_equals( expect=main.TRUE, actual=result,
1720 onpass="Kill switch successful",
1721 onfail="Failed to kill switch?" )
1722
1723 def CASE12( self, main ):
1724 """
1725 Switch Up
1726 """
1727 # NOTE: You should probably run a topology check after this
1728 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001729 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001730 assert main, "main not defined"
1731 assert utilities.assert_equals, "utilities.assert_equals not defined"
1732
1733 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
1734 switch = main.params[ 'kill' ][ 'switch' ]
1735 switchDPID = main.params[ 'kill' ][ 'dpid' ]
1736 links = main.params[ 'kill' ][ 'links' ].split()
1737 description = "Adding a switch to ensure it is discovered correctly"
1738 main.case( description )
1739
1740 main.step( "Add back " + switch )
1741 main.Mininet1.addSwitch( switch, dpid=switchDPID )
1742 for peer in links:
1743 main.Mininet1.addLink( switch, peer )
1744 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -07001745 for i in range( main.numCtrls ):
1746 ipList.append( main.nodes[ i ].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -07001747 main.Mininet1.assignSwController( sw=switch, ip=ipList )
1748 main.log.info( "Waiting " + str( switchSleep ) +
1749 " seconds for switch up to be discovered" )
1750 time.sleep( switchSleep )
1751 device = main.ONOScli1.getDevice( dpid=switchDPID )
1752 # Peek at the deleted switch
1753 main.log.warn( str( device ) )
1754 result = main.FALSE
1755 if device and device[ 'available' ]:
1756 result = main.TRUE
1757 utilities.assert_equals( expect=main.TRUE, actual=result,
1758 onpass="add switch successful",
1759 onfail="Failed to add switch?" )
1760
1761 def CASE13( self, main ):
1762 """
1763 Clean up
1764 """
1765 import os
1766 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001767 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001768 assert main, "main not defined"
1769 assert utilities.assert_equals, "utilities.assert_equals not defined"
1770 # printing colors to terminal
1771 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
1772 'blue': '\033[94m', 'green': '\033[92m',
1773 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
1774 main.case( "Test Cleanup" )
1775 main.step( "Killing tcpdumps" )
1776 main.Mininet2.stopTcpdump()
1777
1778 testname = main.TEST
Jon Hall96091e62015-09-21 17:34:17 -07001779 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall85794ff2015-07-08 14:12:30 -07001780 main.step( "Copying MN pcap and ONOS log files to test station" )
1781 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
1782 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
Jon Hall96091e62015-09-21 17:34:17 -07001783 # NOTE: MN Pcap file is being saved to logdir.
1784 # We scp this file as MN and TestON aren't necessarily the same vm
1785
1786 # FIXME: To be replaced with a Jenkin's post script
Jon Hall85794ff2015-07-08 14:12:30 -07001787 # TODO: Load these from params
1788 # NOTE: must end in /
1789 logFolder = "/opt/onos/log/"
1790 logFiles = [ "karaf.log", "karaf.log.1" ]
1791 # NOTE: must end in /
Jon Hall85794ff2015-07-08 14:12:30 -07001792 for f in logFiles:
Jon Hall96091e62015-09-21 17:34:17 -07001793 for node in main.nodes:
1794 dstName = main.logdir + "/" + node.name + "-" + f
1795 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
1796 logFolder + f, dstName )
Jon Hall85794ff2015-07-08 14:12:30 -07001797 # std*.log's
1798 # NOTE: must end in /
1799 logFolder = "/opt/onos/var/"
1800 logFiles = [ "stderr.log", "stdout.log" ]
1801 # NOTE: must end in /
Jon Hall85794ff2015-07-08 14:12:30 -07001802 for f in logFiles:
Jon Hall96091e62015-09-21 17:34:17 -07001803 for node in main.nodes:
1804 dstName = main.logdir + "/" + node.name + "-" + f
1805 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
1806 logFolder + f, dstName )
1807 else:
1808 main.log.debug( "skipping saving log files" )
Jon Hall85794ff2015-07-08 14:12:30 -07001809
Jon Hall85794ff2015-07-08 14:12:30 -07001810 main.step( "Stopping Mininet" )
1811 mnResult = main.Mininet1.stopNet()
1812 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
1813 onpass="Mininet stopped",
1814 onfail="MN cleanup NOT successful" )
1815
1816 main.step( "Checking ONOS Logs for errors" )
Jon Hall96091e62015-09-21 17:34:17 -07001817 for node in main.nodes:
1818 main.log.debug( "Checking logs for errors on " + node.name + ":" )
1819 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001820
1821 try:
1822 timerLog = open( main.logdir + "/Timers.csv", 'w')
1823 # Overwrite with empty line and close
1824 labels = "Gossip Intents, Restart"
1825 data = str( gossipTime ) + ", " + str( main.restartTime )
1826 timerLog.write( labels + "\n" + data )
1827 timerLog.close()
1828 except NameError, e:
1829 main.log.exception(e)
1830
1831 def CASE14( self, main ):
1832 """
1833 start election app on all onos nodes
1834 """
Jon Halle1a3b752015-07-22 13:02:46 -07001835 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001836 assert main, "main not defined"
1837 assert utilities.assert_equals, "utilities.assert_equals not defined"
1838
1839 main.case("Start Leadership Election app")
1840 main.step( "Install leadership election app" )
1841 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
1842 utilities.assert_equals(
1843 expect=main.TRUE,
1844 actual=appResult,
1845 onpass="Election app installed",
1846 onfail="Something went wrong with installing Leadership election" )
1847
1848 main.step( "Run for election on each node" )
1849 leaderResult = main.ONOScli1.electionTestRun()
1850 # check for leader
1851 leader = main.ONOScli1.electionTestLeader()
1852 # verify leader is ONOS1
Jon Halle1a3b752015-07-22 13:02:46 -07001853 if leader == main.nodes[0].ip_address:
Jon Hall85794ff2015-07-08 14:12:30 -07001854 # all is well
1855 pass
1856 elif leader is None:
1857 # No leader elected
1858 main.log.error( "No leader was elected" )
1859 leaderResult = main.FALSE
1860 elif leader == main.FALSE:
1861 # error in response
1862 # TODO: add check for "Command not found:" in the driver, this
1863 # means the app isn't loaded
1864 main.log.error( "Something is wrong with electionTestLeader" +
1865 " function, check the error logs" )
1866 leaderResult = main.FALSE
1867 else:
1868 # error in response
1869 main.log.error(
1870 "Unexpected response from electionTestLeader function:'" +
1871 str( leader ) +
1872 "'" )
1873 leaderResult = main.FALSE
1874 utilities.assert_equals(
1875 expect=main.TRUE,
1876 actual=leaderResult,
1877 onpass="Successfully ran for leadership",
1878 onfail="Failed to run for leadership" )
1879
1880 def CASE15( self, main ):
1881 """
1882 Check that Leadership Election is still functional
acsmars71adceb2015-08-31 15:09:26 -07001883 15.1 Run election on each node
1884 15.2 Check that each node has the same leaders and candidates
1885 15.3 Find current leader and withdraw
1886 15.4 Check that a new node was elected leader
1887 15.5 Check that that new leader was the candidate of old leader
1888 15.6 Run for election on old leader
1889 15.7 Check that oldLeader is a candidate, and leader if only 1 node
1890 15.8 Make sure that the old leader was added to the candidate list
1891
1892 old and new variable prefixes refer to data from before vs after
1893 withdrawl and later before withdrawl vs after re-election
Jon Hall85794ff2015-07-08 14:12:30 -07001894 """
acsmars71adceb2015-08-31 15:09:26 -07001895 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001896 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001897 assert main, "main not defined"
1898 assert utilities.assert_equals, "utilities.assert_equals not defined"
acsmars71adceb2015-08-31 15:09:26 -07001899 assert main.CLIs, "main.CLIs not defined"
1900 assert main.nodes, "main.nodes not defined"
1901
Jon Hall85794ff2015-07-08 14:12:30 -07001902 description = "Check that Leadership Election is still functional"
1903 main.case( description )
acsmars71adceb2015-08-31 15:09:26 -07001904 # NOTE: Need to re-run since being a canidate is not persistant
1905 # TODO: add check for "Command not found:" in the driver, this
1906 # means the election test app isn't loaded
acsmars2c2fcdd2015-08-25 17:14:13 -07001907
acsmars71adceb2015-08-31 15:09:26 -07001908 oldLeaders = [] # leaders by node before withdrawl from candidates
1909 newLeaders = [] # leaders by node after withdrawl from candidates
1910 oldAllCandidates = [] # list of lists of each nodes' candidates before
1911 newAllCandidates = [] # list of lists of each nodes' candidates after
1912 oldCandidates = [] # list of candidates from node 0 before withdrawl
1913 newCandidates = [] # list of candidates from node 0 after withdrawl
1914 oldLeader = '' # the old leader from oldLeaders, None if not same
1915 newLeader = '' # the new leaders fron newLoeaders, None if not same
1916 oldLeaderCLI = None # the CLI of the old leader used for re-electing
1917 expectNoLeader = False # True when there is only one leader
1918 if main.numCtrls == 1:
1919 expectNoLeader = True
acsmars2c2fcdd2015-08-25 17:14:13 -07001920
acsmars71adceb2015-08-31 15:09:26 -07001921 main.step( "Run for election on each node" )
1922 electionResult = main.TRUE
1923
1924 for cli in main.CLIs: # run test election on each node
1925 if cli.electionTestRun() == main.FALSE:
1926 electionResult = main.FALSE
1927
1928 utilities.assert_equals(
1929 expect=main.TRUE,
1930 actual=electionResult,
1931 onpass="All nodes successfully ran for leadership",
1932 onfail="At least one node failed to run for leadership" )
1933
acsmars3a72bde2015-09-02 14:16:22 -07001934 if electionResult == main.FALSE:
1935 main.log.error(
1936 "Skipping Test Case because Election Test App isn't loaded" )
1937 main.skipCase()
1938
acsmars71adceb2015-08-31 15:09:26 -07001939 main.step( "Check that each node shows the same leader and candidates" )
1940 sameResult = main.TRUE
1941 failMessage = "Nodes have different leaders"
1942 for cli in main.CLIs:
1943 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
1944 oldAllCandidates.append( node )
1945 oldLeaders.append( node[ 0 ] )
1946 oldCandidates = oldAllCandidates[ 0 ]
1947
1948 # Check that each node has the same leader. Defines oldLeader
1949 if len( set( oldLeaders ) ) != 1:
1950 sameResult = main.FALSE
1951 main.log.error( "More than one leader present:" + str( oldLeaders ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001952 oldLeader = None
1953 else:
acsmars71adceb2015-08-31 15:09:26 -07001954 oldLeader = oldLeaders[ 0 ]
1955
1956 # Check that each node's candidate list is the same
acsmars29233db2015-11-04 11:15:00 -08001957 candidateDiscrepancy = False # Boolean of candidate mismatches
acsmars71adceb2015-08-31 15:09:26 -07001958 for candidates in oldAllCandidates:
1959 if set( candidates ) != set( oldCandidates ):
1960 sameResult = main.FALSE
acsmars29233db2015-11-04 11:15:00 -08001961 candidateDiscrepancy = True
1962
1963 if candidateDiscrepancy:
1964 failMessage += " and candidates"
acsmars71adceb2015-08-31 15:09:26 -07001965
1966 utilities.assert_equals(
1967 expect=main.TRUE,
1968 actual=sameResult,
1969 onpass="Leadership is consistent for the election topic",
1970 onfail=failMessage )
1971
1972 main.step( "Find current leader and withdraw" )
1973 withdrawResult = main.TRUE
1974 # do some sanity checking on leader before using it
1975 if oldLeader is None:
1976 main.log.error( "Leadership isn't consistent." )
1977 withdrawResult = main.FALSE
1978 # Get the CLI of the oldLeader
1979 for i in range( len( main.CLIs ) ):
1980 if oldLeader == main.nodes[ i ].ip_address:
1981 oldLeaderCLI = main.CLIs[ i ]
1982 break
1983 else: # FOR/ELSE statement
1984 main.log.error( "Leader election, could not find current leader" )
Jon Hall85794ff2015-07-08 14:12:30 -07001985 if oldLeader:
acsmars71adceb2015-08-31 15:09:26 -07001986 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall85794ff2015-07-08 14:12:30 -07001987 utilities.assert_equals(
1988 expect=main.TRUE,
1989 actual=withdrawResult,
1990 onpass="Node was withdrawn from election",
1991 onfail="Node was not withdrawn from election" )
1992
acsmars71adceb2015-08-31 15:09:26 -07001993 main.step( "Check that a new node was elected leader" )
1994
1995 # FIXME: use threads
1996 newLeaderResult = main.TRUE
1997 failMessage = "Nodes have different leaders"
1998
1999 # Get new leaders and candidates
2000 for cli in main.CLIs:
2001 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2002 # elections might no have finished yet
2003 if node[ 0 ] == 'none' and not expectNoLeader:
2004 main.log.info( "Node has no leader, waiting 5 seconds to be " +
2005 "sure elections are complete." )
2006 time.sleep(5)
2007 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2008 # election still isn't done or there is a problem
2009 if node[ 0 ] == 'none':
2010 main.log.error( "No leader was elected on at least 1 node" )
2011 newLeaderResult = main.FALSE
2012 newAllCandidates.append( node )
2013 newLeaders.append( node[ 0 ] )
2014 newCandidates = newAllCandidates[ 0 ]
2015
2016 # Check that each node has the same leader. Defines newLeader
2017 if len( set( newLeaders ) ) != 1:
2018 newLeaderResult = main.FALSE
2019 main.log.error( "Nodes have different leaders: " +
2020 str( newLeaders ) )
2021 newLeader = None
2022 else:
2023 newLeader = newLeaders[ 0 ]
2024
2025 # Check that each node's candidate list is the same
2026 for candidates in newAllCandidates:
2027 if set( candidates ) != set( newCandidates ):
2028 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07002029 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07002030
2031 # Check that the new leader is not the older leader, which was withdrawn
2032 if newLeader == oldLeader:
2033 newLeaderResult = main.FALSE
2034 main.log.error( "All nodes still see old leader: " + oldLeader +
2035 " as the current leader" )
2036
Jon Hall85794ff2015-07-08 14:12:30 -07002037 utilities.assert_equals(
2038 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002039 actual=newLeaderResult,
2040 onpass="Leadership election passed",
2041 onfail="Something went wrong with Leadership election" )
Jon Hall85794ff2015-07-08 14:12:30 -07002042
acsmars71adceb2015-08-31 15:09:26 -07002043 main.step( "Check that that new leader was the candidate of old leader")
2044 # candidates[ 2 ] should be come the top candidate after withdrawl
2045 correctCandidateResult = main.TRUE
2046 if expectNoLeader:
2047 if newLeader == 'none':
2048 main.log.info( "No leader expected. None found. Pass" )
2049 correctCandidateResult = main.TRUE
2050 else:
2051 main.log.info( "Expected no leader, got: " + str( newLeader ) )
2052 correctCandidateResult = main.FALSE
2053 elif newLeader != oldCandidates[ 2 ]:
2054 correctCandidateResult = main.FALSE
2055 main.log.error( "Candidate " + newLeader + " was elected. " +
2056 oldCandidates[ 2 ] + " should have had priority." )
2057
2058 utilities.assert_equals(
2059 expect=main.TRUE,
2060 actual=correctCandidateResult,
2061 onpass="Correct Candidate Elected",
2062 onfail="Incorrect Candidate Elected" )
2063
Jon Hall85794ff2015-07-08 14:12:30 -07002064 main.step( "Run for election on old leader( just so everyone " +
2065 "is in the hat )" )
acsmars71adceb2015-08-31 15:09:26 -07002066 if oldLeaderCLI is not None:
2067 runResult = oldLeaderCLI.electionTestRun()
Jon Hall85794ff2015-07-08 14:12:30 -07002068 else:
acsmars71adceb2015-08-31 15:09:26 -07002069 main.log.error( "No old leader to re-elect" )
Jon Hall85794ff2015-07-08 14:12:30 -07002070 runResult = main.FALSE
2071 utilities.assert_equals(
2072 expect=main.TRUE,
2073 actual=runResult,
2074 onpass="App re-ran for election",
2075 onfail="App failed to run for election" )
acsmars71adceb2015-08-31 15:09:26 -07002076 main.step(
2077 "Check that oldLeader is a candidate, and leader if only 1 node" )
2078 # verify leader didn't just change
2079 positionResult = main.TRUE
2080 # Get new leaders and candidates, wait if oldLeader is not a candidate yet
Jon Hall85794ff2015-07-08 14:12:30 -07002081
acsmars71adceb2015-08-31 15:09:26 -07002082 # Reset and reuse the new candidate and leaders lists
2083 newAllCandidates = []
2084 newCandidates = []
2085 newLeaders = []
2086 for cli in main.CLIs:
2087 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2088 if oldLeader not in node: # election might no have finished yet
2089 main.log.info( "Old Leader not elected, waiting 5 seconds to " +
2090 "be sure elections are complete" )
2091 time.sleep(5)
2092 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2093 if oldLeader not in node: # election still isn't done, errors
2094 main.log.error(
2095 "Old leader was not elected on at least one node" )
2096 positionResult = main.FALSE
2097 newAllCandidates.append( node )
2098 newLeaders.append( node[ 0 ] )
2099 newCandidates = newAllCandidates[ 0 ]
2100
2101 # Check that each node has the same leader. Defines newLeader
2102 if len( set( newLeaders ) ) != 1:
2103 positionResult = main.FALSE
2104 main.log.error( "Nodes have different leaders: " +
2105 str( newLeaders ) )
2106 newLeader = None
Jon Hall85794ff2015-07-08 14:12:30 -07002107 else:
acsmars71adceb2015-08-31 15:09:26 -07002108 newLeader = newLeaders[ 0 ]
2109
2110 # Check that each node's candidate list is the same
2111 for candidates in newAllCandidates:
2112 if set( candidates ) != set( newCandidates ):
2113 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07002114 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07002115
2116 # Check that the re-elected node is last on the candidate List
2117 if oldLeader != newCandidates[ -1 ]:
2118 main.log.error( "Old Leader (" + oldLeader + ") not in the proper position " +
2119 str( newCandidates ) )
2120 positionResult = main.FALSE
Jon Hall85794ff2015-07-08 14:12:30 -07002121
2122 utilities.assert_equals(
2123 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002124 actual=positionResult,
Jon Hall85794ff2015-07-08 14:12:30 -07002125 onpass="Old leader successfully re-ran for election",
2126 onfail="Something went wrong with Leadership election after " +
2127 "the old leader re-ran for election" )
2128
2129 def CASE16( self, main ):
2130 """
2131 Install Distributed Primitives app
2132 """
Jon Halle1a3b752015-07-22 13:02:46 -07002133 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002134 assert main, "main not defined"
2135 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002136 assert main.CLIs, "main.CLIs not defined"
2137 assert main.nodes, "main.nodes not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002138
2139 # Variables for the distributed primitives tests
2140 global pCounterName
2141 global iCounterName
2142 global pCounterValue
2143 global iCounterValue
2144 global onosSet
2145 global onosSetName
2146 pCounterName = "TestON-Partitions"
2147 iCounterName = "TestON-inMemory"
2148 pCounterValue = 0
2149 iCounterValue = 0
2150 onosSet = set([])
2151 onosSetName = "TestON-set"
2152
2153 description = "Install Primitives app"
2154 main.case( description )
2155 main.step( "Install Primitives app" )
2156 appName = "org.onosproject.distributedprimitives"
Jon Halle1a3b752015-07-22 13:02:46 -07002157 appResults = main.CLIs[0].activateApp( appName )
Jon Hall85794ff2015-07-08 14:12:30 -07002158 utilities.assert_equals( expect=main.TRUE,
2159 actual=appResults,
2160 onpass="Primitives app activated",
2161 onfail="Primitives app not activated" )
2162
2163 def CASE17( self, main ):
2164 """
2165 Check for basic functionality with distributed primitives
2166 """
Jon Hall85794ff2015-07-08 14:12:30 -07002167 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07002168 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002169 assert main, "main not defined"
2170 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002171 assert main.CLIs, "main.CLIs not defined"
2172 assert main.nodes, "main.nodes not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002173 assert pCounterName, "pCounterName not defined"
2174 assert iCounterName, "iCounterName not defined"
2175 assert onosSetName, "onosSetName not defined"
2176 # NOTE: assert fails if value is 0/None/Empty/False
2177 try:
2178 pCounterValue
2179 except NameError:
2180 main.log.error( "pCounterValue not defined, setting to 0" )
2181 pCounterValue = 0
2182 try:
2183 iCounterValue
2184 except NameError:
2185 main.log.error( "iCounterValue not defined, setting to 0" )
2186 iCounterValue = 0
2187 try:
2188 onosSet
2189 except NameError:
2190 main.log.error( "onosSet not defined, setting to empty Set" )
2191 onosSet = set([])
2192 # Variables for the distributed primitives tests. These are local only
2193 addValue = "a"
2194 addAllValue = "a b c d e f"
2195 retainValue = "c d e f"
2196
2197 description = "Check for basic functionality with distributed " +\
2198 "primitives"
2199 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07002200 main.caseExplanation = "Test the methods of the distributed " +\
2201 "primitives (counters and sets) throught the cli"
Jon Hall85794ff2015-07-08 14:12:30 -07002202 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07002203 # Partitioned counters
2204 main.step( "Increment then get a default counter on each node" )
Jon Hall85794ff2015-07-08 14:12:30 -07002205 pCounters = []
2206 threads = []
2207 addedPValues = []
Jon Halle1a3b752015-07-22 13:02:46 -07002208 for i in range( main.numCtrls ):
2209 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2210 name="counterAddAndGet-" + str( i ),
Jon Hall85794ff2015-07-08 14:12:30 -07002211 args=[ pCounterName ] )
2212 pCounterValue += 1
2213 addedPValues.append( pCounterValue )
2214 threads.append( t )
2215 t.start()
2216
2217 for t in threads:
2218 t.join()
2219 pCounters.append( t.result )
2220 # Check that counter incremented numController times
2221 pCounterResults = True
2222 for i in addedPValues:
2223 tmpResult = i in pCounters
2224 pCounterResults = pCounterResults and tmpResult
2225 if not tmpResult:
2226 main.log.error( str( i ) + " is not in partitioned "
2227 "counter incremented results" )
2228 utilities.assert_equals( expect=True,
2229 actual=pCounterResults,
2230 onpass="Default counter incremented",
2231 onfail="Error incrementing default" +
2232 " counter" )
2233
Jon Halle1a3b752015-07-22 13:02:46 -07002234 main.step( "Get then Increment a default counter on each node" )
2235 pCounters = []
2236 threads = []
2237 addedPValues = []
2238 for i in range( main.numCtrls ):
2239 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
2240 name="counterGetAndAdd-" + str( i ),
2241 args=[ pCounterName ] )
2242 addedPValues.append( pCounterValue )
2243 pCounterValue += 1
2244 threads.append( t )
2245 t.start()
2246
2247 for t in threads:
2248 t.join()
2249 pCounters.append( t.result )
2250 # Check that counter incremented numController times
2251 pCounterResults = True
2252 for i in addedPValues:
2253 tmpResult = i in pCounters
2254 pCounterResults = pCounterResults and tmpResult
2255 if not tmpResult:
2256 main.log.error( str( i ) + " is not in partitioned "
2257 "counter incremented results" )
2258 utilities.assert_equals( expect=True,
2259 actual=pCounterResults,
2260 onpass="Default counter incremented",
2261 onfail="Error incrementing default" +
2262 " counter" )
2263
2264 main.step( "Counters we added have the correct values" )
2265 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
2266 utilities.assert_equals( expect=main.TRUE,
2267 actual=incrementCheck,
2268 onpass="Added counters are correct",
2269 onfail="Added counters are incorrect" )
2270
2271 main.step( "Add -8 to then get a default counter on each node" )
2272 pCounters = []
2273 threads = []
2274 addedPValues = []
2275 for i in range( main.numCtrls ):
2276 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2277 name="counterIncrement-" + str( i ),
2278 args=[ pCounterName ],
2279 kwargs={ "delta": -8 } )
2280 pCounterValue += -8
2281 addedPValues.append( pCounterValue )
2282 threads.append( t )
2283 t.start()
2284
2285 for t in threads:
2286 t.join()
2287 pCounters.append( t.result )
2288 # Check that counter incremented numController times
2289 pCounterResults = True
2290 for i in addedPValues:
2291 tmpResult = i in pCounters
2292 pCounterResults = pCounterResults and tmpResult
2293 if not tmpResult:
2294 main.log.error( str( i ) + " is not in partitioned "
2295 "counter incremented results" )
2296 utilities.assert_equals( expect=True,
2297 actual=pCounterResults,
2298 onpass="Default counter incremented",
2299 onfail="Error incrementing default" +
2300 " counter" )
2301
2302 main.step( "Add 5 to then get a default counter on each node" )
2303 pCounters = []
2304 threads = []
2305 addedPValues = []
2306 for i in range( main.numCtrls ):
2307 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2308 name="counterIncrement-" + str( i ),
2309 args=[ pCounterName ],
2310 kwargs={ "delta": 5 } )
2311 pCounterValue += 5
2312 addedPValues.append( pCounterValue )
2313 threads.append( t )
2314 t.start()
2315
2316 for t in threads:
2317 t.join()
2318 pCounters.append( t.result )
2319 # Check that counter incremented numController times
2320 pCounterResults = True
2321 for i in addedPValues:
2322 tmpResult = i in pCounters
2323 pCounterResults = pCounterResults and tmpResult
2324 if not tmpResult:
2325 main.log.error( str( i ) + " is not in partitioned "
2326 "counter incremented results" )
2327 utilities.assert_equals( expect=True,
2328 actual=pCounterResults,
2329 onpass="Default counter incremented",
2330 onfail="Error incrementing default" +
2331 " counter" )
2332
2333 main.step( "Get then add 5 to a default counter on each node" )
2334 pCounters = []
2335 threads = []
2336 addedPValues = []
2337 for i in range( main.numCtrls ):
2338 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
2339 name="counterIncrement-" + str( i ),
2340 args=[ pCounterName ],
2341 kwargs={ "delta": 5 } )
2342 addedPValues.append( pCounterValue )
2343 pCounterValue += 5
2344 threads.append( t )
2345 t.start()
2346
2347 for t in threads:
2348 t.join()
2349 pCounters.append( t.result )
2350 # Check that counter incremented numController times
2351 pCounterResults = True
2352 for i in addedPValues:
2353 tmpResult = i in pCounters
2354 pCounterResults = pCounterResults and tmpResult
2355 if not tmpResult:
2356 main.log.error( str( i ) + " is not in partitioned "
2357 "counter incremented results" )
2358 utilities.assert_equals( expect=True,
2359 actual=pCounterResults,
2360 onpass="Default counter incremented",
2361 onfail="Error incrementing default" +
2362 " counter" )
2363
2364 main.step( "Counters we added have the correct values" )
2365 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
2366 utilities.assert_equals( expect=main.TRUE,
2367 actual=incrementCheck,
2368 onpass="Added counters are correct",
2369 onfail="Added counters are incorrect" )
2370
2371 # In-Memory counters
2372 main.step( "Increment and get an in-memory counter on each node" )
Jon Hall85794ff2015-07-08 14:12:30 -07002373 iCounters = []
2374 addedIValues = []
2375 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002376 for i in range( main.numCtrls ):
2377 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002378 name="icounterIncrement-" + str( i ),
2379 args=[ iCounterName ],
2380 kwargs={ "inMemory": True } )
2381 iCounterValue += 1
2382 addedIValues.append( iCounterValue )
2383 threads.append( t )
2384 t.start()
2385
2386 for t in threads:
2387 t.join()
2388 iCounters.append( t.result )
2389 # Check that counter incremented numController times
2390 iCounterResults = True
2391 for i in addedIValues:
2392 tmpResult = i in iCounters
2393 iCounterResults = iCounterResults and tmpResult
2394 if not tmpResult:
2395 main.log.error( str( i ) + " is not in the in-memory "
2396 "counter incremented results" )
2397 utilities.assert_equals( expect=True,
2398 actual=iCounterResults,
Jon Halle1a3b752015-07-22 13:02:46 -07002399 onpass="In-memory counter incremented",
2400 onfail="Error incrementing in-memory" +
Jon Hall85794ff2015-07-08 14:12:30 -07002401 " counter" )
2402
Jon Halle1a3b752015-07-22 13:02:46 -07002403 main.step( "Get then Increment a in-memory counter on each node" )
2404 iCounters = []
2405 threads = []
2406 addedIValues = []
2407 for i in range( main.numCtrls ):
2408 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
2409 name="counterGetAndAdd-" + str( i ),
2410 args=[ iCounterName ],
2411 kwargs={ "inMemory": True } )
2412 addedIValues.append( iCounterValue )
2413 iCounterValue += 1
2414 threads.append( t )
2415 t.start()
2416
2417 for t in threads:
2418 t.join()
2419 iCounters.append( t.result )
2420 # Check that counter incremented numController times
2421 iCounterResults = True
2422 for i in addedIValues:
2423 tmpResult = i in iCounters
2424 iCounterResults = iCounterResults and tmpResult
2425 if not tmpResult:
2426 main.log.error( str( i ) + " is not in in-memory "
2427 "counter incremented results" )
2428 utilities.assert_equals( expect=True,
2429 actual=iCounterResults,
2430 onpass="In-memory counter incremented",
2431 onfail="Error incrementing in-memory" +
2432 " counter" )
2433
2434 main.step( "Counters we added have the correct values" )
2435 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
2436 utilities.assert_equals( expect=main.TRUE,
2437 actual=incrementCheck,
2438 onpass="Added counters are correct",
2439 onfail="Added counters are incorrect" )
2440
2441 main.step( "Add -8 to then get a in-memory counter on each node" )
2442 iCounters = []
2443 threads = []
2444 addedIValues = []
2445 for i in range( main.numCtrls ):
2446 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2447 name="counterIncrement-" + str( i ),
2448 args=[ iCounterName ],
2449 kwargs={ "delta": -8, "inMemory": True } )
2450 iCounterValue += -8
2451 addedIValues.append( iCounterValue )
2452 threads.append( t )
2453 t.start()
2454
2455 for t in threads:
2456 t.join()
2457 iCounters.append( t.result )
2458 # Check that counter incremented numController times
2459 iCounterResults = True
2460 for i in addedIValues:
2461 tmpResult = i in iCounters
2462 iCounterResults = iCounterResults and tmpResult
2463 if not tmpResult:
2464 main.log.error( str( i ) + " is not in in-memory "
2465 "counter incremented results" )
2466 utilities.assert_equals( expect=True,
2467 actual=pCounterResults,
2468 onpass="In-memory counter incremented",
2469 onfail="Error incrementing in-memory" +
2470 " counter" )
2471
2472 main.step( "Add 5 to then get a in-memory counter on each node" )
2473 iCounters = []
2474 threads = []
2475 addedIValues = []
2476 for i in range( main.numCtrls ):
2477 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2478 name="counterIncrement-" + str( i ),
2479 args=[ iCounterName ],
2480 kwargs={ "delta": 5, "inMemory": True } )
2481 iCounterValue += 5
2482 addedIValues.append( iCounterValue )
2483 threads.append( t )
2484 t.start()
2485
2486 for t in threads:
2487 t.join()
2488 iCounters.append( t.result )
2489 # Check that counter incremented numController times
2490 iCounterResults = True
2491 for i in addedIValues:
2492 tmpResult = i in iCounters
2493 iCounterResults = iCounterResults and tmpResult
2494 if not tmpResult:
2495 main.log.error( str( i ) + " is not in in-memory "
2496 "counter incremented results" )
2497 utilities.assert_equals( expect=True,
2498 actual=pCounterResults,
2499 onpass="In-memory counter incremented",
2500 onfail="Error incrementing in-memory" +
2501 " counter" )
2502
2503 main.step( "Get then add 5 to a in-memory counter on each node" )
2504 iCounters = []
2505 threads = []
2506 addedIValues = []
2507 for i in range( main.numCtrls ):
2508 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
2509 name="counterIncrement-" + str( i ),
2510 args=[ iCounterName ],
2511 kwargs={ "delta": 5, "inMemory": True } )
2512 addedIValues.append( iCounterValue )
2513 iCounterValue += 5
2514 threads.append( t )
2515 t.start()
2516
2517 for t in threads:
2518 t.join()
2519 iCounters.append( t.result )
2520 # Check that counter incremented numController times
2521 iCounterResults = True
2522 for i in addedIValues:
2523 tmpResult = i in iCounters
2524 iCounterResults = iCounterResults and tmpResult
2525 if not tmpResult:
2526 main.log.error( str( i ) + " is not in in-memory "
2527 "counter incremented results" )
2528 utilities.assert_equals( expect=True,
2529 actual=iCounterResults,
2530 onpass="In-memory counter incremented",
2531 onfail="Error incrementing in-memory" +
2532 " counter" )
2533
2534 main.step( "Counters we added have the correct values" )
2535 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
2536 utilities.assert_equals( expect=main.TRUE,
2537 actual=incrementCheck,
2538 onpass="Added counters are correct",
2539 onfail="Added counters are incorrect" )
2540
Jon Hall85794ff2015-07-08 14:12:30 -07002541 main.step( "Check counters are consistant across nodes" )
Jon Hall57b50432015-10-22 10:20:10 -07002542 onosCounters, consistentCounterResults = main.Counters.consistentCheck()
Jon Hall85794ff2015-07-08 14:12:30 -07002543 utilities.assert_equals( expect=main.TRUE,
2544 actual=consistentCounterResults,
2545 onpass="ONOS counters are consistent " +
2546 "across nodes",
2547 onfail="ONOS Counters are inconsistent " +
2548 "across nodes" )
2549
2550 main.step( "Counters we added have the correct values" )
Jon Halle1a3b752015-07-22 13:02:46 -07002551 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
2552 incrementCheck = incrementCheck and \
2553 main.Counters.counterCheck( iCounterName, iCounterValue )
Jon Hall85794ff2015-07-08 14:12:30 -07002554 utilities.assert_equals( expect=main.TRUE,
Jon Halle1a3b752015-07-22 13:02:46 -07002555 actual=incrementCheck,
Jon Hall85794ff2015-07-08 14:12:30 -07002556 onpass="Added counters are correct",
2557 onfail="Added counters are incorrect" )
2558 # DISTRIBUTED SETS
2559 main.step( "Distributed Set get" )
2560 size = len( onosSet )
2561 getResponses = []
2562 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002563 for i in range( main.numCtrls ):
2564 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002565 name="setTestGet-" + str( i ),
2566 args=[ onosSetName ] )
2567 threads.append( t )
2568 t.start()
2569 for t in threads:
2570 t.join()
2571 getResponses.append( t.result )
2572
2573 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002574 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002575 if isinstance( getResponses[ i ], list):
2576 current = set( getResponses[ i ] )
2577 if len( current ) == len( getResponses[ i ] ):
2578 # no repeats
2579 if onosSet != current:
2580 main.log.error( "ONOS" + str( i + 1 ) +
2581 " has incorrect view" +
2582 " of set " + onosSetName + ":\n" +
2583 str( getResponses[ i ] ) )
2584 main.log.debug( "Expected: " + str( onosSet ) )
2585 main.log.debug( "Actual: " + str( current ) )
2586 getResults = main.FALSE
2587 else:
2588 # error, set is not a set
2589 main.log.error( "ONOS" + str( i + 1 ) +
2590 " has repeat elements in" +
2591 " set " + onosSetName + ":\n" +
2592 str( getResponses[ i ] ) )
2593 getResults = main.FALSE
2594 elif getResponses[ i ] == main.ERROR:
2595 getResults = main.FALSE
2596 utilities.assert_equals( expect=main.TRUE,
2597 actual=getResults,
2598 onpass="Set elements are correct",
2599 onfail="Set elements are incorrect" )
2600
2601 main.step( "Distributed Set size" )
2602 sizeResponses = []
2603 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002604 for i in range( main.numCtrls ):
2605 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002606 name="setTestSize-" + str( i ),
2607 args=[ onosSetName ] )
2608 threads.append( t )
2609 t.start()
2610 for t in threads:
2611 t.join()
2612 sizeResponses.append( t.result )
2613
2614 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002615 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002616 if size != sizeResponses[ i ]:
2617 sizeResults = main.FALSE
2618 main.log.error( "ONOS" + str( i + 1 ) +
2619 " expected a size of " + str( size ) +
2620 " for set " + onosSetName +
2621 " but got " + str( sizeResponses[ i ] ) )
2622 utilities.assert_equals( expect=main.TRUE,
2623 actual=sizeResults,
2624 onpass="Set sizes are correct",
2625 onfail="Set sizes are incorrect" )
2626
2627 main.step( "Distributed Set add()" )
2628 onosSet.add( addValue )
2629 addResponses = []
2630 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002631 for i in range( main.numCtrls ):
2632 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07002633 name="setTestAdd-" + str( i ),
2634 args=[ onosSetName, addValue ] )
2635 threads.append( t )
2636 t.start()
2637 for t in threads:
2638 t.join()
2639 addResponses.append( t.result )
2640
2641 # main.TRUE = successfully changed the set
2642 # main.FALSE = action resulted in no change in set
2643 # main.ERROR - Some error in executing the function
2644 addResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002645 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002646 if addResponses[ i ] == main.TRUE:
2647 # All is well
2648 pass
2649 elif addResponses[ i ] == main.FALSE:
2650 # Already in set, probably fine
2651 pass
2652 elif addResponses[ i ] == main.ERROR:
2653 # Error in execution
2654 addResults = main.FALSE
2655 else:
2656 # unexpected result
2657 addResults = main.FALSE
2658 if addResults != main.TRUE:
2659 main.log.error( "Error executing set add" )
2660
2661 # Check if set is still correct
2662 size = len( onosSet )
2663 getResponses = []
2664 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002665 for i in range( main.numCtrls ):
2666 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002667 name="setTestGet-" + str( i ),
2668 args=[ onosSetName ] )
2669 threads.append( t )
2670 t.start()
2671 for t in threads:
2672 t.join()
2673 getResponses.append( t.result )
2674 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002675 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002676 if isinstance( getResponses[ i ], list):
2677 current = set( getResponses[ i ] )
2678 if len( current ) == len( getResponses[ i ] ):
2679 # no repeats
2680 if onosSet != current:
2681 main.log.error( "ONOS" + str( i + 1 ) +
2682 " has incorrect view" +
2683 " of set " + onosSetName + ":\n" +
2684 str( getResponses[ i ] ) )
2685 main.log.debug( "Expected: " + str( onosSet ) )
2686 main.log.debug( "Actual: " + str( current ) )
2687 getResults = main.FALSE
2688 else:
2689 # error, set is not a set
2690 main.log.error( "ONOS" + str( i + 1 ) +
2691 " has repeat elements in" +
2692 " set " + onosSetName + ":\n" +
2693 str( getResponses[ i ] ) )
2694 getResults = main.FALSE
2695 elif getResponses[ i ] == main.ERROR:
2696 getResults = main.FALSE
2697 sizeResponses = []
2698 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002699 for i in range( main.numCtrls ):
2700 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002701 name="setTestSize-" + str( i ),
2702 args=[ onosSetName ] )
2703 threads.append( t )
2704 t.start()
2705 for t in threads:
2706 t.join()
2707 sizeResponses.append( t.result )
2708 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002709 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002710 if size != sizeResponses[ i ]:
2711 sizeResults = main.FALSE
2712 main.log.error( "ONOS" + str( i + 1 ) +
2713 " expected a size of " + str( size ) +
2714 " for set " + onosSetName +
2715 " but got " + str( sizeResponses[ i ] ) )
2716 addResults = addResults and getResults and sizeResults
2717 utilities.assert_equals( expect=main.TRUE,
2718 actual=addResults,
2719 onpass="Set add correct",
2720 onfail="Set add was incorrect" )
2721
2722 main.step( "Distributed Set addAll()" )
2723 onosSet.update( addAllValue.split() )
2724 addResponses = []
2725 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002726 for i in range( main.numCtrls ):
2727 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07002728 name="setTestAddAll-" + str( i ),
2729 args=[ onosSetName, addAllValue ] )
2730 threads.append( t )
2731 t.start()
2732 for t in threads:
2733 t.join()
2734 addResponses.append( t.result )
2735
2736 # main.TRUE = successfully changed the set
2737 # main.FALSE = action resulted in no change in set
2738 # main.ERROR - Some error in executing the function
2739 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002740 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002741 if addResponses[ i ] == main.TRUE:
2742 # All is well
2743 pass
2744 elif addResponses[ i ] == main.FALSE:
2745 # Already in set, probably fine
2746 pass
2747 elif addResponses[ i ] == main.ERROR:
2748 # Error in execution
2749 addAllResults = main.FALSE
2750 else:
2751 # unexpected result
2752 addAllResults = main.FALSE
2753 if addAllResults != main.TRUE:
2754 main.log.error( "Error executing set addAll" )
2755
2756 # Check if set is still correct
2757 size = len( onosSet )
2758 getResponses = []
2759 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002760 for i in range( main.numCtrls ):
2761 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002762 name="setTestGet-" + str( i ),
2763 args=[ onosSetName ] )
2764 threads.append( t )
2765 t.start()
2766 for t in threads:
2767 t.join()
2768 getResponses.append( t.result )
2769 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002770 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002771 if isinstance( getResponses[ i ], list):
2772 current = set( getResponses[ i ] )
2773 if len( current ) == len( getResponses[ i ] ):
2774 # no repeats
2775 if onosSet != current:
2776 main.log.error( "ONOS" + str( i + 1 ) +
2777 " has incorrect view" +
2778 " of set " + onosSetName + ":\n" +
2779 str( getResponses[ i ] ) )
2780 main.log.debug( "Expected: " + str( onosSet ) )
2781 main.log.debug( "Actual: " + str( current ) )
2782 getResults = main.FALSE
2783 else:
2784 # error, set is not a set
2785 main.log.error( "ONOS" + str( i + 1 ) +
2786 " has repeat elements in" +
2787 " set " + onosSetName + ":\n" +
2788 str( getResponses[ i ] ) )
2789 getResults = main.FALSE
2790 elif getResponses[ i ] == main.ERROR:
2791 getResults = main.FALSE
2792 sizeResponses = []
2793 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002794 for i in range( main.numCtrls ):
2795 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002796 name="setTestSize-" + str( i ),
2797 args=[ onosSetName ] )
2798 threads.append( t )
2799 t.start()
2800 for t in threads:
2801 t.join()
2802 sizeResponses.append( t.result )
2803 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002804 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002805 if size != sizeResponses[ i ]:
2806 sizeResults = main.FALSE
2807 main.log.error( "ONOS" + str( i + 1 ) +
2808 " expected a size of " + str( size ) +
2809 " for set " + onosSetName +
2810 " but got " + str( sizeResponses[ i ] ) )
2811 addAllResults = addAllResults and getResults and sizeResults
2812 utilities.assert_equals( expect=main.TRUE,
2813 actual=addAllResults,
2814 onpass="Set addAll correct",
2815 onfail="Set addAll was incorrect" )
2816
2817 main.step( "Distributed Set contains()" )
2818 containsResponses = []
2819 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002820 for i in range( main.numCtrls ):
2821 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002822 name="setContains-" + str( i ),
2823 args=[ onosSetName ],
2824 kwargs={ "values": addValue } )
2825 threads.append( t )
2826 t.start()
2827 for t in threads:
2828 t.join()
2829 # NOTE: This is the tuple
2830 containsResponses.append( t.result )
2831
2832 containsResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002833 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002834 if containsResponses[ i ] == main.ERROR:
2835 containsResults = main.FALSE
2836 else:
2837 containsResults = containsResults and\
2838 containsResponses[ i ][ 1 ]
2839 utilities.assert_equals( expect=main.TRUE,
2840 actual=containsResults,
2841 onpass="Set contains is functional",
2842 onfail="Set contains failed" )
2843
2844 main.step( "Distributed Set containsAll()" )
2845 containsAllResponses = []
2846 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002847 for i in range( main.numCtrls ):
2848 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002849 name="setContainsAll-" + str( i ),
2850 args=[ onosSetName ],
2851 kwargs={ "values": addAllValue } )
2852 threads.append( t )
2853 t.start()
2854 for t in threads:
2855 t.join()
2856 # NOTE: This is the tuple
2857 containsAllResponses.append( t.result )
2858
2859 containsAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002860 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002861 if containsResponses[ i ] == main.ERROR:
2862 containsResults = main.FALSE
2863 else:
2864 containsResults = containsResults and\
2865 containsResponses[ i ][ 1 ]
2866 utilities.assert_equals( expect=main.TRUE,
2867 actual=containsAllResults,
2868 onpass="Set containsAll is functional",
2869 onfail="Set containsAll failed" )
2870
2871 main.step( "Distributed Set remove()" )
2872 onosSet.remove( addValue )
2873 removeResponses = []
2874 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002875 for i in range( main.numCtrls ):
2876 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07002877 name="setTestRemove-" + str( i ),
2878 args=[ onosSetName, addValue ] )
2879 threads.append( t )
2880 t.start()
2881 for t in threads:
2882 t.join()
2883 removeResponses.append( t.result )
2884
2885 # main.TRUE = successfully changed the set
2886 # main.FALSE = action resulted in no change in set
2887 # main.ERROR - Some error in executing the function
2888 removeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002889 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002890 if removeResponses[ i ] == main.TRUE:
2891 # All is well
2892 pass
2893 elif removeResponses[ i ] == main.FALSE:
2894 # not in set, probably fine
2895 pass
2896 elif removeResponses[ i ] == main.ERROR:
2897 # Error in execution
2898 removeResults = main.FALSE
2899 else:
2900 # unexpected result
2901 removeResults = main.FALSE
2902 if removeResults != main.TRUE:
2903 main.log.error( "Error executing set remove" )
2904
2905 # Check if set is still correct
2906 size = len( onosSet )
2907 getResponses = []
2908 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002909 for i in range( main.numCtrls ):
2910 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002911 name="setTestGet-" + str( i ),
2912 args=[ onosSetName ] )
2913 threads.append( t )
2914 t.start()
2915 for t in threads:
2916 t.join()
2917 getResponses.append( t.result )
2918 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002919 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002920 if isinstance( getResponses[ i ], list):
2921 current = set( getResponses[ i ] )
2922 if len( current ) == len( getResponses[ i ] ):
2923 # no repeats
2924 if onosSet != current:
2925 main.log.error( "ONOS" + str( i + 1 ) +
2926 " has incorrect view" +
2927 " of set " + onosSetName + ":\n" +
2928 str( getResponses[ i ] ) )
2929 main.log.debug( "Expected: " + str( onosSet ) )
2930 main.log.debug( "Actual: " + str( current ) )
2931 getResults = main.FALSE
2932 else:
2933 # error, set is not a set
2934 main.log.error( "ONOS" + str( i + 1 ) +
2935 " has repeat elements in" +
2936 " set " + onosSetName + ":\n" +
2937 str( getResponses[ i ] ) )
2938 getResults = main.FALSE
2939 elif getResponses[ i ] == main.ERROR:
2940 getResults = main.FALSE
2941 sizeResponses = []
2942 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002943 for i in range( main.numCtrls ):
2944 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002945 name="setTestSize-" + str( i ),
2946 args=[ onosSetName ] )
2947 threads.append( t )
2948 t.start()
2949 for t in threads:
2950 t.join()
2951 sizeResponses.append( t.result )
2952 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002953 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002954 if size != sizeResponses[ i ]:
2955 sizeResults = main.FALSE
2956 main.log.error( "ONOS" + str( i + 1 ) +
2957 " expected a size of " + str( size ) +
2958 " for set " + onosSetName +
2959 " but got " + str( sizeResponses[ i ] ) )
2960 removeResults = removeResults and getResults and sizeResults
2961 utilities.assert_equals( expect=main.TRUE,
2962 actual=removeResults,
2963 onpass="Set remove correct",
2964 onfail="Set remove was incorrect" )
2965
2966 main.step( "Distributed Set removeAll()" )
2967 onosSet.difference_update( addAllValue.split() )
2968 removeAllResponses = []
2969 threads = []
2970 try:
Jon Halle1a3b752015-07-22 13:02:46 -07002971 for i in range( main.numCtrls ):
2972 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07002973 name="setTestRemoveAll-" + str( i ),
2974 args=[ onosSetName, addAllValue ] )
2975 threads.append( t )
2976 t.start()
2977 for t in threads:
2978 t.join()
2979 removeAllResponses.append( t.result )
2980 except Exception, e:
2981 main.log.exception(e)
2982
2983 # main.TRUE = successfully changed the set
2984 # main.FALSE = action resulted in no change in set
2985 # main.ERROR - Some error in executing the function
2986 removeAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002987 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002988 if removeAllResponses[ i ] == main.TRUE:
2989 # All is well
2990 pass
2991 elif removeAllResponses[ i ] == main.FALSE:
2992 # not in set, probably fine
2993 pass
2994 elif removeAllResponses[ i ] == main.ERROR:
2995 # Error in execution
2996 removeAllResults = main.FALSE
2997 else:
2998 # unexpected result
2999 removeAllResults = main.FALSE
3000 if removeAllResults != main.TRUE:
3001 main.log.error( "Error executing set removeAll" )
3002
3003 # Check if set is still correct
3004 size = len( onosSet )
3005 getResponses = []
3006 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003007 for i in range( main.numCtrls ):
3008 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003009 name="setTestGet-" + str( i ),
3010 args=[ onosSetName ] )
3011 threads.append( t )
3012 t.start()
3013 for t in threads:
3014 t.join()
3015 getResponses.append( t.result )
3016 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003017 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003018 if isinstance( getResponses[ i ], list):
3019 current = set( getResponses[ i ] )
3020 if len( current ) == len( getResponses[ i ] ):
3021 # no repeats
3022 if onosSet != current:
3023 main.log.error( "ONOS" + str( i + 1 ) +
3024 " has incorrect view" +
3025 " of set " + onosSetName + ":\n" +
3026 str( getResponses[ i ] ) )
3027 main.log.debug( "Expected: " + str( onosSet ) )
3028 main.log.debug( "Actual: " + str( current ) )
3029 getResults = main.FALSE
3030 else:
3031 # error, set is not a set
3032 main.log.error( "ONOS" + str( i + 1 ) +
3033 " has repeat elements in" +
3034 " set " + onosSetName + ":\n" +
3035 str( getResponses[ i ] ) )
3036 getResults = main.FALSE
3037 elif getResponses[ i ] == main.ERROR:
3038 getResults = main.FALSE
3039 sizeResponses = []
3040 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003041 for i in range( main.numCtrls ):
3042 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003043 name="setTestSize-" + str( i ),
3044 args=[ onosSetName ] )
3045 threads.append( t )
3046 t.start()
3047 for t in threads:
3048 t.join()
3049 sizeResponses.append( t.result )
3050 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003051 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003052 if size != sizeResponses[ i ]:
3053 sizeResults = main.FALSE
3054 main.log.error( "ONOS" + str( i + 1 ) +
3055 " expected a size of " + str( size ) +
3056 " for set " + onosSetName +
3057 " but got " + str( sizeResponses[ i ] ) )
3058 removeAllResults = removeAllResults and getResults and sizeResults
3059 utilities.assert_equals( expect=main.TRUE,
3060 actual=removeAllResults,
3061 onpass="Set removeAll correct",
3062 onfail="Set removeAll was incorrect" )
3063
3064 main.step( "Distributed Set addAll()" )
3065 onosSet.update( addAllValue.split() )
3066 addResponses = []
3067 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003068 for i in range( main.numCtrls ):
3069 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07003070 name="setTestAddAll-" + str( i ),
3071 args=[ onosSetName, addAllValue ] )
3072 threads.append( t )
3073 t.start()
3074 for t in threads:
3075 t.join()
3076 addResponses.append( t.result )
3077
3078 # main.TRUE = successfully changed the set
3079 # main.FALSE = action resulted in no change in set
3080 # main.ERROR - Some error in executing the function
3081 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003082 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003083 if addResponses[ i ] == main.TRUE:
3084 # All is well
3085 pass
3086 elif addResponses[ i ] == main.FALSE:
3087 # Already in set, probably fine
3088 pass
3089 elif addResponses[ i ] == main.ERROR:
3090 # Error in execution
3091 addAllResults = main.FALSE
3092 else:
3093 # unexpected result
3094 addAllResults = main.FALSE
3095 if addAllResults != main.TRUE:
3096 main.log.error( "Error executing set addAll" )
3097
3098 # Check if set is still correct
3099 size = len( onosSet )
3100 getResponses = []
3101 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003102 for i in range( main.numCtrls ):
3103 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003104 name="setTestGet-" + str( i ),
3105 args=[ onosSetName ] )
3106 threads.append( t )
3107 t.start()
3108 for t in threads:
3109 t.join()
3110 getResponses.append( t.result )
3111 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003112 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003113 if isinstance( getResponses[ i ], list):
3114 current = set( getResponses[ i ] )
3115 if len( current ) == len( getResponses[ i ] ):
3116 # no repeats
3117 if onosSet != current:
3118 main.log.error( "ONOS" + str( i + 1 ) +
3119 " has incorrect view" +
3120 " of set " + onosSetName + ":\n" +
3121 str( getResponses[ i ] ) )
3122 main.log.debug( "Expected: " + str( onosSet ) )
3123 main.log.debug( "Actual: " + str( current ) )
3124 getResults = main.FALSE
3125 else:
3126 # error, set is not a set
3127 main.log.error( "ONOS" + str( i + 1 ) +
3128 " has repeat elements in" +
3129 " set " + onosSetName + ":\n" +
3130 str( getResponses[ i ] ) )
3131 getResults = main.FALSE
3132 elif getResponses[ i ] == main.ERROR:
3133 getResults = main.FALSE
3134 sizeResponses = []
3135 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003136 for i in range( main.numCtrls ):
3137 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003138 name="setTestSize-" + str( i ),
3139 args=[ onosSetName ] )
3140 threads.append( t )
3141 t.start()
3142 for t in threads:
3143 t.join()
3144 sizeResponses.append( t.result )
3145 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003146 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003147 if size != sizeResponses[ i ]:
3148 sizeResults = main.FALSE
3149 main.log.error( "ONOS" + str( i + 1 ) +
3150 " expected a size of " + str( size ) +
3151 " for set " + onosSetName +
3152 " but got " + str( sizeResponses[ i ] ) )
3153 addAllResults = addAllResults and getResults and sizeResults
3154 utilities.assert_equals( expect=main.TRUE,
3155 actual=addAllResults,
3156 onpass="Set addAll correct",
3157 onfail="Set addAll was incorrect" )
3158
3159 main.step( "Distributed Set clear()" )
3160 onosSet.clear()
3161 clearResponses = []
3162 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003163 for i in range( main.numCtrls ):
3164 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07003165 name="setTestClear-" + str( i ),
3166 args=[ onosSetName, " "], # Values doesn't matter
3167 kwargs={ "clear": True } )
3168 threads.append( t )
3169 t.start()
3170 for t in threads:
3171 t.join()
3172 clearResponses.append( t.result )
3173
3174 # main.TRUE = successfully changed the set
3175 # main.FALSE = action resulted in no change in set
3176 # main.ERROR - Some error in executing the function
3177 clearResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003178 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003179 if clearResponses[ i ] == main.TRUE:
3180 # All is well
3181 pass
3182 elif clearResponses[ i ] == main.FALSE:
3183 # Nothing set, probably fine
3184 pass
3185 elif clearResponses[ i ] == main.ERROR:
3186 # Error in execution
3187 clearResults = main.FALSE
3188 else:
3189 # unexpected result
3190 clearResults = main.FALSE
3191 if clearResults != main.TRUE:
3192 main.log.error( "Error executing set clear" )
3193
3194 # Check if set is still correct
3195 size = len( onosSet )
3196 getResponses = []
3197 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003198 for i in range( main.numCtrls ):
3199 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003200 name="setTestGet-" + str( i ),
3201 args=[ onosSetName ] )
3202 threads.append( t )
3203 t.start()
3204 for t in threads:
3205 t.join()
3206 getResponses.append( t.result )
3207 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003208 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003209 if isinstance( getResponses[ i ], list):
3210 current = set( getResponses[ i ] )
3211 if len( current ) == len( getResponses[ i ] ):
3212 # no repeats
3213 if onosSet != current:
3214 main.log.error( "ONOS" + str( i + 1 ) +
3215 " has incorrect view" +
3216 " of set " + onosSetName + ":\n" +
3217 str( getResponses[ i ] ) )
3218 main.log.debug( "Expected: " + str( onosSet ) )
3219 main.log.debug( "Actual: " + str( current ) )
3220 getResults = main.FALSE
3221 else:
3222 # error, set is not a set
3223 main.log.error( "ONOS" + str( i + 1 ) +
3224 " has repeat elements in" +
3225 " set " + onosSetName + ":\n" +
3226 str( getResponses[ i ] ) )
3227 getResults = main.FALSE
3228 elif getResponses[ i ] == main.ERROR:
3229 getResults = main.FALSE
3230 sizeResponses = []
3231 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003232 for i in range( main.numCtrls ):
3233 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003234 name="setTestSize-" + str( i ),
3235 args=[ onosSetName ] )
3236 threads.append( t )
3237 t.start()
3238 for t in threads:
3239 t.join()
3240 sizeResponses.append( t.result )
3241 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003242 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003243 if size != sizeResponses[ i ]:
3244 sizeResults = main.FALSE
3245 main.log.error( "ONOS" + str( i + 1 ) +
3246 " expected a size of " + str( size ) +
3247 " for set " + onosSetName +
3248 " but got " + str( sizeResponses[ i ] ) )
3249 clearResults = clearResults and getResults and sizeResults
3250 utilities.assert_equals( expect=main.TRUE,
3251 actual=clearResults,
3252 onpass="Set clear correct",
3253 onfail="Set clear was incorrect" )
3254
3255 main.step( "Distributed Set addAll()" )
3256 onosSet.update( addAllValue.split() )
3257 addResponses = []
3258 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003259 for i in range( main.numCtrls ):
3260 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07003261 name="setTestAddAll-" + str( i ),
3262 args=[ onosSetName, addAllValue ] )
3263 threads.append( t )
3264 t.start()
3265 for t in threads:
3266 t.join()
3267 addResponses.append( t.result )
3268
3269 # main.TRUE = successfully changed the set
3270 # main.FALSE = action resulted in no change in set
3271 # main.ERROR - Some error in executing the function
3272 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003273 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003274 if addResponses[ i ] == main.TRUE:
3275 # All is well
3276 pass
3277 elif addResponses[ i ] == main.FALSE:
3278 # Already in set, probably fine
3279 pass
3280 elif addResponses[ i ] == main.ERROR:
3281 # Error in execution
3282 addAllResults = main.FALSE
3283 else:
3284 # unexpected result
3285 addAllResults = main.FALSE
3286 if addAllResults != main.TRUE:
3287 main.log.error( "Error executing set addAll" )
3288
3289 # Check if set is still correct
3290 size = len( onosSet )
3291 getResponses = []
3292 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003293 for i in range( main.numCtrls ):
3294 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003295 name="setTestGet-" + str( i ),
3296 args=[ onosSetName ] )
3297 threads.append( t )
3298 t.start()
3299 for t in threads:
3300 t.join()
3301 getResponses.append( t.result )
3302 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003303 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003304 if isinstance( getResponses[ i ], list):
3305 current = set( getResponses[ i ] )
3306 if len( current ) == len( getResponses[ i ] ):
3307 # no repeats
3308 if onosSet != current:
3309 main.log.error( "ONOS" + str( i + 1 ) +
3310 " has incorrect view" +
3311 " of set " + onosSetName + ":\n" +
3312 str( getResponses[ i ] ) )
3313 main.log.debug( "Expected: " + str( onosSet ) )
3314 main.log.debug( "Actual: " + str( current ) )
3315 getResults = main.FALSE
3316 else:
3317 # error, set is not a set
3318 main.log.error( "ONOS" + str( i + 1 ) +
3319 " has repeat elements in" +
3320 " set " + onosSetName + ":\n" +
3321 str( getResponses[ i ] ) )
3322 getResults = main.FALSE
3323 elif getResponses[ i ] == main.ERROR:
3324 getResults = main.FALSE
3325 sizeResponses = []
3326 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003327 for i in range( main.numCtrls ):
3328 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003329 name="setTestSize-" + str( i ),
3330 args=[ onosSetName ] )
3331 threads.append( t )
3332 t.start()
3333 for t in threads:
3334 t.join()
3335 sizeResponses.append( t.result )
3336 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003337 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003338 if size != sizeResponses[ i ]:
3339 sizeResults = main.FALSE
3340 main.log.error( "ONOS" + str( i + 1 ) +
3341 " expected a size of " + str( size ) +
3342 " for set " + onosSetName +
3343 " but got " + str( sizeResponses[ i ] ) )
3344 addAllResults = addAllResults and getResults and sizeResults
3345 utilities.assert_equals( expect=main.TRUE,
3346 actual=addAllResults,
3347 onpass="Set addAll correct",
3348 onfail="Set addAll was incorrect" )
3349
3350 main.step( "Distributed Set retain()" )
3351 onosSet.intersection_update( retainValue.split() )
3352 retainResponses = []
3353 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003354 for i in range( main.numCtrls ):
3355 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07003356 name="setTestRetain-" + str( i ),
3357 args=[ onosSetName, retainValue ],
3358 kwargs={ "retain": True } )
3359 threads.append( t )
3360 t.start()
3361 for t in threads:
3362 t.join()
3363 retainResponses.append( t.result )
3364
3365 # main.TRUE = successfully changed the set
3366 # main.FALSE = action resulted in no change in set
3367 # main.ERROR - Some error in executing the function
3368 retainResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003369 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003370 if retainResponses[ i ] == main.TRUE:
3371 # All is well
3372 pass
3373 elif retainResponses[ i ] == main.FALSE:
3374 # Already in set, probably fine
3375 pass
3376 elif retainResponses[ i ] == main.ERROR:
3377 # Error in execution
3378 retainResults = main.FALSE
3379 else:
3380 # unexpected result
3381 retainResults = main.FALSE
3382 if retainResults != main.TRUE:
3383 main.log.error( "Error executing set retain" )
3384
3385 # Check if set is still correct
3386 size = len( onosSet )
3387 getResponses = []
3388 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003389 for i in range( main.numCtrls ):
3390 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003391 name="setTestGet-" + str( i ),
3392 args=[ onosSetName ] )
3393 threads.append( t )
3394 t.start()
3395 for t in threads:
3396 t.join()
3397 getResponses.append( t.result )
3398 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003399 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003400 if isinstance( getResponses[ i ], list):
3401 current = set( getResponses[ i ] )
3402 if len( current ) == len( getResponses[ i ] ):
3403 # no repeats
3404 if onosSet != current:
3405 main.log.error( "ONOS" + str( i + 1 ) +
3406 " has incorrect view" +
3407 " of set " + onosSetName + ":\n" +
3408 str( getResponses[ i ] ) )
3409 main.log.debug( "Expected: " + str( onosSet ) )
3410 main.log.debug( "Actual: " + str( current ) )
3411 getResults = main.FALSE
3412 else:
3413 # error, set is not a set
3414 main.log.error( "ONOS" + str( i + 1 ) +
3415 " has repeat elements in" +
3416 " set " + onosSetName + ":\n" +
3417 str( getResponses[ i ] ) )
3418 getResults = main.FALSE
3419 elif getResponses[ i ] == main.ERROR:
3420 getResults = main.FALSE
3421 sizeResponses = []
3422 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003423 for i in range( main.numCtrls ):
3424 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003425 name="setTestSize-" + str( i ),
3426 args=[ onosSetName ] )
3427 threads.append( t )
3428 t.start()
3429 for t in threads:
3430 t.join()
3431 sizeResponses.append( t.result )
3432 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003433 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003434 if size != sizeResponses[ i ]:
3435 sizeResults = main.FALSE
3436 main.log.error( "ONOS" + str( i + 1 ) +
3437 " expected a size of " +
3438 str( size ) + " for set " + onosSetName +
3439 " but got " + str( sizeResponses[ i ] ) )
3440 retainResults = retainResults and getResults and sizeResults
3441 utilities.assert_equals( expect=main.TRUE,
3442 actual=retainResults,
3443 onpass="Set retain correct",
3444 onfail="Set retain was incorrect" )
3445
Jon Hall2a5002c2015-08-21 16:49:11 -07003446 # Transactional maps
3447 main.step( "Partitioned Transactional maps put" )
3448 tMapValue = "Testing"
3449 numKeys = 100
3450 putResult = True
3451 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue )
3452 if len( putResponses ) == 100:
3453 for i in putResponses:
3454 if putResponses[ i ][ 'value' ] != tMapValue:
3455 putResult = False
3456 else:
3457 putResult = False
3458 if not putResult:
3459 main.log.debug( "Put response values: " + str( putResponses ) )
3460 utilities.assert_equals( expect=True,
3461 actual=putResult,
3462 onpass="Partitioned Transactional Map put successful",
3463 onfail="Partitioned Transactional Map put values are incorrect" )
3464
3465 main.step( "Partitioned Transactional maps get" )
3466 getCheck = True
3467 for n in range( 1, numKeys + 1 ):
3468 getResponses = []
3469 threads = []
3470 valueCheck = True
3471 for i in range( main.numCtrls ):
3472 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
3473 name="TMap-get-" + str( i ),
3474 args=[ "Key" + str ( n ) ] )
3475 threads.append( t )
3476 t.start()
3477 for t in threads:
3478 t.join()
3479 getResponses.append( t.result )
3480 for node in getResponses:
3481 if node != tMapValue:
3482 valueCheck = False
3483 if not valueCheck:
3484 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
3485 main.log.warn( getResponses )
3486 getCheck = getCheck and valueCheck
3487 utilities.assert_equals( expect=True,
3488 actual=getCheck,
3489 onpass="Partitioned Transactional Map get values were correct",
3490 onfail="Partitioned Transactional Map values incorrect" )
3491
3492 main.step( "In-memory Transactional maps put" )
3493 tMapValue = "Testing"
3494 numKeys = 100
3495 putResult = True
3496 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue, inMemory=True )
3497 if len( putResponses ) == 100:
3498 for i in putResponses:
3499 if putResponses[ i ][ 'value' ] != tMapValue:
3500 putResult = False
3501 else:
3502 putResult = False
3503 if not putResult:
3504 main.log.debug( "Put response values: " + str( putResponses ) )
3505 utilities.assert_equals( expect=True,
3506 actual=putResult,
3507 onpass="In-Memory Transactional Map put successful",
3508 onfail="In-Memory Transactional Map put values are incorrect" )
3509
3510 main.step( "In-Memory Transactional maps get" )
3511 getCheck = True
3512 for n in range( 1, numKeys + 1 ):
3513 getResponses = []
3514 threads = []
3515 valueCheck = True
3516 for i in range( main.numCtrls ):
3517 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
3518 name="TMap-get-" + str( i ),
3519 args=[ "Key" + str ( n ) ],
3520 kwargs={ "inMemory": True } )
3521 threads.append( t )
3522 t.start()
3523 for t in threads:
3524 t.join()
3525 getResponses.append( t.result )
3526 for node in getResponses:
3527 if node != tMapValue:
3528 valueCheck = False
3529 if not valueCheck:
3530 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
3531 main.log.warn( getResponses )
3532 getCheck = getCheck and valueCheck
3533 utilities.assert_equals( expect=True,
3534 actual=getCheck,
3535 onpass="In-Memory Transactional Map get values were correct",
3536 onfail="In-Memory Transactional Map values incorrect" )