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