blob: 8646c3355eec84d1f7a281bcc15d1005ec0d806f [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 """
50 main.log.info( "ONOS Single node cluster restart " +
51 "HA test - initialization" )
52 main.case( "Setting up test environment" )
Jon Hall783bbf92015-07-23 14:33:19 -070053 main.caseExplanation = "Setup the test environment including " +\
Jon Hall85794ff2015-07-08 14:12:30 -070054 "installing ONOS, starting Mininet and ONOS" +\
55 "cli sessions."
56 # TODO: save all the timers and output them for plotting
57
58 # load some variables from the params file
59 PULLCODE = False
60 if main.params[ 'Git' ] == 'True':
61 PULLCODE = True
62 gitBranch = main.params[ 'branch' ]
63 cellName = main.params[ 'ENV' ][ 'cellName' ]
64
65 # set global variables
66 global numControllers
67 numControllers = int( main.params[ 'num_controllers' ] )
Jon Hall5cf14d52015-07-16 12:15:19 -070068 if main.ONOSbench.maxNodes:
69 if main.ONOSbench.maxNodes < numControllers:
70 numControllers = int( main.ONOSbench.maxNodes )
Jon Hall85794ff2015-07-08 14:12:30 -070071
72 global CLIs
73 CLIs = []
74 global nodes
75 nodes = []
Jon Hall5cf14d52015-07-16 12:15:19 -070076 ipList = []
77 for i in range( 1, int( main.ONOSbench.maxNodes ) + 1 ):
78 try:
79 CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
80 nodes.append( getattr( main, 'ONOS' + str( i ) ) )
81 ipList.append( nodes[ -1 ].ip_address )
82 except AttributeError:
83 break
Jon Hall85794ff2015-07-08 14:12:30 -070084
Jon Hall5cf14d52015-07-16 12:15:19 -070085 main.step( "Create cell file" )
86 cellAppString = main.params[ 'ENV' ][ 'appString' ]
87 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, cellName,
88 main.Mininet1.ip_address,
89 cellAppString, ipList )
Jon Hall85794ff2015-07-08 14:12:30 -070090 main.step( "Applying cell variable to environment" )
91 cellResult = main.ONOSbench.setCell( cellName )
92 verifyResult = main.ONOSbench.verifyCell()
93
94 # FIXME:this is short term fix
95 main.log.info( "Removing raft logs" )
96 main.ONOSbench.onosRemoveRaftLogs()
97
98 main.log.info( "Uninstalling ONOS" )
99 for node in nodes:
100 main.ONOSbench.onosUninstall( node.ip_address )
101
102 # Make sure ONOS is DEAD
103 main.log.info( "Killing any ONOS processes" )
104 killResults = main.TRUE
105 for node in nodes:
106 killed = main.ONOSbench.onosKill( node.ip_address )
107 killResults = killResults and killed
108
109 cleanInstallResult = main.TRUE
110 gitPullResult = main.TRUE
111
112 main.step( "Starting Mininet" )
113 # scp topo file to mininet
114 # TODO: move to params?
115 topoName = "obelisk.py"
116 filePath = main.ONOSbench.home + "/tools/test/topos/"
117 main.ONOSbench.copyMininetFile( topoName, filePath,
118 main.Mininet1.user_name,
119 main.Mininet1.ip_address )
120 mnResult = main.Mininet1.startNet( )
121 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
122 onpass="Mininet Started",
123 onfail="Error starting Mininet" )
124
125 main.step( "Git checkout and pull " + gitBranch )
126 if PULLCODE:
127 main.ONOSbench.gitCheckout( gitBranch )
128 gitPullResult = main.ONOSbench.gitPull()
129 # values of 1 or 3 are good
130 utilities.assert_lesser( expect=0, actual=gitPullResult,
131 onpass="Git pull successful",
132 onfail="Git pull failed" )
133 main.ONOSbench.getVersion( report=True )
134
135 main.step( "Using mvn clean install" )
136 cleanInstallResult = main.TRUE
137 if PULLCODE and gitPullResult == main.TRUE:
138 cleanInstallResult = main.ONOSbench.cleanInstall()
139 else:
140 main.log.warn( "Did not pull new code so skipping mvn " +
141 "clean install" )
142 utilities.assert_equals( expect=main.TRUE,
143 actual=cleanInstallResult,
144 onpass="MCI successful",
145 onfail="MCI failed" )
146 # GRAPHS
147 # NOTE: important params here:
148 # job = name of Jenkins job
149 # Plot Name = Plot-HA, only can be used if multiple plots
150 # index = The number of the graph under plot name
Jon Hall5cf14d52015-07-16 12:15:19 -0700151 job = "HAsingleInstanceRestart"
Jon Hall85794ff2015-07-08 14:12:30 -0700152 plotName = "Plot-HA"
153 graphs = '<ac:structured-macro ac:name="html">\n'
154 graphs += '<ac:plain-text-body><![CDATA[\n'
155 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
156 '/plot/' + plotName + '/getPlot?index=0' +\
157 '&width=500&height=300"' +\
158 'noborder="0" width="500" height="300" scrolling="yes" ' +\
159 'seamless="seamless"></iframe>\n'
160 graphs += ']]></ac:plain-text-body>\n'
161 graphs += '</ac:structured-macro>\n'
162 main.log.wiki(graphs)
163
Jon Hall5cf14d52015-07-16 12:15:19 -0700164 CLIs = []
165 nodes = []
166 ipList = []
167 for i in range( 1, numControllers + 1 ):
168 CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
169 nodes.append( getattr( main, 'ONOS' + str( i ) ) )
170 ipList.append( nodes[ -1 ].ip_address )
171
172 main.ONOSbench.createCellFile( main.ONOSbench.ip_address, "SingleHA",
173 main.Mininet1.ip_address,
174 cellAppString, ipList[ 0 ] )
Jon Hall85794ff2015-07-08 14:12:30 -0700175 cellResult = main.ONOSbench.setCell( "SingleHA" )
176 verifyResult = main.ONOSbench.verifyCell()
177 main.step( "Creating ONOS package" )
178 packageResult = main.ONOSbench.onosPackage()
179 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
180 onpass="ONOS package successful",
181 onfail="ONOS package failed" )
182
183 main.step( "Installing ONOS package" )
184 onosInstallResult = main.ONOSbench.onosInstall(
185 options="-f", node=nodes[0].ip_address )
186 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
187 onpass="ONOS install successful",
188 onfail="ONOS install failed" )
189
190 main.step( "Checking if ONOS is up yet" )
191 for i in range( 2 ):
192 onos1Isup = main.ONOSbench.isup( nodes[0].ip_address )
193 if onos1Isup:
194 break
195 utilities.assert_equals( expect=main.TRUE, actual=onos1Isup,
196 onpass="ONOS startup successful",
197 onfail="ONOS startup failed" )
198
199 main.log.step( "Starting ONOS CLI sessions" )
200 cliResults = main.ONOScli1.startOnosCli( nodes[0].ip_address )
201 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
202 onpass="ONOS cli startup successful",
203 onfail="ONOS cli startup failed" )
204
205 if main.params[ 'tcpdump' ].lower() == "true":
206 main.step( "Start Packet Capture MN" )
207 main.Mininet2.startTcpdump(
208 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
209 + "-MN.pcap",
210 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
211 port=main.params[ 'MNtcpdump' ][ 'port' ] )
212
213 main.step( "App Ids check" )
214 appCheck = main.ONOScli1.appToIDCheck()
215 if appCheck != main.TRUE:
216 main.log.warn( CLIs[0].apps() )
217 main.log.warn( CLIs[0].appIDs() )
218 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
219 onpass="App Ids seem to be correct",
220 onfail="Something is wrong with app Ids" )
221
222 if cliResults == main.FALSE:
223 main.log.error( "Failed to start ONOS, stopping test" )
224 main.cleanup()
225 main.exit()
226
227 def CASE2( self, main ):
228 """
229 Assign devices to controllers
230 """
231 import re
232 import time
233 assert numControllers, "numControllers not defined"
234 assert main, "main not defined"
235 assert utilities.assert_equals, "utilities.assert_equals not defined"
236
237 main.case( "Assigning devices to controllers" )
Jon Hall783bbf92015-07-23 14:33:19 -0700238 main.caseExplanation = "Assign switches to ONOS using 'ovs-vsctl' " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700239 "and check that an ONOS node becomes the " +\
240 "master of the device."
241 main.step( "Assign switches to controllers" )
242
243 ipList = []
244 for i in range( numControllers ):
245 ipList.append( nodes[ i ].ip_address )
246 swList = []
247 for i in range( 1, 29 ):
248 swList.append( "s" + str( i ) )
249 main.Mininet1.assignSwController( sw=swList, ip=ipList )
250
251 mastershipCheck = main.TRUE
252 for i in range( 1, 29 ):
253 response = main.Mininet1.getSwController( "s" + str( i ) )
254 try:
255 main.log.info( str( response ) )
256 except Exception:
257 main.log.info( repr( response ) )
258 if re.search( "tcp:" + nodes[0].ip_address, response ):
259 mastershipCheck = mastershipCheck and main.TRUE
260 else:
261 mastershipCheck = main.FALSE
262 if mastershipCheck == main.TRUE:
263 main.log.info( "Switch mastership assigned correctly" )
264 utilities.assert_equals(
265 expect=main.TRUE,
266 actual=mastershipCheck,
267 onpass="Switch mastership assigned correctly",
268 onfail="Switches not assigned correctly to controllers" )
269
270 def CASE21( self, main ):
271 """
272 Assign mastership to controllers
273 """
274 import re
275 import time
276 assert numControllers, "numControllers not defined"
277 assert main, "main not defined"
278 assert utilities.assert_equals, "utilities.assert_equals not defined"
279 assert CLIs, "CLIs not defined"
280 assert nodes, "nodes not defined"
281
282 main.case( "Assigning Controller roles for switches" )
Jon Hall783bbf92015-07-23 14:33:19 -0700283 main.caseExplanation = "Check that ONOS is connected to each " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700284 "device. Then manually assign" +\
285 " mastership to specific ONOS nodes using" +\
286 " 'device-role'"
287 main.step( "Assign mastership of switches to specific controllers" )
288 roleCall = main.TRUE
289 roleCheck = main.TRUE
290 try:
291 for i in range( 1, 29 ): # switches 1 through 28
292 ip = nodes[ 0 ].ip_address # ONOS1
293 # set up correct variables:
294 if i == 1:
295 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
296 elif i == 2:
297 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
298 elif i == 3:
299 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
300 elif i == 4:
301 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
302 elif i == 5:
303 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
304 elif i == 6:
305 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
306 elif i == 7:
307 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
308 elif i >= 8 and i <= 17:
309 dpid = '3' + str( i ).zfill( 3 )
310 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
311 elif i >= 18 and i <= 27:
312 dpid = '6' + str( i ).zfill( 3 )
313 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
314 elif i == 28:
315 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
316 else:
317 main.log.error( "You didn't write an else statement for " +
318 "switch s" + str( i ) )
319 # Assign switch
320 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
321 # TODO: make this controller dynamic
322 roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
323 ip )
324 # Check assignment
325 master = main.ONOScli1.getRole( deviceId ).get( 'master' )
326 if ip in master:
327 roleCheck = roleCheck and main.TRUE
328 else:
329 roleCheck = roleCheck and main.FALSE
330 main.log.error( "Error, controller " + ip + " is not" +
331 " master " + "of device " +
332 str( deviceId ) + ". Master is " +
333 repr( master ) + "." )
334 except ( AttributeError, AssertionError ):
335 main.log.exception( "Something is wrong with ONOS device view" )
336 main.log.info( main.ONOScli1.devices() )
337 utilities.assert_equals(
338 expect=main.TRUE,
339 actual=roleCall,
340 onpass="Re-assigned switch mastership to designated controller",
341 onfail="Something wrong with deviceRole calls" )
342
343 main.step( "Check mastership was correctly assigned" )
344 utilities.assert_equals(
345 expect=main.TRUE,
346 actual=roleCheck,
347 onpass="Switches were successfully reassigned to designated " +
348 "controller",
349 onfail="Switches were not successfully reassigned" )
350
351 def CASE3( self, main ):
352 """
353 Assign intents
354 """
355 import time
356 import json
357 assert numControllers, "numControllers not defined"
358 assert main, "main not defined"
359 assert utilities.assert_equals, "utilities.assert_equals not defined"
360 # NOTE: we must reinstall intents until we have a persistant intent
361 # datastore!
362 main.case( "Adding host Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700363 main.caseExplanation = "Discover hosts by using pingall then " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700364 "assign predetermined host-to-host intents." +\
365 " After installation, check that the intent" +\
366 " is distributed to all nodes and the state" +\
367 " is INSTALLED"
368
369 # install onos-app-fwd
370 main.step( "Install reactive forwarding app" )
371 installResults = CLIs[0].activateApp( "org.onosproject.fwd" )
372 utilities.assert_equals( expect=main.TRUE, actual=installResults,
373 onpass="Install fwd successful",
374 onfail="Install fwd failed" )
375
376 main.step( "Check app ids" )
377 appCheck = main.ONOScli1.appToIDCheck()
378 if appCheck != main.TRUE:
379 main.log.warn( CLIs[0].apps() )
380 main.log.warn( CLIs[0].appIDs() )
381 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
382 onpass="App Ids seem to be correct",
383 onfail="Something is wrong with app Ids" )
384
385 main.step( "Discovering Hosts( Via pingall for now )" )
386 # FIXME: Once we have a host discovery mechanism, use that instead
387 # REACTIVE FWD test
388 pingResult = main.FALSE
389 for i in range(2): # Retry if pingall fails first time
390 time1 = time.time()
391 pingResult = main.Mininet1.pingall()
392 if i == 0:
393 utilities.assert_equals(
394 expect=main.TRUE,
395 actual=pingResult,
396 onpass="Reactive Pingall test passed",
397 onfail="Reactive Pingall failed, " +
398 "one or more ping pairs failed" )
399 time2 = time.time()
400 main.log.info( "Time for pingall: %2f seconds" %
401 ( time2 - time1 ) )
402 # timeout for fwd flows
403 time.sleep( 11 )
404 # uninstall onos-app-fwd
405 main.step( "Uninstall reactive forwarding app" )
406 uninstallResult = CLIs[0].deactivateApp( "org.onosproject.fwd" )
407 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
408 onpass="Uninstall fwd successful",
409 onfail="Uninstall fwd failed" )
410
411 main.step( "Check app ids" )
412 appCheck2 = main.ONOScli1.appToIDCheck()
413 if appCheck2 != main.TRUE:
414 main.log.warn( CLIs[0].apps() )
415 main.log.warn( CLIs[0].appIDs() )
416 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
417 onpass="App Ids seem to be correct",
418 onfail="Something is wrong with app Ids" )
419
420 main.step( "Add host intents via cli" )
421 intentIds = []
422 # TODO: move the host numbers to params
423 # Maybe look at all the paths we ping?
424 intentAddResult = True
425 hostResult = main.TRUE
426 for i in range( 8, 18 ):
427 main.log.info( "Adding host intent between h" + str( i ) +
428 " and h" + str( i + 10 ) )
429 host1 = "00:00:00:00:00:" + \
430 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
431 host2 = "00:00:00:00:00:" + \
432 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
433 # NOTE: getHost can return None
434 host1Dict = main.ONOScli1.getHost( host1 )
435 host2Dict = main.ONOScli1.getHost( host2 )
436 host1Id = None
437 host2Id = None
438 if host1Dict and host2Dict:
439 host1Id = host1Dict.get( 'id', None )
440 host2Id = host2Dict.get( 'id', None )
441 if host1Id and host2Id:
442 tmpId = main.ONOScli1.addHostIntent( host1Id, host2Id )
443 if tmpId:
444 main.log.info( "Added intent with id: " + tmpId )
445 intentIds.append( tmpId )
446 else:
447 main.log.error( "addHostIntent returned: " +
448 repr( tmpId ) )
449 else:
450 main.log.error( "Error, getHost() failed for h" + str( i ) +
451 " and/or h" + str( i + 10 ) )
452 hosts = main.ONOScli1.hosts()
453 main.log.warn( "Hosts output: " )
454 try:
455 main.log.warn( json.dumps( json.loads( hosts ),
456 sort_keys=True,
457 indent=4,
458 separators=( ',', ': ' ) ) )
459 except ( ValueError, TypeError ):
460 main.log.warn( repr( hosts ) )
461 hostResult = main.FALSE
462 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
463 onpass="Found a host id for each host",
464 onfail="Error looking up host ids" )
465
466 intentStart = time.time()
467 onosIds = main.ONOScli1.getAllIntentsId()
468 main.log.info( "Submitted intents: " + str( intentIds ) )
469 main.log.info( "Intents in ONOS: " + str( onosIds ) )
470 for intent in intentIds:
471 if intent in onosIds:
472 pass # intent submitted is in onos
473 else:
474 intentAddResult = False
475 if intentAddResult:
476 intentStop = time.time()
477 else:
478 intentStop = None
479 # Print the intent states
480 intents = main.ONOScli1.intents()
481 intentStates = []
482 installedCheck = True
483 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
484 count = 0
485 try:
486 for intent in json.loads( intents ):
487 state = intent.get( 'state', None )
488 if "INSTALLED" not in state:
489 installedCheck = False
490 intentId = intent.get( 'id', None )
491 intentStates.append( ( intentId, state ) )
492 except ( ValueError, TypeError ):
493 main.log.exception( "Error parsing intents" )
494 # add submitted intents not in the store
495 tmplist = [ i for i, s in intentStates ]
496 missingIntents = False
497 for i in intentIds:
498 if i not in tmplist:
499 intentStates.append( ( i, " - " ) )
500 missingIntents = True
501 intentStates.sort()
502 for i, s in intentStates:
503 count += 1
504 main.log.info( "%-6s%-15s%-15s" %
505 ( str( count ), str( i ), str( s ) ) )
506 leaders = main.ONOScli1.leaders()
507 try:
508 missing = False
509 if leaders:
510 parsedLeaders = json.loads( leaders )
511 main.log.warn( json.dumps( parsedLeaders,
512 sort_keys=True,
513 indent=4,
514 separators=( ',', ': ' ) ) )
515 # check for all intent partitions
516 topics = []
517 for i in range( 14 ):
518 topics.append( "intent-partition-" + str( i ) )
519 main.log.debug( topics )
520 ONOStopics = [ j['topic'] for j in parsedLeaders ]
521 for topic in topics:
522 if topic not in ONOStopics:
523 main.log.error( "Error: " + topic +
524 " not in leaders" )
525 missing = True
526 else:
527 main.log.error( "leaders() returned None" )
528 except ( ValueError, TypeError ):
529 main.log.exception( "Error parsing leaders" )
530 main.log.error( repr( leaders ) )
531 # Check all nodes
532 if missing:
533 response = main.ONOScli1.leaders( jsonFormat=False)
534 main.log.warn( "ONOS1 leaders output: \n" +
535 str( response ) )
536
537 partitions = main.ONOScli1.partitions()
538 try:
539 if partitions :
540 parsedPartitions = json.loads( partitions )
541 main.log.warn( json.dumps( parsedPartitions,
542 sort_keys=True,
543 indent=4,
544 separators=( ',', ': ' ) ) )
545 # TODO check for a leader in all paritions
546 # TODO check for consistency among nodes
547 else:
548 main.log.error( "partitions() returned None" )
549 except ( ValueError, TypeError ):
550 main.log.exception( "Error parsing partitions" )
551 main.log.error( repr( partitions ) )
552 pendingMap = main.ONOScli1.pendingMap()
553 try:
554 if pendingMap :
555 parsedPending = json.loads( pendingMap )
556 main.log.warn( json.dumps( parsedPending,
557 sort_keys=True,
558 indent=4,
559 separators=( ',', ': ' ) ) )
560 # TODO check something here?
561 else:
562 main.log.error( "pendingMap() returned None" )
563 except ( ValueError, TypeError ):
564 main.log.exception( "Error parsing pending map" )
565 main.log.error( repr( pendingMap ) )
566
567 intentAddResult = bool( intentAddResult and not missingIntents and
568 installedCheck )
569 if not intentAddResult:
570 main.log.error( "Error in pushing host intents to ONOS" )
571
572 main.step( "Intent Anti-Entropy dispersion" )
573 for i in range(100):
574 correct = True
575 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
576 for cli in CLIs:
577 onosIds = []
578 ids = cli.getAllIntentsId()
579 onosIds.append( ids )
580 main.log.debug( "Intents in " + cli.name + ": " +
581 str( sorted( onosIds ) ) )
582 if sorted( ids ) != sorted( intentIds ):
583 main.log.warn( "Set of intent IDs doesn't match" )
584 correct = False
585 break
586 else:
587 intents = json.loads( cli.intents() )
588 for intent in intents:
589 if intent[ 'state' ] != "INSTALLED":
590 main.log.warn( "Intent " + intent[ 'id' ] +
591 " is " + intent[ 'state' ] )
592 correct = False
593 break
594 if correct:
595 break
596 else:
597 time.sleep(1)
598 if not intentStop:
599 intentStop = time.time()
600 global gossipTime
601 gossipTime = intentStop - intentStart
602 main.log.info( "It took about " + str( gossipTime ) +
603 " seconds for all intents to appear in each node" )
604 # FIXME: make this time configurable/calculate based off of number of
605 # nodes and gossip rounds
606 utilities.assert_greater_equals(
607 expect=40, actual=gossipTime,
608 onpass="ECM anti-entropy for intents worked within " +
609 "expected time",
610 onfail="Intent ECM anti-entropy took too long" )
611 if gossipTime <= 40:
612 intentAddResult = True
613
614 if not intentAddResult or "key" in pendingMap:
615 import time
616 installedCheck = True
617 main.log.info( "Sleeping 60 seconds to see if intents are found" )
618 time.sleep( 60 )
619 onosIds = main.ONOScli1.getAllIntentsId()
620 main.log.info( "Submitted intents: " + str( intentIds ) )
621 main.log.info( "Intents in ONOS: " + str( onosIds ) )
622 # Print the intent states
623 intents = main.ONOScli1.intents()
624 intentStates = []
625 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
626 count = 0
627 try:
628 for intent in json.loads( intents ):
629 # Iter through intents of a node
630 state = intent.get( 'state', None )
631 if "INSTALLED" not in state:
632 installedCheck = False
633 intentId = intent.get( 'id', None )
634 intentStates.append( ( intentId, state ) )
635 except ( ValueError, TypeError ):
636 main.log.exception( "Error parsing intents" )
637 # add submitted intents not in the store
638 tmplist = [ i for i, s in intentStates ]
639 for i in intentIds:
640 if i not in tmplist:
641 intentStates.append( ( i, " - " ) )
642 intentStates.sort()
643 for i, s in intentStates:
644 count += 1
645 main.log.info( "%-6s%-15s%-15s" %
646 ( str( count ), str( i ), str( s ) ) )
647 leaders = main.ONOScli1.leaders()
648 try:
649 missing = False
650 if leaders:
651 parsedLeaders = json.loads( leaders )
652 main.log.warn( json.dumps( parsedLeaders,
653 sort_keys=True,
654 indent=4,
655 separators=( ',', ': ' ) ) )
656 # check for all intent partitions
657 # check for election
658 topics = []
659 for i in range( 14 ):
660 topics.append( "intent-partition-" + str( i ) )
661 # FIXME: this should only be after we start the app
662 topics.append( "org.onosproject.election" )
663 main.log.debug( topics )
664 ONOStopics = [ j['topic'] for j in parsedLeaders ]
665 for topic in topics:
666 if topic not in ONOStopics:
667 main.log.error( "Error: " + topic +
668 " not in leaders" )
669 missing = True
670 else:
671 main.log.error( "leaders() returned None" )
672 except ( ValueError, TypeError ):
673 main.log.exception( "Error parsing leaders" )
674 main.log.error( repr( leaders ) )
675 # Check all nodes
676 if missing:
677 response = main.ONOScli1.leaders( jsonFormat=False)
678 main.log.warn( "ONOS1 leaders output: \n" +
679 str( response ) )
680 partitions = main.ONOScli1.partitions()
681 try:
682 if partitions :
683 parsedPartitions = json.loads( partitions )
684 main.log.warn( json.dumps( parsedPartitions,
685 sort_keys=True,
686 indent=4,
687 separators=( ',', ': ' ) ) )
688 # TODO check for a leader in all paritions
689 # TODO check for consistency among nodes
690 else:
691 main.log.error( "partitions() returned None" )
692 except ( ValueError, TypeError ):
693 main.log.exception( "Error parsing partitions" )
694 main.log.error( repr( partitions ) )
695 pendingMap = main.ONOScli1.pendingMap()
696 try:
697 if pendingMap :
698 parsedPending = json.loads( pendingMap )
699 main.log.warn( json.dumps( parsedPending,
700 sort_keys=True,
701 indent=4,
702 separators=( ',', ': ' ) ) )
703 # TODO check something here?
704 else:
705 main.log.error( "pendingMap() returned None" )
706 except ( ValueError, TypeError ):
707 main.log.exception( "Error parsing pending map" )
708 main.log.error( repr( pendingMap ) )
709
710 def CASE4( self, main ):
711 """
712 Ping across added host intents
713 """
714 import json
715 import time
716 assert numControllers, "numControllers not defined"
717 assert main, "main not defined"
718 assert utilities.assert_equals, "utilities.assert_equals not defined"
719 main.case( "Verify connectivity by sendind traffic across Intents" )
Jon Hall783bbf92015-07-23 14:33:19 -0700720 main.caseExplanation = "Ping across added host intents to check " +\
Jon Hall85794ff2015-07-08 14:12:30 -0700721 "functionality and check the state of " +\
722 "the intent"
723 main.step( "Ping across added host intents" )
724 PingResult = main.TRUE
725 for i in range( 8, 18 ):
726 ping = main.Mininet1.pingHost( src="h" + str( i ),
727 target="h" + str( i + 10 ) )
728 PingResult = PingResult and ping
729 if ping == main.FALSE:
730 main.log.warn( "Ping failed between h" + str( i ) +
731 " and h" + str( i + 10 ) )
732 elif ping == main.TRUE:
733 main.log.info( "Ping test passed!" )
734 # Don't set PingResult or you'd override failures
735 if PingResult == main.FALSE:
736 main.log.error(
737 "Intents have not been installed correctly, pings failed." )
738 # TODO: pretty print
739 main.log.warn( "ONOS1 intents: " )
740 try:
741 tmpIntents = main.ONOScli1.intents()
742 main.log.warn( json.dumps( json.loads( tmpIntents ),
743 sort_keys=True,
744 indent=4,
745 separators=( ',', ': ' ) ) )
746 except ( ValueError, TypeError ):
747 main.log.warn( repr( tmpIntents ) )
748 utilities.assert_equals(
749 expect=main.TRUE,
750 actual=PingResult,
751 onpass="Intents have been installed correctly and pings work",
752 onfail="Intents have not been installed correctly, pings failed." )
753
754 main.step( "Check Intent state" )
755 installedCheck = True
756 # Print the intent states
757 intents = main.ONOScli1.intents()
758 intentStates = []
759 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
760 count = 0
761 # Iter through intents of a node
762 try:
763 for intent in json.loads( intents ):
764 state = intent.get( 'state', None )
765 if "INSTALLED" not in state:
766 installedCheck = False
767 intentId = intent.get( 'id', None )
768 intentStates.append( ( intentId, state ) )
769 except ( ValueError, TypeError ):
770 main.log.exception( "Error parsing intents." )
771 # Print states
772 intentStates.sort()
773 for i, s in intentStates:
774 count += 1
775 main.log.info( "%-6s%-15s%-15s" %
776 ( str( count ), str( i ), str( s ) ) )
777 utilities.assert_equals( expect=True, actual=installedCheck,
778 onpass="Intents are all INSTALLED",
779 onfail="Intents are not all in " +
780 "INSTALLED state" )
781
782 main.step( "Check leadership of topics" )
783 leaders = main.ONOScli1.leaders()
784 topicCheck = main.TRUE
785 try:
786 if leaders:
787 parsedLeaders = json.loads( leaders )
788 main.log.warn( json.dumps( parsedLeaders,
789 sort_keys=True,
790 indent=4,
791 separators=( ',', ': ' ) ) )
792 # check for all intent partitions
793 # check for election
794 # TODO: Look at Devices as topics now that it uses this system
795 topics = []
796 for i in range( 14 ):
797 topics.append( "intent-partition-" + str( i ) )
798 # FIXME: this should only be after we start the app
799 # FIXME: topics.append( "org.onosproject.election" )
800 # Print leaders output
801 main.log.debug( topics )
802 ONOStopics = [ j['topic'] for j in parsedLeaders ]
803 for topic in topics:
804 if topic not in ONOStopics:
805 main.log.error( "Error: " + topic +
806 " not in leaders" )
807 topicCheck = main.FALSE
808 else:
809 main.log.error( "leaders() returned None" )
810 topicCheck = main.FALSE
811 except ( ValueError, TypeError ):
812 topicCheck = main.FALSE
813 main.log.exception( "Error parsing leaders" )
814 main.log.error( repr( leaders ) )
815 # TODO: Check for a leader of these topics
816 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
817 onpass="intent Partitions is in leaders",
818 onfail="Some topics were lost " )
819 # Print partitions
820 partitions = main.ONOScli1.partitions()
821 try:
822 if partitions :
823 parsedPartitions = json.loads( partitions )
824 main.log.warn( json.dumps( parsedPartitions,
825 sort_keys=True,
826 indent=4,
827 separators=( ',', ': ' ) ) )
828 # TODO check for a leader in all paritions
829 # TODO check for consistency among nodes
830 else:
831 main.log.error( "partitions() returned None" )
832 except ( ValueError, TypeError ):
833 main.log.exception( "Error parsing partitions" )
834 main.log.error( repr( partitions ) )
835 # Print Pending Map
836 pendingMap = main.ONOScli1.pendingMap()
837 try:
838 if pendingMap :
839 parsedPending = json.loads( pendingMap )
840 main.log.warn( json.dumps( parsedPending,
841 sort_keys=True,
842 indent=4,
843 separators=( ',', ': ' ) ) )
844 # TODO check something here?
845 else:
846 main.log.error( "pendingMap() returned None" )
847 except ( ValueError, TypeError ):
848 main.log.exception( "Error parsing pending map" )
849 main.log.error( repr( pendingMap ) )
850
851 if not installedCheck:
852 main.log.info( "Waiting 60 seconds to see if the state of " +
853 "intents change" )
854 time.sleep( 60 )
855 # Print the intent states
856 intents = main.ONOScli1.intents()
857 intentStates = []
858 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
859 count = 0
860 # Iter through intents of a node
861 try:
862 for intent in json.loads( intents ):
863 state = intent.get( 'state', None )
864 if "INSTALLED" not in state:
865 installedCheck = False
866 intentId = intent.get( 'id', None )
867 intentStates.append( ( intentId, state ) )
868 except ( ValueError, TypeError ):
869 main.log.exception( "Error parsing intents." )
870 intentStates.sort()
871 for i, s in intentStates:
872 count += 1
873 main.log.info( "%-6s%-15s%-15s" %
874 ( str( count ), str( i ), str( s ) ) )
875 leaders = main.ONOScli1.leaders()
876 try:
877 missing = False
878 if leaders:
879 parsedLeaders = json.loads( leaders )
880 main.log.warn( json.dumps( parsedLeaders,
881 sort_keys=True,
882 indent=4,
883 separators=( ',', ': ' ) ) )
884 # check for all intent partitions
885 # check for election
886 topics = []
887 for i in range( 14 ):
888 topics.append( "intent-partition-" + str( i ) )
889 # FIXME: this should only be after we start the app
890 topics.append( "org.onosproject.election" )
891 main.log.debug( topics )
892 ONOStopics = [ j['topic'] for j in parsedLeaders ]
893 for topic in topics:
894 if topic not in ONOStopics:
895 main.log.error( "Error: " + topic +
896 " not in leaders" )
897 missing = True
898 else:
899 main.log.error( "leaders() returned None" )
900 except ( ValueError, TypeError ):
901 main.log.exception( "Error parsing leaders" )
902 main.log.error( repr( leaders ) )
903 if missing:
904 response = main.ONOScli1.leaders( jsonFormat=False)
905 main.log.warn( "ONOS1 leaders output: \n" +
906 str( response ) )
907 partitions = main.ONOScli1.partitions()
908 try:
909 if partitions :
910 parsedPartitions = json.loads( partitions )
911 main.log.warn( json.dumps( parsedPartitions,
912 sort_keys=True,
913 indent=4,
914 separators=( ',', ': ' ) ) )
915 # TODO check for a leader in all paritions
916 # TODO check for consistency among nodes
917 else:
918 main.log.error( "partitions() returned None" )
919 except ( ValueError, TypeError ):
920 main.log.exception( "Error parsing partitions" )
921 main.log.error( repr( partitions ) )
922 pendingMap = main.ONOScli1.pendingMap()
923 try:
924 if pendingMap :
925 parsedPending = json.loads( pendingMap )
926 main.log.warn( json.dumps( parsedPending,
927 sort_keys=True,
928 indent=4,
929 separators=( ',', ': ' ) ) )
930 # TODO check something here?
931 else:
932 main.log.error( "pendingMap() returned None" )
933 except ( ValueError, TypeError ):
934 main.log.exception( "Error parsing pending map" )
935 main.log.error( repr( pendingMap ) )
936 # Print flowrules
937 main.log.debug( CLIs[0].flows( jsonFormat=False ) )
938 main.step( "Wait a minute then ping again" )
939 # the wait is above
940 PingResult = main.TRUE
941 for i in range( 8, 18 ):
942 ping = main.Mininet1.pingHost( src="h" + str( i ),
943 target="h" + str( i + 10 ) )
944 PingResult = PingResult and ping
945 if ping == main.FALSE:
946 main.log.warn( "Ping failed between h" + str( i ) +
947 " and h" + str( i + 10 ) )
948 elif ping == main.TRUE:
949 main.log.info( "Ping test passed!" )
950 # Don't set PingResult or you'd override failures
951 if PingResult == main.FALSE:
952 main.log.error(
953 "Intents have not been installed correctly, pings failed." )
954 # TODO: pretty print
955 main.log.warn( "ONOS1 intents: " )
956 try:
957 tmpIntents = main.ONOScli1.intents()
958 main.log.warn( json.dumps( json.loads( tmpIntents ),
959 sort_keys=True,
960 indent=4,
961 separators=( ',', ': ' ) ) )
962 except ( ValueError, TypeError ):
963 main.log.warn( repr( tmpIntents ) )
964 utilities.assert_equals(
965 expect=main.TRUE,
966 actual=PingResult,
967 onpass="Intents have been installed correctly and pings work",
968 onfail="Intents have not been installed correctly, pings failed." )
969
970 def CASE5( self, main ):
971 """
972 Reading state of ONOS
973 """
974 import json
975 assert numControllers, "numControllers not defined"
976 assert main, "main not defined"
977 assert utilities.assert_equals, "utilities.assert_equals not defined"
978
979 main.case( "Setting up and gathering data for current state" )
980 # The general idea for this test case is to pull the state of
981 # ( intents,flows, topology,... ) from each ONOS node
982 # We can then compare them with each other and also with past states
983
984 main.step( "Check that each switch has a master" )
985 global mastershipState
986 mastershipState = '[]'
987
988 # Assert that each device has a master
989 rolesNotNull = main.ONOScli1.rolesNotNull()
990 utilities.assert_equals(
991 expect=main.TRUE,
992 actual=rolesNotNull,
993 onpass="Each device has a master",
994 onfail="Some devices don't have a master assigned" )
995
996 main.step( "Get the Mastership of each switch" )
997 ONOS1Mastership = main.ONOScli1.roles()
998 # TODO: Make this a meaningful check
999 if "Error" in ONOS1Mastership or not ONOS1Mastership:
1000 main.log.error( "Error in getting ONOS roles" )
1001 main.log.warn(
1002 "ONOS1 mastership response: " +
1003 repr( ONOS1Mastership ) )
1004 consistentMastership = main.FALSE
1005 else:
1006 mastershipState = ONOS1Mastership
1007 consistentMastership = main.TRUE
1008
1009 main.step( "Get the intents from each controller" )
1010 global intentState
1011 intentState = []
1012 ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
1013 intentCheck = main.FALSE
1014 if "Error" in ONOS1Intents or not ONOS1Intents:
1015 main.log.error( "Error in getting ONOS intents" )
1016 main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
1017 else:
1018 intentCheck = main.TRUE
1019
1020 main.step( "Get the flows from each controller" )
1021 global flowState
1022 flowState = []
1023 flowCheck = main.FALSE
1024 ONOS1Flows = main.ONOScli1.flows( jsonFormat=True )
1025 if "Error" in ONOS1Flows or not ONOS1Flows:
1026 main.log.error( "Error in getting ONOS flows" )
1027 main.log.warn( "ONOS1 flows repsponse: " + ONOS1Flows )
1028 else:
1029 # TODO: Do a better check, maybe compare flows on switches?
1030 flowState = ONOS1Flows
1031 flowCheck = main.TRUE
1032
1033 main.step( "Get the OF Table entries" )
1034 global flows
1035 flows = []
1036 for i in range( 1, 29 ):
1037 flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
1038 if flowCheck == main.FALSE:
1039 for table in flows:
1040 main.log.warn( table )
1041 # TODO: Compare switch flow tables with ONOS flow tables
1042
1043 main.step( "Collecting topology information from ONOS" )
1044 devices = []
1045 devices.append( main.ONOScli1.devices() )
1046 hosts = []
1047 hosts.append( json.loads( main.ONOScli1.hosts() ) )
1048 ports = []
1049 ports.append( main.ONOScli1.ports() )
1050 links = []
1051 links.append( main.ONOScli1.links() )
1052 clusters = []
1053 clusters.append( main.ONOScli1.clusters() )
1054
1055 main.step( "Each host has an IP address" )
1056 ipResult = main.TRUE
1057 for controller in range( 0, len( hosts ) ):
1058 controllerStr = str( controller + 1 )
1059 for host in hosts[ controller ]:
1060 if host is None or host.get( 'ipAddresses', [] ) == []:
1061 main.log.error(
1062 "DEBUG:Error with host ips on controller" +
1063 controllerStr + ": " + str( host ) )
1064 ipResult = main.FALSE
1065 utilities.assert_equals(
1066 expect=main.TRUE,
1067 actual=ipResult,
1068 onpass="The ips of the hosts aren't empty",
1069 onfail="The ip of at least one host is missing" )
1070
1071 # there should always only be one cluster
1072 main.step( "There is only one dataplane cluster" )
1073 try:
1074 numClusters = len( json.loads( clusters[ 0 ] ) )
1075 except ( ValueError, TypeError ):
1076 main.log.exception( "Error parsing clusters[0]: " +
1077 repr( clusters[ 0 ] ) )
1078 clusterResults = main.FALSE
1079 if numClusters == 1:
1080 clusterResults = main.TRUE
1081 utilities.assert_equals(
1082 expect=1,
1083 actual=numClusters,
1084 onpass="ONOS shows 1 SCC",
1085 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1086
1087 main.step( "Comparing ONOS topology to MN" )
1088 devicesResults = main.TRUE
1089 linksResults = main.TRUE
1090 hostsResults = main.TRUE
1091 mnSwitches = main.Mininet1.getSwitches()
1092 mnLinks = main.Mininet1.getLinks()
1093 mnHosts = main.Mininet1.getHosts()
1094 for controller in range( numControllers ):
1095 controllerStr = str( controller + 1 )
1096 if devices[ controller ] and ports[ controller ] and\
1097 "Error" not in devices[ controller ] and\
1098 "Error" not in ports[ controller ]:
1099
1100 currentDevicesResult = main.Mininet1.compareSwitches(
1101 mnSwitches,
1102 json.loads( devices[ controller ] ),
1103 json.loads( ports[ controller ] ) )
1104 else:
1105 currentDevicesResult = main.FALSE
1106 utilities.assert_equals( expect=main.TRUE,
1107 actual=currentDevicesResult,
1108 onpass="ONOS" + controllerStr +
1109 " Switches view is correct",
1110 onfail="ONOS" + controllerStr +
1111 " Switches view is incorrect" )
1112 if links[ controller ] and "Error" not in links[ controller ]:
1113 currentLinksResult = main.Mininet1.compareLinks(
1114 mnSwitches, mnLinks,
1115 json.loads( links[ controller ] ) )
1116 else:
1117 currentLinksResult = main.FALSE
1118 utilities.assert_equals( expect=main.TRUE,
1119 actual=currentLinksResult,
1120 onpass="ONOS" + controllerStr +
1121 " links view is correct",
1122 onfail="ONOS" + controllerStr +
1123 " links view is incorrect" )
1124
1125 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1126 currentHostsResult = main.Mininet1.compareHosts(
1127 mnHosts,
1128 hosts[ controller ] )
1129 else:
1130 currentHostsResult = main.FALSE
1131 utilities.assert_equals( expect=main.TRUE,
1132 actual=currentHostsResult,
1133 onpass="ONOS" + controllerStr +
1134 " hosts exist in Mininet",
1135 onfail="ONOS" + controllerStr +
1136 " hosts don't match Mininet" )
1137
1138 devicesResults = devicesResults and currentDevicesResult
1139 linksResults = linksResults and currentLinksResult
1140 hostsResults = hostsResults and currentHostsResult
1141
1142 main.step( "Device information is correct" )
1143 utilities.assert_equals(
1144 expect=main.TRUE,
1145 actual=devicesResults,
1146 onpass="Device information is correct",
1147 onfail="Device information is incorrect" )
1148
1149 main.step( "Links are correct" )
1150 utilities.assert_equals(
1151 expect=main.TRUE,
1152 actual=linksResults,
1153 onpass="Link are correct",
1154 onfail="Links are incorrect" )
1155
1156 main.step( "Hosts are correct" )
1157 utilities.assert_equals(
1158 expect=main.TRUE,
1159 actual=hostsResults,
1160 onpass="Hosts are correct",
1161 onfail="Hosts are incorrect" )
1162
1163 def CASE6( self, main ):
1164 """
1165 The Failure case.
1166 """
1167 import time
1168 assert numControllers, "numControllers not defined"
1169 assert main, "main not defined"
1170 assert utilities.assert_equals, "utilities.assert_equals not defined"
1171
1172 # Reset non-persistent variables
1173 try:
1174 iCounterValue = 0
1175 except NameError:
1176 main.log.error( "iCounterValue not defined, setting to 0" )
1177 iCounterValue = 0
1178
1179 main.case( "Restart ONOS node" )
Jon Hall783bbf92015-07-23 14:33:19 -07001180 main.caseExplanation = "Killing ONOS process and restart cli " +\
Jon Hall85794ff2015-07-08 14:12:30 -07001181 "sessions once onos is up."
1182 main.step( "Killing ONOS processes" )
1183 killResult = main.ONOSbench.onosKill( nodes[0].ip_address )
1184 start = time.time()
1185 utilities.assert_equals( expect=main.TRUE, actual=killResult,
1186 onpass="ONOS Killed",
1187 onfail="Error killing ONOS" )
1188
1189 main.step( "Checking if ONOS is up yet" )
1190 count = 0
1191 while count < 10:
1192 onos1Isup = main.ONOSbench.isup( nodes[0].ip_address )
1193 if onos1Isup == main.TRUE:
1194 elapsed = time.time() - start
1195 break
1196 else:
1197 count = count + 1
1198 utilities.assert_equals( expect=main.TRUE, actual=onos1Isup,
1199 onpass="ONOS is back up",
1200 onfail="ONOS failed to start" )
1201
1202 main.log.step( "Starting ONOS CLI sessions" )
1203 cliResults = main.ONOScli1.startOnosCli( nodes[0].ip_address )
1204 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1205 onpass="ONOS cli startup successful",
1206 onfail="ONOS cli startup failed" )
1207
1208 if elapsed:
1209 main.log.info( "ESTIMATE: ONOS took %s seconds to restart" %
1210 str( elapsed ) )
1211 main.restartTime = elapsed
1212 else:
1213 main.restartTime = -1
1214 time.sleep( 5 )
1215 # rerun on election apps
1216 main.ONOScli1.electionTestRun()
1217
1218 def CASE7( self, main ):
1219 """
1220 Check state after ONOS failure
1221 """
1222 import json
1223 assert numControllers, "numControllers not defined"
1224 assert main, "main not defined"
1225 assert utilities.assert_equals, "utilities.assert_equals not defined"
1226 main.case( "Running ONOS Constant State Tests" )
1227 main.step( "Check that each switch has a master" )
1228 # Assert that each device has a master
1229 rolesNotNull = main.ONOScli1.rolesNotNull()
1230 utilities.assert_equals(
1231 expect=main.TRUE,
1232 actual=rolesNotNull,
1233 onpass="Each device has a master",
1234 onfail="Some devices don't have a master assigned" )
1235
1236 main.step( "Check if switch roles are consistent across all nodes" )
1237 ONOS1Mastership = main.ONOScli1.roles()
1238 # FIXME: Refactor this whole case for single instance
1239 if "Error" in ONOS1Mastership or not ONOS1Mastership:
1240 main.log.error( "Error in getting ONOS mastership" )
1241 main.log.warn( "ONOS1 mastership response: " +
1242 repr( ONOS1Mastership ) )
1243 consistentMastership = main.FALSE
1244 else:
1245 consistentMastership = main.TRUE
1246 utilities.assert_equals(
1247 expect=main.TRUE,
1248 actual=consistentMastership,
1249 onpass="Switch roles are consistent across all ONOS nodes",
1250 onfail="ONOS nodes have different views of switch roles" )
1251
1252 description2 = "Compare switch roles from before failure"
1253 main.step( description2 )
1254
1255 currentJson = json.loads( ONOS1Mastership )
1256 oldJson = json.loads( mastershipState )
1257 mastershipCheck = main.TRUE
1258 for i in range( 1, 29 ):
1259 switchDPID = str(
1260 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
1261
1262 current = [ switch[ 'master' ] for switch in currentJson
1263 if switchDPID in switch[ 'id' ] ]
1264 old = [ switch[ 'master' ] for switch in oldJson
1265 if switchDPID in switch[ 'id' ] ]
1266 if current == old:
1267 mastershipCheck = mastershipCheck and main.TRUE
1268 else:
1269 main.log.warn( "Mastership of switch %s changed" % switchDPID )
1270 mastershipCheck = main.FALSE
1271 utilities.assert_equals(
1272 expect=main.TRUE,
1273 actual=mastershipCheck,
1274 onpass="Mastership of Switches was not changed",
1275 onfail="Mastership of some switches changed" )
1276 mastershipCheck = mastershipCheck and consistentMastership
1277
1278 main.step( "Get the intents and compare across all nodes" )
1279 ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
1280 intentCheck = main.FALSE
1281 if "Error" in ONOS1Intents or not ONOS1Intents:
1282 main.log.error( "Error in getting ONOS intents" )
1283 main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
1284 else:
1285 intentCheck = main.TRUE
1286 utilities.assert_equals(
1287 expect=main.TRUE,
1288 actual=intentCheck,
1289 onpass="Intents are consistent across all ONOS nodes",
1290 onfail="ONOS nodes have different views of intents" )
1291 # Print the intent states
1292 intents = []
1293 intents.append( ONOS1Intents )
1294 intentStates = []
1295 for node in intents: # Iter through ONOS nodes
1296 nodeStates = []
1297 # Iter through intents of a node
1298 for intent in json.loads( node ):
1299 nodeStates.append( intent[ 'state' ] )
1300 intentStates.append( nodeStates )
1301 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1302 main.log.info( dict( out ) )
1303
1304 # NOTE: Store has no durability, so intents are lost across system
1305 # restarts
1306 """
1307 main.step( "Compare current intents with intents before the failure" )
1308 # NOTE: this requires case 5 to pass for intentState to be set.
1309 # maybe we should stop the test if that fails?
1310 sameIntents = main.FALSE
1311 if intentState and intentState == ONOSIntents[ 0 ]:
1312 sameIntents = main.TRUE
1313 main.log.info( "Intents are consistent with before failure" )
1314 # TODO: possibly the states have changed? we may need to figure out
1315 # what the acceptable states are
1316 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
1317 sameIntents = main.TRUE
1318 try:
1319 before = json.loads( intentState )
1320 after = json.loads( ONOSIntents[ 0 ] )
1321 for intent in before:
1322 if intent not in after:
1323 sameIntents = main.FALSE
1324 main.log.debug( "Intent is not currently in ONOS " +
1325 "(at least in the same form):" )
1326 main.log.debug( json.dumps( intent ) )
1327 except ( ValueError, TypeError ):
1328 main.log.exception( "Exception printing intents" )
1329 main.log.debug( repr( ONOSIntents[0] ) )
1330 main.log.debug( repr( intentState ) )
1331 if sameIntents == main.FALSE:
1332 try:
1333 main.log.debug( "ONOS intents before: " )
1334 main.log.debug( json.dumps( json.loads( intentState ),
1335 sort_keys=True, indent=4,
1336 separators=( ',', ': ' ) ) )
1337 main.log.debug( "Current ONOS intents: " )
1338 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1339 sort_keys=True, indent=4,
1340 separators=( ',', ': ' ) ) )
1341 except ( ValueError, TypeError ):
1342 main.log.exception( "Exception printing intents" )
1343 main.log.debug( repr( ONOSIntents[0] ) )
1344 main.log.debug( repr( intentState ) )
1345 utilities.assert_equals(
1346 expect=main.TRUE,
1347 actual=sameIntents,
1348 onpass="Intents are consistent with before failure",
1349 onfail="The Intents changed during failure" )
1350 intentCheck = intentCheck and sameIntents
1351 """
1352 main.step( "Get the OF Table entries and compare to before " +
1353 "component failure" )
1354 FlowTables = main.TRUE
1355 flows2 = []
1356 for i in range( 28 ):
1357 main.log.info( "Checking flow table on s" + str( i + 1 ) )
1358 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
1359 flows2.append( tmpFlows )
1360 tempResult = main.Mininet2.flowComp(
1361 flow1=flows[ i ],
1362 flow2=tmpFlows )
1363 FlowTables = FlowTables and tempResult
1364 if FlowTables == main.FALSE:
1365 main.log.info( "Differences in flow table for switch: s" +
1366 str( i + 1 ) )
1367 utilities.assert_equals(
1368 expect=main.TRUE,
1369 actual=FlowTables,
1370 onpass="No changes were found in the flow tables",
1371 onfail="Changes were found in the flow tables" )
1372
1373 main.step( "Leadership Election is still functional" )
1374 # Test of LeadershipElection
1375
1376 leader = nodes[0].ip_address
1377 leaderResult = main.TRUE
1378 for controller in range( 1, numControllers + 1 ):
1379 # loop through ONOScli handlers
1380 node = getattr( main, ( 'ONOScli' + str( controller ) ) )
1381 leaderN = node.electionTestLeader()
1382 # verify leader is ONOS1
1383 # NOTE even though we restarted ONOS, it is the only one so onos 1
1384 # must be leader
1385 if leaderN == leader:
1386 # all is well
1387 pass
1388 elif leaderN == main.FALSE:
1389 # error in response
1390 main.log.error( "Something is wrong with " +
1391 "electionTestLeader function, check the" +
1392 " error logs" )
1393 leaderResult = main.FALSE
1394 elif leader != leaderN:
1395 leaderResult = main.FALSE
1396 main.log.error( "ONOS" + str( controller ) + " sees " +
1397 str( leaderN ) +
1398 " as the leader of the election app. " +
1399 "Leader should be " + str( leader ) )
1400 utilities.assert_equals(
1401 expect=main.TRUE,
1402 actual=leaderResult,
1403 onpass="Leadership election passed",
1404 onfail="Something went wrong with Leadership election" )
1405
1406 def CASE8( self, main ):
1407 """
1408 Compare topo
1409 """
1410 import json
1411 import time
1412 assert numControllers, "numControllers not defined"
1413 assert main, "main not defined"
1414 assert utilities.assert_equals, "utilities.assert_equals not defined"
1415
1416 main.case( "Compare ONOS Topology view to Mininet topology" )
Jon Hall783bbf92015-07-23 14:33:19 -07001417 main.caseExplanation = "Compare topology objects between Mininet" +\
Jon Hall85794ff2015-07-08 14:12:30 -07001418 " and ONOS"
1419
1420 main.step( "Comparing ONOS topology to MN" )
1421 devicesResults = main.TRUE
1422 linksResults = main.TRUE
1423 hostsResults = main.TRUE
1424 hostAttachmentResults = True
1425 topoResult = main.FALSE
1426 elapsed = 0
1427 count = 0
1428 main.step( "Collecting topology information from ONOS" )
1429 startTime = time.time()
1430 # Give time for Gossip to work
1431 while topoResult == main.FALSE and elapsed < 60:
1432 count += 1
1433 cliStart = time.time()
1434 devices = []
1435 devices.append( main.ONOScli1.devices() )
1436 hosts = []
1437 hosts.append( json.loads( main.ONOScli1.hosts() ) )
1438 ipResult = main.TRUE
1439 for controller in range( 0, len( hosts ) ):
1440 controllerStr = str( controller + 1 )
1441 for host in hosts[ controller ]:
1442 if host is None or host.get( 'ipAddresses', [] ) == []:
1443 main.log.error(
1444 "DEBUG:Error with host ips on controller" +
1445 controllerStr + ": " + str( host ) )
1446 ipResult = main.FALSE
1447 ports = []
1448 ports.append( main.ONOScli1.ports() )
1449 links = []
1450 links.append( main.ONOScli1.links() )
1451 clusters = []
1452 clusters.append( main.ONOScli1.clusters() )
1453
1454 elapsed = time.time() - startTime
1455 cliTime = time.time() - cliStart
1456 print "CLI time: " + str( cliTime )
1457
1458 mnSwitches = main.Mininet1.getSwitches()
1459 mnLinks = main.Mininet1.getLinks()
1460 mnHosts = main.Mininet1.getHosts()
1461 for controller in range( numControllers ):
1462 controllerStr = str( controller + 1 )
1463 if devices[ controller ] and ports[ controller ] and\
1464 "Error" not in devices[ controller ] and\
1465 "Error" not in ports[ controller ]:
1466
1467 currentDevicesResult = main.Mininet1.compareSwitches(
1468 mnSwitches,
1469 json.loads( devices[ controller ] ),
1470 json.loads( ports[ controller ] ) )
1471 else:
1472 currentDevicesResult = main.FALSE
1473 utilities.assert_equals( expect=main.TRUE,
1474 actual=currentDevicesResult,
1475 onpass="ONOS" + controllerStr +
1476 " Switches view is correct",
1477 onfail="ONOS" + controllerStr +
1478 " Switches view is incorrect" )
1479
1480 if links[ controller ] and "Error" not in links[ controller ]:
1481 currentLinksResult = main.Mininet1.compareLinks(
1482 mnSwitches, mnLinks,
1483 json.loads( links[ controller ] ) )
1484 else:
1485 currentLinksResult = main.FALSE
1486 utilities.assert_equals( expect=main.TRUE,
1487 actual=currentLinksResult,
1488 onpass="ONOS" + controllerStr +
1489 " links view is correct",
1490 onfail="ONOS" + controllerStr +
1491 " links view is incorrect" )
1492
1493 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1494 currentHostsResult = main.Mininet1.compareHosts(
1495 mnHosts,
1496 hosts[ controller ] )
1497 else:
1498 currentHostsResult = main.FALSE
1499 utilities.assert_equals( expect=main.TRUE,
1500 actual=currentHostsResult,
1501 onpass="ONOS" + controllerStr +
1502 " hosts exist in Mininet",
1503 onfail="ONOS" + controllerStr +
1504 " hosts don't match Mininet" )
1505 # CHECKING HOST ATTACHMENT POINTS
1506 hostAttachment = True
1507 zeroHosts = False
1508 # FIXME: topo-HA/obelisk specific mappings:
1509 # key is mac and value is dpid
1510 mappings = {}
1511 for i in range( 1, 29 ): # hosts 1 through 28
1512 # set up correct variables:
1513 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
1514 if i == 1:
1515 deviceId = "1000".zfill(16)
1516 elif i == 2:
1517 deviceId = "2000".zfill(16)
1518 elif i == 3:
1519 deviceId = "3000".zfill(16)
1520 elif i == 4:
1521 deviceId = "3004".zfill(16)
1522 elif i == 5:
1523 deviceId = "5000".zfill(16)
1524 elif i == 6:
1525 deviceId = "6000".zfill(16)
1526 elif i == 7:
1527 deviceId = "6007".zfill(16)
1528 elif i >= 8 and i <= 17:
1529 dpid = '3' + str( i ).zfill( 3 )
1530 deviceId = dpid.zfill(16)
1531 elif i >= 18 and i <= 27:
1532 dpid = '6' + str( i ).zfill( 3 )
1533 deviceId = dpid.zfill(16)
1534 elif i == 28:
1535 deviceId = "2800".zfill(16)
1536 mappings[ macId ] = deviceId
1537 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1538 if hosts[ controller ] == []:
1539 main.log.warn( "There are no hosts discovered" )
1540 zeroHosts = True
1541 else:
1542 for host in hosts[ controller ]:
1543 mac = None
1544 location = None
1545 device = None
1546 port = None
1547 try:
1548 mac = host.get( 'mac' )
1549 assert mac, "mac field could not be found for this host object"
1550
1551 location = host.get( 'location' )
1552 assert location, "location field could not be found for this host object"
1553
1554 # Trim the protocol identifier off deviceId
1555 device = str( location.get( 'elementId' ) ).split(':')[1]
1556 assert device, "elementId field could not be found for this host location object"
1557
1558 port = location.get( 'port' )
1559 assert port, "port field could not be found for this host location object"
1560
1561 # Now check if this matches where they should be
1562 if mac and device and port:
1563 if str( port ) != "1":
1564 main.log.error( "The attachment port is incorrect for " +
1565 "host " + str( mac ) +
1566 ". Expected: 1 Actual: " + str( port) )
1567 hostAttachment = False
1568 if device != mappings[ str( mac ) ]:
1569 main.log.error( "The attachment device is incorrect for " +
1570 "host " + str( mac ) +
1571 ". Expected: " + mappings[ str( mac ) ] +
1572 " Actual: " + device )
1573 hostAttachment = False
1574 else:
1575 hostAttachment = False
1576 except AssertionError:
1577 main.log.exception( "Json object not as expected" )
1578 main.log.error( repr( host ) )
1579 hostAttachment = False
1580 else:
1581 main.log.error( "No hosts json output or \"Error\"" +
1582 " in output. hosts = " +
1583 repr( hosts[ controller ] ) )
1584 if zeroHosts is False:
1585 hostAttachment = True
1586
1587
1588 devicesResults = devicesResults and currentDevicesResult
1589 linksResults = linksResults and currentLinksResult
1590 hostsResults = hostsResults and currentHostsResult
1591 hostAttachmentResults = hostAttachmentResults and\
1592 hostAttachment
1593
1594 # "consistent" results don't make sense for single instance
1595 # there should always only be one cluster
1596 numClusters = len( json.loads( clusters[ 0 ] ) )
1597 clusterResults = main.FALSE
1598 if numClusters == 1:
1599 clusterResults = main.TRUE
1600 utilities.assert_equals(
1601 expect=1,
1602 actual=numClusters,
1603 onpass="ONOS shows 1 SCC",
1604 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
1605
1606 topoResult = ( devicesResults and linksResults
1607 and hostsResults and ipResult and clusterResults and
1608 hostAttachmentResults )
1609
1610 topoResult = topoResult and int( count <= 2 )
1611 note = "note it takes about " + str( int( cliTime ) ) + \
1612 " seconds for the test to make all the cli calls to fetch " +\
1613 "the topology from each ONOS instance"
1614 main.log.info(
1615 "Very crass estimate for topology discovery/convergence( " +
1616 str( note ) + " ): " + str( elapsed ) + " seconds, " +
1617 str( count ) + " tries" )
1618 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
1619 onpass="Topology Check Test successful",
1620 onfail="Topology Check Test NOT successful" )
1621
1622 def CASE9( self, main ):
1623 """
1624 Link s3-s28 down
1625 """
1626 import time
1627 assert numControllers, "numControllers not defined"
1628 assert main, "main not defined"
1629 assert utilities.assert_equals, "utilities.assert_equals not defined"
1630 # NOTE: You should probably run a topology check after this
1631
1632 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
1633
1634 description = "Turn off a link to ensure that Link Discovery " +\
1635 "is working properly"
1636 main.case( description )
1637
1638 main.step( "Kill Link between s3 and s28" )
1639 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
1640 main.log.info( "Waiting " + str( linkSleep ) +
1641 " seconds for link down to be discovered" )
1642 time.sleep( linkSleep )
1643 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
1644 onpass="Link down successful",
1645 onfail="Failed to bring link down" )
1646 # TODO do some sort of check here
1647
1648 def CASE10( self, main ):
1649 """
1650 Link s3-s28 up
1651 """
1652 import time
1653 assert numControllers, "numControllers not defined"
1654 assert main, "main not defined"
1655 assert utilities.assert_equals, "utilities.assert_equals not defined"
1656 # NOTE: You should probably run a topology check after this
1657
1658 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
1659
1660 description = "Restore a link to ensure that Link Discovery is " + \
1661 "working properly"
1662 main.case( description )
1663
1664 main.step( "Bring link between s3 and s28 back up" )
1665 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
1666 main.log.info( "Waiting " + str( linkSleep ) +
1667 " seconds for link up to be discovered" )
1668 time.sleep( linkSleep )
1669 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
1670 onpass="Link up successful",
1671 onfail="Failed to bring link up" )
1672 # TODO do some sort of check here
1673
1674 def CASE11( self, main ):
1675 """
1676 Switch Down
1677 """
1678 # NOTE: You should probably run a topology check after this
1679 import time
1680 assert numControllers, "numControllers not defined"
1681 assert main, "main not defined"
1682 assert utilities.assert_equals, "utilities.assert_equals not defined"
1683
1684 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
1685
1686 description = "Killing a switch to ensure it is discovered correctly"
1687 main.case( description )
1688 switch = main.params[ 'kill' ][ 'switch' ]
1689 switchDPID = main.params[ 'kill' ][ 'dpid' ]
1690
1691 # TODO: Make this switch parameterizable
1692 main.step( "Kill " + switch )
1693 main.log.info( "Deleting " + switch )
1694 main.Mininet1.delSwitch( switch )
1695 main.log.info( "Waiting " + str( switchSleep ) +
1696 " seconds for switch down to be discovered" )
1697 time.sleep( switchSleep )
1698 device = main.ONOScli1.getDevice( dpid=switchDPID )
1699 # Peek at the deleted switch
1700 main.log.warn( str( device ) )
1701 result = main.FALSE
1702 if device and device[ 'available' ] is False:
1703 result = main.TRUE
1704 utilities.assert_equals( expect=main.TRUE, actual=result,
1705 onpass="Kill switch successful",
1706 onfail="Failed to kill switch?" )
1707
1708 def CASE12( self, main ):
1709 """
1710 Switch Up
1711 """
1712 # NOTE: You should probably run a topology check after this
1713 import time
1714 assert numControllers, "numControllers not defined"
1715 assert main, "main not defined"
1716 assert utilities.assert_equals, "utilities.assert_equals not defined"
1717
1718 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
1719 switch = main.params[ 'kill' ][ 'switch' ]
1720 switchDPID = main.params[ 'kill' ][ 'dpid' ]
1721 links = main.params[ 'kill' ][ 'links' ].split()
1722 description = "Adding a switch to ensure it is discovered correctly"
1723 main.case( description )
1724
1725 main.step( "Add back " + switch )
1726 main.Mininet1.addSwitch( switch, dpid=switchDPID )
1727 for peer in links:
1728 main.Mininet1.addLink( switch, peer )
1729 ipList = []
1730 for i in range( numControllers ):
1731 ipList.append( nodes[ i ].ip_address )
1732 main.Mininet1.assignSwController( sw=switch, ip=ipList )
1733 main.log.info( "Waiting " + str( switchSleep ) +
1734 " seconds for switch up to be discovered" )
1735 time.sleep( switchSleep )
1736 device = main.ONOScli1.getDevice( dpid=switchDPID )
1737 # Peek at the deleted switch
1738 main.log.warn( str( device ) )
1739 result = main.FALSE
1740 if device and device[ 'available' ]:
1741 result = main.TRUE
1742 utilities.assert_equals( expect=main.TRUE, actual=result,
1743 onpass="add switch successful",
1744 onfail="Failed to add switch?" )
1745
1746 def CASE13( self, main ):
1747 """
1748 Clean up
1749 """
1750 import os
1751 import time
1752 assert numControllers, "numControllers not defined"
1753 assert main, "main not defined"
1754 assert utilities.assert_equals, "utilities.assert_equals not defined"
1755 # printing colors to terminal
1756 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
1757 'blue': '\033[94m', 'green': '\033[92m',
1758 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
1759 main.case( "Test Cleanup" )
1760 main.step( "Killing tcpdumps" )
1761 main.Mininet2.stopTcpdump()
1762
1763 testname = main.TEST
1764 if main.params[ 'BACKUP' ] == "True":
1765 main.step( "Copying MN pcap and ONOS log files to test station" )
1766 teststationUser = main.params[ 'BACKUP' ][ 'TESTONUSER' ]
1767 teststationIP = main.params[ 'BACKUP' ][ 'TESTONIP' ]
1768 # NOTE: MN Pcap file is being saved to ~/packet_captures
1769 # scp this file as MN and TestON aren't necessarily the same vm
1770 # FIXME: scp
1771 # mn files
1772 # TODO: Load these from params
1773 # NOTE: must end in /
1774 logFolder = "/opt/onos/log/"
1775 logFiles = [ "karaf.log", "karaf.log.1" ]
1776 # NOTE: must end in /
1777 dstDir = "~/packet_captures/"
1778 for f in logFiles:
1779 main.ONOSbench.handle.sendline( "scp sdn@" + nodes[0].ip_address + ":" +
1780 logFolder + f + " " +
1781 teststationUser + "@" +
1782 teststationIP + ":" + dstDir +
1783 str( testname ) + "-ONOS1-" + f )
1784 main.ONOSbench.handle.expect( "\$" )
1785
1786 # std*.log's
1787 # NOTE: must end in /
1788 logFolder = "/opt/onos/var/"
1789 logFiles = [ "stderr.log", "stdout.log" ]
1790 # NOTE: must end in /
1791 dstDir = "~/packet_captures/"
1792 for f in logFiles:
1793 main.ONOSbench.handle.sendline( "scp sdn@" + nodes[0].ip_address + ":" +
1794 logFolder + f + " " +
1795 teststationUser + "@" +
1796 teststationIP + ":" + dstDir +
1797 str( testname ) + "-ONOS1-" + f )
1798 main.ONOSbench.handle.expect( "\$" )
1799 # sleep so scp can finish
1800 time.sleep( 10 )
1801 main.step( "Packing and rotating pcap archives" )
1802 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
1803
Jon Hall85794ff2015-07-08 14:12:30 -07001804 main.step( "Stopping Mininet" )
1805 mnResult = main.Mininet1.stopNet()
1806 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
1807 onpass="Mininet stopped",
1808 onfail="MN cleanup NOT successful" )
1809
1810 main.step( "Checking ONOS Logs for errors" )
1811 print colors[ 'purple' ] + "Checking logs for errors on ONOS1:" + \
1812 colors[ 'end' ]
1813 print main.ONOSbench.checkLogs( nodes[0].ip_address, restart=True )
1814
1815 try:
1816 timerLog = open( main.logdir + "/Timers.csv", 'w')
1817 # Overwrite with empty line and close
1818 labels = "Gossip Intents, Restart"
1819 data = str( gossipTime ) + ", " + str( main.restartTime )
1820 timerLog.write( labels + "\n" + data )
1821 timerLog.close()
1822 except NameError, e:
1823 main.log.exception(e)
1824
1825 def CASE14( self, main ):
1826 """
1827 start election app on all onos nodes
1828 """
1829 assert numControllers, "numControllers not defined"
1830 assert main, "main not defined"
1831 assert utilities.assert_equals, "utilities.assert_equals not defined"
1832
1833 main.case("Start Leadership Election app")
1834 main.step( "Install leadership election app" )
1835 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
1836 utilities.assert_equals(
1837 expect=main.TRUE,
1838 actual=appResult,
1839 onpass="Election app installed",
1840 onfail="Something went wrong with installing Leadership election" )
1841
1842 main.step( "Run for election on each node" )
1843 leaderResult = main.ONOScli1.electionTestRun()
1844 # check for leader
1845 leader = main.ONOScli1.electionTestLeader()
1846 # verify leader is ONOS1
1847 if leader == nodes[0].ip_address:
1848 # all is well
1849 pass
1850 elif leader is None:
1851 # No leader elected
1852 main.log.error( "No leader was elected" )
1853 leaderResult = main.FALSE
1854 elif leader == main.FALSE:
1855 # error in response
1856 # TODO: add check for "Command not found:" in the driver, this
1857 # means the app isn't loaded
1858 main.log.error( "Something is wrong with electionTestLeader" +
1859 " function, check the error logs" )
1860 leaderResult = main.FALSE
1861 else:
1862 # error in response
1863 main.log.error(
1864 "Unexpected response from electionTestLeader function:'" +
1865 str( leader ) +
1866 "'" )
1867 leaderResult = main.FALSE
1868 utilities.assert_equals(
1869 expect=main.TRUE,
1870 actual=leaderResult,
1871 onpass="Successfully ran for leadership",
1872 onfail="Failed to run for leadership" )
1873
1874 def CASE15( self, main ):
1875 """
1876 Check that Leadership Election is still functional
1877 """
1878 assert numControllers, "numControllers not defined"
1879 assert main, "main not defined"
1880 assert utilities.assert_equals, "utilities.assert_equals not defined"
1881 leaderResult = main.TRUE
1882 description = "Check that Leadership Election is still functional"
1883 main.case( description )
1884 main.step( "Find current leader and withdraw" )
1885 leader = main.ONOScli1.electionTestLeader()
1886 # do some sanity checking on leader before using it
1887 withdrawResult = main.FALSE
1888 if leader == nodes[0].ip_address:
1889 oldLeader = getattr( main, "ONOScli1" )
1890 elif leader is None or leader == main.FALSE:
1891 main.log.error(
1892 "Leader for the election app should be an ONOS node," +
1893 "instead got '" + str( leader ) + "'" )
1894 leaderResult = main.FALSE
1895 oldLeader = None
1896 else:
1897 main.log.error( "Leader election --- why am I HERE?!?")
1898 leaderResult = main.FALSE
1899 oldLeader = None
1900 if oldLeader:
1901 withdrawResult = oldLeader.electionTestWithdraw()
1902 utilities.assert_equals(
1903 expect=main.TRUE,
1904 actual=withdrawResult,
1905 onpass="Node was withdrawn from election",
1906 onfail="Node was not withdrawn from election" )
1907
1908 main.step( "Make sure new leader is elected" )
1909 leaderN = main.ONOScli1.electionTestLeader()
1910 if leaderN == leader:
1911 main.log.error( "ONOS still sees " + str( leaderN ) +
1912 " as leader after they withdrew" )
1913 leaderResult = main.FALSE
1914 elif leaderN == main.FALSE:
1915 # error in response
1916 # TODO: add check for "Command not found:" in the driver, this
1917 # means the app isn't loaded
1918 main.log.error( "Something is wrong with electionTestLeader " +
1919 "function, check the error logs" )
1920 leaderResult = main.FALSE
1921 elif leaderN is None:
1922 main.log.info(
1923 "There is no leader after the app withdrew from election" )
1924 leaderResult = main.TRUE
1925 utilities.assert_equals(
1926 expect=main.TRUE,
1927 actual=leaderResult,
1928 onpass="Leadership election passed",
1929 onfail="Something went wrong with Leadership election" )
1930
1931 main.step( "Run for election on old leader( just so everyone " +
1932 "is in the hat )" )
1933 if oldLeader:
1934 runResult = oldLeader.electionTestRun()
1935 else:
1936 runResult = main.FALSE
1937 utilities.assert_equals(
1938 expect=main.TRUE,
1939 actual=runResult,
1940 onpass="App re-ran for election",
1941 onfail="App failed to run for election" )
1942
1943 main.step( "Node became leader when it ran for election" )
1944 afterRun = main.ONOScli1.electionTestLeader()
1945 # verify leader is ONOS1
1946 if afterRun == nodes[0].ip_address:
1947 afterResult = main.TRUE
1948 else:
1949 afterResult = main.FALSE
1950
1951 utilities.assert_equals(
1952 expect=main.TRUE,
1953 actual=afterResult,
1954 onpass="Old leader successfully re-ran for election",
1955 onfail="Something went wrong with Leadership election after " +
1956 "the old leader re-ran for election" )
1957
1958 def CASE16( self, main ):
1959 """
1960 Install Distributed Primitives app
1961 """
1962 assert numControllers, "numControllers not defined"
1963 assert main, "main not defined"
1964 assert utilities.assert_equals, "utilities.assert_equals not defined"
1965 assert CLIs, "CLIs not defined"
1966 assert nodes, "nodes not defined"
1967
1968 # Variables for the distributed primitives tests
1969 global pCounterName
1970 global iCounterName
1971 global pCounterValue
1972 global iCounterValue
1973 global onosSet
1974 global onosSetName
1975 pCounterName = "TestON-Partitions"
1976 iCounterName = "TestON-inMemory"
1977 pCounterValue = 0
1978 iCounterValue = 0
1979 onosSet = set([])
1980 onosSetName = "TestON-set"
1981
1982 description = "Install Primitives app"
1983 main.case( description )
1984 main.step( "Install Primitives app" )
1985 appName = "org.onosproject.distributedprimitives"
1986 appResults = CLIs[0].activateApp( appName )
1987 utilities.assert_equals( expect=main.TRUE,
1988 actual=appResults,
1989 onpass="Primitives app activated",
1990 onfail="Primitives app not activated" )
1991
1992 def CASE17( self, main ):
1993 """
1994 Check for basic functionality with distributed primitives
1995 """
1996 import json
1997 # Make sure variables are defined/set
1998 assert numControllers, "numControllers not defined"
1999 assert main, "main not defined"
2000 assert utilities.assert_equals, "utilities.assert_equals not defined"
2001 assert CLIs, "CLIs not defined"
2002 assert nodes, "nodes not defined"
2003 assert pCounterName, "pCounterName not defined"
2004 assert iCounterName, "iCounterName not defined"
2005 assert onosSetName, "onosSetName not defined"
2006 # NOTE: assert fails if value is 0/None/Empty/False
2007 try:
2008 pCounterValue
2009 except NameError:
2010 main.log.error( "pCounterValue not defined, setting to 0" )
2011 pCounterValue = 0
2012 try:
2013 iCounterValue
2014 except NameError:
2015 main.log.error( "iCounterValue not defined, setting to 0" )
2016 iCounterValue = 0
2017 try:
2018 onosSet
2019 except NameError:
2020 main.log.error( "onosSet not defined, setting to empty Set" )
2021 onosSet = set([])
2022 # Variables for the distributed primitives tests. These are local only
2023 addValue = "a"
2024 addAllValue = "a b c d e f"
2025 retainValue = "c d e f"
2026
2027 description = "Check for basic functionality with distributed " +\
2028 "primitives"
2029 main.case( description )
Jon Hall783bbf92015-07-23 14:33:19 -07002030 main.caseExplanation = "Test the methods of the distributed primitives (counters and sets) throught the cli"
Jon Hall85794ff2015-07-08 14:12:30 -07002031 # DISTRIBUTED ATOMIC COUNTERS
2032 main.step( "Increment and get a default counter on each node" )
2033 pCounters = []
2034 threads = []
2035 addedPValues = []
2036 for i in range( numControllers ):
2037 t = main.Thread( target=CLIs[i].counterTestIncrement,
2038 name="counterIncrement-" + str( i ),
2039 args=[ pCounterName ] )
2040 pCounterValue += 1
2041 addedPValues.append( pCounterValue )
2042 threads.append( t )
2043 t.start()
2044
2045 for t in threads:
2046 t.join()
2047 pCounters.append( t.result )
2048 # Check that counter incremented numController times
2049 pCounterResults = True
2050 for i in addedPValues:
2051 tmpResult = i in pCounters
2052 pCounterResults = pCounterResults and tmpResult
2053 if not tmpResult:
2054 main.log.error( str( i ) + " is not in partitioned "
2055 "counter incremented results" )
2056 utilities.assert_equals( expect=True,
2057 actual=pCounterResults,
2058 onpass="Default counter incremented",
2059 onfail="Error incrementing default" +
2060 " counter" )
2061
2062 main.step( "Increment and get an in memory counter on each node" )
2063 iCounters = []
2064 addedIValues = []
2065 threads = []
2066 for i in range( numControllers ):
2067 t = main.Thread( target=CLIs[i].counterTestIncrement,
2068 name="icounterIncrement-" + str( i ),
2069 args=[ iCounterName ],
2070 kwargs={ "inMemory": True } )
2071 iCounterValue += 1
2072 addedIValues.append( iCounterValue )
2073 threads.append( t )
2074 t.start()
2075
2076 for t in threads:
2077 t.join()
2078 iCounters.append( t.result )
2079 # Check that counter incremented numController times
2080 iCounterResults = True
2081 for i in addedIValues:
2082 tmpResult = i in iCounters
2083 iCounterResults = iCounterResults and tmpResult
2084 if not tmpResult:
2085 main.log.error( str( i ) + " is not in the in-memory "
2086 "counter incremented results" )
2087 utilities.assert_equals( expect=True,
2088 actual=iCounterResults,
2089 onpass="In memory counter incremented",
2090 onfail="Error incrementing in memory" +
2091 " counter" )
2092
2093 main.step( "Check counters are consistant across nodes" )
2094 onosCounters = []
2095 threads = []
2096 for i in range( numControllers ):
2097 t = main.Thread( target=CLIs[i].counters,
2098 name="counters-" + str( i ) )
2099 threads.append( t )
2100 t.start()
2101 for t in threads:
2102 t.join()
2103 onosCounters.append( t.result )
2104 tmp = [ i == onosCounters[ 0 ] for i in onosCounters ]
2105 if all( tmp ):
2106 main.log.info( "Counters are consistent across all nodes" )
2107 consistentCounterResults = main.TRUE
2108 else:
2109 main.log.error( "Counters are not consistent across all nodes" )
2110 consistentCounterResults = main.FALSE
2111 utilities.assert_equals( expect=main.TRUE,
2112 actual=consistentCounterResults,
2113 onpass="ONOS counters are consistent " +
2114 "across nodes",
2115 onfail="ONOS Counters are inconsistent " +
2116 "across nodes" )
2117
2118 main.step( "Counters we added have the correct values" )
2119 correctResults = main.TRUE
2120 for i in range( numControllers ):
Jon Hall5cf14d52015-07-16 12:15:19 -07002121 try:
2122 current = json.loads( onosCounters[i] )
2123 except ( ValueError, TypeError ):
2124 main.log.error( "Could not parse counters response from ONOS" +
2125 str( i + 1 ) )
2126 main.log.warn( repr( onosCounters[ i ] ) )
Jon Hall85794ff2015-07-08 14:12:30 -07002127 pValue = None
2128 iValue = None
2129 try:
2130 for database in current:
2131 partitioned = database.get( 'partitionedDatabaseCounters' )
2132 if partitioned:
2133 for value in partitioned:
2134 if value.get( 'name' ) == pCounterName:
2135 pValue = value.get( 'value' )
2136 break
2137 inMemory = database.get( 'inMemoryDatabaseCounters' )
2138 if inMemory:
2139 for value in inMemory:
2140 if value.get( 'name' ) == iCounterName:
2141 iValue = value.get( 'value' )
2142 break
2143 except AttributeError, e:
2144 main.log.error( "ONOS" + str( i + 1 ) + " counters result " +
2145 "is not as expected" )
2146 correctResults = main.FALSE
2147 if pValue == pCounterValue:
2148 main.log.info( "Partitioned counter value is correct" )
2149 else:
2150 main.log.error( "Partitioned counter value is incorrect," +
2151 " expected value: " + str( pCounterValue )
2152 + " current value: " + str( pValue ) )
2153 correctResults = main.FALSE
2154 if iValue == iCounterValue:
2155 main.log.info( "In memory counter value is correct" )
2156 else:
2157 main.log.error( "In memory counter value is incorrect, " +
2158 "expected value: " + str( iCounterValue ) +
2159 " current value: " + str( iValue ) )
2160 correctResults = main.FALSE
2161 utilities.assert_equals( expect=main.TRUE,
2162 actual=correctResults,
2163 onpass="Added counters are correct",
2164 onfail="Added counters are incorrect" )
2165 # DISTRIBUTED SETS
2166 main.step( "Distributed Set get" )
2167 size = len( onosSet )
2168 getResponses = []
2169 threads = []
2170 for i in range( numControllers ):
2171 t = main.Thread( target=CLIs[i].setTestGet,
2172 name="setTestGet-" + str( i ),
2173 args=[ onosSetName ] )
2174 threads.append( t )
2175 t.start()
2176 for t in threads:
2177 t.join()
2178 getResponses.append( t.result )
2179
2180 getResults = main.TRUE
2181 for i in range( numControllers ):
2182 if isinstance( getResponses[ i ], list):
2183 current = set( getResponses[ i ] )
2184 if len( current ) == len( getResponses[ i ] ):
2185 # no repeats
2186 if onosSet != current:
2187 main.log.error( "ONOS" + str( i + 1 ) +
2188 " has incorrect view" +
2189 " of set " + onosSetName + ":\n" +
2190 str( getResponses[ i ] ) )
2191 main.log.debug( "Expected: " + str( onosSet ) )
2192 main.log.debug( "Actual: " + str( current ) )
2193 getResults = main.FALSE
2194 else:
2195 # error, set is not a set
2196 main.log.error( "ONOS" + str( i + 1 ) +
2197 " has repeat elements in" +
2198 " set " + onosSetName + ":\n" +
2199 str( getResponses[ i ] ) )
2200 getResults = main.FALSE
2201 elif getResponses[ i ] == main.ERROR:
2202 getResults = main.FALSE
2203 utilities.assert_equals( expect=main.TRUE,
2204 actual=getResults,
2205 onpass="Set elements are correct",
2206 onfail="Set elements are incorrect" )
2207
2208 main.step( "Distributed Set size" )
2209 sizeResponses = []
2210 threads = []
2211 for i in range( numControllers ):
2212 t = main.Thread( target=CLIs[i].setTestSize,
2213 name="setTestSize-" + str( i ),
2214 args=[ onosSetName ] )
2215 threads.append( t )
2216 t.start()
2217 for t in threads:
2218 t.join()
2219 sizeResponses.append( t.result )
2220
2221 sizeResults = main.TRUE
2222 for i in range( numControllers ):
2223 if size != sizeResponses[ i ]:
2224 sizeResults = main.FALSE
2225 main.log.error( "ONOS" + str( i + 1 ) +
2226 " expected a size of " + str( size ) +
2227 " for set " + onosSetName +
2228 " but got " + str( sizeResponses[ i ] ) )
2229 utilities.assert_equals( expect=main.TRUE,
2230 actual=sizeResults,
2231 onpass="Set sizes are correct",
2232 onfail="Set sizes are incorrect" )
2233
2234 main.step( "Distributed Set add()" )
2235 onosSet.add( addValue )
2236 addResponses = []
2237 threads = []
2238 for i in range( numControllers ):
2239 t = main.Thread( target=CLIs[i].setTestAdd,
2240 name="setTestAdd-" + str( i ),
2241 args=[ onosSetName, addValue ] )
2242 threads.append( t )
2243 t.start()
2244 for t in threads:
2245 t.join()
2246 addResponses.append( t.result )
2247
2248 # main.TRUE = successfully changed the set
2249 # main.FALSE = action resulted in no change in set
2250 # main.ERROR - Some error in executing the function
2251 addResults = main.TRUE
2252 for i in range( numControllers ):
2253 if addResponses[ i ] == main.TRUE:
2254 # All is well
2255 pass
2256 elif addResponses[ i ] == main.FALSE:
2257 # Already in set, probably fine
2258 pass
2259 elif addResponses[ i ] == main.ERROR:
2260 # Error in execution
2261 addResults = main.FALSE
2262 else:
2263 # unexpected result
2264 addResults = main.FALSE
2265 if addResults != main.TRUE:
2266 main.log.error( "Error executing set add" )
2267
2268 # Check if set is still correct
2269 size = len( onosSet )
2270 getResponses = []
2271 threads = []
2272 for i in range( numControllers ):
2273 t = main.Thread( target=CLIs[i].setTestGet,
2274 name="setTestGet-" + str( i ),
2275 args=[ onosSetName ] )
2276 threads.append( t )
2277 t.start()
2278 for t in threads:
2279 t.join()
2280 getResponses.append( t.result )
2281 getResults = main.TRUE
2282 for i in range( numControllers ):
2283 if isinstance( getResponses[ i ], list):
2284 current = set( getResponses[ i ] )
2285 if len( current ) == len( getResponses[ i ] ):
2286 # no repeats
2287 if onosSet != current:
2288 main.log.error( "ONOS" + str( i + 1 ) +
2289 " has incorrect view" +
2290 " of set " + onosSetName + ":\n" +
2291 str( getResponses[ i ] ) )
2292 main.log.debug( "Expected: " + str( onosSet ) )
2293 main.log.debug( "Actual: " + str( current ) )
2294 getResults = main.FALSE
2295 else:
2296 # error, set is not a set
2297 main.log.error( "ONOS" + str( i + 1 ) +
2298 " has repeat elements in" +
2299 " set " + onosSetName + ":\n" +
2300 str( getResponses[ i ] ) )
2301 getResults = main.FALSE
2302 elif getResponses[ i ] == main.ERROR:
2303 getResults = main.FALSE
2304 sizeResponses = []
2305 threads = []
2306 for i in range( numControllers ):
2307 t = main.Thread( target=CLIs[i].setTestSize,
2308 name="setTestSize-" + str( i ),
2309 args=[ onosSetName ] )
2310 threads.append( t )
2311 t.start()
2312 for t in threads:
2313 t.join()
2314 sizeResponses.append( t.result )
2315 sizeResults = main.TRUE
2316 for i in range( numControllers ):
2317 if size != sizeResponses[ i ]:
2318 sizeResults = main.FALSE
2319 main.log.error( "ONOS" + str( i + 1 ) +
2320 " expected a size of " + str( size ) +
2321 " for set " + onosSetName +
2322 " but got " + str( sizeResponses[ i ] ) )
2323 addResults = addResults and getResults and sizeResults
2324 utilities.assert_equals( expect=main.TRUE,
2325 actual=addResults,
2326 onpass="Set add correct",
2327 onfail="Set add was incorrect" )
2328
2329 main.step( "Distributed Set addAll()" )
2330 onosSet.update( addAllValue.split() )
2331 addResponses = []
2332 threads = []
2333 for i in range( numControllers ):
2334 t = main.Thread( target=CLIs[i].setTestAdd,
2335 name="setTestAddAll-" + str( i ),
2336 args=[ onosSetName, addAllValue ] )
2337 threads.append( t )
2338 t.start()
2339 for t in threads:
2340 t.join()
2341 addResponses.append( t.result )
2342
2343 # main.TRUE = successfully changed the set
2344 # main.FALSE = action resulted in no change in set
2345 # main.ERROR - Some error in executing the function
2346 addAllResults = main.TRUE
2347 for i in range( numControllers ):
2348 if addResponses[ i ] == main.TRUE:
2349 # All is well
2350 pass
2351 elif addResponses[ i ] == main.FALSE:
2352 # Already in set, probably fine
2353 pass
2354 elif addResponses[ i ] == main.ERROR:
2355 # Error in execution
2356 addAllResults = main.FALSE
2357 else:
2358 # unexpected result
2359 addAllResults = main.FALSE
2360 if addAllResults != main.TRUE:
2361 main.log.error( "Error executing set addAll" )
2362
2363 # Check if set is still correct
2364 size = len( onosSet )
2365 getResponses = []
2366 threads = []
2367 for i in range( numControllers ):
2368 t = main.Thread( target=CLIs[i].setTestGet,
2369 name="setTestGet-" + str( i ),
2370 args=[ onosSetName ] )
2371 threads.append( t )
2372 t.start()
2373 for t in threads:
2374 t.join()
2375 getResponses.append( t.result )
2376 getResults = main.TRUE
2377 for i in range( numControllers ):
2378 if isinstance( getResponses[ i ], list):
2379 current = set( getResponses[ i ] )
2380 if len( current ) == len( getResponses[ i ] ):
2381 # no repeats
2382 if onosSet != current:
2383 main.log.error( "ONOS" + str( i + 1 ) +
2384 " has incorrect view" +
2385 " of set " + onosSetName + ":\n" +
2386 str( getResponses[ i ] ) )
2387 main.log.debug( "Expected: " + str( onosSet ) )
2388 main.log.debug( "Actual: " + str( current ) )
2389 getResults = main.FALSE
2390 else:
2391 # error, set is not a set
2392 main.log.error( "ONOS" + str( i + 1 ) +
2393 " has repeat elements in" +
2394 " set " + onosSetName + ":\n" +
2395 str( getResponses[ i ] ) )
2396 getResults = main.FALSE
2397 elif getResponses[ i ] == main.ERROR:
2398 getResults = main.FALSE
2399 sizeResponses = []
2400 threads = []
2401 for i in range( numControllers ):
2402 t = main.Thread( target=CLIs[i].setTestSize,
2403 name="setTestSize-" + str( i ),
2404 args=[ onosSetName ] )
2405 threads.append( t )
2406 t.start()
2407 for t in threads:
2408 t.join()
2409 sizeResponses.append( t.result )
2410 sizeResults = main.TRUE
2411 for i in range( numControllers ):
2412 if size != sizeResponses[ i ]:
2413 sizeResults = main.FALSE
2414 main.log.error( "ONOS" + str( i + 1 ) +
2415 " expected a size of " + str( size ) +
2416 " for set " + onosSetName +
2417 " but got " + str( sizeResponses[ i ] ) )
2418 addAllResults = addAllResults and getResults and sizeResults
2419 utilities.assert_equals( expect=main.TRUE,
2420 actual=addAllResults,
2421 onpass="Set addAll correct",
2422 onfail="Set addAll was incorrect" )
2423
2424 main.step( "Distributed Set contains()" )
2425 containsResponses = []
2426 threads = []
2427 for i in range( numControllers ):
2428 t = main.Thread( target=CLIs[i].setTestGet,
2429 name="setContains-" + str( i ),
2430 args=[ onosSetName ],
2431 kwargs={ "values": addValue } )
2432 threads.append( t )
2433 t.start()
2434 for t in threads:
2435 t.join()
2436 # NOTE: This is the tuple
2437 containsResponses.append( t.result )
2438
2439 containsResults = main.TRUE
2440 for i in range( numControllers ):
2441 if containsResponses[ i ] == main.ERROR:
2442 containsResults = main.FALSE
2443 else:
2444 containsResults = containsResults and\
2445 containsResponses[ i ][ 1 ]
2446 utilities.assert_equals( expect=main.TRUE,
2447 actual=containsResults,
2448 onpass="Set contains is functional",
2449 onfail="Set contains failed" )
2450
2451 main.step( "Distributed Set containsAll()" )
2452 containsAllResponses = []
2453 threads = []
2454 for i in range( numControllers ):
2455 t = main.Thread( target=CLIs[i].setTestGet,
2456 name="setContainsAll-" + str( i ),
2457 args=[ onosSetName ],
2458 kwargs={ "values": addAllValue } )
2459 threads.append( t )
2460 t.start()
2461 for t in threads:
2462 t.join()
2463 # NOTE: This is the tuple
2464 containsAllResponses.append( t.result )
2465
2466 containsAllResults = main.TRUE
2467 for i in range( numControllers ):
2468 if containsResponses[ i ] == main.ERROR:
2469 containsResults = main.FALSE
2470 else:
2471 containsResults = containsResults and\
2472 containsResponses[ i ][ 1 ]
2473 utilities.assert_equals( expect=main.TRUE,
2474 actual=containsAllResults,
2475 onpass="Set containsAll is functional",
2476 onfail="Set containsAll failed" )
2477
2478 main.step( "Distributed Set remove()" )
2479 onosSet.remove( addValue )
2480 removeResponses = []
2481 threads = []
2482 for i in range( numControllers ):
2483 t = main.Thread( target=CLIs[i].setTestRemove,
2484 name="setTestRemove-" + str( i ),
2485 args=[ onosSetName, addValue ] )
2486 threads.append( t )
2487 t.start()
2488 for t in threads:
2489 t.join()
2490 removeResponses.append( t.result )
2491
2492 # main.TRUE = successfully changed the set
2493 # main.FALSE = action resulted in no change in set
2494 # main.ERROR - Some error in executing the function
2495 removeResults = main.TRUE
2496 for i in range( numControllers ):
2497 if removeResponses[ i ] == main.TRUE:
2498 # All is well
2499 pass
2500 elif removeResponses[ i ] == main.FALSE:
2501 # not in set, probably fine
2502 pass
2503 elif removeResponses[ i ] == main.ERROR:
2504 # Error in execution
2505 removeResults = main.FALSE
2506 else:
2507 # unexpected result
2508 removeResults = main.FALSE
2509 if removeResults != main.TRUE:
2510 main.log.error( "Error executing set remove" )
2511
2512 # Check if set is still correct
2513 size = len( onosSet )
2514 getResponses = []
2515 threads = []
2516 for i in range( numControllers ):
2517 t = main.Thread( target=CLIs[i].setTestGet,
2518 name="setTestGet-" + str( i ),
2519 args=[ onosSetName ] )
2520 threads.append( t )
2521 t.start()
2522 for t in threads:
2523 t.join()
2524 getResponses.append( t.result )
2525 getResults = main.TRUE
2526 for i in range( numControllers ):
2527 if isinstance( getResponses[ i ], list):
2528 current = set( getResponses[ i ] )
2529 if len( current ) == len( getResponses[ i ] ):
2530 # no repeats
2531 if onosSet != current:
2532 main.log.error( "ONOS" + str( i + 1 ) +
2533 " has incorrect view" +
2534 " of set " + onosSetName + ":\n" +
2535 str( getResponses[ i ] ) )
2536 main.log.debug( "Expected: " + str( onosSet ) )
2537 main.log.debug( "Actual: " + str( current ) )
2538 getResults = main.FALSE
2539 else:
2540 # error, set is not a set
2541 main.log.error( "ONOS" + str( i + 1 ) +
2542 " has repeat elements in" +
2543 " set " + onosSetName + ":\n" +
2544 str( getResponses[ i ] ) )
2545 getResults = main.FALSE
2546 elif getResponses[ i ] == main.ERROR:
2547 getResults = main.FALSE
2548 sizeResponses = []
2549 threads = []
2550 for i in range( numControllers ):
2551 t = main.Thread( target=CLIs[i].setTestSize,
2552 name="setTestSize-" + str( i ),
2553 args=[ onosSetName ] )
2554 threads.append( t )
2555 t.start()
2556 for t in threads:
2557 t.join()
2558 sizeResponses.append( t.result )
2559 sizeResults = main.TRUE
2560 for i in range( numControllers ):
2561 if size != sizeResponses[ i ]:
2562 sizeResults = main.FALSE
2563 main.log.error( "ONOS" + str( i + 1 ) +
2564 " expected a size of " + str( size ) +
2565 " for set " + onosSetName +
2566 " but got " + str( sizeResponses[ i ] ) )
2567 removeResults = removeResults and getResults and sizeResults
2568 utilities.assert_equals( expect=main.TRUE,
2569 actual=removeResults,
2570 onpass="Set remove correct",
2571 onfail="Set remove was incorrect" )
2572
2573 main.step( "Distributed Set removeAll()" )
2574 onosSet.difference_update( addAllValue.split() )
2575 removeAllResponses = []
2576 threads = []
2577 try:
2578 for i in range( numControllers ):
2579 t = main.Thread( target=CLIs[i].setTestRemove,
2580 name="setTestRemoveAll-" + str( i ),
2581 args=[ onosSetName, addAllValue ] )
2582 threads.append( t )
2583 t.start()
2584 for t in threads:
2585 t.join()
2586 removeAllResponses.append( t.result )
2587 except Exception, e:
2588 main.log.exception(e)
2589
2590 # main.TRUE = successfully changed the set
2591 # main.FALSE = action resulted in no change in set
2592 # main.ERROR - Some error in executing the function
2593 removeAllResults = main.TRUE
2594 for i in range( numControllers ):
2595 if removeAllResponses[ i ] == main.TRUE:
2596 # All is well
2597 pass
2598 elif removeAllResponses[ i ] == main.FALSE:
2599 # not in set, probably fine
2600 pass
2601 elif removeAllResponses[ i ] == main.ERROR:
2602 # Error in execution
2603 removeAllResults = main.FALSE
2604 else:
2605 # unexpected result
2606 removeAllResults = main.FALSE
2607 if removeAllResults != main.TRUE:
2608 main.log.error( "Error executing set removeAll" )
2609
2610 # Check if set is still correct
2611 size = len( onosSet )
2612 getResponses = []
2613 threads = []
2614 for i in range( numControllers ):
2615 t = main.Thread( target=CLIs[i].setTestGet,
2616 name="setTestGet-" + str( i ),
2617 args=[ onosSetName ] )
2618 threads.append( t )
2619 t.start()
2620 for t in threads:
2621 t.join()
2622 getResponses.append( t.result )
2623 getResults = main.TRUE
2624 for i in range( numControllers ):
2625 if isinstance( getResponses[ i ], list):
2626 current = set( getResponses[ i ] )
2627 if len( current ) == len( getResponses[ i ] ):
2628 # no repeats
2629 if onosSet != current:
2630 main.log.error( "ONOS" + str( i + 1 ) +
2631 " has incorrect view" +
2632 " of set " + onosSetName + ":\n" +
2633 str( getResponses[ i ] ) )
2634 main.log.debug( "Expected: " + str( onosSet ) )
2635 main.log.debug( "Actual: " + str( current ) )
2636 getResults = main.FALSE
2637 else:
2638 # error, set is not a set
2639 main.log.error( "ONOS" + str( i + 1 ) +
2640 " has repeat elements in" +
2641 " set " + onosSetName + ":\n" +
2642 str( getResponses[ i ] ) )
2643 getResults = main.FALSE
2644 elif getResponses[ i ] == main.ERROR:
2645 getResults = main.FALSE
2646 sizeResponses = []
2647 threads = []
2648 for i in range( numControllers ):
2649 t = main.Thread( target=CLIs[i].setTestSize,
2650 name="setTestSize-" + str( i ),
2651 args=[ onosSetName ] )
2652 threads.append( t )
2653 t.start()
2654 for t in threads:
2655 t.join()
2656 sizeResponses.append( t.result )
2657 sizeResults = main.TRUE
2658 for i in range( numControllers ):
2659 if size != sizeResponses[ i ]:
2660 sizeResults = main.FALSE
2661 main.log.error( "ONOS" + str( i + 1 ) +
2662 " expected a size of " + str( size ) +
2663 " for set " + onosSetName +
2664 " but got " + str( sizeResponses[ i ] ) )
2665 removeAllResults = removeAllResults and getResults and sizeResults
2666 utilities.assert_equals( expect=main.TRUE,
2667 actual=removeAllResults,
2668 onpass="Set removeAll correct",
2669 onfail="Set removeAll was incorrect" )
2670
2671 main.step( "Distributed Set addAll()" )
2672 onosSet.update( addAllValue.split() )
2673 addResponses = []
2674 threads = []
2675 for i in range( numControllers ):
2676 t = main.Thread( target=CLIs[i].setTestAdd,
2677 name="setTestAddAll-" + str( i ),
2678 args=[ onosSetName, addAllValue ] )
2679 threads.append( t )
2680 t.start()
2681 for t in threads:
2682 t.join()
2683 addResponses.append( t.result )
2684
2685 # main.TRUE = successfully changed the set
2686 # main.FALSE = action resulted in no change in set
2687 # main.ERROR - Some error in executing the function
2688 addAllResults = main.TRUE
2689 for i in range( numControllers ):
2690 if addResponses[ i ] == main.TRUE:
2691 # All is well
2692 pass
2693 elif addResponses[ i ] == main.FALSE:
2694 # Already in set, probably fine
2695 pass
2696 elif addResponses[ i ] == main.ERROR:
2697 # Error in execution
2698 addAllResults = main.FALSE
2699 else:
2700 # unexpected result
2701 addAllResults = main.FALSE
2702 if addAllResults != main.TRUE:
2703 main.log.error( "Error executing set addAll" )
2704
2705 # Check if set is still correct
2706 size = len( onosSet )
2707 getResponses = []
2708 threads = []
2709 for i in range( numControllers ):
2710 t = main.Thread( target=CLIs[i].setTestGet,
2711 name="setTestGet-" + str( i ),
2712 args=[ onosSetName ] )
2713 threads.append( t )
2714 t.start()
2715 for t in threads:
2716 t.join()
2717 getResponses.append( t.result )
2718 getResults = main.TRUE
2719 for i in range( numControllers ):
2720 if isinstance( getResponses[ i ], list):
2721 current = set( getResponses[ i ] )
2722 if len( current ) == len( getResponses[ i ] ):
2723 # no repeats
2724 if onosSet != current:
2725 main.log.error( "ONOS" + str( i + 1 ) +
2726 " has incorrect view" +
2727 " of set " + onosSetName + ":\n" +
2728 str( getResponses[ i ] ) )
2729 main.log.debug( "Expected: " + str( onosSet ) )
2730 main.log.debug( "Actual: " + str( current ) )
2731 getResults = main.FALSE
2732 else:
2733 # error, set is not a set
2734 main.log.error( "ONOS" + str( i + 1 ) +
2735 " has repeat elements in" +
2736 " set " + onosSetName + ":\n" +
2737 str( getResponses[ i ] ) )
2738 getResults = main.FALSE
2739 elif getResponses[ i ] == main.ERROR:
2740 getResults = main.FALSE
2741 sizeResponses = []
2742 threads = []
2743 for i in range( numControllers ):
2744 t = main.Thread( target=CLIs[i].setTestSize,
2745 name="setTestSize-" + str( i ),
2746 args=[ onosSetName ] )
2747 threads.append( t )
2748 t.start()
2749 for t in threads:
2750 t.join()
2751 sizeResponses.append( t.result )
2752 sizeResults = main.TRUE
2753 for i in range( numControllers ):
2754 if size != sizeResponses[ i ]:
2755 sizeResults = main.FALSE
2756 main.log.error( "ONOS" + str( i + 1 ) +
2757 " expected a size of " + str( size ) +
2758 " for set " + onosSetName +
2759 " but got " + str( sizeResponses[ i ] ) )
2760 addAllResults = addAllResults and getResults and sizeResults
2761 utilities.assert_equals( expect=main.TRUE,
2762 actual=addAllResults,
2763 onpass="Set addAll correct",
2764 onfail="Set addAll was incorrect" )
2765
2766 main.step( "Distributed Set clear()" )
2767 onosSet.clear()
2768 clearResponses = []
2769 threads = []
2770 for i in range( numControllers ):
2771 t = main.Thread( target=CLIs[i].setTestRemove,
2772 name="setTestClear-" + str( i ),
2773 args=[ onosSetName, " "], # Values doesn't matter
2774 kwargs={ "clear": True } )
2775 threads.append( t )
2776 t.start()
2777 for t in threads:
2778 t.join()
2779 clearResponses.append( t.result )
2780
2781 # main.TRUE = successfully changed the set
2782 # main.FALSE = action resulted in no change in set
2783 # main.ERROR - Some error in executing the function
2784 clearResults = main.TRUE
2785 for i in range( numControllers ):
2786 if clearResponses[ i ] == main.TRUE:
2787 # All is well
2788 pass
2789 elif clearResponses[ i ] == main.FALSE:
2790 # Nothing set, probably fine
2791 pass
2792 elif clearResponses[ i ] == main.ERROR:
2793 # Error in execution
2794 clearResults = main.FALSE
2795 else:
2796 # unexpected result
2797 clearResults = main.FALSE
2798 if clearResults != main.TRUE:
2799 main.log.error( "Error executing set clear" )
2800
2801 # Check if set is still correct
2802 size = len( onosSet )
2803 getResponses = []
2804 threads = []
2805 for i in range( numControllers ):
2806 t = main.Thread( target=CLIs[i].setTestGet,
2807 name="setTestGet-" + str( i ),
2808 args=[ onosSetName ] )
2809 threads.append( t )
2810 t.start()
2811 for t in threads:
2812 t.join()
2813 getResponses.append( t.result )
2814 getResults = main.TRUE
2815 for i in range( numControllers ):
2816 if isinstance( getResponses[ i ], list):
2817 current = set( getResponses[ i ] )
2818 if len( current ) == len( getResponses[ i ] ):
2819 # no repeats
2820 if onosSet != current:
2821 main.log.error( "ONOS" + str( i + 1 ) +
2822 " has incorrect view" +
2823 " of set " + onosSetName + ":\n" +
2824 str( getResponses[ i ] ) )
2825 main.log.debug( "Expected: " + str( onosSet ) )
2826 main.log.debug( "Actual: " + str( current ) )
2827 getResults = main.FALSE
2828 else:
2829 # error, set is not a set
2830 main.log.error( "ONOS" + str( i + 1 ) +
2831 " has repeat elements in" +
2832 " set " + onosSetName + ":\n" +
2833 str( getResponses[ i ] ) )
2834 getResults = main.FALSE
2835 elif getResponses[ i ] == main.ERROR:
2836 getResults = main.FALSE
2837 sizeResponses = []
2838 threads = []
2839 for i in range( numControllers ):
2840 t = main.Thread( target=CLIs[i].setTestSize,
2841 name="setTestSize-" + str( i ),
2842 args=[ onosSetName ] )
2843 threads.append( t )
2844 t.start()
2845 for t in threads:
2846 t.join()
2847 sizeResponses.append( t.result )
2848 sizeResults = main.TRUE
2849 for i in range( numControllers ):
2850 if size != sizeResponses[ i ]:
2851 sizeResults = main.FALSE
2852 main.log.error( "ONOS" + str( i + 1 ) +
2853 " expected a size of " + str( size ) +
2854 " for set " + onosSetName +
2855 " but got " + str( sizeResponses[ i ] ) )
2856 clearResults = clearResults and getResults and sizeResults
2857 utilities.assert_equals( expect=main.TRUE,
2858 actual=clearResults,
2859 onpass="Set clear correct",
2860 onfail="Set clear was incorrect" )
2861
2862 main.step( "Distributed Set addAll()" )
2863 onosSet.update( addAllValue.split() )
2864 addResponses = []
2865 threads = []
2866 for i in range( numControllers ):
2867 t = main.Thread( target=CLIs[i].setTestAdd,
2868 name="setTestAddAll-" + str( i ),
2869 args=[ onosSetName, addAllValue ] )
2870 threads.append( t )
2871 t.start()
2872 for t in threads:
2873 t.join()
2874 addResponses.append( t.result )
2875
2876 # main.TRUE = successfully changed the set
2877 # main.FALSE = action resulted in no change in set
2878 # main.ERROR - Some error in executing the function
2879 addAllResults = main.TRUE
2880 for i in range( numControllers ):
2881 if addResponses[ i ] == main.TRUE:
2882 # All is well
2883 pass
2884 elif addResponses[ i ] == main.FALSE:
2885 # Already in set, probably fine
2886 pass
2887 elif addResponses[ i ] == main.ERROR:
2888 # Error in execution
2889 addAllResults = main.FALSE
2890 else:
2891 # unexpected result
2892 addAllResults = main.FALSE
2893 if addAllResults != main.TRUE:
2894 main.log.error( "Error executing set addAll" )
2895
2896 # Check if set is still correct
2897 size = len( onosSet )
2898 getResponses = []
2899 threads = []
2900 for i in range( numControllers ):
2901 t = main.Thread( target=CLIs[i].setTestGet,
2902 name="setTestGet-" + str( i ),
2903 args=[ onosSetName ] )
2904 threads.append( t )
2905 t.start()
2906 for t in threads:
2907 t.join()
2908 getResponses.append( t.result )
2909 getResults = main.TRUE
2910 for i in range( numControllers ):
2911 if isinstance( getResponses[ i ], list):
2912 current = set( getResponses[ i ] )
2913 if len( current ) == len( getResponses[ i ] ):
2914 # no repeats
2915 if onosSet != current:
2916 main.log.error( "ONOS" + str( i + 1 ) +
2917 " has incorrect view" +
2918 " of set " + onosSetName + ":\n" +
2919 str( getResponses[ i ] ) )
2920 main.log.debug( "Expected: " + str( onosSet ) )
2921 main.log.debug( "Actual: " + str( current ) )
2922 getResults = main.FALSE
2923 else:
2924 # error, set is not a set
2925 main.log.error( "ONOS" + str( i + 1 ) +
2926 " has repeat elements in" +
2927 " set " + onosSetName + ":\n" +
2928 str( getResponses[ i ] ) )
2929 getResults = main.FALSE
2930 elif getResponses[ i ] == main.ERROR:
2931 getResults = main.FALSE
2932 sizeResponses = []
2933 threads = []
2934 for i in range( numControllers ):
2935 t = main.Thread( target=CLIs[i].setTestSize,
2936 name="setTestSize-" + str( i ),
2937 args=[ onosSetName ] )
2938 threads.append( t )
2939 t.start()
2940 for t in threads:
2941 t.join()
2942 sizeResponses.append( t.result )
2943 sizeResults = main.TRUE
2944 for i in range( numControllers ):
2945 if size != sizeResponses[ i ]:
2946 sizeResults = main.FALSE
2947 main.log.error( "ONOS" + str( i + 1 ) +
2948 " expected a size of " + str( size ) +
2949 " for set " + onosSetName +
2950 " but got " + str( sizeResponses[ i ] ) )
2951 addAllResults = addAllResults and getResults and sizeResults
2952 utilities.assert_equals( expect=main.TRUE,
2953 actual=addAllResults,
2954 onpass="Set addAll correct",
2955 onfail="Set addAll was incorrect" )
2956
2957 main.step( "Distributed Set retain()" )
2958 onosSet.intersection_update( retainValue.split() )
2959 retainResponses = []
2960 threads = []
2961 for i in range( numControllers ):
2962 t = main.Thread( target=CLIs[i].setTestRemove,
2963 name="setTestRetain-" + str( i ),
2964 args=[ onosSetName, retainValue ],
2965 kwargs={ "retain": True } )
2966 threads.append( t )
2967 t.start()
2968 for t in threads:
2969 t.join()
2970 retainResponses.append( t.result )
2971
2972 # main.TRUE = successfully changed the set
2973 # main.FALSE = action resulted in no change in set
2974 # main.ERROR - Some error in executing the function
2975 retainResults = main.TRUE
2976 for i in range( numControllers ):
2977 if retainResponses[ i ] == main.TRUE:
2978 # All is well
2979 pass
2980 elif retainResponses[ i ] == main.FALSE:
2981 # Already in set, probably fine
2982 pass
2983 elif retainResponses[ i ] == main.ERROR:
2984 # Error in execution
2985 retainResults = main.FALSE
2986 else:
2987 # unexpected result
2988 retainResults = main.FALSE
2989 if retainResults != main.TRUE:
2990 main.log.error( "Error executing set retain" )
2991
2992 # Check if set is still correct
2993 size = len( onosSet )
2994 getResponses = []
2995 threads = []
2996 for i in range( numControllers ):
2997 t = main.Thread( target=CLIs[i].setTestGet,
2998 name="setTestGet-" + str( i ),
2999 args=[ onosSetName ] )
3000 threads.append( t )
3001 t.start()
3002 for t in threads:
3003 t.join()
3004 getResponses.append( t.result )
3005 getResults = main.TRUE
3006 for i in range( numControllers ):
3007 if isinstance( getResponses[ i ], list):
3008 current = set( getResponses[ i ] )
3009 if len( current ) == len( getResponses[ i ] ):
3010 # no repeats
3011 if onosSet != current:
3012 main.log.error( "ONOS" + str( i + 1 ) +
3013 " has incorrect view" +
3014 " of set " + onosSetName + ":\n" +
3015 str( getResponses[ i ] ) )
3016 main.log.debug( "Expected: " + str( onosSet ) )
3017 main.log.debug( "Actual: " + str( current ) )
3018 getResults = main.FALSE
3019 else:
3020 # error, set is not a set
3021 main.log.error( "ONOS" + str( i + 1 ) +
3022 " has repeat elements in" +
3023 " set " + onosSetName + ":\n" +
3024 str( getResponses[ i ] ) )
3025 getResults = main.FALSE
3026 elif getResponses[ i ] == main.ERROR:
3027 getResults = main.FALSE
3028 sizeResponses = []
3029 threads = []
3030 for i in range( numControllers ):
3031 t = main.Thread( target=CLIs[i].setTestSize,
3032 name="setTestSize-" + str( i ),
3033 args=[ onosSetName ] )
3034 threads.append( t )
3035 t.start()
3036 for t in threads:
3037 t.join()
3038 sizeResponses.append( t.result )
3039 sizeResults = main.TRUE
3040 for i in range( numControllers ):
3041 if size != sizeResponses[ i ]:
3042 sizeResults = main.FALSE
3043 main.log.error( "ONOS" + str( i + 1 ) +
3044 " expected a size of " +
3045 str( size ) + " for set " + onosSetName +
3046 " but got " + str( sizeResponses[ i ] ) )
3047 retainResults = retainResults and getResults and sizeResults
3048 utilities.assert_equals( expect=main.TRUE,
3049 actual=retainResults,
3050 onpass="Set retain correct",
3051 onfail="Set retain was incorrect" )
3052