blob: 2f2b01b705f3f67e3551cc8e7cbec0f5f9690df2 [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"
162 graphs = '<ac:structured-macro ac:name="html">\n'
163 graphs += '<ac:plain-text-body><![CDATA[\n'
164 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
165 '/plot/' + plotName + '/getPlot?index=0' +\
166 '&width=500&height=300"' +\
167 'noborder="0" width="500" height="300" scrolling="yes" ' +\
168 'seamless="seamless"></iframe>\n'
169 graphs += ']]></ac:plain-text-body>\n'
170 graphs += '</ac:structured-macro>\n'
171 main.log.wiki(graphs)
172
Jon Halle1a3b752015-07-22 13:02:46 -0700173 main.CLIs = []
174 main.nodes = []
Jon Hall5cf14d52015-07-16 12:15:19 -0700175 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700176 for i in range( 1, main.numCtrls + 1 ):
177 main.CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
178 main.nodes.append( getattr( main, 'ONOS' + str( i ) ) )
179 ipList.append( main.nodes[ -1 ].ip_address )
Jon Hall5cf14d52015-07-16 12:15:19 -0700180
181 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, "SingleHA",
182 main.Mininet1.ip_address,
183 cellAppString, ipList[ 0 ] )
Jon Hall85794ff2015-07-08 14:12:30 -0700184 cellResult = main.ONOSbench.setCell( "SingleHA" )
185 verifyResult = main.ONOSbench.verifyCell()
186 main.step( "Creating ONOS package" )
187 packageResult = main.ONOSbench.onosPackage()
188 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
189 onpass="ONOS package successful",
190 onfail="ONOS package failed" )
191
192 main.step( "Installing ONOS package" )
193 onosInstallResult = main.ONOSbench.onosInstall(
Jon Halle1a3b752015-07-22 13:02:46 -0700194 options="-f", node=main.nodes[0].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -0700195 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
196 onpass="ONOS install successful",
197 onfail="ONOS install failed" )
198
199 main.step( "Checking if ONOS is up yet" )
200 for i in range( 2 ):
Jon Halle1a3b752015-07-22 13:02:46 -0700201 onos1Isup = main.ONOSbench.isup( main.nodes[0].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -0700202 if onos1Isup:
203 break
204 utilities.assert_equals( expect=main.TRUE, actual=onos1Isup,
205 onpass="ONOS startup successful",
206 onfail="ONOS startup failed" )
207
208 main.log.step( "Starting ONOS CLI sessions" )
Jon Halle1a3b752015-07-22 13:02:46 -0700209 cliResults = main.ONOScli1.startOnosCli( main.nodes[0].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -0700210 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
211 onpass="ONOS cli startup successful",
212 onfail="ONOS cli startup failed" )
213
214 if main.params[ 'tcpdump' ].lower() == "true":
215 main.step( "Start Packet Capture MN" )
216 main.Mininet2.startTcpdump(
217 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
218 + "-MN.pcap",
219 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
220 port=main.params[ 'MNtcpdump' ][ 'port' ] )
221
222 main.step( "App Ids check" )
Jon Hallf3d16e72015-12-16 17:45:08 -0800223 time.sleep(60)
Jon Hall85794ff2015-07-08 14:12:30 -0700224 appCheck = main.ONOScli1.appToIDCheck()
225 if appCheck != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700226 main.log.warn( main.CLIs[0].apps() )
227 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall85794ff2015-07-08 14:12:30 -0700228 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
229 onpass="App Ids seem to be correct",
230 onfail="Something is wrong with app Ids" )
231
232 if cliResults == main.FALSE:
233 main.log.error( "Failed to start ONOS, stopping test" )
234 main.cleanup()
235 main.exit()
236
237 def CASE2( self, main ):
238 """
239 Assign devices to controllers
240 """
241 import re
Jon Halle1a3b752015-07-22 13:02:46 -0700242 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700243 assert main, "main not defined"
244 assert utilities.assert_equals, "utilities.assert_equals not defined"
245
246 main.case( "Assigning devices to controllers" )
Jon Hall783bbf92015-07-23 14:33:19 -0700247 main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700248 "and check that an ONOS node becomes the " +\
249 "master of the device."
250 main.step( "Assign switches to controllers" )
251
252 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -0700253 for i in range( main.numCtrls ):
254 ipList.append( main.nodes[ i ].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -0700255 swList = []
256 for i in range( 1, 29 ):
257 swList.append( "s" + str( i ) )
258 main.Mininet1.assignSwController( sw=swList, ip=ipList )
259
260 mastershipCheck = main.TRUE
261 for i in range( 1, 29 ):
262 response = main.Mininet1.getSwController( "s" + str( i ) )
263 try:
264 main.log.info( str( response ) )
265 except Exception:
266 main.log.info( repr( response ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700267 if re.search( "tcp:" + main.nodes[0].ip_address, response ):
Jon Hall85794ff2015-07-08 14:12:30 -0700268 mastershipCheck = mastershipCheck and main.TRUE
269 else:
270 mastershipCheck = main.FALSE
271 if mastershipCheck == main.TRUE:
272 main.log.info( "Switch mastership assigned correctly" )
273 utilities.assert_equals(
274 expect=main.TRUE,
275 actual=mastershipCheck,
276 onpass="Switch mastership assigned correctly",
277 onfail="Switches not assigned correctly to controllers" )
278
279 def CASE21( self, main ):
280 """
281 Assign mastership to controllers
282 """
Jon Halle1a3b752015-07-22 13:02:46 -0700283 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700284 assert main, "main not defined"
285 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -0700286 assert main.CLIs, "main.CLIs not defined"
287 assert main.nodes, "main.nodes not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700288
289 main.case( "Assigning Controller roles for switches" )
Jon Hall783bbf92015-07-23 14:33:19 -0700290 main.caseExplanation = "Check that ONOS is connected to each " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700291 "device. Then manually assign" +\
292 " mastership to specific ONOS nodes using" +\
293 " 'device-role'"
294 main.step( "Assign mastership of switches to specific controllers" )
295 roleCall = main.TRUE
296 roleCheck = main.TRUE
297 try:
298 for i in range( 1, 29 ): # switches 1 through 28
Jon Halle1a3b752015-07-22 13:02:46 -0700299 ip = main.nodes[ 0 ].ip_address # ONOS1
Jon Hall85794ff2015-07-08 14:12:30 -0700300 # set up correct variables:
301 if i == 1:
302 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
303 elif i == 2:
304 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
305 elif i == 3:
306 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
307 elif i == 4:
308 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
309 elif i == 5:
310 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
311 elif i == 6:
312 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
313 elif i == 7:
314 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
315 elif i >= 8 and i <= 17:
316 dpid = '3' + str( i ).zfill( 3 )
317 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
318 elif i >= 18 and i <= 27:
319 dpid = '6' + str( i ).zfill( 3 )
320 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
321 elif i == 28:
322 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
323 else:
324 main.log.error( "You didn't write an else statement for " +
325 "switch s" + str( i ) )
326 # Assign switch
327 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
328 # TODO: make this controller dynamic
329 roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
330 ip )
331 # Check assignment
332 master = main.ONOScli1.getRole( deviceId ).get( 'master' )
333 if ip in master:
334 roleCheck = roleCheck and main.TRUE
335 else:
336 roleCheck = roleCheck and main.FALSE
337 main.log.error( "Error, controller " + ip + " is not" +
338 " master " + "of device " +
339 str( deviceId ) + ". Master is " +
340 repr( master ) + "." )
341 except ( AttributeError, AssertionError ):
342 main.log.exception( "Something is wrong with ONOS device view" )
343 main.log.info( main.ONOScli1.devices() )
344 utilities.assert_equals(
345 expect=main.TRUE,
346 actual=roleCall,
347 onpass="Re-assigned switch mastership to designated controller",
348 onfail="Something wrong with deviceRole calls" )
349
350 main.step( "Check mastership was correctly assigned" )
351 utilities.assert_equals(
352 expect=main.TRUE,
353 actual=roleCheck,
354 onpass="Switches were successfully reassigned to designated " +
355 "controller",
356 onfail="Switches were not successfully reassigned" )
357
358 def CASE3( self, main ):
359 """
360 Assign intents
361 """
362 import time
363 import json
Jon Halle1a3b752015-07-22 13:02:46 -0700364 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700365 assert main, "main not defined"
366 assert utilities.assert_equals, "utilities.assert_equals not defined"
367 # NOTE: we must reinstall intents until we have a persistant intent
368 # datastore!
369 main.case( "Adding host Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700370 main.caseExplanation = "Discover hosts by using pingall then " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700371 "assign predetermined host-to-host intents." +\
372 " After installation, check that the intent" +\
373 " is distributed to all nodes and the state" +\
374 " is INSTALLED"
375
376 # install onos-app-fwd
377 main.step( "Install reactive forwarding app" )
Jon Halle1a3b752015-07-22 13:02:46 -0700378 installResults = main.CLIs[0].activateApp( "org.onosproject.fwd" )
Jon Hall85794ff2015-07-08 14:12:30 -0700379 utilities.assert_equals( expect=main.TRUE, actual=installResults,
380 onpass="Install fwd successful",
381 onfail="Install fwd failed" )
382
383 main.step( "Check app ids" )
384 appCheck = main.ONOScli1.appToIDCheck()
385 if appCheck != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700386 main.log.warn( main.CLIs[0].apps() )
387 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall85794ff2015-07-08 14:12:30 -0700388 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
389 onpass="App Ids seem to be correct",
390 onfail="Something is wrong with app Ids" )
391
392 main.step( "Discovering Hosts( Via pingall for now )" )
393 # FIXME: Once we have a host discovery mechanism, use that instead
394 # REACTIVE FWD test
395 pingResult = main.FALSE
Jon Hall96091e62015-09-21 17:34:17 -0700396 passMsg = "Reactive Pingall test passed"
397 time1 = time.time()
398 pingResult = main.Mininet1.pingall()
399 time2 = time.time()
400 if not pingResult:
401 main.log.warn("First pingall failed. Trying again...")
Jon Hall85794ff2015-07-08 14:12:30 -0700402 pingResult = main.Mininet1.pingall()
Jon Hall96091e62015-09-21 17:34:17 -0700403 passMsg += " on the second try"
404 utilities.assert_equals(
405 expect=main.TRUE,
406 actual=pingResult,
407 onpass= passMsg,
408 onfail="Reactive Pingall failed, " +
409 "one or more ping pairs failed" )
410 main.log.info( "Time for pingall: %2f seconds" %
411 ( time2 - time1 ) )
Jon Hall85794ff2015-07-08 14:12:30 -0700412 # timeout for fwd flows
413 time.sleep( 11 )
414 # uninstall onos-app-fwd
415 main.step( "Uninstall reactive forwarding app" )
Jon Halle1a3b752015-07-22 13:02:46 -0700416 uninstallResult = main.CLIs[0].deactivateApp( "org.onosproject.fwd" )
Jon Hall85794ff2015-07-08 14:12:30 -0700417 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
418 onpass="Uninstall fwd successful",
419 onfail="Uninstall fwd failed" )
420
421 main.step( "Check app ids" )
422 appCheck2 = main.ONOScli1.appToIDCheck()
423 if appCheck2 != main.TRUE:
Jon Halle1a3b752015-07-22 13:02:46 -0700424 main.log.warn( main.CLIs[0].apps() )
425 main.log.warn( main.CLIs[0].appIDs() )
Jon Hall85794ff2015-07-08 14:12:30 -0700426 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
427 onpass="App Ids seem to be correct",
428 onfail="Something is wrong with app Ids" )
429
430 main.step( "Add host intents via cli" )
431 intentIds = []
432 # TODO: move the host numbers to params
433 # Maybe look at all the paths we ping?
434 intentAddResult = True
435 hostResult = main.TRUE
436 for i in range( 8, 18 ):
437 main.log.info( "Adding host intent between h" + str( i ) +
438 " and h" + str( i + 10 ) )
439 host1 = "00:00:00:00:00:" + \
440 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
441 host2 = "00:00:00:00:00:" + \
442 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
443 # NOTE: getHost can return None
444 host1Dict = main.ONOScli1.getHost( host1 )
445 host2Dict = main.ONOScli1.getHost( host2 )
446 host1Id = None
447 host2Id = None
448 if host1Dict and host2Dict:
449 host1Id = host1Dict.get( 'id', None )
450 host2Id = host2Dict.get( 'id', None )
451 if host1Id and host2Id:
452 tmpId = main.ONOScli1.addHostIntent( host1Id, host2Id )
453 if tmpId:
454 main.log.info( "Added intent with id: " + tmpId )
455 intentIds.append( tmpId )
456 else:
457 main.log.error( "addHostIntent returned: " +
458 repr( tmpId ) )
459 else:
460 main.log.error( "Error, getHost() failed for h" + str( i ) +
461 " and/or h" + str( i + 10 ) )
462 hosts = main.ONOScli1.hosts()
463 main.log.warn( "Hosts output: " )
464 try:
465 main.log.warn( json.dumps( json.loads( hosts ),
466 sort_keys=True,
467 indent=4,
468 separators=( ',', ': ' ) ) )
469 except ( ValueError, TypeError ):
470 main.log.warn( repr( hosts ) )
471 hostResult = main.FALSE
472 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
473 onpass="Found a host id for each host",
474 onfail="Error looking up host ids" )
475
476 intentStart = time.time()
477 onosIds = main.ONOScli1.getAllIntentsId()
478 main.log.info( "Submitted intents: " + str( intentIds ) )
479 main.log.info( "Intents in ONOS: " + str( onosIds ) )
480 for intent in intentIds:
481 if intent in onosIds:
482 pass # intent submitted is in onos
483 else:
484 intentAddResult = False
485 if intentAddResult:
486 intentStop = time.time()
487 else:
488 intentStop = None
489 # Print the intent states
490 intents = main.ONOScli1.intents()
491 intentStates = []
492 installedCheck = True
493 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
494 count = 0
495 try:
496 for intent in json.loads( intents ):
497 state = intent.get( 'state', None )
498 if "INSTALLED" not in state:
499 installedCheck = False
500 intentId = intent.get( 'id', None )
501 intentStates.append( ( intentId, state ) )
502 except ( ValueError, TypeError ):
503 main.log.exception( "Error parsing intents" )
504 # add submitted intents not in the store
505 tmplist = [ i for i, s in intentStates ]
506 missingIntents = False
507 for i in intentIds:
508 if i not in tmplist:
509 intentStates.append( ( i, " - " ) )
510 missingIntents = True
511 intentStates.sort()
512 for i, s in intentStates:
513 count += 1
514 main.log.info( "%-6s%-15s%-15s" %
515 ( str( count ), str( i ), str( s ) ) )
516 leaders = main.ONOScli1.leaders()
517 try:
518 missing = False
519 if leaders:
520 parsedLeaders = json.loads( leaders )
521 main.log.warn( json.dumps( parsedLeaders,
522 sort_keys=True,
523 indent=4,
524 separators=( ',', ': ' ) ) )
525 # check for all intent partitions
526 topics = []
527 for i in range( 14 ):
528 topics.append( "intent-partition-" + str( i ) )
529 main.log.debug( topics )
530 ONOStopics = [ j['topic'] for j in parsedLeaders ]
531 for topic in topics:
532 if topic not in ONOStopics:
533 main.log.error( "Error: " + topic +
534 " not in leaders" )
535 missing = True
536 else:
537 main.log.error( "leaders() returned None" )
538 except ( ValueError, TypeError ):
539 main.log.exception( "Error parsing leaders" )
540 main.log.error( repr( leaders ) )
541 # Check all nodes
542 if missing:
543 response = main.ONOScli1.leaders( jsonFormat=False)
544 main.log.warn( "ONOS1 leaders output: \n" +
545 str( response ) )
546
547 partitions = main.ONOScli1.partitions()
548 try:
549 if partitions :
550 parsedPartitions = json.loads( partitions )
551 main.log.warn( json.dumps( parsedPartitions,
552 sort_keys=True,
553 indent=4,
554 separators=( ',', ': ' ) ) )
555 # TODO check for a leader in all paritions
556 # TODO check for consistency among nodes
557 else:
558 main.log.error( "partitions() returned None" )
559 except ( ValueError, TypeError ):
560 main.log.exception( "Error parsing partitions" )
561 main.log.error( repr( partitions ) )
562 pendingMap = main.ONOScli1.pendingMap()
563 try:
564 if pendingMap :
565 parsedPending = json.loads( pendingMap )
566 main.log.warn( json.dumps( parsedPending,
567 sort_keys=True,
568 indent=4,
569 separators=( ',', ': ' ) ) )
570 # TODO check something here?
571 else:
572 main.log.error( "pendingMap() returned None" )
573 except ( ValueError, TypeError ):
574 main.log.exception( "Error parsing pending map" )
575 main.log.error( repr( pendingMap ) )
576
577 intentAddResult = bool( intentAddResult and not missingIntents and
578 installedCheck )
579 if not intentAddResult:
580 main.log.error( "Error in pushing host intents to ONOS" )
581
582 main.step( "Intent Anti-Entropy dispersion" )
583 for i in range(100):
584 correct = True
585 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Halle1a3b752015-07-22 13:02:46 -0700586 for cli in main.CLIs:
Jon Hall85794ff2015-07-08 14:12:30 -0700587 onosIds = []
588 ids = cli.getAllIntentsId()
589 onosIds.append( ids )
590 main.log.debug( "Intents in " + cli.name + ": " +
591 str( sorted( onosIds ) ) )
592 if sorted( ids ) != sorted( intentIds ):
593 main.log.warn( "Set of intent IDs doesn't match" )
594 correct = False
595 break
596 else:
597 intents = json.loads( cli.intents() )
598 for intent in intents:
599 if intent[ 'state' ] != "INSTALLED":
600 main.log.warn( "Intent " + intent[ 'id' ] +
601 " is " + intent[ 'state' ] )
602 correct = False
603 break
604 if correct:
605 break
606 else:
607 time.sleep(1)
608 if not intentStop:
609 intentStop = time.time()
610 global gossipTime
611 gossipTime = intentStop - intentStart
612 main.log.info( "It took about " + str( gossipTime ) +
613 " seconds for all intents to appear in each node" )
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700614 gossipPeriod = int( main.params['timers']['gossip'] )
615 maxGossipTime = gossipPeriod * len( main.nodes )
Jon Hall85794ff2015-07-08 14:12:30 -0700616 utilities.assert_greater_equals(
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700617 expect=maxGossipTime, actual=gossipTime,
Jon Hall85794ff2015-07-08 14:12:30 -0700618 onpass="ECM anti-entropy for intents worked within " +
619 "expected time",
Jon Hallb3ed8ed2015-10-28 16:43:55 -0700620 onfail="Intent ECM anti-entropy took too long. " +
621 "Expected time:{}, Actual time:{}".format( maxGossipTime,
622 gossipTime ) )
623 if gossipTime <= maxGossipTime:
Jon Hall85794ff2015-07-08 14:12:30 -0700624 intentAddResult = True
625
626 if not intentAddResult or "key" in pendingMap:
627 import time
628 installedCheck = True
629 main.log.info( "Sleeping 60 seconds to see if intents are found" )
630 time.sleep( 60 )
631 onosIds = main.ONOScli1.getAllIntentsId()
632 main.log.info( "Submitted intents: " + str( intentIds ) )
633 main.log.info( "Intents in ONOS: " + str( onosIds ) )
634 # Print the intent states
635 intents = main.ONOScli1.intents()
636 intentStates = []
637 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
638 count = 0
639 try:
640 for intent in json.loads( intents ):
641 # Iter through intents of a node
642 state = intent.get( 'state', None )
643 if "INSTALLED" not in state:
644 installedCheck = False
645 intentId = intent.get( 'id', None )
646 intentStates.append( ( intentId, state ) )
647 except ( ValueError, TypeError ):
648 main.log.exception( "Error parsing intents" )
649 # add submitted intents not in the store
650 tmplist = [ i for i, s in intentStates ]
651 for i in intentIds:
652 if i not in tmplist:
653 intentStates.append( ( i, " - " ) )
654 intentStates.sort()
655 for i, s in intentStates:
656 count += 1
657 main.log.info( "%-6s%-15s%-15s" %
658 ( str( count ), str( i ), str( s ) ) )
659 leaders = main.ONOScli1.leaders()
660 try:
661 missing = False
662 if leaders:
663 parsedLeaders = json.loads( leaders )
664 main.log.warn( json.dumps( parsedLeaders,
665 sort_keys=True,
666 indent=4,
667 separators=( ',', ': ' ) ) )
668 # check for all intent partitions
669 # check for election
670 topics = []
671 for i in range( 14 ):
672 topics.append( "intent-partition-" + str( i ) )
673 # FIXME: this should only be after we start the app
674 topics.append( "org.onosproject.election" )
675 main.log.debug( topics )
676 ONOStopics = [ j['topic'] for j in parsedLeaders ]
677 for topic in topics:
678 if topic not in ONOStopics:
679 main.log.error( "Error: " + topic +
680 " not in leaders" )
681 missing = True
682 else:
683 main.log.error( "leaders() returned None" )
684 except ( ValueError, TypeError ):
685 main.log.exception( "Error parsing leaders" )
686 main.log.error( repr( leaders ) )
687 # Check all nodes
688 if missing:
689 response = main.ONOScli1.leaders( jsonFormat=False)
690 main.log.warn( "ONOS1 leaders output: \n" +
691 str( response ) )
692 partitions = main.ONOScli1.partitions()
693 try:
694 if partitions :
695 parsedPartitions = json.loads( partitions )
696 main.log.warn( json.dumps( parsedPartitions,
697 sort_keys=True,
698 indent=4,
699 separators=( ',', ': ' ) ) )
700 # TODO check for a leader in all paritions
701 # TODO check for consistency among nodes
702 else:
703 main.log.error( "partitions() returned None" )
704 except ( ValueError, TypeError ):
705 main.log.exception( "Error parsing partitions" )
706 main.log.error( repr( partitions ) )
707 pendingMap = main.ONOScli1.pendingMap()
708 try:
709 if pendingMap :
710 parsedPending = json.loads( pendingMap )
711 main.log.warn( json.dumps( parsedPending,
712 sort_keys=True,
713 indent=4,
714 separators=( ',', ': ' ) ) )
715 # TODO check something here?
716 else:
717 main.log.error( "pendingMap() returned None" )
718 except ( ValueError, TypeError ):
719 main.log.exception( "Error parsing pending map" )
720 main.log.error( repr( pendingMap ) )
721
722 def CASE4( self, main ):
723 """
724 Ping across added host intents
725 """
726 import json
727 import time
Jon Halle1a3b752015-07-22 13:02:46 -0700728 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700729 assert main, "main not defined"
730 assert utilities.assert_equals, "utilities.assert_equals not defined"
731 main.case( "Verify connectivity by sendind traffic across Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700732 main.caseExplanation = "Ping across added host intents to check " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700733 "functionality and check the state of " +\
734 "the intent"
735 main.step( "Ping across added host intents" )
736 PingResult = main.TRUE
737 for i in range( 8, 18 ):
738 ping = main.Mininet1.pingHost( src="h" + str( i ),
739 target="h" + str( i + 10 ) )
740 PingResult = PingResult and ping
741 if ping == main.FALSE:
742 main.log.warn( "Ping failed between h" + str( i ) +
743 " and h" + str( i + 10 ) )
744 elif ping == main.TRUE:
745 main.log.info( "Ping test passed!" )
746 # Don't set PingResult or you'd override failures
747 if PingResult == main.FALSE:
748 main.log.error(
749 "Intents have not been installed correctly, pings failed." )
750 # TODO: pretty print
751 main.log.warn( "ONOS1 intents: " )
752 try:
753 tmpIntents = main.ONOScli1.intents()
754 main.log.warn( json.dumps( json.loads( tmpIntents ),
755 sort_keys=True,
756 indent=4,
757 separators=( ',', ': ' ) ) )
758 except ( ValueError, TypeError ):
759 main.log.warn( repr( tmpIntents ) )
760 utilities.assert_equals(
761 expect=main.TRUE,
762 actual=PingResult,
763 onpass="Intents have been installed correctly and pings work",
764 onfail="Intents have not been installed correctly, pings failed." )
765
766 main.step( "Check Intent state" )
767 installedCheck = True
768 # Print the intent states
769 intents = main.ONOScli1.intents()
770 intentStates = []
771 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
772 count = 0
773 # Iter through intents of a node
774 try:
775 for intent in json.loads( intents ):
776 state = intent.get( 'state', None )
777 if "INSTALLED" not in state:
778 installedCheck = False
779 intentId = intent.get( 'id', None )
780 intentStates.append( ( intentId, state ) )
781 except ( ValueError, TypeError ):
782 main.log.exception( "Error parsing intents." )
783 # Print states
784 intentStates.sort()
785 for i, s in intentStates:
786 count += 1
787 main.log.info( "%-6s%-15s%-15s" %
788 ( str( count ), str( i ), str( s ) ) )
789 utilities.assert_equals( expect=True, actual=installedCheck,
790 onpass="Intents are all INSTALLED",
791 onfail="Intents are not all in " +
792 "INSTALLED state" )
793
794 main.step( "Check leadership of topics" )
795 leaders = main.ONOScli1.leaders()
796 topicCheck = main.TRUE
797 try:
798 if leaders:
799 parsedLeaders = json.loads( leaders )
800 main.log.warn( json.dumps( parsedLeaders,
801 sort_keys=True,
802 indent=4,
803 separators=( ',', ': ' ) ) )
804 # check for all intent partitions
805 # check for election
806 # TODO: Look at Devices as topics now that it uses this system
807 topics = []
808 for i in range( 14 ):
809 topics.append( "intent-partition-" + str( i ) )
810 # FIXME: this should only be after we start the app
811 # FIXME: topics.append( "org.onosproject.election" )
812 # Print leaders output
813 main.log.debug( topics )
814 ONOStopics = [ j['topic'] for j in parsedLeaders ]
815 for topic in topics:
816 if topic not in ONOStopics:
817 main.log.error( "Error: " + topic +
818 " not in leaders" )
819 topicCheck = main.FALSE
820 else:
821 main.log.error( "leaders() returned None" )
822 topicCheck = main.FALSE
823 except ( ValueError, TypeError ):
824 topicCheck = main.FALSE
825 main.log.exception( "Error parsing leaders" )
826 main.log.error( repr( leaders ) )
827 # TODO: Check for a leader of these topics
828 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
829 onpass="intent Partitions is in leaders",
830 onfail="Some topics were lost " )
831 # Print partitions
832 partitions = main.ONOScli1.partitions()
833 try:
834 if partitions :
835 parsedPartitions = json.loads( partitions )
836 main.log.warn( json.dumps( parsedPartitions,
837 sort_keys=True,
838 indent=4,
839 separators=( ',', ': ' ) ) )
840 # TODO check for a leader in all paritions
841 # TODO check for consistency among nodes
842 else:
843 main.log.error( "partitions() returned None" )
844 except ( ValueError, TypeError ):
845 main.log.exception( "Error parsing partitions" )
846 main.log.error( repr( partitions ) )
847 # Print Pending Map
848 pendingMap = main.ONOScli1.pendingMap()
849 try:
850 if pendingMap :
851 parsedPending = json.loads( pendingMap )
852 main.log.warn( json.dumps( parsedPending,
853 sort_keys=True,
854 indent=4,
855 separators=( ',', ': ' ) ) )
856 # TODO check something here?
857 else:
858 main.log.error( "pendingMap() returned None" )
859 except ( ValueError, TypeError ):
860 main.log.exception( "Error parsing pending map" )
861 main.log.error( repr( pendingMap ) )
862
863 if not installedCheck:
864 main.log.info( "Waiting 60 seconds to see if the state of " +
865 "intents change" )
866 time.sleep( 60 )
867 # Print the intent states
868 intents = main.ONOScli1.intents()
869 intentStates = []
870 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
871 count = 0
872 # Iter through intents of a node
873 try:
874 for intent in json.loads( intents ):
875 state = intent.get( 'state', None )
876 if "INSTALLED" not in state:
877 installedCheck = False
878 intentId = intent.get( 'id', None )
879 intentStates.append( ( intentId, state ) )
880 except ( ValueError, TypeError ):
881 main.log.exception( "Error parsing intents." )
882 intentStates.sort()
883 for i, s in intentStates:
884 count += 1
885 main.log.info( "%-6s%-15s%-15s" %
886 ( str( count ), str( i ), str( s ) ) )
887 leaders = main.ONOScli1.leaders()
888 try:
889 missing = False
890 if leaders:
891 parsedLeaders = json.loads( leaders )
892 main.log.warn( json.dumps( parsedLeaders,
893 sort_keys=True,
894 indent=4,
895 separators=( ',', ': ' ) ) )
896 # check for all intent partitions
897 # check for election
898 topics = []
899 for i in range( 14 ):
900 topics.append( "intent-partition-" + str( i ) )
901 # FIXME: this should only be after we start the app
902 topics.append( "org.onosproject.election" )
903 main.log.debug( topics )
904 ONOStopics = [ j['topic'] for j in parsedLeaders ]
905 for topic in topics:
906 if topic not in ONOStopics:
907 main.log.error( "Error: " + topic +
908 " not in leaders" )
909 missing = True
910 else:
911 main.log.error( "leaders() returned None" )
912 except ( ValueError, TypeError ):
913 main.log.exception( "Error parsing leaders" )
914 main.log.error( repr( leaders ) )
915 if missing:
916 response = main.ONOScli1.leaders( jsonFormat=False)
917 main.log.warn( "ONOS1 leaders output: \n" +
918 str( response ) )
919 partitions = main.ONOScli1.partitions()
920 try:
921 if partitions :
922 parsedPartitions = json.loads( partitions )
923 main.log.warn( json.dumps( parsedPartitions,
924 sort_keys=True,
925 indent=4,
926 separators=( ',', ': ' ) ) )
927 # TODO check for a leader in all paritions
928 # TODO check for consistency among nodes
929 else:
930 main.log.error( "partitions() returned None" )
931 except ( ValueError, TypeError ):
932 main.log.exception( "Error parsing partitions" )
933 main.log.error( repr( partitions ) )
934 pendingMap = main.ONOScli1.pendingMap()
935 try:
936 if pendingMap :
937 parsedPending = json.loads( pendingMap )
938 main.log.warn( json.dumps( parsedPending,
939 sort_keys=True,
940 indent=4,
941 separators=( ',', ': ' ) ) )
942 # TODO check something here?
943 else:
944 main.log.error( "pendingMap() returned None" )
945 except ( ValueError, TypeError ):
946 main.log.exception( "Error parsing pending map" )
947 main.log.error( repr( pendingMap ) )
948 # Print flowrules
Jon Halle1a3b752015-07-22 13:02:46 -0700949 main.log.debug( main.CLIs[0].flows( jsonFormat=False ) )
Jon Hall85794ff2015-07-08 14:12:30 -0700950 main.step( "Wait a minute then ping again" )
951 # the wait is above
952 PingResult = main.TRUE
953 for i in range( 8, 18 ):
954 ping = main.Mininet1.pingHost( src="h" + str( i ),
955 target="h" + str( i + 10 ) )
956 PingResult = PingResult and ping
957 if ping == main.FALSE:
958 main.log.warn( "Ping failed between h" + str( i ) +
959 " and h" + str( i + 10 ) )
960 elif ping == main.TRUE:
961 main.log.info( "Ping test passed!" )
962 # Don't set PingResult or you'd override failures
963 if PingResult == main.FALSE:
964 main.log.error(
965 "Intents have not been installed correctly, pings failed." )
966 # TODO: pretty print
967 main.log.warn( "ONOS1 intents: " )
968 try:
969 tmpIntents = main.ONOScli1.intents()
970 main.log.warn( json.dumps( json.loads( tmpIntents ),
971 sort_keys=True,
972 indent=4,
973 separators=( ',', ': ' ) ) )
974 except ( ValueError, TypeError ):
975 main.log.warn( repr( tmpIntents ) )
976 utilities.assert_equals(
977 expect=main.TRUE,
978 actual=PingResult,
979 onpass="Intents have been installed correctly and pings work",
980 onfail="Intents have not been installed correctly, pings failed." )
981
982 def CASE5( self, main ):
983 """
984 Reading state of ONOS
985 """
986 import json
Jon Halle1a3b752015-07-22 13:02:46 -0700987 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -0700988 assert main, "main not defined"
989 assert utilities.assert_equals, "utilities.assert_equals not defined"
990
991 main.case( "Setting up and gathering data for current state" )
992 # The general idea for this test case is to pull the state of
993 # ( intents,flows, topology,... ) from each ONOS node
994 # We can then compare them with each other and also with past states
995
996 main.step( "Check that each switch has a master" )
997 global mastershipState
998 mastershipState = '[]'
999
1000 # Assert that each device has a master
1001 rolesNotNull = main.ONOScli1.rolesNotNull()
1002 utilities.assert_equals(
1003 expect=main.TRUE,
1004 actual=rolesNotNull,
1005 onpass="Each device has a master",
1006 onfail="Some devices don't have a master assigned" )
1007
1008 main.step( "Get the Mastership of each switch" )
1009 ONOS1Mastership = main.ONOScli1.roles()
1010 # TODO: Make this a meaningful check
1011 if "Error" in ONOS1Mastership or not ONOS1Mastership:
1012 main.log.error( "Error in getting ONOS roles" )
1013 main.log.warn(
1014 "ONOS1 mastership response: " +
1015 repr( ONOS1Mastership ) )
1016 consistentMastership = main.FALSE
1017 else:
1018 mastershipState = ONOS1Mastership
1019 consistentMastership = main.TRUE
1020
1021 main.step( "Get the intents from each controller" )
1022 global intentState
1023 intentState = []
1024 ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
1025 intentCheck = main.FALSE
1026 if "Error" in ONOS1Intents or not ONOS1Intents:
1027 main.log.error( "Error in getting ONOS intents" )
1028 main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
1029 else:
1030 intentCheck = main.TRUE
1031
1032 main.step( "Get the flows from each controller" )
1033 global flowState
1034 flowState = []
1035 flowCheck = main.FALSE
1036 ONOS1Flows = main.ONOScli1.flows( jsonFormat=True )
1037 if "Error" in ONOS1Flows or not ONOS1Flows:
1038 main.log.error( "Error in getting ONOS flows" )
1039 main.log.warn( "ONOS1 flows repsponse: " + ONOS1Flows )
1040 else:
1041 # TODO: Do a better check, maybe compare flows on switches?
1042 flowState = ONOS1Flows
1043 flowCheck = main.TRUE
1044
1045 main.step( "Get the OF Table entries" )
1046 global flows
1047 flows = []
1048 for i in range( 1, 29 ):
GlennRC68467eb2015-11-16 18:01:01 -08001049 flows.append( main.Mininet1.getFlowTable( "s" + str( i ), version="1.3", debug=False ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001050 if flowCheck == main.FALSE:
1051 for table in flows:
1052 main.log.warn( table )
1053 # TODO: Compare switch flow tables with ONOS flow tables
1054
1055 main.step( "Collecting topology information from ONOS" )
1056 devices = []
1057 devices.append( main.ONOScli1.devices() )
1058 hosts = []
1059 hosts.append( json.loads( main.ONOScli1.hosts() ) )
1060 ports = []
1061 ports.append( main.ONOScli1.ports() )
1062 links = []
1063 links.append( main.ONOScli1.links() )
1064 clusters = []
1065 clusters.append( main.ONOScli1.clusters() )
1066
1067 main.step( "Each host has an IP address" )
1068 ipResult = main.TRUE
1069 for controller in range( 0, len( hosts ) ):
1070 controllerStr = str( controller + 1 )
1071 for host in hosts[ controller ]:
1072 if host is None or host.get( 'ipAddresses', [] ) == []:
1073 main.log.error(
1074 "DEBUG:Error with host ips on controller" +
1075 controllerStr + ": " + str( host ) )
1076 ipResult = main.FALSE
1077 utilities.assert_equals(
1078 expect=main.TRUE,
1079 actual=ipResult,
1080 onpass="The ips of the hosts aren't empty",
1081 onfail="The ip of at least one host is missing" )
1082
1083 # there should always only be one cluster
1084 main.step( "There is only one dataplane cluster" )
1085 try:
1086 numClusters = len( json.loads( clusters[ 0 ] ) )
1087 except ( ValueError, TypeError ):
1088 main.log.exception( "Error parsing clusters[0]: " +
1089 repr( clusters[ 0 ] ) )
1090 clusterResults = main.FALSE
1091 if numClusters == 1:
1092 clusterResults = main.TRUE
1093 utilities.assert_equals(
1094 expect=1,
1095 actual=numClusters,
1096 onpass="ONOS shows 1 SCC",
1097 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1098
1099 main.step( "Comparing ONOS topology to MN" )
1100 devicesResults = main.TRUE
1101 linksResults = main.TRUE
1102 hostsResults = main.TRUE
1103 mnSwitches = main.Mininet1.getSwitches()
1104 mnLinks = main.Mininet1.getLinks()
1105 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07001106 for controller in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07001107 controllerStr = str( controller + 1 )
1108 if devices[ controller ] and ports[ controller ] and\
1109 "Error" not in devices[ controller ] and\
1110 "Error" not in ports[ controller ]:
1111
1112 currentDevicesResult = main.Mininet1.compareSwitches(
1113 mnSwitches,
1114 json.loads( devices[ controller ] ),
1115 json.loads( ports[ controller ] ) )
1116 else:
1117 currentDevicesResult = main.FALSE
1118 utilities.assert_equals( expect=main.TRUE,
1119 actual=currentDevicesResult,
1120 onpass="ONOS" + controllerStr +
1121 " Switches view is correct",
1122 onfail="ONOS" + controllerStr +
1123 " Switches view is incorrect" )
1124 if links[ controller ] and "Error" not in links[ controller ]:
1125 currentLinksResult = main.Mininet1.compareLinks(
1126 mnSwitches, mnLinks,
1127 json.loads( links[ controller ] ) )
1128 else:
1129 currentLinksResult = main.FALSE
1130 utilities.assert_equals( expect=main.TRUE,
1131 actual=currentLinksResult,
1132 onpass="ONOS" + controllerStr +
1133 " links view is correct",
1134 onfail="ONOS" + controllerStr +
1135 " links view is incorrect" )
1136
1137 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1138 currentHostsResult = main.Mininet1.compareHosts(
1139 mnHosts,
1140 hosts[ controller ] )
1141 else:
1142 currentHostsResult = main.FALSE
1143 utilities.assert_equals( expect=main.TRUE,
1144 actual=currentHostsResult,
1145 onpass="ONOS" + controllerStr +
1146 " hosts exist in Mininet",
1147 onfail="ONOS" + controllerStr +
1148 " hosts don't match Mininet" )
1149
1150 devicesResults = devicesResults and currentDevicesResult
1151 linksResults = linksResults and currentLinksResult
1152 hostsResults = hostsResults and currentHostsResult
1153
1154 main.step( "Device information is correct" )
1155 utilities.assert_equals(
1156 expect=main.TRUE,
1157 actual=devicesResults,
1158 onpass="Device information is correct",
1159 onfail="Device information is incorrect" )
1160
1161 main.step( "Links are correct" )
1162 utilities.assert_equals(
1163 expect=main.TRUE,
1164 actual=linksResults,
1165 onpass="Link are correct",
1166 onfail="Links are incorrect" )
1167
1168 main.step( "Hosts are correct" )
1169 utilities.assert_equals(
1170 expect=main.TRUE,
1171 actual=hostsResults,
1172 onpass="Hosts are correct",
1173 onfail="Hosts are incorrect" )
1174
1175 def CASE6( self, main ):
1176 """
1177 The Failure case.
1178 """
1179 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001180 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001181 assert main, "main not defined"
1182 assert utilities.assert_equals, "utilities.assert_equals not defined"
1183
1184 # Reset non-persistent variables
1185 try:
1186 iCounterValue = 0
1187 except NameError:
1188 main.log.error( "iCounterValue not defined, setting to 0" )
1189 iCounterValue = 0
1190
1191 main.case( "Restart ONOS node" )
Jon Hall783bbf92015-07-23 14:33:19 -07001192 main.caseExplanation = "Killing ONOS process and restart cli " +\
Jon Hall85794ff2015-07-08 14:12:30 -07001193 "sessions once onos is up."
Jon Hall96091e62015-09-21 17:34:17 -07001194
1195 main.step( "Checking ONOS Logs for errors" )
1196 for node in main.nodes:
1197 main.log.debug( "Checking logs for errors on " + node.name + ":" )
1198 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
1199
Jon Hall85794ff2015-07-08 14:12:30 -07001200 main.step( "Killing ONOS processes" )
Jon Halle1a3b752015-07-22 13:02:46 -07001201 killResult = main.ONOSbench.onosKill( main.nodes[0].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -07001202 start = time.time()
1203 utilities.assert_equals( expect=main.TRUE, actual=killResult,
1204 onpass="ONOS Killed",
1205 onfail="Error killing ONOS" )
1206
1207 main.step( "Checking if ONOS is up yet" )
1208 count = 0
1209 while count < 10:
Jon Halle1a3b752015-07-22 13:02:46 -07001210 onos1Isup = main.ONOSbench.isup( main.nodes[0].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -07001211 if onos1Isup == main.TRUE:
1212 elapsed = time.time() - start
1213 break
1214 else:
1215 count = count + 1
1216 utilities.assert_equals( expect=main.TRUE, actual=onos1Isup,
1217 onpass="ONOS is back up",
1218 onfail="ONOS failed to start" )
1219
1220 main.log.step( "Starting ONOS CLI sessions" )
Jon Halle1a3b752015-07-22 13:02:46 -07001221 cliResults = main.ONOScli1.startOnosCli( main.nodes[0].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -07001222 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1223 onpass="ONOS cli startup successful",
1224 onfail="ONOS cli startup failed" )
1225
1226 if elapsed:
1227 main.log.info( "ESTIMATE: ONOS took %s seconds to restart" %
1228 str( elapsed ) )
1229 main.restartTime = elapsed
1230 else:
1231 main.restartTime = -1
1232 time.sleep( 5 )
1233 # rerun on election apps
1234 main.ONOScli1.electionTestRun()
1235
1236 def CASE7( self, main ):
1237 """
1238 Check state after ONOS failure
1239 """
1240 import json
Jon Halle1a3b752015-07-22 13:02:46 -07001241 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001242 assert main, "main not defined"
1243 assert utilities.assert_equals, "utilities.assert_equals not defined"
1244 main.case( "Running ONOS Constant State Tests" )
1245 main.step( "Check that each switch has a master" )
1246 # Assert that each device has a master
1247 rolesNotNull = main.ONOScli1.rolesNotNull()
1248 utilities.assert_equals(
1249 expect=main.TRUE,
1250 actual=rolesNotNull,
1251 onpass="Each device has a master",
1252 onfail="Some devices don't have a master assigned" )
1253
1254 main.step( "Check if switch roles are consistent across all nodes" )
1255 ONOS1Mastership = main.ONOScli1.roles()
1256 # FIXME: Refactor this whole case for single instance
1257 if "Error" in ONOS1Mastership or not ONOS1Mastership:
1258 main.log.error( "Error in getting ONOS mastership" )
1259 main.log.warn( "ONOS1 mastership response: " +
1260 repr( ONOS1Mastership ) )
1261 consistentMastership = main.FALSE
1262 else:
1263 consistentMastership = main.TRUE
1264 utilities.assert_equals(
1265 expect=main.TRUE,
1266 actual=consistentMastership,
1267 onpass="Switch roles are consistent across all ONOS nodes",
1268 onfail="ONOS nodes have different views of switch roles" )
1269
1270 description2 = "Compare switch roles from before failure"
1271 main.step( description2 )
1272
1273 currentJson = json.loads( ONOS1Mastership )
1274 oldJson = json.loads( mastershipState )
1275 mastershipCheck = main.TRUE
1276 for i in range( 1, 29 ):
1277 switchDPID = str(
1278 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
1279
1280 current = [ switch[ 'master' ] for switch in currentJson
1281 if switchDPID in switch[ 'id' ] ]
1282 old = [ switch[ 'master' ] for switch in oldJson
1283 if switchDPID in switch[ 'id' ] ]
1284 if current == old:
1285 mastershipCheck = mastershipCheck and main.TRUE
1286 else:
1287 main.log.warn( "Mastership of switch %s changed" % switchDPID )
1288 mastershipCheck = main.FALSE
1289 utilities.assert_equals(
1290 expect=main.TRUE,
1291 actual=mastershipCheck,
1292 onpass="Mastership of Switches was not changed",
1293 onfail="Mastership of some switches changed" )
1294 mastershipCheck = mastershipCheck and consistentMastership
1295
1296 main.step( "Get the intents and compare across all nodes" )
1297 ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
1298 intentCheck = main.FALSE
1299 if "Error" in ONOS1Intents or not ONOS1Intents:
1300 main.log.error( "Error in getting ONOS intents" )
1301 main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
1302 else:
1303 intentCheck = main.TRUE
1304 utilities.assert_equals(
1305 expect=main.TRUE,
1306 actual=intentCheck,
1307 onpass="Intents are consistent across all ONOS nodes",
1308 onfail="ONOS nodes have different views of intents" )
1309 # Print the intent states
1310 intents = []
1311 intents.append( ONOS1Intents )
1312 intentStates = []
1313 for node in intents: # Iter through ONOS nodes
1314 nodeStates = []
1315 # Iter through intents of a node
1316 for intent in json.loads( node ):
1317 nodeStates.append( intent[ 'state' ] )
1318 intentStates.append( nodeStates )
1319 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1320 main.log.info( dict( out ) )
1321
1322 # NOTE: Store has no durability, so intents are lost across system
1323 # restarts
1324 """
1325 main.step( "Compare current intents with intents before the failure" )
1326 # NOTE: this requires case 5 to pass for intentState to be set.
1327 # maybe we should stop the test if that fails?
1328 sameIntents = main.FALSE
1329 if intentState and intentState == ONOSIntents[ 0 ]:
1330 sameIntents = main.TRUE
1331 main.log.info( "Intents are consistent with before failure" )
1332 # TODO: possibly the states have changed? we may need to figure out
1333 # what the acceptable states are
1334 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
1335 sameIntents = main.TRUE
1336 try:
1337 before = json.loads( intentState )
1338 after = json.loads( ONOSIntents[ 0 ] )
1339 for intent in before:
1340 if intent not in after:
1341 sameIntents = main.FALSE
1342 main.log.debug( "Intent is not currently in ONOS " +
1343 "(at least in the same form):" )
1344 main.log.debug( json.dumps( intent ) )
1345 except ( ValueError, TypeError ):
1346 main.log.exception( "Exception printing intents" )
1347 main.log.debug( repr( ONOSIntents[0] ) )
1348 main.log.debug( repr( intentState ) )
1349 if sameIntents == main.FALSE:
1350 try:
1351 main.log.debug( "ONOS intents before: " )
1352 main.log.debug( json.dumps( json.loads( intentState ),
1353 sort_keys=True, indent=4,
1354 separators=( ',', ': ' ) ) )
1355 main.log.debug( "Current ONOS intents: " )
1356 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1357 sort_keys=True, indent=4,
1358 separators=( ',', ': ' ) ) )
1359 except ( ValueError, TypeError ):
1360 main.log.exception( "Exception printing intents" )
1361 main.log.debug( repr( ONOSIntents[0] ) )
1362 main.log.debug( repr( intentState ) )
1363 utilities.assert_equals(
1364 expect=main.TRUE,
1365 actual=sameIntents,
1366 onpass="Intents are consistent with before failure",
1367 onfail="The Intents changed during failure" )
1368 intentCheck = intentCheck and sameIntents
1369 """
1370 main.step( "Get the OF Table entries and compare to before " +
1371 "component failure" )
1372 FlowTables = main.TRUE
Jon Hall85794ff2015-07-08 14:12:30 -07001373 for i in range( 28 ):
1374 main.log.info( "Checking flow table on s" + str( i + 1 ) )
GlennRC68467eb2015-11-16 18:01:01 -08001375 tmpFlows = main.Mininet1.getFlowTable( "s" + str( i + 1 ), version="1.3", debug=False )
1376 FlowTables = FlowTables and main.Mininet1.flowTableComp( flows[i], tmpFlows )
Jon Hall85794ff2015-07-08 14:12:30 -07001377 if FlowTables == main.FALSE:
GlennRC68467eb2015-11-16 18:01:01 -08001378 main.log.warn( "Differences in flow table for switch: s{}".format( i + 1 ) )
1379
Jon Hall85794ff2015-07-08 14:12:30 -07001380 utilities.assert_equals(
1381 expect=main.TRUE,
1382 actual=FlowTables,
1383 onpass="No changes were found in the flow tables",
1384 onfail="Changes were found in the flow tables" )
1385
1386 main.step( "Leadership Election is still functional" )
1387 # Test of LeadershipElection
1388
Jon Halle1a3b752015-07-22 13:02:46 -07001389 leader = main.nodes[0].ip_address
Jon Hall85794ff2015-07-08 14:12:30 -07001390 leaderResult = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07001391 for controller in range( 1, main.numCtrls + 1 ):
Jon Hall85794ff2015-07-08 14:12:30 -07001392 # loop through ONOScli handlers
1393 node = getattr( main, ( 'ONOScli' + str( controller ) ) )
1394 leaderN = node.electionTestLeader()
1395 # verify leader is ONOS1
1396 # NOTE even though we restarted ONOS, it is the only one so onos 1
1397 # must be leader
1398 if leaderN == leader:
1399 # all is well
1400 pass
1401 elif leaderN == main.FALSE:
1402 # error in response
1403 main.log.error( "Something is wrong with " +
1404 "electionTestLeader function, check the" +
1405 " error logs" )
1406 leaderResult = main.FALSE
1407 elif leader != leaderN:
1408 leaderResult = main.FALSE
1409 main.log.error( "ONOS" + str( controller ) + " sees " +
1410 str( leaderN ) +
1411 " as the leader of the election app. " +
1412 "Leader should be " + str( leader ) )
1413 utilities.assert_equals(
1414 expect=main.TRUE,
1415 actual=leaderResult,
1416 onpass="Leadership election passed",
1417 onfail="Something went wrong with Leadership election" )
1418
1419 def CASE8( self, main ):
1420 """
1421 Compare topo
1422 """
1423 import json
1424 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001425 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001426 assert main, "main not defined"
1427 assert utilities.assert_equals, "utilities.assert_equals not defined"
1428
1429 main.case( "Compare ONOS Topology view to Mininet topology" )
Jon Hall783bbf92015-07-23 14:33:19 -07001430 main.caseExplanation = "Compare topology objects between Mininet" +\
Jon Hall85794ff2015-07-08 14:12:30 -07001431 " and ONOS"
Jon Hall85794ff2015-07-08 14:12:30 -07001432 topoResult = main.FALSE
1433 elapsed = 0
1434 count = 0
Jon Halle9b1fa32015-12-08 15:32:21 -08001435 main.step( "Comparing ONOS topology to MN topology" )
Jon Hall85794ff2015-07-08 14:12:30 -07001436 startTime = time.time()
1437 # Give time for Gossip to work
Jon Halle9b1fa32015-12-08 15:32:21 -08001438 while topoResult == main.FALSE and ( elapsed < 60 or count < 3 ):
Jon Hall96091e62015-09-21 17:34:17 -07001439 devicesResults = main.TRUE
1440 linksResults = main.TRUE
1441 hostsResults = main.TRUE
1442 hostAttachmentResults = True
Jon Hall85794ff2015-07-08 14:12:30 -07001443 count += 1
1444 cliStart = time.time()
1445 devices = []
1446 devices.append( main.ONOScli1.devices() )
1447 hosts = []
1448 hosts.append( json.loads( main.ONOScli1.hosts() ) )
1449 ipResult = main.TRUE
1450 for controller in range( 0, len( hosts ) ):
1451 controllerStr = str( controller + 1 )
1452 for host in hosts[ controller ]:
1453 if host is None or host.get( 'ipAddresses', [] ) == []:
1454 main.log.error(
1455 "DEBUG:Error with host ips on controller" +
1456 controllerStr + ": " + str( host ) )
1457 ipResult = main.FALSE
1458 ports = []
1459 ports.append( main.ONOScli1.ports() )
1460 links = []
1461 links.append( main.ONOScli1.links() )
1462 clusters = []
1463 clusters.append( main.ONOScli1.clusters() )
1464
1465 elapsed = time.time() - startTime
1466 cliTime = time.time() - cliStart
1467 print "CLI time: " + str( cliTime )
1468
1469 mnSwitches = main.Mininet1.getSwitches()
1470 mnLinks = main.Mininet1.getLinks()
1471 mnHosts = main.Mininet1.getHosts()
Jon Halle1a3b752015-07-22 13:02:46 -07001472 for controller in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07001473 controllerStr = str( controller + 1 )
1474 if devices[ controller ] and ports[ controller ] and\
1475 "Error" not in devices[ controller ] and\
1476 "Error" not in ports[ controller ]:
1477
1478 currentDevicesResult = main.Mininet1.compareSwitches(
1479 mnSwitches,
1480 json.loads( devices[ controller ] ),
1481 json.loads( ports[ controller ] ) )
1482 else:
1483 currentDevicesResult = main.FALSE
1484 utilities.assert_equals( expect=main.TRUE,
1485 actual=currentDevicesResult,
1486 onpass="ONOS" + controllerStr +
1487 " Switches view is correct",
1488 onfail="ONOS" + controllerStr +
1489 " Switches view is incorrect" )
1490
1491 if links[ controller ] and "Error" not in links[ controller ]:
1492 currentLinksResult = main.Mininet1.compareLinks(
1493 mnSwitches, mnLinks,
1494 json.loads( links[ controller ] ) )
1495 else:
1496 currentLinksResult = main.FALSE
1497 utilities.assert_equals( expect=main.TRUE,
1498 actual=currentLinksResult,
1499 onpass="ONOS" + controllerStr +
1500 " links view is correct",
1501 onfail="ONOS" + controllerStr +
1502 " links view is incorrect" )
1503
1504 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1505 currentHostsResult = main.Mininet1.compareHosts(
1506 mnHosts,
1507 hosts[ controller ] )
1508 else:
1509 currentHostsResult = main.FALSE
1510 utilities.assert_equals( expect=main.TRUE,
1511 actual=currentHostsResult,
1512 onpass="ONOS" + controllerStr +
1513 " hosts exist in Mininet",
1514 onfail="ONOS" + controllerStr +
1515 " hosts don't match Mininet" )
1516 # CHECKING HOST ATTACHMENT POINTS
1517 hostAttachment = True
1518 zeroHosts = False
1519 # FIXME: topo-HA/obelisk specific mappings:
1520 # key is mac and value is dpid
1521 mappings = {}
1522 for i in range( 1, 29 ): # hosts 1 through 28
1523 # set up correct variables:
1524 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
1525 if i == 1:
1526 deviceId = "1000".zfill(16)
1527 elif i == 2:
1528 deviceId = "2000".zfill(16)
1529 elif i == 3:
1530 deviceId = "3000".zfill(16)
1531 elif i == 4:
1532 deviceId = "3004".zfill(16)
1533 elif i == 5:
1534 deviceId = "5000".zfill(16)
1535 elif i == 6:
1536 deviceId = "6000".zfill(16)
1537 elif i == 7:
1538 deviceId = "6007".zfill(16)
1539 elif i >= 8 and i <= 17:
1540 dpid = '3' + str( i ).zfill( 3 )
1541 deviceId = dpid.zfill(16)
1542 elif i >= 18 and i <= 27:
1543 dpid = '6' + str( i ).zfill( 3 )
1544 deviceId = dpid.zfill(16)
1545 elif i == 28:
1546 deviceId = "2800".zfill(16)
1547 mappings[ macId ] = deviceId
1548 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1549 if hosts[ controller ] == []:
1550 main.log.warn( "There are no hosts discovered" )
1551 zeroHosts = True
1552 else:
1553 for host in hosts[ controller ]:
1554 mac = None
1555 location = None
1556 device = None
1557 port = None
1558 try:
1559 mac = host.get( 'mac' )
1560 assert mac, "mac field could not be found for this host object"
1561
1562 location = host.get( 'location' )
1563 assert location, "location field could not be found for this host object"
1564
1565 # Trim the protocol identifier off deviceId
1566 device = str( location.get( 'elementId' ) ).split(':')[1]
1567 assert device, "elementId field could not be found for this host location object"
1568
1569 port = location.get( 'port' )
1570 assert port, "port field could not be found for this host location object"
1571
1572 # Now check if this matches where they should be
1573 if mac and device and port:
1574 if str( port ) != "1":
1575 main.log.error( "The attachment port is incorrect for " +
1576 "host " + str( mac ) +
1577 ". Expected: 1 Actual: " + str( port) )
1578 hostAttachment = False
1579 if device != mappings[ str( mac ) ]:
1580 main.log.error( "The attachment device is incorrect for " +
1581 "host " + str( mac ) +
1582 ". Expected: " + mappings[ str( mac ) ] +
1583 " Actual: " + device )
1584 hostAttachment = False
1585 else:
1586 hostAttachment = False
1587 except AssertionError:
1588 main.log.exception( "Json object not as expected" )
1589 main.log.error( repr( host ) )
1590 hostAttachment = False
1591 else:
1592 main.log.error( "No hosts json output or \"Error\"" +
1593 " in output. hosts = " +
1594 repr( hosts[ controller ] ) )
1595 if zeroHosts is False:
1596 hostAttachment = True
1597
Jon Hall85794ff2015-07-08 14:12:30 -07001598 devicesResults = devicesResults and currentDevicesResult
1599 linksResults = linksResults and currentLinksResult
1600 hostsResults = hostsResults and currentHostsResult
1601 hostAttachmentResults = hostAttachmentResults and\
1602 hostAttachment
1603
1604 # "consistent" results don't make sense for single instance
1605 # there should always only be one cluster
1606 numClusters = len( json.loads( clusters[ 0 ] ) )
1607 clusterResults = main.FALSE
1608 if numClusters == 1:
1609 clusterResults = main.TRUE
1610 utilities.assert_equals(
1611 expect=1,
1612 actual=numClusters,
1613 onpass="ONOS shows 1 SCC",
1614 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1615
1616 topoResult = ( devicesResults and linksResults
1617 and hostsResults and ipResult and clusterResults and
1618 hostAttachmentResults )
1619
1620 topoResult = topoResult and int( count <= 2 )
1621 note = "note it takes about " + str( int( cliTime ) ) + \
1622 " seconds for the test to make all the cli calls to fetch " +\
1623 "the topology from each ONOS instance"
1624 main.log.info(
1625 "Very crass estimate for topology discovery/convergence( " +
1626 str( note ) + " ): " + str( elapsed ) + " seconds, " +
1627 str( count ) + " tries" )
1628 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
1629 onpass="Topology Check Test successful",
1630 onfail="Topology Check Test NOT successful" )
1631
1632 def CASE9( self, main ):
1633 """
1634 Link s3-s28 down
1635 """
1636 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001637 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001638 assert main, "main not defined"
1639 assert utilities.assert_equals, "utilities.assert_equals not defined"
1640 # NOTE: You should probably run a topology check after this
1641
1642 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
1643
1644 description = "Turn off a link to ensure that Link Discovery " +\
1645 "is working properly"
1646 main.case( description )
1647
1648 main.step( "Kill Link between s3 and s28" )
1649 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
1650 main.log.info( "Waiting " + str( linkSleep ) +
1651 " seconds for link down to be discovered" )
1652 time.sleep( linkSleep )
1653 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
1654 onpass="Link down successful",
1655 onfail="Failed to bring link down" )
1656 # TODO do some sort of check here
1657
1658 def CASE10( self, main ):
1659 """
1660 Link s3-s28 up
1661 """
1662 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001663 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001664 assert main, "main not defined"
1665 assert utilities.assert_equals, "utilities.assert_equals not defined"
1666 # NOTE: You should probably run a topology check after this
1667
1668 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
1669
1670 description = "Restore a link to ensure that Link Discovery is " + \
1671 "working properly"
1672 main.case( description )
1673
1674 main.step( "Bring link between s3 and s28 back up" )
1675 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
1676 main.log.info( "Waiting " + str( linkSleep ) +
1677 " seconds for link up to be discovered" )
1678 time.sleep( linkSleep )
1679 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
1680 onpass="Link up successful",
1681 onfail="Failed to bring link up" )
1682 # TODO do some sort of check here
1683
1684 def CASE11( self, main ):
1685 """
1686 Switch Down
1687 """
1688 # NOTE: You should probably run a topology check after this
1689 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001690 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001691 assert main, "main not defined"
1692 assert utilities.assert_equals, "utilities.assert_equals not defined"
1693
1694 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
1695
1696 description = "Killing a switch to ensure it is discovered correctly"
1697 main.case( description )
1698 switch = main.params[ 'kill' ][ 'switch' ]
1699 switchDPID = main.params[ 'kill' ][ 'dpid' ]
1700
1701 # TODO: Make this switch parameterizable
1702 main.step( "Kill " + switch )
1703 main.log.info( "Deleting " + switch )
1704 main.Mininet1.delSwitch( switch )
1705 main.log.info( "Waiting " + str( switchSleep ) +
1706 " seconds for switch down to be discovered" )
1707 time.sleep( switchSleep )
1708 device = main.ONOScli1.getDevice( dpid=switchDPID )
1709 # Peek at the deleted switch
1710 main.log.warn( str( device ) )
1711 result = main.FALSE
1712 if device and device[ 'available' ] is False:
1713 result = main.TRUE
1714 utilities.assert_equals( expect=main.TRUE, actual=result,
1715 onpass="Kill switch successful",
1716 onfail="Failed to kill switch?" )
1717
1718 def CASE12( self, main ):
1719 """
1720 Switch Up
1721 """
1722 # NOTE: You should probably run a topology check after this
1723 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001724 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001725 assert main, "main not defined"
1726 assert utilities.assert_equals, "utilities.assert_equals not defined"
1727
1728 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
1729 switch = main.params[ 'kill' ][ 'switch' ]
1730 switchDPID = main.params[ 'kill' ][ 'dpid' ]
1731 links = main.params[ 'kill' ][ 'links' ].split()
1732 description = "Adding a switch to ensure it is discovered correctly"
1733 main.case( description )
1734
1735 main.step( "Add back " + switch )
1736 main.Mininet1.addSwitch( switch, dpid=switchDPID )
1737 for peer in links:
1738 main.Mininet1.addLink( switch, peer )
1739 ipList = []
Jon Halle1a3b752015-07-22 13:02:46 -07001740 for i in range( main.numCtrls ):
1741 ipList.append( main.nodes[ i ].ip_address )
Jon Hall85794ff2015-07-08 14:12:30 -07001742 main.Mininet1.assignSwController( sw=switch, ip=ipList )
1743 main.log.info( "Waiting " + str( switchSleep ) +
1744 " seconds for switch up to be discovered" )
1745 time.sleep( switchSleep )
1746 device = main.ONOScli1.getDevice( dpid=switchDPID )
1747 # Peek at the deleted switch
1748 main.log.warn( str( device ) )
1749 result = main.FALSE
1750 if device and device[ 'available' ]:
1751 result = main.TRUE
1752 utilities.assert_equals( expect=main.TRUE, actual=result,
1753 onpass="add switch successful",
1754 onfail="Failed to add switch?" )
1755
1756 def CASE13( self, main ):
1757 """
1758 Clean up
1759 """
1760 import os
1761 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001762 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001763 assert main, "main not defined"
1764 assert utilities.assert_equals, "utilities.assert_equals not defined"
1765 # printing colors to terminal
1766 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
1767 'blue': '\033[94m', 'green': '\033[92m',
1768 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
1769 main.case( "Test Cleanup" )
1770 main.step( "Killing tcpdumps" )
1771 main.Mininet2.stopTcpdump()
1772
1773 testname = main.TEST
Jon Hall96091e62015-09-21 17:34:17 -07001774 if main.params[ 'BACKUP' ][ 'ENABLED' ] == "True":
Jon Hall85794ff2015-07-08 14:12:30 -07001775 main.step( "Copying MN pcap and ONOS log files to test station" )
1776 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
1777 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
Jon Hall96091e62015-09-21 17:34:17 -07001778 # NOTE: MN Pcap file is being saved to logdir.
1779 # We scp this file as MN and TestON aren't necessarily the same vm
1780
1781 # FIXME: To be replaced with a Jenkin's post script
Jon Hall85794ff2015-07-08 14:12:30 -07001782 # TODO: Load these from params
1783 # NOTE: must end in /
1784 logFolder = "/opt/onos/log/"
1785 logFiles = [ "karaf.log", "karaf.log.1" ]
1786 # NOTE: must end in /
Jon Hall85794ff2015-07-08 14:12:30 -07001787 for f in logFiles:
Jon Hall96091e62015-09-21 17:34:17 -07001788 for node in main.nodes:
1789 dstName = main.logdir + "/" + node.name + "-" + f
1790 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
1791 logFolder + f, dstName )
Jon Hall85794ff2015-07-08 14:12:30 -07001792 # std*.log's
1793 # NOTE: must end in /
1794 logFolder = "/opt/onos/var/"
1795 logFiles = [ "stderr.log", "stdout.log" ]
1796 # NOTE: must end in /
Jon Hall85794ff2015-07-08 14:12:30 -07001797 for f in logFiles:
Jon Hall96091e62015-09-21 17:34:17 -07001798 for node in main.nodes:
1799 dstName = main.logdir + "/" + node.name + "-" + f
1800 main.ONOSbench.secureCopy( node.user_name, node.ip_address,
1801 logFolder + f, dstName )
1802 else:
1803 main.log.debug( "skipping saving log files" )
Jon Hall85794ff2015-07-08 14:12:30 -07001804
Jon Hall85794ff2015-07-08 14:12:30 -07001805 main.step( "Stopping Mininet" )
1806 mnResult = main.Mininet1.stopNet()
1807 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
1808 onpass="Mininet stopped",
1809 onfail="MN cleanup NOT successful" )
1810
1811 main.step( "Checking ONOS Logs for errors" )
Jon Hall96091e62015-09-21 17:34:17 -07001812 for node in main.nodes:
1813 main.log.debug( "Checking logs for errors on " + node.name + ":" )
1814 main.log.warn( main.ONOSbench.checkLogs( node.ip_address ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001815
1816 try:
1817 timerLog = open( main.logdir + "/Timers.csv", 'w')
1818 # Overwrite with empty line and close
1819 labels = "Gossip Intents, Restart"
1820 data = str( gossipTime ) + ", " + str( main.restartTime )
1821 timerLog.write( labels + "\n" + data )
1822 timerLog.close()
1823 except NameError, e:
1824 main.log.exception(e)
1825
1826 def CASE14( self, main ):
1827 """
1828 start election app on all onos nodes
1829 """
Jon Halle1a3b752015-07-22 13:02:46 -07001830 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001831 assert main, "main not defined"
1832 assert utilities.assert_equals, "utilities.assert_equals not defined"
1833
1834 main.case("Start Leadership Election app")
1835 main.step( "Install leadership election app" )
1836 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
1837 utilities.assert_equals(
1838 expect=main.TRUE,
1839 actual=appResult,
1840 onpass="Election app installed",
1841 onfail="Something went wrong with installing Leadership election" )
1842
1843 main.step( "Run for election on each node" )
1844 leaderResult = main.ONOScli1.electionTestRun()
1845 # check for leader
1846 leader = main.ONOScli1.electionTestLeader()
1847 # verify leader is ONOS1
Jon Halle1a3b752015-07-22 13:02:46 -07001848 if leader == main.nodes[0].ip_address:
Jon Hall85794ff2015-07-08 14:12:30 -07001849 # all is well
1850 pass
1851 elif leader is None:
1852 # No leader elected
1853 main.log.error( "No leader was elected" )
1854 leaderResult = main.FALSE
1855 elif leader == main.FALSE:
1856 # error in response
1857 # TODO: add check for "Command not found:" in the driver, this
1858 # means the app isn't loaded
1859 main.log.error( "Something is wrong with electionTestLeader" +
1860 " function, check the error logs" )
1861 leaderResult = main.FALSE
1862 else:
1863 # error in response
1864 main.log.error(
1865 "Unexpected response from electionTestLeader function:'" +
1866 str( leader ) +
1867 "'" )
1868 leaderResult = main.FALSE
1869 utilities.assert_equals(
1870 expect=main.TRUE,
1871 actual=leaderResult,
1872 onpass="Successfully ran for leadership",
1873 onfail="Failed to run for leadership" )
1874
1875 def CASE15( self, main ):
1876 """
1877 Check that Leadership Election is still functional
acsmars71adceb2015-08-31 15:09:26 -07001878 15.1 Run election on each node
1879 15.2 Check that each node has the same leaders and candidates
1880 15.3 Find current leader and withdraw
1881 15.4 Check that a new node was elected leader
1882 15.5 Check that that new leader was the candidate of old leader
1883 15.6 Run for election on old leader
1884 15.7 Check that oldLeader is a candidate, and leader if only 1 node
1885 15.8 Make sure that the old leader was added to the candidate list
1886
1887 old and new variable prefixes refer to data from before vs after
1888 withdrawl and later before withdrawl vs after re-election
Jon Hall85794ff2015-07-08 14:12:30 -07001889 """
acsmars71adceb2015-08-31 15:09:26 -07001890 import time
Jon Halle1a3b752015-07-22 13:02:46 -07001891 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07001892 assert main, "main not defined"
1893 assert utilities.assert_equals, "utilities.assert_equals not defined"
acsmars71adceb2015-08-31 15:09:26 -07001894 assert main.CLIs, "main.CLIs not defined"
1895 assert main.nodes, "main.nodes not defined"
1896
Jon Hall85794ff2015-07-08 14:12:30 -07001897 description = "Check that Leadership Election is still functional"
1898 main.case( description )
acsmars71adceb2015-08-31 15:09:26 -07001899 # NOTE: Need to re-run since being a canidate is not persistant
1900 # TODO: add check for "Command not found:" in the driver, this
1901 # means the election test app isn't loaded
acsmars2c2fcdd2015-08-25 17:14:13 -07001902
acsmars71adceb2015-08-31 15:09:26 -07001903 oldLeaders = [] # leaders by node before withdrawl from candidates
1904 newLeaders = [] # leaders by node after withdrawl from candidates
1905 oldAllCandidates = [] # list of lists of each nodes' candidates before
1906 newAllCandidates = [] # list of lists of each nodes' candidates after
1907 oldCandidates = [] # list of candidates from node 0 before withdrawl
1908 newCandidates = [] # list of candidates from node 0 after withdrawl
1909 oldLeader = '' # the old leader from oldLeaders, None if not same
1910 newLeader = '' # the new leaders fron newLoeaders, None if not same
1911 oldLeaderCLI = None # the CLI of the old leader used for re-electing
1912 expectNoLeader = False # True when there is only one leader
1913 if main.numCtrls == 1:
1914 expectNoLeader = True
acsmars2c2fcdd2015-08-25 17:14:13 -07001915
acsmars71adceb2015-08-31 15:09:26 -07001916 main.step( "Run for election on each node" )
1917 electionResult = main.TRUE
1918
1919 for cli in main.CLIs: # run test election on each node
1920 if cli.electionTestRun() == main.FALSE:
1921 electionResult = main.FALSE
1922
1923 utilities.assert_equals(
1924 expect=main.TRUE,
1925 actual=electionResult,
1926 onpass="All nodes successfully ran for leadership",
1927 onfail="At least one node failed to run for leadership" )
1928
acsmars3a72bde2015-09-02 14:16:22 -07001929 if electionResult == main.FALSE:
1930 main.log.error(
1931 "Skipping Test Case because Election Test App isn't loaded" )
1932 main.skipCase()
1933
acsmars71adceb2015-08-31 15:09:26 -07001934 main.step( "Check that each node shows the same leader and candidates" )
1935 sameResult = main.TRUE
1936 failMessage = "Nodes have different leaders"
1937 for cli in main.CLIs:
1938 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
1939 oldAllCandidates.append( node )
1940 oldLeaders.append( node[ 0 ] )
1941 oldCandidates = oldAllCandidates[ 0 ]
1942
1943 # Check that each node has the same leader. Defines oldLeader
1944 if len( set( oldLeaders ) ) != 1:
1945 sameResult = main.FALSE
1946 main.log.error( "More than one leader present:" + str( oldLeaders ) )
Jon Hall85794ff2015-07-08 14:12:30 -07001947 oldLeader = None
1948 else:
acsmars71adceb2015-08-31 15:09:26 -07001949 oldLeader = oldLeaders[ 0 ]
1950
1951 # Check that each node's candidate list is the same
acsmars29233db2015-11-04 11:15:00 -08001952 candidateDiscrepancy = False # Boolean of candidate mismatches
acsmars71adceb2015-08-31 15:09:26 -07001953 for candidates in oldAllCandidates:
1954 if set( candidates ) != set( oldCandidates ):
1955 sameResult = main.FALSE
acsmars29233db2015-11-04 11:15:00 -08001956 candidateDiscrepancy = True
1957
1958 if candidateDiscrepancy:
1959 failMessage += " and candidates"
acsmars71adceb2015-08-31 15:09:26 -07001960
1961 utilities.assert_equals(
1962 expect=main.TRUE,
1963 actual=sameResult,
1964 onpass="Leadership is consistent for the election topic",
1965 onfail=failMessage )
1966
1967 main.step( "Find current leader and withdraw" )
1968 withdrawResult = main.TRUE
1969 # do some sanity checking on leader before using it
1970 if oldLeader is None:
1971 main.log.error( "Leadership isn't consistent." )
1972 withdrawResult = main.FALSE
1973 # Get the CLI of the oldLeader
1974 for i in range( len( main.CLIs ) ):
1975 if oldLeader == main.nodes[ i ].ip_address:
1976 oldLeaderCLI = main.CLIs[ i ]
1977 break
1978 else: # FOR/ELSE statement
1979 main.log.error( "Leader election, could not find current leader" )
Jon Hall85794ff2015-07-08 14:12:30 -07001980 if oldLeader:
acsmars71adceb2015-08-31 15:09:26 -07001981 withdrawResult = oldLeaderCLI.electionTestWithdraw()
Jon Hall85794ff2015-07-08 14:12:30 -07001982 utilities.assert_equals(
1983 expect=main.TRUE,
1984 actual=withdrawResult,
1985 onpass="Node was withdrawn from election",
1986 onfail="Node was not withdrawn from election" )
1987
acsmars71adceb2015-08-31 15:09:26 -07001988 main.step( "Check that a new node was elected leader" )
1989
1990 # FIXME: use threads
1991 newLeaderResult = main.TRUE
1992 failMessage = "Nodes have different leaders"
1993
1994 # Get new leaders and candidates
1995 for cli in main.CLIs:
1996 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
1997 # elections might no have finished yet
1998 if node[ 0 ] == 'none' and not expectNoLeader:
1999 main.log.info( "Node has no leader, waiting 5 seconds to be " +
2000 "sure elections are complete." )
2001 time.sleep(5)
2002 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2003 # election still isn't done or there is a problem
2004 if node[ 0 ] == 'none':
2005 main.log.error( "No leader was elected on at least 1 node" )
2006 newLeaderResult = main.FALSE
2007 newAllCandidates.append( node )
2008 newLeaders.append( node[ 0 ] )
2009 newCandidates = newAllCandidates[ 0 ]
2010
2011 # Check that each node has the same leader. Defines newLeader
2012 if len( set( newLeaders ) ) != 1:
2013 newLeaderResult = main.FALSE
2014 main.log.error( "Nodes have different leaders: " +
2015 str( newLeaders ) )
2016 newLeader = None
2017 else:
2018 newLeader = newLeaders[ 0 ]
2019
2020 # Check that each node's candidate list is the same
2021 for candidates in newAllCandidates:
2022 if set( candidates ) != set( newCandidates ):
2023 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07002024 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07002025
2026 # Check that the new leader is not the older leader, which was withdrawn
2027 if newLeader == oldLeader:
2028 newLeaderResult = main.FALSE
2029 main.log.error( "All nodes still see old leader: " + oldLeader +
2030 " as the current leader" )
2031
Jon Hall85794ff2015-07-08 14:12:30 -07002032 utilities.assert_equals(
2033 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002034 actual=newLeaderResult,
2035 onpass="Leadership election passed",
2036 onfail="Something went wrong with Leadership election" )
Jon Hall85794ff2015-07-08 14:12:30 -07002037
acsmars71adceb2015-08-31 15:09:26 -07002038 main.step( "Check that that new leader was the candidate of old leader")
2039 # candidates[ 2 ] should be come the top candidate after withdrawl
2040 correctCandidateResult = main.TRUE
2041 if expectNoLeader:
2042 if newLeader == 'none':
2043 main.log.info( "No leader expected. None found. Pass" )
2044 correctCandidateResult = main.TRUE
2045 else:
2046 main.log.info( "Expected no leader, got: " + str( newLeader ) )
2047 correctCandidateResult = main.FALSE
2048 elif newLeader != oldCandidates[ 2 ]:
2049 correctCandidateResult = main.FALSE
2050 main.log.error( "Candidate " + newLeader + " was elected. " +
2051 oldCandidates[ 2 ] + " should have had priority." )
2052
2053 utilities.assert_equals(
2054 expect=main.TRUE,
2055 actual=correctCandidateResult,
2056 onpass="Correct Candidate Elected",
2057 onfail="Incorrect Candidate Elected" )
2058
Jon Hall85794ff2015-07-08 14:12:30 -07002059 main.step( "Run for election on old leader( just so everyone " +
2060 "is in the hat )" )
acsmars71adceb2015-08-31 15:09:26 -07002061 if oldLeaderCLI is not None:
2062 runResult = oldLeaderCLI.electionTestRun()
Jon Hall85794ff2015-07-08 14:12:30 -07002063 else:
acsmars71adceb2015-08-31 15:09:26 -07002064 main.log.error( "No old leader to re-elect" )
Jon Hall85794ff2015-07-08 14:12:30 -07002065 runResult = main.FALSE
2066 utilities.assert_equals(
2067 expect=main.TRUE,
2068 actual=runResult,
2069 onpass="App re-ran for election",
2070 onfail="App failed to run for election" )
acsmars71adceb2015-08-31 15:09:26 -07002071 main.step(
2072 "Check that oldLeader is a candidate, and leader if only 1 node" )
2073 # verify leader didn't just change
2074 positionResult = main.TRUE
2075 # Get new leaders and candidates, wait if oldLeader is not a candidate yet
Jon Hall85794ff2015-07-08 14:12:30 -07002076
acsmars71adceb2015-08-31 15:09:26 -07002077 # Reset and reuse the new candidate and leaders lists
2078 newAllCandidates = []
2079 newCandidates = []
2080 newLeaders = []
2081 for cli in main.CLIs:
2082 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2083 if oldLeader not in node: # election might no have finished yet
2084 main.log.info( "Old Leader not elected, waiting 5 seconds to " +
2085 "be sure elections are complete" )
2086 time.sleep(5)
2087 node = cli.specificLeaderCandidate( 'org.onosproject.election' )
2088 if oldLeader not in node: # election still isn't done, errors
2089 main.log.error(
2090 "Old leader was not elected on at least one node" )
2091 positionResult = main.FALSE
2092 newAllCandidates.append( node )
2093 newLeaders.append( node[ 0 ] )
2094 newCandidates = newAllCandidates[ 0 ]
2095
2096 # Check that each node has the same leader. Defines newLeader
2097 if len( set( newLeaders ) ) != 1:
2098 positionResult = main.FALSE
2099 main.log.error( "Nodes have different leaders: " +
2100 str( newLeaders ) )
2101 newLeader = None
Jon Hall85794ff2015-07-08 14:12:30 -07002102 else:
acsmars71adceb2015-08-31 15:09:26 -07002103 newLeader = newLeaders[ 0 ]
2104
2105 # Check that each node's candidate list is the same
2106 for candidates in newAllCandidates:
2107 if set( candidates ) != set( newCandidates ):
2108 newLeaderResult = main.FALSE
Jon Hallceb4abb2015-09-25 12:03:06 -07002109 main.log.error( "Discrepancy in candidate lists detected" )
acsmars71adceb2015-08-31 15:09:26 -07002110
2111 # Check that the re-elected node is last on the candidate List
2112 if oldLeader != newCandidates[ -1 ]:
2113 main.log.error( "Old Leader (" + oldLeader + ") not in the proper position " +
2114 str( newCandidates ) )
2115 positionResult = main.FALSE
Jon Hall85794ff2015-07-08 14:12:30 -07002116
2117 utilities.assert_equals(
2118 expect=main.TRUE,
acsmars71adceb2015-08-31 15:09:26 -07002119 actual=positionResult,
Jon Hall85794ff2015-07-08 14:12:30 -07002120 onpass="Old leader successfully re-ran for election",
2121 onfail="Something went wrong with Leadership election after " +
2122 "the old leader re-ran for election" )
2123
2124 def CASE16( self, main ):
2125 """
2126 Install Distributed Primitives app
2127 """
Jon Halle1a3b752015-07-22 13:02:46 -07002128 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002129 assert main, "main not defined"
2130 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002131 assert main.CLIs, "main.CLIs not defined"
2132 assert main.nodes, "main.nodes not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002133
2134 # Variables for the distributed primitives tests
2135 global pCounterName
2136 global iCounterName
2137 global pCounterValue
2138 global iCounterValue
2139 global onosSet
2140 global onosSetName
2141 pCounterName = "TestON-Partitions"
2142 iCounterName = "TestON-inMemory"
2143 pCounterValue = 0
2144 iCounterValue = 0
2145 onosSet = set([])
2146 onosSetName = "TestON-set"
2147
2148 description = "Install Primitives app"
2149 main.case( description )
2150 main.step( "Install Primitives app" )
2151 appName = "org.onosproject.distributedprimitives"
Jon Halle1a3b752015-07-22 13:02:46 -07002152 appResults = main.CLIs[0].activateApp( appName )
Jon Hall85794ff2015-07-08 14:12:30 -07002153 utilities.assert_equals( expect=main.TRUE,
2154 actual=appResults,
2155 onpass="Primitives app activated",
2156 onfail="Primitives app not activated" )
2157
2158 def CASE17( self, main ):
2159 """
2160 Check for basic functionality with distributed primitives
2161 """
Jon Hall85794ff2015-07-08 14:12:30 -07002162 # Make sure variables are defined/set
Jon Halle1a3b752015-07-22 13:02:46 -07002163 assert main.numCtrls, "main.numCtrls not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002164 assert main, "main not defined"
2165 assert utilities.assert_equals, "utilities.assert_equals not defined"
Jon Halle1a3b752015-07-22 13:02:46 -07002166 assert main.CLIs, "main.CLIs not defined"
2167 assert main.nodes, "main.nodes not defined"
Jon Hall85794ff2015-07-08 14:12:30 -07002168 assert pCounterName, "pCounterName not defined"
2169 assert iCounterName, "iCounterName not defined"
2170 assert onosSetName, "onosSetName not defined"
2171 # NOTE: assert fails if value is 0/None/Empty/False
2172 try:
2173 pCounterValue
2174 except NameError:
2175 main.log.error( "pCounterValue not defined, setting to 0" )
2176 pCounterValue = 0
2177 try:
2178 iCounterValue
2179 except NameError:
2180 main.log.error( "iCounterValue not defined, setting to 0" )
2181 iCounterValue = 0
2182 try:
2183 onosSet
2184 except NameError:
2185 main.log.error( "onosSet not defined, setting to empty Set" )
2186 onosSet = set([])
2187 # Variables for the distributed primitives tests. These are local only
2188 addValue = "a"
2189 addAllValue = "a b c d e f"
2190 retainValue = "c d e f"
2191
2192 description = "Check for basic functionality with distributed " +\
2193 "primitives"
2194 main.case( description )
Jon Halle1a3b752015-07-22 13:02:46 -07002195 main.caseExplanation = "Test the methods of the distributed " +\
2196 "primitives (counters and sets) throught the cli"
Jon Hall85794ff2015-07-08 14:12:30 -07002197 # DISTRIBUTED ATOMIC COUNTERS
Jon Halle1a3b752015-07-22 13:02:46 -07002198 # Partitioned counters
2199 main.step( "Increment then get a default counter on each node" )
Jon Hall85794ff2015-07-08 14:12:30 -07002200 pCounters = []
2201 threads = []
2202 addedPValues = []
Jon Halle1a3b752015-07-22 13:02:46 -07002203 for i in range( main.numCtrls ):
2204 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2205 name="counterAddAndGet-" + str( i ),
Jon Hall85794ff2015-07-08 14:12:30 -07002206 args=[ pCounterName ] )
2207 pCounterValue += 1
2208 addedPValues.append( pCounterValue )
2209 threads.append( t )
2210 t.start()
2211
2212 for t in threads:
2213 t.join()
2214 pCounters.append( t.result )
2215 # Check that counter incremented numController times
2216 pCounterResults = True
2217 for i in addedPValues:
2218 tmpResult = i in pCounters
2219 pCounterResults = pCounterResults and tmpResult
2220 if not tmpResult:
2221 main.log.error( str( i ) + " is not in partitioned "
2222 "counter incremented results" )
2223 utilities.assert_equals( expect=True,
2224 actual=pCounterResults,
2225 onpass="Default counter incremented",
2226 onfail="Error incrementing default" +
2227 " counter" )
2228
Jon Halle1a3b752015-07-22 13:02:46 -07002229 main.step( "Get then Increment a default counter on each node" )
2230 pCounters = []
2231 threads = []
2232 addedPValues = []
2233 for i in range( main.numCtrls ):
2234 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
2235 name="counterGetAndAdd-" + str( i ),
2236 args=[ pCounterName ] )
2237 addedPValues.append( pCounterValue )
2238 pCounterValue += 1
2239 threads.append( t )
2240 t.start()
2241
2242 for t in threads:
2243 t.join()
2244 pCounters.append( t.result )
2245 # Check that counter incremented numController times
2246 pCounterResults = True
2247 for i in addedPValues:
2248 tmpResult = i in pCounters
2249 pCounterResults = pCounterResults and tmpResult
2250 if not tmpResult:
2251 main.log.error( str( i ) + " is not in partitioned "
2252 "counter incremented results" )
2253 utilities.assert_equals( expect=True,
2254 actual=pCounterResults,
2255 onpass="Default counter incremented",
2256 onfail="Error incrementing default" +
2257 " counter" )
2258
2259 main.step( "Counters we added have the correct values" )
2260 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
2261 utilities.assert_equals( expect=main.TRUE,
2262 actual=incrementCheck,
2263 onpass="Added counters are correct",
2264 onfail="Added counters are incorrect" )
2265
2266 main.step( "Add -8 to then get a default counter on each node" )
2267 pCounters = []
2268 threads = []
2269 addedPValues = []
2270 for i in range( main.numCtrls ):
2271 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2272 name="counterIncrement-" + str( i ),
2273 args=[ pCounterName ],
2274 kwargs={ "delta": -8 } )
2275 pCounterValue += -8
2276 addedPValues.append( pCounterValue )
2277 threads.append( t )
2278 t.start()
2279
2280 for t in threads:
2281 t.join()
2282 pCounters.append( t.result )
2283 # Check that counter incremented numController times
2284 pCounterResults = True
2285 for i in addedPValues:
2286 tmpResult = i in pCounters
2287 pCounterResults = pCounterResults and tmpResult
2288 if not tmpResult:
2289 main.log.error( str( i ) + " is not in partitioned "
2290 "counter incremented results" )
2291 utilities.assert_equals( expect=True,
2292 actual=pCounterResults,
2293 onpass="Default counter incremented",
2294 onfail="Error incrementing default" +
2295 " counter" )
2296
2297 main.step( "Add 5 to then get a default counter on each node" )
2298 pCounters = []
2299 threads = []
2300 addedPValues = []
2301 for i in range( main.numCtrls ):
2302 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2303 name="counterIncrement-" + str( i ),
2304 args=[ pCounterName ],
2305 kwargs={ "delta": 5 } )
2306 pCounterValue += 5
2307 addedPValues.append( pCounterValue )
2308 threads.append( t )
2309 t.start()
2310
2311 for t in threads:
2312 t.join()
2313 pCounters.append( t.result )
2314 # Check that counter incremented numController times
2315 pCounterResults = True
2316 for i in addedPValues:
2317 tmpResult = i in pCounters
2318 pCounterResults = pCounterResults and tmpResult
2319 if not tmpResult:
2320 main.log.error( str( i ) + " is not in partitioned "
2321 "counter incremented results" )
2322 utilities.assert_equals( expect=True,
2323 actual=pCounterResults,
2324 onpass="Default counter incremented",
2325 onfail="Error incrementing default" +
2326 " counter" )
2327
2328 main.step( "Get then add 5 to a default counter on each node" )
2329 pCounters = []
2330 threads = []
2331 addedPValues = []
2332 for i in range( main.numCtrls ):
2333 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
2334 name="counterIncrement-" + str( i ),
2335 args=[ pCounterName ],
2336 kwargs={ "delta": 5 } )
2337 addedPValues.append( pCounterValue )
2338 pCounterValue += 5
2339 threads.append( t )
2340 t.start()
2341
2342 for t in threads:
2343 t.join()
2344 pCounters.append( t.result )
2345 # Check that counter incremented numController times
2346 pCounterResults = True
2347 for i in addedPValues:
2348 tmpResult = i in pCounters
2349 pCounterResults = pCounterResults and tmpResult
2350 if not tmpResult:
2351 main.log.error( str( i ) + " is not in partitioned "
2352 "counter incremented results" )
2353 utilities.assert_equals( expect=True,
2354 actual=pCounterResults,
2355 onpass="Default counter incremented",
2356 onfail="Error incrementing default" +
2357 " counter" )
2358
2359 main.step( "Counters we added have the correct values" )
2360 incrementCheck = main.Counters.counterCheck( pCounterName, pCounterValue )
2361 utilities.assert_equals( expect=main.TRUE,
2362 actual=incrementCheck,
2363 onpass="Added counters are correct",
2364 onfail="Added counters are incorrect" )
2365
2366 # In-Memory counters
2367 main.step( "Increment and get an in-memory counter on each node" )
Jon Hall85794ff2015-07-08 14:12:30 -07002368 iCounters = []
2369 addedIValues = []
2370 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002371 for i in range( main.numCtrls ):
2372 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002373 name="icounterIncrement-" + str( i ),
2374 args=[ iCounterName ],
2375 kwargs={ "inMemory": True } )
2376 iCounterValue += 1
2377 addedIValues.append( iCounterValue )
2378 threads.append( t )
2379 t.start()
2380
2381 for t in threads:
2382 t.join()
2383 iCounters.append( t.result )
2384 # Check that counter incremented numController times
2385 iCounterResults = True
2386 for i in addedIValues:
2387 tmpResult = i in iCounters
2388 iCounterResults = iCounterResults and tmpResult
2389 if not tmpResult:
2390 main.log.error( str( i ) + " is not in the in-memory "
2391 "counter incremented results" )
2392 utilities.assert_equals( expect=True,
2393 actual=iCounterResults,
Jon Halle1a3b752015-07-22 13:02:46 -07002394 onpass="In-memory counter incremented",
2395 onfail="Error incrementing in-memory" +
Jon Hall85794ff2015-07-08 14:12:30 -07002396 " counter" )
2397
Jon Halle1a3b752015-07-22 13:02:46 -07002398 main.step( "Get then Increment a in-memory counter on each node" )
2399 iCounters = []
2400 threads = []
2401 addedIValues = []
2402 for i in range( main.numCtrls ):
2403 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
2404 name="counterGetAndAdd-" + str( i ),
2405 args=[ iCounterName ],
2406 kwargs={ "inMemory": True } )
2407 addedIValues.append( iCounterValue )
2408 iCounterValue += 1
2409 threads.append( t )
2410 t.start()
2411
2412 for t in threads:
2413 t.join()
2414 iCounters.append( t.result )
2415 # Check that counter incremented numController times
2416 iCounterResults = True
2417 for i in addedIValues:
2418 tmpResult = i in iCounters
2419 iCounterResults = iCounterResults and tmpResult
2420 if not tmpResult:
2421 main.log.error( str( i ) + " is not in in-memory "
2422 "counter incremented results" )
2423 utilities.assert_equals( expect=True,
2424 actual=iCounterResults,
2425 onpass="In-memory counter incremented",
2426 onfail="Error incrementing in-memory" +
2427 " counter" )
2428
2429 main.step( "Counters we added have the correct values" )
2430 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
2431 utilities.assert_equals( expect=main.TRUE,
2432 actual=incrementCheck,
2433 onpass="Added counters are correct",
2434 onfail="Added counters are incorrect" )
2435
2436 main.step( "Add -8 to then get a in-memory counter on each node" )
2437 iCounters = []
2438 threads = []
2439 addedIValues = []
2440 for i in range( main.numCtrls ):
2441 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2442 name="counterIncrement-" + str( i ),
2443 args=[ iCounterName ],
2444 kwargs={ "delta": -8, "inMemory": True } )
2445 iCounterValue += -8
2446 addedIValues.append( iCounterValue )
2447 threads.append( t )
2448 t.start()
2449
2450 for t in threads:
2451 t.join()
2452 iCounters.append( t.result )
2453 # Check that counter incremented numController times
2454 iCounterResults = True
2455 for i in addedIValues:
2456 tmpResult = i in iCounters
2457 iCounterResults = iCounterResults and tmpResult
2458 if not tmpResult:
2459 main.log.error( str( i ) + " is not in in-memory "
2460 "counter incremented results" )
2461 utilities.assert_equals( expect=True,
2462 actual=pCounterResults,
2463 onpass="In-memory counter incremented",
2464 onfail="Error incrementing in-memory" +
2465 " counter" )
2466
2467 main.step( "Add 5 to then get a in-memory counter on each node" )
2468 iCounters = []
2469 threads = []
2470 addedIValues = []
2471 for i in range( main.numCtrls ):
2472 t = main.Thread( target=main.CLIs[i].counterTestAddAndGet,
2473 name="counterIncrement-" + str( i ),
2474 args=[ iCounterName ],
2475 kwargs={ "delta": 5, "inMemory": True } )
2476 iCounterValue += 5
2477 addedIValues.append( iCounterValue )
2478 threads.append( t )
2479 t.start()
2480
2481 for t in threads:
2482 t.join()
2483 iCounters.append( t.result )
2484 # Check that counter incremented numController times
2485 iCounterResults = True
2486 for i in addedIValues:
2487 tmpResult = i in iCounters
2488 iCounterResults = iCounterResults and tmpResult
2489 if not tmpResult:
2490 main.log.error( str( i ) + " is not in in-memory "
2491 "counter incremented results" )
2492 utilities.assert_equals( expect=True,
2493 actual=pCounterResults,
2494 onpass="In-memory counter incremented",
2495 onfail="Error incrementing in-memory" +
2496 " counter" )
2497
2498 main.step( "Get then add 5 to a in-memory counter on each node" )
2499 iCounters = []
2500 threads = []
2501 addedIValues = []
2502 for i in range( main.numCtrls ):
2503 t = main.Thread( target=main.CLIs[i].counterTestGetAndAdd,
2504 name="counterIncrement-" + str( i ),
2505 args=[ iCounterName ],
2506 kwargs={ "delta": 5, "inMemory": True } )
2507 addedIValues.append( iCounterValue )
2508 iCounterValue += 5
2509 threads.append( t )
2510 t.start()
2511
2512 for t in threads:
2513 t.join()
2514 iCounters.append( t.result )
2515 # Check that counter incremented numController times
2516 iCounterResults = True
2517 for i in addedIValues:
2518 tmpResult = i in iCounters
2519 iCounterResults = iCounterResults and tmpResult
2520 if not tmpResult:
2521 main.log.error( str( i ) + " is not in in-memory "
2522 "counter incremented results" )
2523 utilities.assert_equals( expect=True,
2524 actual=iCounterResults,
2525 onpass="In-memory counter incremented",
2526 onfail="Error incrementing in-memory" +
2527 " counter" )
2528
2529 main.step( "Counters we added have the correct values" )
2530 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
2531 utilities.assert_equals( expect=main.TRUE,
2532 actual=incrementCheck,
2533 onpass="Added counters are correct",
2534 onfail="Added counters are incorrect" )
2535
Jon Hall85794ff2015-07-08 14:12:30 -07002536 main.step( "Check counters are consistant across nodes" )
Jon Hall57b50432015-10-22 10:20:10 -07002537 onosCounters, consistentCounterResults = main.Counters.consistentCheck()
Jon Hall85794ff2015-07-08 14:12:30 -07002538 utilities.assert_equals( expect=main.TRUE,
2539 actual=consistentCounterResults,
2540 onpass="ONOS counters are consistent " +
2541 "across nodes",
2542 onfail="ONOS Counters are inconsistent " +
2543 "across nodes" )
2544
2545 main.step( "Counters we added have the correct values" )
Jon Halle1a3b752015-07-22 13:02:46 -07002546 incrementCheck = main.Counters.counterCheck( iCounterName, iCounterValue )
2547 incrementCheck = incrementCheck and \
2548 main.Counters.counterCheck( iCounterName, iCounterValue )
Jon Hall85794ff2015-07-08 14:12:30 -07002549 utilities.assert_equals( expect=main.TRUE,
Jon Halle1a3b752015-07-22 13:02:46 -07002550 actual=incrementCheck,
Jon Hall85794ff2015-07-08 14:12:30 -07002551 onpass="Added counters are correct",
2552 onfail="Added counters are incorrect" )
2553 # DISTRIBUTED SETS
2554 main.step( "Distributed Set get" )
2555 size = len( onosSet )
2556 getResponses = []
2557 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002558 for i in range( main.numCtrls ):
2559 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002560 name="setTestGet-" + str( i ),
2561 args=[ onosSetName ] )
2562 threads.append( t )
2563 t.start()
2564 for t in threads:
2565 t.join()
2566 getResponses.append( t.result )
2567
2568 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002569 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002570 if isinstance( getResponses[ i ], list):
2571 current = set( getResponses[ i ] )
2572 if len( current ) == len( getResponses[ i ] ):
2573 # no repeats
2574 if onosSet != current:
2575 main.log.error( "ONOS" + str( i + 1 ) +
2576 " has incorrect view" +
2577 " of set " + onosSetName + ":\n" +
2578 str( getResponses[ i ] ) )
2579 main.log.debug( "Expected: " + str( onosSet ) )
2580 main.log.debug( "Actual: " + str( current ) )
2581 getResults = main.FALSE
2582 else:
2583 # error, set is not a set
2584 main.log.error( "ONOS" + str( i + 1 ) +
2585 " has repeat elements in" +
2586 " set " + onosSetName + ":\n" +
2587 str( getResponses[ i ] ) )
2588 getResults = main.FALSE
2589 elif getResponses[ i ] == main.ERROR:
2590 getResults = main.FALSE
2591 utilities.assert_equals( expect=main.TRUE,
2592 actual=getResults,
2593 onpass="Set elements are correct",
2594 onfail="Set elements are incorrect" )
2595
2596 main.step( "Distributed Set size" )
2597 sizeResponses = []
2598 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002599 for i in range( main.numCtrls ):
2600 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002601 name="setTestSize-" + str( i ),
2602 args=[ onosSetName ] )
2603 threads.append( t )
2604 t.start()
2605 for t in threads:
2606 t.join()
2607 sizeResponses.append( t.result )
2608
2609 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002610 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002611 if size != sizeResponses[ i ]:
2612 sizeResults = main.FALSE
2613 main.log.error( "ONOS" + str( i + 1 ) +
2614 " expected a size of " + str( size ) +
2615 " for set " + onosSetName +
2616 " but got " + str( sizeResponses[ i ] ) )
2617 utilities.assert_equals( expect=main.TRUE,
2618 actual=sizeResults,
2619 onpass="Set sizes are correct",
2620 onfail="Set sizes are incorrect" )
2621
2622 main.step( "Distributed Set add()" )
2623 onosSet.add( addValue )
2624 addResponses = []
2625 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002626 for i in range( main.numCtrls ):
2627 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07002628 name="setTestAdd-" + str( i ),
2629 args=[ onosSetName, addValue ] )
2630 threads.append( t )
2631 t.start()
2632 for t in threads:
2633 t.join()
2634 addResponses.append( t.result )
2635
2636 # main.TRUE = successfully changed the set
2637 # main.FALSE = action resulted in no change in set
2638 # main.ERROR - Some error in executing the function
2639 addResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002640 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002641 if addResponses[ i ] == main.TRUE:
2642 # All is well
2643 pass
2644 elif addResponses[ i ] == main.FALSE:
2645 # Already in set, probably fine
2646 pass
2647 elif addResponses[ i ] == main.ERROR:
2648 # Error in execution
2649 addResults = main.FALSE
2650 else:
2651 # unexpected result
2652 addResults = main.FALSE
2653 if addResults != main.TRUE:
2654 main.log.error( "Error executing set add" )
2655
2656 # Check if set is still correct
2657 size = len( onosSet )
2658 getResponses = []
2659 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002660 for i in range( main.numCtrls ):
2661 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002662 name="setTestGet-" + str( i ),
2663 args=[ onosSetName ] )
2664 threads.append( t )
2665 t.start()
2666 for t in threads:
2667 t.join()
2668 getResponses.append( t.result )
2669 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002670 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002671 if isinstance( getResponses[ i ], list):
2672 current = set( getResponses[ i ] )
2673 if len( current ) == len( getResponses[ i ] ):
2674 # no repeats
2675 if onosSet != current:
2676 main.log.error( "ONOS" + str( i + 1 ) +
2677 " has incorrect view" +
2678 " of set " + onosSetName + ":\n" +
2679 str( getResponses[ i ] ) )
2680 main.log.debug( "Expected: " + str( onosSet ) )
2681 main.log.debug( "Actual: " + str( current ) )
2682 getResults = main.FALSE
2683 else:
2684 # error, set is not a set
2685 main.log.error( "ONOS" + str( i + 1 ) +
2686 " has repeat elements in" +
2687 " set " + onosSetName + ":\n" +
2688 str( getResponses[ i ] ) )
2689 getResults = main.FALSE
2690 elif getResponses[ i ] == main.ERROR:
2691 getResults = main.FALSE
2692 sizeResponses = []
2693 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002694 for i in range( main.numCtrls ):
2695 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002696 name="setTestSize-" + str( i ),
2697 args=[ onosSetName ] )
2698 threads.append( t )
2699 t.start()
2700 for t in threads:
2701 t.join()
2702 sizeResponses.append( t.result )
2703 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002704 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002705 if size != sizeResponses[ i ]:
2706 sizeResults = main.FALSE
2707 main.log.error( "ONOS" + str( i + 1 ) +
2708 " expected a size of " + str( size ) +
2709 " for set " + onosSetName +
2710 " but got " + str( sizeResponses[ i ] ) )
2711 addResults = addResults and getResults and sizeResults
2712 utilities.assert_equals( expect=main.TRUE,
2713 actual=addResults,
2714 onpass="Set add correct",
2715 onfail="Set add was incorrect" )
2716
2717 main.step( "Distributed Set addAll()" )
2718 onosSet.update( addAllValue.split() )
2719 addResponses = []
2720 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002721 for i in range( main.numCtrls ):
2722 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07002723 name="setTestAddAll-" + str( i ),
2724 args=[ onosSetName, addAllValue ] )
2725 threads.append( t )
2726 t.start()
2727 for t in threads:
2728 t.join()
2729 addResponses.append( t.result )
2730
2731 # main.TRUE = successfully changed the set
2732 # main.FALSE = action resulted in no change in set
2733 # main.ERROR - Some error in executing the function
2734 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002735 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002736 if addResponses[ i ] == main.TRUE:
2737 # All is well
2738 pass
2739 elif addResponses[ i ] == main.FALSE:
2740 # Already in set, probably fine
2741 pass
2742 elif addResponses[ i ] == main.ERROR:
2743 # Error in execution
2744 addAllResults = main.FALSE
2745 else:
2746 # unexpected result
2747 addAllResults = main.FALSE
2748 if addAllResults != main.TRUE:
2749 main.log.error( "Error executing set addAll" )
2750
2751 # Check if set is still correct
2752 size = len( onosSet )
2753 getResponses = []
2754 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002755 for i in range( main.numCtrls ):
2756 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002757 name="setTestGet-" + str( i ),
2758 args=[ onosSetName ] )
2759 threads.append( t )
2760 t.start()
2761 for t in threads:
2762 t.join()
2763 getResponses.append( t.result )
2764 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002765 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002766 if isinstance( getResponses[ i ], list):
2767 current = set( getResponses[ i ] )
2768 if len( current ) == len( getResponses[ i ] ):
2769 # no repeats
2770 if onosSet != current:
2771 main.log.error( "ONOS" + str( i + 1 ) +
2772 " has incorrect view" +
2773 " of set " + onosSetName + ":\n" +
2774 str( getResponses[ i ] ) )
2775 main.log.debug( "Expected: " + str( onosSet ) )
2776 main.log.debug( "Actual: " + str( current ) )
2777 getResults = main.FALSE
2778 else:
2779 # error, set is not a set
2780 main.log.error( "ONOS" + str( i + 1 ) +
2781 " has repeat elements in" +
2782 " set " + onosSetName + ":\n" +
2783 str( getResponses[ i ] ) )
2784 getResults = main.FALSE
2785 elif getResponses[ i ] == main.ERROR:
2786 getResults = main.FALSE
2787 sizeResponses = []
2788 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002789 for i in range( main.numCtrls ):
2790 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002791 name="setTestSize-" + str( i ),
2792 args=[ onosSetName ] )
2793 threads.append( t )
2794 t.start()
2795 for t in threads:
2796 t.join()
2797 sizeResponses.append( t.result )
2798 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002799 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002800 if size != sizeResponses[ i ]:
2801 sizeResults = main.FALSE
2802 main.log.error( "ONOS" + str( i + 1 ) +
2803 " expected a size of " + str( size ) +
2804 " for set " + onosSetName +
2805 " but got " + str( sizeResponses[ i ] ) )
2806 addAllResults = addAllResults and getResults and sizeResults
2807 utilities.assert_equals( expect=main.TRUE,
2808 actual=addAllResults,
2809 onpass="Set addAll correct",
2810 onfail="Set addAll was incorrect" )
2811
2812 main.step( "Distributed Set contains()" )
2813 containsResponses = []
2814 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002815 for i in range( main.numCtrls ):
2816 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002817 name="setContains-" + str( i ),
2818 args=[ onosSetName ],
2819 kwargs={ "values": addValue } )
2820 threads.append( t )
2821 t.start()
2822 for t in threads:
2823 t.join()
2824 # NOTE: This is the tuple
2825 containsResponses.append( t.result )
2826
2827 containsResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002828 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002829 if containsResponses[ i ] == main.ERROR:
2830 containsResults = main.FALSE
2831 else:
2832 containsResults = containsResults and\
2833 containsResponses[ i ][ 1 ]
2834 utilities.assert_equals( expect=main.TRUE,
2835 actual=containsResults,
2836 onpass="Set contains is functional",
2837 onfail="Set contains failed" )
2838
2839 main.step( "Distributed Set containsAll()" )
2840 containsAllResponses = []
2841 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002842 for i in range( main.numCtrls ):
2843 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002844 name="setContainsAll-" + str( i ),
2845 args=[ onosSetName ],
2846 kwargs={ "values": addAllValue } )
2847 threads.append( t )
2848 t.start()
2849 for t in threads:
2850 t.join()
2851 # NOTE: This is the tuple
2852 containsAllResponses.append( t.result )
2853
2854 containsAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002855 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002856 if containsResponses[ i ] == main.ERROR:
2857 containsResults = main.FALSE
2858 else:
2859 containsResults = containsResults and\
2860 containsResponses[ i ][ 1 ]
2861 utilities.assert_equals( expect=main.TRUE,
2862 actual=containsAllResults,
2863 onpass="Set containsAll is functional",
2864 onfail="Set containsAll failed" )
2865
2866 main.step( "Distributed Set remove()" )
2867 onosSet.remove( addValue )
2868 removeResponses = []
2869 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002870 for i in range( main.numCtrls ):
2871 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07002872 name="setTestRemove-" + str( i ),
2873 args=[ onosSetName, addValue ] )
2874 threads.append( t )
2875 t.start()
2876 for t in threads:
2877 t.join()
2878 removeResponses.append( t.result )
2879
2880 # main.TRUE = successfully changed the set
2881 # main.FALSE = action resulted in no change in set
2882 # main.ERROR - Some error in executing the function
2883 removeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002884 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002885 if removeResponses[ i ] == main.TRUE:
2886 # All is well
2887 pass
2888 elif removeResponses[ i ] == main.FALSE:
2889 # not in set, probably fine
2890 pass
2891 elif removeResponses[ i ] == main.ERROR:
2892 # Error in execution
2893 removeResults = main.FALSE
2894 else:
2895 # unexpected result
2896 removeResults = main.FALSE
2897 if removeResults != main.TRUE:
2898 main.log.error( "Error executing set remove" )
2899
2900 # Check if set is still correct
2901 size = len( onosSet )
2902 getResponses = []
2903 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002904 for i in range( main.numCtrls ):
2905 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07002906 name="setTestGet-" + str( i ),
2907 args=[ onosSetName ] )
2908 threads.append( t )
2909 t.start()
2910 for t in threads:
2911 t.join()
2912 getResponses.append( t.result )
2913 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002914 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002915 if isinstance( getResponses[ i ], list):
2916 current = set( getResponses[ i ] )
2917 if len( current ) == len( getResponses[ i ] ):
2918 # no repeats
2919 if onosSet != current:
2920 main.log.error( "ONOS" + str( i + 1 ) +
2921 " has incorrect view" +
2922 " of set " + onosSetName + ":\n" +
2923 str( getResponses[ i ] ) )
2924 main.log.debug( "Expected: " + str( onosSet ) )
2925 main.log.debug( "Actual: " + str( current ) )
2926 getResults = main.FALSE
2927 else:
2928 # error, set is not a set
2929 main.log.error( "ONOS" + str( i + 1 ) +
2930 " has repeat elements in" +
2931 " set " + onosSetName + ":\n" +
2932 str( getResponses[ i ] ) )
2933 getResults = main.FALSE
2934 elif getResponses[ i ] == main.ERROR:
2935 getResults = main.FALSE
2936 sizeResponses = []
2937 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07002938 for i in range( main.numCtrls ):
2939 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07002940 name="setTestSize-" + str( i ),
2941 args=[ onosSetName ] )
2942 threads.append( t )
2943 t.start()
2944 for t in threads:
2945 t.join()
2946 sizeResponses.append( t.result )
2947 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002948 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002949 if size != sizeResponses[ i ]:
2950 sizeResults = main.FALSE
2951 main.log.error( "ONOS" + str( i + 1 ) +
2952 " expected a size of " + str( size ) +
2953 " for set " + onosSetName +
2954 " but got " + str( sizeResponses[ i ] ) )
2955 removeResults = removeResults and getResults and sizeResults
2956 utilities.assert_equals( expect=main.TRUE,
2957 actual=removeResults,
2958 onpass="Set remove correct",
2959 onfail="Set remove was incorrect" )
2960
2961 main.step( "Distributed Set removeAll()" )
2962 onosSet.difference_update( addAllValue.split() )
2963 removeAllResponses = []
2964 threads = []
2965 try:
Jon Halle1a3b752015-07-22 13:02:46 -07002966 for i in range( main.numCtrls ):
2967 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07002968 name="setTestRemoveAll-" + str( i ),
2969 args=[ onosSetName, addAllValue ] )
2970 threads.append( t )
2971 t.start()
2972 for t in threads:
2973 t.join()
2974 removeAllResponses.append( t.result )
2975 except Exception, e:
2976 main.log.exception(e)
2977
2978 # main.TRUE = successfully changed the set
2979 # main.FALSE = action resulted in no change in set
2980 # main.ERROR - Some error in executing the function
2981 removeAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07002982 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07002983 if removeAllResponses[ i ] == main.TRUE:
2984 # All is well
2985 pass
2986 elif removeAllResponses[ i ] == main.FALSE:
2987 # not in set, probably fine
2988 pass
2989 elif removeAllResponses[ i ] == main.ERROR:
2990 # Error in execution
2991 removeAllResults = main.FALSE
2992 else:
2993 # unexpected result
2994 removeAllResults = main.FALSE
2995 if removeAllResults != main.TRUE:
2996 main.log.error( "Error executing set removeAll" )
2997
2998 # Check if set is still correct
2999 size = len( onosSet )
3000 getResponses = []
3001 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003002 for i in range( main.numCtrls ):
3003 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003004 name="setTestGet-" + str( i ),
3005 args=[ onosSetName ] )
3006 threads.append( t )
3007 t.start()
3008 for t in threads:
3009 t.join()
3010 getResponses.append( t.result )
3011 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003012 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003013 if isinstance( getResponses[ i ], list):
3014 current = set( getResponses[ i ] )
3015 if len( current ) == len( getResponses[ i ] ):
3016 # no repeats
3017 if onosSet != current:
3018 main.log.error( "ONOS" + str( i + 1 ) +
3019 " has incorrect view" +
3020 " of set " + onosSetName + ":\n" +
3021 str( getResponses[ i ] ) )
3022 main.log.debug( "Expected: " + str( onosSet ) )
3023 main.log.debug( "Actual: " + str( current ) )
3024 getResults = main.FALSE
3025 else:
3026 # error, set is not a set
3027 main.log.error( "ONOS" + str( i + 1 ) +
3028 " has repeat elements in" +
3029 " set " + onosSetName + ":\n" +
3030 str( getResponses[ i ] ) )
3031 getResults = main.FALSE
3032 elif getResponses[ i ] == main.ERROR:
3033 getResults = main.FALSE
3034 sizeResponses = []
3035 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003036 for i in range( main.numCtrls ):
3037 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003038 name="setTestSize-" + str( i ),
3039 args=[ onosSetName ] )
3040 threads.append( t )
3041 t.start()
3042 for t in threads:
3043 t.join()
3044 sizeResponses.append( t.result )
3045 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003046 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003047 if size != sizeResponses[ i ]:
3048 sizeResults = main.FALSE
3049 main.log.error( "ONOS" + str( i + 1 ) +
3050 " expected a size of " + str( size ) +
3051 " for set " + onosSetName +
3052 " but got " + str( sizeResponses[ i ] ) )
3053 removeAllResults = removeAllResults and getResults and sizeResults
3054 utilities.assert_equals( expect=main.TRUE,
3055 actual=removeAllResults,
3056 onpass="Set removeAll correct",
3057 onfail="Set removeAll was incorrect" )
3058
3059 main.step( "Distributed Set addAll()" )
3060 onosSet.update( addAllValue.split() )
3061 addResponses = []
3062 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003063 for i in range( main.numCtrls ):
3064 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07003065 name="setTestAddAll-" + str( i ),
3066 args=[ onosSetName, addAllValue ] )
3067 threads.append( t )
3068 t.start()
3069 for t in threads:
3070 t.join()
3071 addResponses.append( t.result )
3072
3073 # main.TRUE = successfully changed the set
3074 # main.FALSE = action resulted in no change in set
3075 # main.ERROR - Some error in executing the function
3076 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003077 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003078 if addResponses[ i ] == main.TRUE:
3079 # All is well
3080 pass
3081 elif addResponses[ i ] == main.FALSE:
3082 # Already in set, probably fine
3083 pass
3084 elif addResponses[ i ] == main.ERROR:
3085 # Error in execution
3086 addAllResults = main.FALSE
3087 else:
3088 # unexpected result
3089 addAllResults = main.FALSE
3090 if addAllResults != main.TRUE:
3091 main.log.error( "Error executing set addAll" )
3092
3093 # Check if set is still correct
3094 size = len( onosSet )
3095 getResponses = []
3096 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003097 for i in range( main.numCtrls ):
3098 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003099 name="setTestGet-" + str( i ),
3100 args=[ onosSetName ] )
3101 threads.append( t )
3102 t.start()
3103 for t in threads:
3104 t.join()
3105 getResponses.append( t.result )
3106 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003107 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003108 if isinstance( getResponses[ i ], list):
3109 current = set( getResponses[ i ] )
3110 if len( current ) == len( getResponses[ i ] ):
3111 # no repeats
3112 if onosSet != current:
3113 main.log.error( "ONOS" + str( i + 1 ) +
3114 " has incorrect view" +
3115 " of set " + onosSetName + ":\n" +
3116 str( getResponses[ i ] ) )
3117 main.log.debug( "Expected: " + str( onosSet ) )
3118 main.log.debug( "Actual: " + str( current ) )
3119 getResults = main.FALSE
3120 else:
3121 # error, set is not a set
3122 main.log.error( "ONOS" + str( i + 1 ) +
3123 " has repeat elements in" +
3124 " set " + onosSetName + ":\n" +
3125 str( getResponses[ i ] ) )
3126 getResults = main.FALSE
3127 elif getResponses[ i ] == main.ERROR:
3128 getResults = main.FALSE
3129 sizeResponses = []
3130 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003131 for i in range( main.numCtrls ):
3132 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003133 name="setTestSize-" + str( i ),
3134 args=[ onosSetName ] )
3135 threads.append( t )
3136 t.start()
3137 for t in threads:
3138 t.join()
3139 sizeResponses.append( t.result )
3140 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003141 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003142 if size != sizeResponses[ i ]:
3143 sizeResults = main.FALSE
3144 main.log.error( "ONOS" + str( i + 1 ) +
3145 " expected a size of " + str( size ) +
3146 " for set " + onosSetName +
3147 " but got " + str( sizeResponses[ i ] ) )
3148 addAllResults = addAllResults and getResults and sizeResults
3149 utilities.assert_equals( expect=main.TRUE,
3150 actual=addAllResults,
3151 onpass="Set addAll correct",
3152 onfail="Set addAll was incorrect" )
3153
3154 main.step( "Distributed Set clear()" )
3155 onosSet.clear()
3156 clearResponses = []
3157 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003158 for i in range( main.numCtrls ):
3159 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07003160 name="setTestClear-" + str( i ),
3161 args=[ onosSetName, " "], # Values doesn't matter
3162 kwargs={ "clear": True } )
3163 threads.append( t )
3164 t.start()
3165 for t in threads:
3166 t.join()
3167 clearResponses.append( t.result )
3168
3169 # main.TRUE = successfully changed the set
3170 # main.FALSE = action resulted in no change in set
3171 # main.ERROR - Some error in executing the function
3172 clearResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003173 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003174 if clearResponses[ i ] == main.TRUE:
3175 # All is well
3176 pass
3177 elif clearResponses[ i ] == main.FALSE:
3178 # Nothing set, probably fine
3179 pass
3180 elif clearResponses[ i ] == main.ERROR:
3181 # Error in execution
3182 clearResults = main.FALSE
3183 else:
3184 # unexpected result
3185 clearResults = main.FALSE
3186 if clearResults != main.TRUE:
3187 main.log.error( "Error executing set clear" )
3188
3189 # Check if set is still correct
3190 size = len( onosSet )
3191 getResponses = []
3192 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003193 for i in range( main.numCtrls ):
3194 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003195 name="setTestGet-" + str( i ),
3196 args=[ onosSetName ] )
3197 threads.append( t )
3198 t.start()
3199 for t in threads:
3200 t.join()
3201 getResponses.append( t.result )
3202 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003203 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003204 if isinstance( getResponses[ i ], list):
3205 current = set( getResponses[ i ] )
3206 if len( current ) == len( getResponses[ i ] ):
3207 # no repeats
3208 if onosSet != current:
3209 main.log.error( "ONOS" + str( i + 1 ) +
3210 " has incorrect view" +
3211 " of set " + onosSetName + ":\n" +
3212 str( getResponses[ i ] ) )
3213 main.log.debug( "Expected: " + str( onosSet ) )
3214 main.log.debug( "Actual: " + str( current ) )
3215 getResults = main.FALSE
3216 else:
3217 # error, set is not a set
3218 main.log.error( "ONOS" + str( i + 1 ) +
3219 " has repeat elements in" +
3220 " set " + onosSetName + ":\n" +
3221 str( getResponses[ i ] ) )
3222 getResults = main.FALSE
3223 elif getResponses[ i ] == main.ERROR:
3224 getResults = main.FALSE
3225 sizeResponses = []
3226 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003227 for i in range( main.numCtrls ):
3228 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003229 name="setTestSize-" + str( i ),
3230 args=[ onosSetName ] )
3231 threads.append( t )
3232 t.start()
3233 for t in threads:
3234 t.join()
3235 sizeResponses.append( t.result )
3236 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003237 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003238 if size != sizeResponses[ i ]:
3239 sizeResults = main.FALSE
3240 main.log.error( "ONOS" + str( i + 1 ) +
3241 " expected a size of " + str( size ) +
3242 " for set " + onosSetName +
3243 " but got " + str( sizeResponses[ i ] ) )
3244 clearResults = clearResults and getResults and sizeResults
3245 utilities.assert_equals( expect=main.TRUE,
3246 actual=clearResults,
3247 onpass="Set clear correct",
3248 onfail="Set clear was incorrect" )
3249
3250 main.step( "Distributed Set addAll()" )
3251 onosSet.update( addAllValue.split() )
3252 addResponses = []
3253 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003254 for i in range( main.numCtrls ):
3255 t = main.Thread( target=main.CLIs[i].setTestAdd,
Jon Hall85794ff2015-07-08 14:12:30 -07003256 name="setTestAddAll-" + str( i ),
3257 args=[ onosSetName, addAllValue ] )
3258 threads.append( t )
3259 t.start()
3260 for t in threads:
3261 t.join()
3262 addResponses.append( t.result )
3263
3264 # main.TRUE = successfully changed the set
3265 # main.FALSE = action resulted in no change in set
3266 # main.ERROR - Some error in executing the function
3267 addAllResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003268 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003269 if addResponses[ i ] == main.TRUE:
3270 # All is well
3271 pass
3272 elif addResponses[ i ] == main.FALSE:
3273 # Already in set, probably fine
3274 pass
3275 elif addResponses[ i ] == main.ERROR:
3276 # Error in execution
3277 addAllResults = main.FALSE
3278 else:
3279 # unexpected result
3280 addAllResults = main.FALSE
3281 if addAllResults != main.TRUE:
3282 main.log.error( "Error executing set addAll" )
3283
3284 # Check if set is still correct
3285 size = len( onosSet )
3286 getResponses = []
3287 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003288 for i in range( main.numCtrls ):
3289 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003290 name="setTestGet-" + str( i ),
3291 args=[ onosSetName ] )
3292 threads.append( t )
3293 t.start()
3294 for t in threads:
3295 t.join()
3296 getResponses.append( t.result )
3297 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003298 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003299 if isinstance( getResponses[ i ], list):
3300 current = set( getResponses[ i ] )
3301 if len( current ) == len( getResponses[ i ] ):
3302 # no repeats
3303 if onosSet != current:
3304 main.log.error( "ONOS" + str( i + 1 ) +
3305 " has incorrect view" +
3306 " of set " + onosSetName + ":\n" +
3307 str( getResponses[ i ] ) )
3308 main.log.debug( "Expected: " + str( onosSet ) )
3309 main.log.debug( "Actual: " + str( current ) )
3310 getResults = main.FALSE
3311 else:
3312 # error, set is not a set
3313 main.log.error( "ONOS" + str( i + 1 ) +
3314 " has repeat elements in" +
3315 " set " + onosSetName + ":\n" +
3316 str( getResponses[ i ] ) )
3317 getResults = main.FALSE
3318 elif getResponses[ i ] == main.ERROR:
3319 getResults = main.FALSE
3320 sizeResponses = []
3321 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003322 for i in range( main.numCtrls ):
3323 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003324 name="setTestSize-" + str( i ),
3325 args=[ onosSetName ] )
3326 threads.append( t )
3327 t.start()
3328 for t in threads:
3329 t.join()
3330 sizeResponses.append( t.result )
3331 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003332 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003333 if size != sizeResponses[ i ]:
3334 sizeResults = main.FALSE
3335 main.log.error( "ONOS" + str( i + 1 ) +
3336 " expected a size of " + str( size ) +
3337 " for set " + onosSetName +
3338 " but got " + str( sizeResponses[ i ] ) )
3339 addAllResults = addAllResults and getResults and sizeResults
3340 utilities.assert_equals( expect=main.TRUE,
3341 actual=addAllResults,
3342 onpass="Set addAll correct",
3343 onfail="Set addAll was incorrect" )
3344
3345 main.step( "Distributed Set retain()" )
3346 onosSet.intersection_update( retainValue.split() )
3347 retainResponses = []
3348 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003349 for i in range( main.numCtrls ):
3350 t = main.Thread( target=main.CLIs[i].setTestRemove,
Jon Hall85794ff2015-07-08 14:12:30 -07003351 name="setTestRetain-" + str( i ),
3352 args=[ onosSetName, retainValue ],
3353 kwargs={ "retain": True } )
3354 threads.append( t )
3355 t.start()
3356 for t in threads:
3357 t.join()
3358 retainResponses.append( t.result )
3359
3360 # main.TRUE = successfully changed the set
3361 # main.FALSE = action resulted in no change in set
3362 # main.ERROR - Some error in executing the function
3363 retainResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003364 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003365 if retainResponses[ i ] == main.TRUE:
3366 # All is well
3367 pass
3368 elif retainResponses[ i ] == main.FALSE:
3369 # Already in set, probably fine
3370 pass
3371 elif retainResponses[ i ] == main.ERROR:
3372 # Error in execution
3373 retainResults = main.FALSE
3374 else:
3375 # unexpected result
3376 retainResults = main.FALSE
3377 if retainResults != main.TRUE:
3378 main.log.error( "Error executing set retain" )
3379
3380 # Check if set is still correct
3381 size = len( onosSet )
3382 getResponses = []
3383 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003384 for i in range( main.numCtrls ):
3385 t = main.Thread( target=main.CLIs[i].setTestGet,
Jon Hall85794ff2015-07-08 14:12:30 -07003386 name="setTestGet-" + str( i ),
3387 args=[ onosSetName ] )
3388 threads.append( t )
3389 t.start()
3390 for t in threads:
3391 t.join()
3392 getResponses.append( t.result )
3393 getResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003394 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003395 if isinstance( getResponses[ i ], list):
3396 current = set( getResponses[ i ] )
3397 if len( current ) == len( getResponses[ i ] ):
3398 # no repeats
3399 if onosSet != current:
3400 main.log.error( "ONOS" + str( i + 1 ) +
3401 " has incorrect view" +
3402 " of set " + onosSetName + ":\n" +
3403 str( getResponses[ i ] ) )
3404 main.log.debug( "Expected: " + str( onosSet ) )
3405 main.log.debug( "Actual: " + str( current ) )
3406 getResults = main.FALSE
3407 else:
3408 # error, set is not a set
3409 main.log.error( "ONOS" + str( i + 1 ) +
3410 " has repeat elements in" +
3411 " set " + onosSetName + ":\n" +
3412 str( getResponses[ i ] ) )
3413 getResults = main.FALSE
3414 elif getResponses[ i ] == main.ERROR:
3415 getResults = main.FALSE
3416 sizeResponses = []
3417 threads = []
Jon Halle1a3b752015-07-22 13:02:46 -07003418 for i in range( main.numCtrls ):
3419 t = main.Thread( target=main.CLIs[i].setTestSize,
Jon Hall85794ff2015-07-08 14:12:30 -07003420 name="setTestSize-" + str( i ),
3421 args=[ onosSetName ] )
3422 threads.append( t )
3423 t.start()
3424 for t in threads:
3425 t.join()
3426 sizeResponses.append( t.result )
3427 sizeResults = main.TRUE
Jon Halle1a3b752015-07-22 13:02:46 -07003428 for i in range( main.numCtrls ):
Jon Hall85794ff2015-07-08 14:12:30 -07003429 if size != sizeResponses[ i ]:
3430 sizeResults = main.FALSE
3431 main.log.error( "ONOS" + str( i + 1 ) +
3432 " expected a size of " +
3433 str( size ) + " for set " + onosSetName +
3434 " but got " + str( sizeResponses[ i ] ) )
3435 retainResults = retainResults and getResults and sizeResults
3436 utilities.assert_equals( expect=main.TRUE,
3437 actual=retainResults,
3438 onpass="Set retain correct",
3439 onfail="Set retain was incorrect" )
3440
Jon Hall2a5002c2015-08-21 16:49:11 -07003441 # Transactional maps
3442 main.step( "Partitioned Transactional maps put" )
3443 tMapValue = "Testing"
3444 numKeys = 100
3445 putResult = True
3446 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue )
3447 if len( putResponses ) == 100:
3448 for i in putResponses:
3449 if putResponses[ i ][ 'value' ] != tMapValue:
3450 putResult = False
3451 else:
3452 putResult = False
3453 if not putResult:
3454 main.log.debug( "Put response values: " + str( putResponses ) )
3455 utilities.assert_equals( expect=True,
3456 actual=putResult,
3457 onpass="Partitioned Transactional Map put successful",
3458 onfail="Partitioned Transactional Map put values are incorrect" )
3459
3460 main.step( "Partitioned Transactional maps get" )
3461 getCheck = True
3462 for n in range( 1, numKeys + 1 ):
3463 getResponses = []
3464 threads = []
3465 valueCheck = True
3466 for i in range( main.numCtrls ):
3467 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
3468 name="TMap-get-" + str( i ),
3469 args=[ "Key" + str ( n ) ] )
3470 threads.append( t )
3471 t.start()
3472 for t in threads:
3473 t.join()
3474 getResponses.append( t.result )
3475 for node in getResponses:
3476 if node != tMapValue:
3477 valueCheck = False
3478 if not valueCheck:
3479 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
3480 main.log.warn( getResponses )
3481 getCheck = getCheck and valueCheck
3482 utilities.assert_equals( expect=True,
3483 actual=getCheck,
3484 onpass="Partitioned Transactional Map get values were correct",
3485 onfail="Partitioned Transactional Map values incorrect" )
3486
3487 main.step( "In-memory Transactional maps put" )
3488 tMapValue = "Testing"
3489 numKeys = 100
3490 putResult = True
3491 putResponses = main.CLIs[ 0 ].transactionalMapPut( numKeys, tMapValue, inMemory=True )
3492 if len( putResponses ) == 100:
3493 for i in putResponses:
3494 if putResponses[ i ][ 'value' ] != tMapValue:
3495 putResult = False
3496 else:
3497 putResult = False
3498 if not putResult:
3499 main.log.debug( "Put response values: " + str( putResponses ) )
3500 utilities.assert_equals( expect=True,
3501 actual=putResult,
3502 onpass="In-Memory Transactional Map put successful",
3503 onfail="In-Memory Transactional Map put values are incorrect" )
3504
3505 main.step( "In-Memory Transactional maps get" )
3506 getCheck = True
3507 for n in range( 1, numKeys + 1 ):
3508 getResponses = []
3509 threads = []
3510 valueCheck = True
3511 for i in range( main.numCtrls ):
3512 t = main.Thread( target=main.CLIs[i].transactionalMapGet,
3513 name="TMap-get-" + str( i ),
3514 args=[ "Key" + str ( n ) ],
3515 kwargs={ "inMemory": True } )
3516 threads.append( t )
3517 t.start()
3518 for t in threads:
3519 t.join()
3520 getResponses.append( t.result )
3521 for node in getResponses:
3522 if node != tMapValue:
3523 valueCheck = False
3524 if not valueCheck:
3525 main.log.warn( "Values for key 'Key" + str( n ) + "' do not match:" )
3526 main.log.warn( getResponses )
3527 getCheck = getCheck and valueCheck
3528 utilities.assert_equals( expect=True,
3529 actual=getCheck,
3530 onpass="In-Memory Transactional Map get values were correct",
3531 onfail="In-Memory Transactional Map values incorrect" )