blob: 3c4541c496dce1b1e7dd4b522cd73188e67bda67 [file] [log] [blame]
Jon Hall63604932015-02-26 17:09:50 -08001"""
2Description: This test is to determine how ONOS behaves in a control network
3 partion. ONOS 1,2,3 will be split into a sub cluster and ONOS
4 4,5,6,7 will be in another sub-cluster.
5
6List of test cases:
7CASE1: Compile ONOS and push it to the test machines
8CASE2: Assign mastership to controllers
9CASE3: Assign intents
10CASE4: Ping across added host intents
11CASE5: Reading state of ONOS
12CASE6: The Failure case. We will create IPTables rules here.
13CASE7: Check state after control plane partition.
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: Repair network partition
23"""
24# FIXME: Add new comparison case for during the failure?
25class HATestNetworkPartition:
26
27 def __init__( self ):
28 self.default = ''
29
30 def CASE1( self, main ):
31 """
32 CASE1 is to compile ONOS and push it to the test machines
33
34 Startup sequence:
35 cell <name>
36 onos-verify-cell
37 NOTE: temporary - onos-remove-raft-logs
38 onos-uninstall
39 start mininet
40 git pull
41 mvn clean install
42 onos-package
43 onos-install -f
44 onos-wait-for-start
45 start cli sessions
46 start tcpdump
47 """
48 main.log.report( "ONOS HA test: Network partition - initialization" )
49 main.log.report( "This test will partition a 7 node cluster into " +
50 "3 node and 4 node sub clusters by blocking " +
51 "communication between nodes." )
52 main.case( "Setting up test environment" )
53 # TODO: save all the timers and output them for plotting
54
55 # load some vairables from the params file
56 PULLCODE = False
57 if main.params[ 'Git' ] == 'True':
58 PULLCODE = True
59 gitBranch = main.params[ 'branch' ]
60 cellName = main.params[ 'ENV' ][ 'cellName' ]
61
62 # set global variables
63 global ONOS1Ip
64 global ONOS1Port
65 global ONOS2Ip
66 global ONOS2Port
67 global ONOS3Ip
68 global ONOS3Port
69 global ONOS4Ip
70 global ONOS4Port
71 global ONOS5Ip
72 global ONOS5Port
73 global ONOS6Ip
74 global ONOS6Port
75 global ONOS7Ip
76 global ONOS7Port
77 global numControllers
78
79 ONOS1Ip = main.params[ 'CTRL' ][ 'ip1' ]
80 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
81 ONOS2Ip = main.params[ 'CTRL' ][ 'ip2' ]
82 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
83 ONOS3Ip = main.params[ 'CTRL' ][ 'ip3' ]
84 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
85 ONOS4Ip = main.params[ 'CTRL' ][ 'ip4' ]
86 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
87 ONOS5Ip = main.params[ 'CTRL' ][ 'ip5' ]
88 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
89 ONOS6Ip = main.params[ 'CTRL' ][ 'ip6' ]
90 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
91 ONOS7Ip = main.params[ 'CTRL' ][ 'ip7' ]
92 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
93 numControllers = int( main.params[ 'num_controllers' ] )
94
95 main.step( "Applying cell variable to environment" )
96 cellResult = main.ONOSbench.setCell( cellName )
97 verifyResult = main.ONOSbench.verifyCell()
98
99 # FIXME:this is short term fix
100 main.log.report( "Removing raft logs" )
101 main.ONOSbench.onosRemoveRaftLogs()
102 main.log.report( "Uninstalling ONOS" )
103 main.ONOSbench.onosUninstall( ONOS1Ip )
104 main.ONOSbench.onosUninstall( ONOS2Ip )
105 main.ONOSbench.onosUninstall( ONOS3Ip )
106 main.ONOSbench.onosUninstall( ONOS4Ip )
107 main.ONOSbench.onosUninstall( ONOS5Ip )
108 main.ONOSbench.onosUninstall( ONOS6Ip )
109 main.ONOSbench.onosUninstall( ONOS7Ip )
110
111 cleanInstallResult = main.TRUE
112 gitPullResult = main.TRUE
113
114 main.step( "Starting Mininet" )
115 main.Mininet1.startNet( )
116
117 main.step( "Compiling the latest version of ONOS" )
118 if PULLCODE:
119 main.step( "Git checkout and pull " + gitBranch )
120 main.ONOSbench.gitCheckout( gitBranch )
121 gitPullResult = main.ONOSbench.gitPull()
122
123 main.step( "Using mvn clean & install" )
124 cleanInstallResult = main.ONOSbench.cleanInstall()
125 else:
126 main.log.warn( "Did not pull new code so skipping mvn " +
127 "clean install" )
128 main.ONOSbench.getVersion( report=True )
129
130 main.step( "Creating ONOS package" )
131 packageResult = main.ONOSbench.onosPackage()
132
133 main.step( "Installing ONOS package" )
134 onos1InstallResult = main.ONOSbench.onosInstall( options="-f",
135 node=ONOS1Ip )
136 onos2InstallResult = main.ONOSbench.onosInstall( options="-f",
137 node=ONOS2Ip )
138 onos3InstallResult = main.ONOSbench.onosInstall( options="-f",
139 node=ONOS3Ip )
140 onos4InstallResult = main.ONOSbench.onosInstall( options="-f",
141 node=ONOS4Ip )
142 onos5InstallResult = main.ONOSbench.onosInstall( options="-f",
143 node=ONOS5Ip )
144 onos6InstallResult = main.ONOSbench.onosInstall( options="-f",
145 node=ONOS6Ip )
146 onos7InstallResult = main.ONOSbench.onosInstall( options="-f",
147 node=ONOS7Ip )
148 onosInstallResult = onos1InstallResult and onos2InstallResult\
149 and onos3InstallResult and onos4InstallResult\
150 and onos5InstallResult and onos6InstallResult\
151 and onos7InstallResult
152
153 main.step( "Checking if ONOS is up yet" )
154 for i in range( 2 ):
155 onos1Isup = main.ONOSbench.isup( ONOS1Ip )
156 if not onos1Isup:
157 main.log.report( "ONOS1 didn't start!" )
158 main.ONOSbench.onosStop( ONOS1Ip )
159 main.ONOSbench.onosStart( ONOS1Ip )
160 onos2Isup = main.ONOSbench.isup( ONOS2Ip )
161 if not onos2Isup:
162 main.log.report( "ONOS2 didn't start!" )
163 main.ONOSbench.onosStop( ONOS2Ip )
164 main.ONOSbench.onosStart( ONOS2Ip )
165 onos3Isup = main.ONOSbench.isup( ONOS3Ip )
166 if not onos3Isup:
167 main.log.report( "ONOS3 didn't start!" )
168 main.ONOSbench.onosStop( ONOS3Ip )
169 main.ONOSbench.onosStart( ONOS3Ip )
170 onos4Isup = main.ONOSbench.isup( ONOS4Ip )
171 if not onos4Isup:
172 main.log.report( "ONOS4 didn't start!" )
173 main.ONOSbench.onosStop( ONOS4Ip )
174 main.ONOSbench.onosStart( ONOS4Ip )
175 onos5Isup = main.ONOSbench.isup( ONOS5Ip )
176 if not onos5Isup:
177 main.log.report( "ONOS5 didn't start!" )
178 main.ONOSbench.onosStop( ONOS5Ip )
179 main.ONOSbench.onosStart( ONOS5Ip )
180 onos6Isup = main.ONOSbench.isup( ONOS6Ip )
181 if not onos6Isup:
182 main.log.report( "ONOS6 didn't start!" )
183 main.ONOSbench.onosStop( ONOS6Ip )
184 main.ONOSbench.onosStart( ONOS6Ip )
185 onos7Isup = main.ONOSbench.isup( ONOS7Ip )
186 if not onos7Isup:
187 main.log.report( "ONOS7 didn't start!" )
188 main.ONOSbench.onosStop( ONOS7Ip )
189 main.ONOSbench.onosStart( ONOS7Ip )
190 onosIsupResult = onos1Isup and onos2Isup and onos3Isup\
191 and onos4Isup and onos5Isup and onos6Isup and onos7Isup
192 if onosIsupResult == main.TRUE:
193 break
194
195 cliResult1 = main.ONOScli1.startOnosCli( ONOS1Ip )
196 cliResult2 = main.ONOScli2.startOnosCli( ONOS2Ip )
197 cliResult3 = main.ONOScli3.startOnosCli( ONOS3Ip )
198 cliResult4 = main.ONOScli4.startOnosCli( ONOS4Ip )
199 cliResult5 = main.ONOScli5.startOnosCli( ONOS5Ip )
200 cliResult6 = main.ONOScli6.startOnosCli( ONOS6Ip )
201 cliResult7 = main.ONOScli7.startOnosCli( ONOS7Ip )
202 cliResults = cliResult1 and cliResult2 and cliResult3 and\
203 cliResult4 and cliResult5 and cliResult6 and cliResult7
204
205 main.step( "Start Packet Capture MN" )
206 main.Mininet2.startTcpdump(
207 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
208 + "-MN.pcap",
209 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
210 port=main.params[ 'MNtcpdump' ][ 'port' ] )
211
212 case1Result = ( cleanInstallResult and packageResult and
213 cellResult and verifyResult and onosInstallResult
214 and onosIsupResult and cliResults )
215
216 utilities.assert_equals( expect=main.TRUE, actual=case1Result,
217 onpass="Test startup successful",
218 onfail="Test startup NOT successful" )
219
220 if case1Result == main.FALSE:
221 main.cleanup()
222 main.exit()
223
224 def CASE2( self, main ):
225 """
226 Assign mastership to controllers
227 """
228 import re
229
230 main.log.report( "Assigning switches to controllers" )
231 main.case( "Assigning Controllers" )
232 main.step( "Assign switches to controllers" )
233
234 for i in range( 1, 29 ):
235 main.Mininet1.assignSwController(
236 sw=str( i ),
237 count=numControllers,
238 ip1=ONOS1Ip, port1=ONOS1Port,
239 ip2=ONOS2Ip, port2=ONOS2Port,
240 ip3=ONOS3Ip, port3=ONOS3Port,
241 ip4=ONOS4Ip, port4=ONOS4Port,
242 ip5=ONOS5Ip, port5=ONOS5Port,
243 ip6=ONOS6Ip, port6=ONOS6Port,
244 ip7=ONOS7Ip, port7=ONOS7Port )
245
246 mastershipCheck = main.TRUE
247 for i in range( 1, 29 ):
248 response = main.Mininet1.getSwController( "s" + str( i ) )
249 try:
250 main.log.info( str( response ) )
251 except:
252 main.log.info( repr( response ) )
253 if re.search( "tcp:" + ONOS1Ip, response )\
254 and re.search( "tcp:" + ONOS2Ip, response )\
255 and re.search( "tcp:" + ONOS3Ip, response )\
256 and re.search( "tcp:" + ONOS4Ip, response )\
257 and re.search( "tcp:" + ONOS5Ip, response )\
258 and re.search( "tcp:" + ONOS6Ip, response )\
259 and re.search( "tcp:" + ONOS7Ip, response ):
260 mastershipCheck = mastershipCheck and main.TRUE
261 else:
262 mastershipCheck = main.FALSE
263 if mastershipCheck == main.TRUE:
264 main.log.report( "Switch mastership assigned correctly" )
265 utilities.assert_equals(
266 expect=main.TRUE,
267 actual=mastershipCheck,
268 onpass="Switch mastership assigned correctly",
269 onfail="Switches not assigned correctly to controllers" )
270
271 # Manually assign mastership to the controller we want
272 roleCall = main.TRUE
273 roleCheck = main.TRUE
274
275 # Assign switch
276 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
277 roleCall = roleCall and main.ONOScli1.deviceRole(
278 deviceId,
279 ONOS1Ip )
280 # Check assignment
281 if ONOS1Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
282 roleCheck = roleCheck and main.TRUE
283 else:
284 roleCheck = roleCheck and main.FALSE
285
286 # Assign switch
287 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
288 roleCall = roleCall and main.ONOScli1.deviceRole(
289 deviceId,
290 ONOS1Ip )
291 # Check assignment
292 if ONOS1Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
293 roleCheck = roleCheck and main.TRUE
294 else:
295 roleCheck = roleCheck and main.FALSE
296
297 # Assign switch
298 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
299 roleCall = roleCall and main.ONOScli1.deviceRole(
300 deviceId,
301 ONOS2Ip )
302 # Check assignment
303 if ONOS2Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
304 roleCheck = roleCheck and main.TRUE
305 else:
306 roleCheck = roleCheck and main.FALSE
307
308 # Assign switch
309 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
310 roleCall = roleCall and main.ONOScli1.deviceRole(
311 deviceId,
312 ONOS2Ip )
313 # Check assignment
314 if ONOS2Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
315 roleCheck = roleCheck and main.TRUE
316 else:
317 roleCheck = roleCheck and main.FALSE
318
319 # Assign switch
320 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
321 roleCall = roleCall and main.ONOScli1.deviceRole(
322 deviceId,
323 ONOS3Ip )
324 # Check assignment
325 if ONOS3Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
326 roleCheck = roleCheck and main.TRUE
327 else:
328 roleCheck = roleCheck and main.FALSE
329
330 # Assign switch
331 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
332 roleCall = roleCall and main.ONOScli1.deviceRole(
333 deviceId,
334 ONOS3Ip )
335 # Check assignment
336 if ONOS3Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
337 roleCheck = roleCheck and main.TRUE
338 else:
339 roleCheck = roleCheck and main.FALSE
340
341 # Assign switch
342 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
343 roleCall = roleCall and main.ONOScli1.deviceRole(
344 deviceId,
345 ONOS4Ip )
346 # Check assignment
347 if ONOS4Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
348 roleCheck = roleCheck and main.TRUE
349 else:
350 roleCheck = roleCheck and main.FALSE
351
352 for i in range( 8, 18 ):
353 dpid = '3' + str( i ).zfill( 3 )
354 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
355 roleCall = roleCall and main.ONOScli1.deviceRole(
356 deviceId,
357 ONOS5Ip )
358 # Check assignment
359 if ONOS5Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
360 roleCheck = roleCheck and main.TRUE
361 else:
362 roleCheck = roleCheck and main.FALSE
363
364 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
365 roleCall = roleCall and main.ONOScli1.deviceRole(
366 deviceId,
367 ONOS6Ip )
368 # Check assignment
369 if ONOS6Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
370 roleCheck = roleCheck and main.TRUE
371 else:
372 roleCheck = roleCheck and main.FALSE
373
374 for i in range( 18, 28 ):
375 dpid = '6' + str( i ).zfill( 3 )
376 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
377 roleCall = roleCall and main.ONOScli1.deviceRole(
378 deviceId,
379 ONOS7Ip )
380 # Check assignment
381 if ONOS7Ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
382 roleCheck = roleCheck and main.TRUE
383 else:
384 roleCheck = roleCheck and main.FALSE
385
386 utilities.assert_equals(
387 expect=main.TRUE,
388 actual=roleCall,
389 onpass="Re-assigned switch mastership to designated controller",
390 onfail="Something wrong with deviceRole calls" )
391
392 utilities.assert_equals(
393 expect=main.TRUE,
394 actual=roleCheck,
395 onpass="Switches were successfully reassigned to designated " +
396 "controller",
397 onfail="Switches were not successfully reassigned" )
398 mastershipCheck = mastershipCheck and roleCall and roleCheck
399 utilities.assert_equals( expect=main.TRUE, actual=mastershipCheck,
400 onpass="Switch mastership correctly assigned",
401 onfail="Error in (re)assigning switch" +
402 " mastership" )
403
404 def CASE3( self, main ):
405 """
406 Assign intents
407 """
408 import time
409 import json
410 main.log.report( "Adding host intents" )
411 main.case( "Adding host Intents" )
412
413 main.step( "Discovering Hosts( Via pingall for now )" )
414 # FIXME: Once we have a host discovery mechanism, use that instead
415
416 # install onos-app-fwd
417 main.log.info( "Install reactive forwarding app" )
Jon Halla9d26da2015-03-30 16:45:32 -0700418 appResults = CLIs[0].activateApp( "org.onosproject.fwd" )
419 '''
Jon Hall63604932015-02-26 17:09:50 -0800420 main.ONOScli1.featureInstall( "onos-app-fwd" )
421 main.ONOScli2.featureInstall( "onos-app-fwd" )
422 main.ONOScli3.featureInstall( "onos-app-fwd" )
423 main.ONOScli4.featureInstall( "onos-app-fwd" )
424 main.ONOScli5.featureInstall( "onos-app-fwd" )
425 main.ONOScli6.featureInstall( "onos-app-fwd" )
426 main.ONOScli7.featureInstall( "onos-app-fwd" )
Jon Halla9d26da2015-03-30 16:45:32 -0700427 '''
Jon Hall63604932015-02-26 17:09:50 -0800428
429 # REACTIVE FWD test
430 pingResult = main.FALSE
431 time1 = time.time()
432 pingResult = main.Mininet1.pingall()
433 utilities.assert_equals(
434 expect=main.TRUE,
435 actual=pingResult,
436 onpass="Reactive Pingall test passed",
437 onfail="Reactive Pingall failed, one or more ping pairs failed" )
438 time2 = time.time()
439 main.log.info( "Time for pingall: %2f seconds" % ( time2 - time1 ) )
440
441 # uninstall onos-app-fwd
442 main.log.info( "Uninstall reactive forwarding app" )
Jon Halla9d26da2015-03-30 16:45:32 -0700443 appResults = appResults and CLIs[0].deactivateApp( "org.onosproject.fwd" )
444 '''
Jon Hall63604932015-02-26 17:09:50 -0800445 main.ONOScli1.featureUninstall( "onos-app-fwd" )
446 main.ONOScli2.featureUninstall( "onos-app-fwd" )
447 main.ONOScli3.featureUninstall( "onos-app-fwd" )
448 main.ONOScli4.featureUninstall( "onos-app-fwd" )
449 main.ONOScli5.featureUninstall( "onos-app-fwd" )
450 main.ONOScli6.featureUninstall( "onos-app-fwd" )
451 main.ONOScli7.featureUninstall( "onos-app-fwd" )
Jon Halla9d26da2015-03-30 16:45:32 -0700452 '''
Jon Hall63604932015-02-26 17:09:50 -0800453 # timeout for fwd flows
454 time.sleep( 10 )
455
456 main.step( "Add host intents" )
457 # TODO: move the host numbers to params
458 # Maybe look at all the paths we ping?
459 intentAddResult = True
460 for i in range( 8, 18 ):
461 main.log.info( "Adding host intent between h" + str( i ) +
462 " and h" + str( i + 10 ) )
463 host1 = "00:00:00:00:00:" + \
464 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
465 host2 = "00:00:00:00:00:" + \
466 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
467 # NOTE: getHost can return None
468 host1Dict = main.ONOScli1.getHost( host1 )
469 host2Dict = main.ONOScli1.getHost( host2 )
470 host1Id = None
471 host2Id = None
472 if host1Dict and host2Dict:
473 host1Id = host1Dict.get( 'id', None )
474 host2Id = host2Dict.get( 'id', None )
475 if host1Id and host2Id:
476 # distribute the intents across ONOS nodes
477 nodeNum = ( i % 7 ) + 1
478 node = getattr( main, ( 'ONOScli' + str( nodeNum ) ) )
479 tmpResult = node.addHostIntent(
480 host1Id,
481 host2Id )
482 else:
483 main.log.error( "Error, getHost() failed" )
484 main.log.warn( json.dumps( json.loads( main.ONOScli1.hosts() ),
485 sort_keys=True,
486 indent=4,
487 separators=( ',', ': ' ) ) )
488 tmpResult = main.FALSE
489 intentAddResult = bool( pingResult and intentAddResult
490 and tmpResult )
491 # FIXME Check that intents were added?
492 # TODO Use the new return from add host command and look at each
493 # intent individually
494 #
495 #
496 #
497 #
498 #
499 #
500 # End of for loop to add intents
501 # Print the intent states
502 intents = main.ONOScli1.intents( )
503 intentStates = []
504 for intent in json.loads( intents ): # Iter through intents of a node
505 intentStates.append( intent.get( 'state', None ) )
506 out = [ (i, intentStates.count( i ) ) for i in set( intentStates ) ]
507 main.log.info( dict( out ) )
508
509 utilities.assert_equals(
510 expect=True,
511 actual=intentAddResult,
512 onpass="Pushed host intents to ONOS",
513 onfail="Error in pushing host intents to ONOS" )
514 # TODO Check if intents all exist in datastore
515
516 def CASE4( self, main ):
517 """
518 Ping across added host intents
519 """
520 import json
521 description = " Ping across added host intents"
522 main.log.report( description )
523 main.case( description )
524 PingResult = main.TRUE
525 for i in range( 8, 18 ):
526 ping = main.Mininet1.pingHost(
527 src="h" + str( i ), target="h" + str( i + 10 ) )
528 PingResult = PingResult and ping
529 if ping == main.FALSE:
530 main.log.warn( "Ping failed between h" + str( i ) +
531 " and h" + str( i + 10 ) )
532 elif ping == main.TRUE:
533 main.log.info( "Ping test passed!" )
534 # Don't set PingResult or you'd override failures
535 if PingResult == main.FALSE:
536 main.log.report(
537 "Intents have not been installed correctly, pings failed." )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700538 main.log.warn( "ONOS1 intents: " )
Jon Hall63604932015-02-26 17:09:50 -0800539 main.log.warn( json.dumps( json.loads( main.ONOScli1.intents() ),
540 sort_keys=True,
541 indent=4,
542 separators=( ',', ': ' ) ) )
543 if PingResult == main.TRUE:
544 main.log.report(
545 "Intents have been installed correctly and verified by pings" )
546 utilities.assert_equals(
547 expect=main.TRUE,
548 actual=PingResult,
549 onpass="Intents have been installed correctly and pings work",
550 onfail="Intents have not been installed correctly, pings failed." )
551
552 def CASE5( self, main ):
553 """
554 Reading state of ONOS
555 """
556 import json
557 # assumes that sts is already in you PYTHONPATH
558 from sts.topology.teston_topology import TestONTopology
559
560 main.log.report( "Setting up and gathering data for current state" )
561 main.case( "Setting up and gathering data for current state" )
562 # The general idea for this test case is to pull the state of
563 # ( intents,flows, topology,... ) from each ONOS node
564 # We can then compare them with eachother and also with past states
565
566 main.step( "Get the Mastership of each switch from each controller" )
567 global mastershipState
568 mastershipState = []
569
570 # Assert that each device has a master
571 ONOS1MasterNotNull = main.ONOScli1.rolesNotNull()
572 ONOS2MasterNotNull = main.ONOScli2.rolesNotNull()
573 ONOS3MasterNotNull = main.ONOScli3.rolesNotNull()
574 ONOS4MasterNotNull = main.ONOScli4.rolesNotNull()
575 ONOS5MasterNotNull = main.ONOScli5.rolesNotNull()
576 ONOS6MasterNotNull = main.ONOScli6.rolesNotNull()
577 ONOS7MasterNotNull = main.ONOScli7.rolesNotNull()
578 rolesNotNull = ONOS1MasterNotNull and ONOS2MasterNotNull and\
579 ONOS3MasterNotNull and ONOS4MasterNotNull and\
580 ONOS5MasterNotNull and ONOS6MasterNotNull and\
581 ONOS7MasterNotNull
582 utilities.assert_equals(
583 expect=main.TRUE,
584 actual=rolesNotNull,
585 onpass="Each device has a master",
586 onfail="Some devices don't have a master assigned" )
587
588 ONOS1Mastership = main.ONOScli1.roles()
589 ONOS2Mastership = main.ONOScli2.roles()
590 ONOS3Mastership = main.ONOScli3.roles()
591 ONOS4Mastership = main.ONOScli4.roles()
592 ONOS5Mastership = main.ONOScli5.roles()
593 ONOS6Mastership = main.ONOScli6.roles()
594 ONOS7Mastership = main.ONOScli7.roles()
595 if "Error" in ONOS1Mastership or not ONOS1Mastership\
596 or "Error" in ONOS2Mastership or not ONOS2Mastership\
597 or "Error" in ONOS3Mastership or not ONOS3Mastership\
598 or "Error" in ONOS4Mastership or not ONOS4Mastership\
599 or "Error" in ONOS5Mastership or not ONOS5Mastership\
600 or "Error" in ONOS6Mastership or not ONOS6Mastership\
601 or "Error" in ONOS7Mastership or not ONOS7Mastership:
602 main.log.report( "Error in getting ONOS roles" )
603 for i in range( 1, numControllers + 1 ):
604 mastership = eval( "ONOS" + str( i ) + "Mastership" )
605 main.log.warn(
606 "ONOS" + str( i ) + " mastership response: " +
607 repr( mastership ) )
608 consistentMastership = main.FALSE
609 elif ONOS1Mastership == ONOS2Mastership\
610 and ONOS1Mastership == ONOS3Mastership\
611 and ONOS1Mastership == ONOS4Mastership\
612 and ONOS1Mastership == ONOS5Mastership\
613 and ONOS1Mastership == ONOS6Mastership\
614 and ONOS1Mastership == ONOS7Mastership:
615 mastershipState = ONOS1Mastership
616 consistentMastership = main.TRUE
617 main.log.report(
618 "Switch roles are consistent across all ONOS nodes" )
619 else:
620 for i in range( 1, numControllers + 1 ):
621 mastership = eval( "ONOS" + str( i ) + "Mastership" )
622 main.log.warn( "ONOS" + str( i ) + " roles: " +
623 json.dumps( json.loads( mastership ),
624 sort_keys=True,
625 indent=4,
626 separators=( ',', ': ' ) ) )
627 consistentMastership = main.FALSE
628 utilities.assert_equals(
629 expect=main.TRUE,
630 actual=consistentMastership,
631 onpass="Switch roles are consistent across all ONOS nodes",
632 onfail="ONOS nodes have different views of switch roles" )
633
634 main.step( "Get the intents from each controller" )
635 global intentState
636 intentState = []
637 ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
638 ONOS2Intents = main.ONOScli2.intents( jsonFormat=True )
639 ONOS3Intents = main.ONOScli3.intents( jsonFormat=True )
640 ONOS4Intents = main.ONOScli4.intents( jsonFormat=True )
641 ONOS5Intents = main.ONOScli5.intents( jsonFormat=True )
642 ONOS6Intents = main.ONOScli6.intents( jsonFormat=True )
643 ONOS7Intents = main.ONOScli7.intents( jsonFormat=True )
644 intentCheck = main.FALSE
645 if "Error" in ONOS1Intents or not ONOS1Intents\
646 or "Error" in ONOS2Intents or not ONOS2Intents\
647 or "Error" in ONOS3Intents or not ONOS3Intents\
648 or "Error" in ONOS4Intents or not ONOS4Intents\
649 or "Error" in ONOS5Intents or not ONOS5Intents\
650 or "Error" in ONOS6Intents or not ONOS6Intents\
651 or "Error" in ONOS7Intents or not ONOS7Intents:
652 main.log.report( "Error in getting ONOS intents" )
653 for i in range( 1, numControllers + 1 ):
654 intents = eval( "ONOS" + str( i ) + "Intents" )
655 main.log.warn(
656 "ONOS" + str( i ) + " intents response: " +
657 repr( intents ) )
658 elif ONOS1Intents == ONOS2Intents\
659 and ONOS1Intents == ONOS3Intents\
660 and ONOS1Intents == ONOS4Intents\
661 and ONOS1Intents == ONOS5Intents\
662 and ONOS1Intents == ONOS6Intents\
663 and ONOS1Intents == ONOS7Intents:
664 intentState = ONOS1Intents
665 intentCheck = main.TRUE
666 main.log.report( "Intents are consistent across all ONOS nodes" )
667 else:
668 for i in range( 1, numControllers + 1 ):
669 intents = eval( "ONOS" + str( i ) + "Intents" )
670 main.log.warn( "ONOS" + str( i ) + " intents: " +
671 json.dumps( json.loads( intents ),
672 sort_keys=True,
673 indent=4,
674 separators=( ',', ': ' ) ) )
675 utilities.assert_equals(
676 expect=main.TRUE,
677 actual=intentCheck,
678 onpass="Intents are consistent across all ONOS nodes",
679 onfail="ONOS nodes have different views of intents" )
680
681 main.step( "Get the flows from each controller" )
682 global flowState
683 flowState = []
684 ONOS1Flows = main.ONOScli1.flows( jsonFormat=True )
685 ONOS2Flows = main.ONOScli2.flows( jsonFormat=True )
686 ONOS3Flows = main.ONOScli3.flows( jsonFormat=True )
687 ONOS4Flows = main.ONOScli4.flows( jsonFormat=True )
688 ONOS5Flows = main.ONOScli5.flows( jsonFormat=True )
689 ONOS6Flows = main.ONOScli6.flows( jsonFormat=True )
690 ONOS7Flows = main.ONOScli7.flows( jsonFormat=True )
691 ONOS1FlowsJson = json.loads( ONOS1Flows )
692 ONOS2FlowsJson = json.loads( ONOS2Flows )
693 ONOS3FlowsJson = json.loads( ONOS3Flows )
694 ONOS4FlowsJson = json.loads( ONOS4Flows )
695 ONOS5FlowsJson = json.loads( ONOS5Flows )
696 ONOS6FlowsJson = json.loads( ONOS6Flows )
697 ONOS7FlowsJson = json.loads( ONOS7Flows )
698 flowCheck = main.FALSE
699 if "Error" in ONOS1Flows or not ONOS1Flows\
700 or "Error" in ONOS2Flows or not ONOS2Flows\
701 or "Error" in ONOS3Flows or not ONOS3Flows\
702 or "Error" in ONOS4Flows or not ONOS4Flows\
703 or "Error" in ONOS5Flows or not ONOS5Flows\
704 or "Error" in ONOS6Flows or not ONOS6Flows\
705 or "Error" in ONOS7Flows or not ONOS7Flows:
706 main.log.report( "Error in getting ONOS intents" )
707 for i in range( 1, numControllers + 1 ):
708 flowsIter = eval( "ONOS" + str( i ) + "Flows" )
709 main.log.warn( "ONOS" + str( i ) + " flows repsponse: " +
710 flowsIter )
711 elif len( ONOS1FlowsJson ) == len( ONOS2FlowsJson )\
712 and len( ONOS1FlowsJson ) == len( ONOS3FlowsJson )\
713 and len( ONOS1FlowsJson ) == len( ONOS4FlowsJson )\
714 and len( ONOS1FlowsJson ) == len( ONOS5FlowsJson )\
715 and len( ONOS1FlowsJson ) == len( ONOS6FlowsJson )\
716 and len( ONOS1FlowsJson ) == len( ONOS7FlowsJson ):
717 # TODO: Do a better check, maybe compare flows on switches?
718 flowState = ONOS1Flows
719 flowCheck = main.TRUE
720 main.log.report( "Flow count is consistent across all ONOS nodes" )
721 else:
722 for i in range( 1, numControllers + 1 ):
723 flowsJson = eval( "ONOS" + str( i ) + "FlowsJson" )
724 main.log.warn( "ONOS" + str( i ) + " flows repsponse: " +
725 json.dumps( flowsJson,
726 sort_keys=True,
727 indent=4,
728 separators=( ',', ': ' ) ) )
729 utilities.assert_equals(
730 expect=main.TRUE,
731 actual=flowCheck,
732 onpass="The flow count is consistent across all ONOS nodes",
733 onfail="ONOS nodes have different flow counts" )
734
735 main.step( "Get the OF Table entries" )
736 global flows
737 flows = []
738 for i in range( 1, 29 ):
739 flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
740
741 # TODO: Compare switch flow tables with ONOS flow tables
742
743 main.step( "Start continuous pings" )
744 for i in range( 1, 11 ):
745 source = main.params[ 'PING' ][ 'source' + str( i ) ]
746 target = main.params[ 'PING' ][ 'target' + str( i ) ]
747 main.Mininet2.pingLong(
748 src=source,
749 target=target,
750 pingTime=500 )
751 main.step( "Create TestONTopology object" )
752 ctrls = []
753 count = 1
754 while True:
755 temp = ()
756 if ( 'ip' + str( count ) ) in main.params[ 'CTRL' ]:
757 temp = temp + ( getattr( main, ( 'ONOS' + str( count ) ) ), )
758 temp = temp + ( "ONOS" + str( count ), )
759 temp = temp + ( main.params[ 'CTRL' ][ 'ip' + str( count ) ], )
760 temp = temp + \
761 ( eval( main.params[ 'CTRL' ][ 'port' + str( count ) ] ), )
762 ctrls.append( temp )
763 count = count + 1
764 else:
765 break
766 MNTopo = TestONTopology(
767 main.Mininet1,
768 ctrls ) # can also add Intent API info for intent operations
769
770 main.step( "Collecting topology information from ONOS" )
771 # TODO Refactor to a loop? We want all similar calls together?
772 # So get all "devices" as close together as possible
773 devices = []
774 print "ONOS1"
775 devices.append( main.ONOScli1.devices() )
776 print "ONOS2"
777 devices.append( main.ONOScli2.devices() )
778 print "ONOS3"
779 devices.append( main.ONOScli3.devices() )
780 print "ONOS4"
781 devices.append( main.ONOScli4.devices() )
782 print "ONOS5"
783 devices.append( main.ONOScli5.devices() )
784 print "ONOS6"
785 devices.append( main.ONOScli6.devices() )
786 print "ONOS7"
787 devices.append( main.ONOScli7.devices() )
788 hosts = []
789 hosts.append( main.ONOScli1.hosts() )
790 hosts.append( main.ONOScli2.hosts() )
791 hosts.append( main.ONOScli3.hosts() )
792 hosts.append( main.ONOScli4.hosts() )
793 hosts.append( main.ONOScli5.hosts() )
794 hosts.append( main.ONOScli6.hosts() )
795 hosts.append( main.ONOScli7.hosts() )
796 ports = []
797 ports.append( main.ONOScli1.ports() )
798 ports.append( main.ONOScli2.ports() )
799 ports.append( main.ONOScli3.ports() )
800 ports.append( main.ONOScli4.ports() )
801 ports.append( main.ONOScli5.ports() )
802 ports.append( main.ONOScli6.ports() )
803 ports.append( main.ONOScli7.ports() )
804 links = []
805 links.append( main.ONOScli1.links() )
806 links.append( main.ONOScli2.links() )
807 links.append( main.ONOScli3.links() )
808 links.append( main.ONOScli4.links() )
809 links.append( main.ONOScli5.links() )
810 links.append( main.ONOScli6.links() )
811 links.append( main.ONOScli7.links() )
812 clusters = []
813 clusters.append( main.ONOScli1.clusters() )
814 clusters.append( main.ONOScli2.clusters() )
815 clusters.append( main.ONOScli3.clusters() )
816 clusters.append( main.ONOScli4.clusters() )
817 clusters.append( main.ONOScli5.clusters() )
818 clusters.append( main.ONOScli6.clusters() )
819 clusters.append( main.ONOScli7.clusters() )
820 # Compare json objects for hosts and dataplane clusters
821
822 # hosts
823 consistentHostsResult = main.TRUE
824 for controller in range( len( hosts ) ):
825 controllerStr = str( controller + 1 )
826 if "Error" not in hosts[ controller ]:
827 if hosts[ controller ] == hosts[ 0 ]:
828 continue
829 else: # hosts not consistent
830 main.log.report( "hosts from ONOS" +
831 controllerStr +
832 " is inconsistent with ONOS1" )
833 main.log.warn( repr( hosts[ controller ] ) )
834 consistentHostsResult = main.FALSE
835
836 else:
837 main.log.report( "Error in getting ONOS hosts from ONOS" +
838 controllerStr )
839 consistentHostsResult = main.FALSE
840 main.log.warn( "ONOS" + controllerStr +
841 " hosts response: " +
842 repr( hosts[ controller ] ) )
843 utilities.assert_equals(
844 expect=main.TRUE,
845 actual=consistentHostsResult,
846 onpass="Hosts view is consistent across all ONOS nodes",
847 onfail="ONOS nodes have different views of hosts" )
848
849 # Strongly connected clusters of devices
850 consistentClustersResult = main.TRUE
851 for controller in range( len( clusters ) ):
852 if "Error" not in clusters[ controller ]:
853 if clusters[ controller ] == clusters[ 0 ]:
854 continue
855 else: # clusters not consistent
856 main.log.report( "clusters from ONOS" +
857 controllerStr +
858 " is inconsistent with ONOS1" )
859 consistentClustersResult = main.FALSE
860
861 else:
862 main.log.report( "Error in getting dataplane clusters " +
863 "from ONOS" + controllerStr )
864 consistentClustersResult = main.FALSE
865 main.log.warn( "ONOS" + controllerStr +
866 " clusters response: " +
867 repr( clusters[ controller ] ) )
868 utilities.assert_equals(
869 expect=main.TRUE,
870 actual=consistentClustersResult,
871 onpass="Clusters view is consistent across all ONOS nodes",
872 onfail="ONOS nodes have different views of clusters" )
873 # there should always only be one cluster
874 numClusters = len( json.loads( clusters[ 0 ] ) )
875 utilities.assert_equals(
876 expect=1,
877 actual=numClusters,
878 onpass="ONOS shows 1 SCC",
879 onfail="ONOS shows " +
880 str( numClusters ) +
881 " SCCs" )
882
883 main.step( "Comparing ONOS topology to MN" )
884 devicesResults = main.TRUE
885 portsResults = main.TRUE
886 linksResults = main.TRUE
887 for controller in range( numControllers ):
888 controllerStr = str( controller + 1 )
889 if devices[ controller ] or "Error" not in devices[ controller ]:
890 currentDevicesResult = main.Mininet1.compareSwitches(
891 MNTopo,
892 json.loads(
893 devices[ controller ] ) )
894 else:
895 currentDevicesResult = main.FALSE
896 utilities.assert_equals( expect=main.TRUE,
897 actual=currentDevicesResult,
898 onpass="ONOS" + controllerStr +
899 " Switches view is correct",
900 onfail="ONOS" + controllerStr +
901 " Switches view is incorrect" )
902
903 if ports[ controller ] or "Error" not in ports[ controller ]:
904 currentPortsResult = main.Mininet1.comparePorts(
905 MNTopo,
906 json.loads(
907 ports[ controller ] ) )
908 else:
909 currentPortsResult = main.FALSE
910 utilities.assert_equals( expect=main.TRUE,
911 actual=currentPortsResult,
912 onpass="ONOS" + controllerStr +
913 " ports view is correct",
914 onfail="ONOS" + controllerStr +
915 " ports view is incorrect" )
916
917 if links[ controller ] or "Error" not in links[ controller ]:
918 currentLinksResult = main.Mininet1.compareLinks(
919 MNTopo,
920 json.loads(
921 links[ controller ] ) )
922 else:
923 currentLinksResult = main.FALSE
924 utilities.assert_equals( expect=main.TRUE,
925 actual=currentLinksResult,
926 onpass="ONOS" + controllerStr +
927 " links view is correct",
928 onfail="ONOS" + controllerStr +
929 " links view is incorrect" )
930
931 devicesResults = devicesResults and currentDevicesResult
932 portsResults = portsResults and currentPortsResult
933 linksResults = linksResults and currentLinksResult
934
935 topoResult = devicesResults and portsResults and linksResults\
936 and consistentHostsResult and consistentClustersResult
937 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
938 onpass="Topology Check Test successful",
939 onfail="Topology Check Test NOT successful" )
940
941 finalAssert = main.TRUE
942 finalAssert = finalAssert and topoResult and flowCheck \
943 and intentCheck and consistentMastership and rolesNotNull
944 utilities.assert_equals( expect=main.TRUE, actual=finalAssert,
945 onpass="State check successful",
946 onfail="State check NOT successful" )
947
948 def CASE6( self, main ):
949 """
950 The Failure case. We will create IPTables rules here.
951 """
952 import time
953 main.log.report( "Wait 30 seconds instead of inducing a failure" )
954 time.sleep( 30 )
955
956 # 1 blocks 4,5,6,7, mn
957 # 2 blocks 4,5,6,7, mn
958 # 3 blocks 4,5,6,7, mn
959 # 4 block 1,2,3
960 # 5 blocks 1,2,3
961 # 6 blocks 1,2,3
962 # 7 blocks 1,2,3
963
964 # TODO: use new log command
965 logcmd = "log:log \" About to partition the ONOS nodes\""
966 main.ONOScli1.handle.sendline( logcmd )
967 main.ONOScli1.handle.expect( "onos>" )
968 print main.ONOScli1.handle.before
969 main.ONOScli2.handle.sendline( logcmd )
970 main.ONOScli2.handle.expect( "onos>" )
971 print main.ONOScli2.handle.before
972 main.ONOScli3.handle.sendline( logcmd )
973 main.ONOScli3.handle.expect( "onos>" )
974 print main.ONOScli3.handle.before
975 main.ONOScli4.handle.sendline( logcmd )
976 main.ONOScli4.handle.expect( "onos>" )
977 print main.ONOScli4.handle.before
978 main.ONOScli5.handle.sendline( logcmd )
979 main.ONOScli5.handle.expect( "onos>" )
980 print main.ONOScli5.handle.before
981 main.ONOScli6.handle.sendline( logcmd )
982 main.ONOScli6.handle.expect( "onos>" )
983 print main.ONOScli6.handle.before
984 main.ONOScli7.handle.sendline( logcmd )
985 main.ONOScli7.handle.expect( "onos>" )
986 print main.ONOScli7.handle.before
987
988 nodes = []
989 #create list of ONOS components
990 for controller in range( 1, numControllers + 1 ):
991 # loop through ONOS handlers
992 node = getattr( main, ( 'ONOS' + str( controller ) ) )
993 nodes.append( node )
994 for node in nodes:
995 # if node is in first half (rounded down )
996 # ( 0 through 2 ) < ( 3.5 - 1)
997 if nodes.index( node ) < ( numControllers / 2.0 - 1 ):
998 # blocked nodes are the last half ( rounded up )
999 # // is forced integer division
1000 for blockNode in nodes[ (numControllers // 2 + 1) * -1: ]:
1001 # block all traffic between these ONOS nodes
1002 # NOTE: ONOS 1 and 2 don't support state tracking
1003 node.setIpTables( blockNode.ip_address, states=False )
1004 node.setIpTables( blockNode.ip_address,
1005 direction="OUTPUT" , states=False )
1006 # block traffic between smaller subcluster and Mininet
1007 # TODO make OF controller port confgigurable
1008 # FIXME Remove this once ONOS can deal with the conflicting
1009 # device mastership
1010 node.setIpTables( main.Mininet1.ip_address, 6633,
1011 packet_type="tcp", states=False )
1012 else: # the larger subcluster
1013 # blocked nodes are the first half
1014 for blockNode in nodes[ :(numControllers // 2 ) ]:
1015 # block all traffic between these ONOS nodes
1016 node.setIpTables( blockNode.ip_address )
1017 node.setIpTables( blockNode.ip_address,
1018 direction="OUTPUT" )
1019 #FIXME update this
1020 utilities.assert_equals(
1021 expect=main.TRUE,
1022 actual=main.TRUE,
1023 onpass="Sleeping 30 seconds",
1024 onfail="Something is terribly wrong with my math" )
1025 main.ONOScli1.handle.sendline( "devices -j" )
1026 main.ONOScli1.handle.expect( ["onos>", "\$"] )
1027 print main.ONOScli1.handle.before
1028 main.ONOScli2.handle.sendline( "devices -j" )
1029 main.ONOScli2.handle.expect( ["onos>", "\$"] )
1030 print main.ONOScli2.handle.before
1031 main.ONOScli3.handle.sendline( "devices -j" )
1032 main.ONOScli3.handle.expect( ["onos>", "\$"] )
1033 print main.ONOScli3.handle.before
1034 main.ONOScli4.handle.sendline( "devices -j" )
1035 main.ONOScli4.handle.expect( ["onos>", "\$"] )
1036 print main.ONOScli4.handle.before
1037 main.ONOScli5.handle.sendline( "devices -j" )
1038 main.ONOScli5.handle.expect( ["onos>", "\$"] )
1039 print main.ONOScli5.handle.before
1040 main.ONOScli6.handle.sendline( "devices -j" )
1041 main.ONOScli6.handle.expect( ["onos>", "\$"] )
1042 print main.ONOScli6.handle.before
1043 main.ONOScli7.handle.sendline( "devices -j" )
1044 main.ONOScli7.handle.expect( ["onos>", "\$"] )
1045 print main.ONOScli7.handle.before
1046 time.sleep(100000)
1047
1048
1049 def CASE7( self, main ):
1050 """
1051 Check state after ONOS failure
1052 """
1053 import json
1054 main.case( "Running ONOS Constant State Tests" )
1055
1056 # Assert that each device has a master
1057 ONOS1MasterNotNull = main.ONOScli1.rolesNotNull()
1058 ONOS2MasterNotNull = main.ONOScli2.rolesNotNull()
1059 ONOS3MasterNotNull = main.ONOScli3.rolesNotNull()
1060 ONOS4MasterNotNull = main.ONOScli4.rolesNotNull()
1061 ONOS5MasterNotNull = main.ONOScli5.rolesNotNull()
1062 ONOS6MasterNotNull = main.ONOScli6.rolesNotNull()
1063 ONOS7MasterNotNull = main.ONOScli7.rolesNotNull()
1064 rolesNotNull = ONOS1MasterNotNull and ONOS2MasterNotNull and\
1065 ONOS3MasterNotNull and ONOS4MasterNotNull and\
1066 ONOS5MasterNotNull and ONOS6MasterNotNull and\
1067 ONOS7MasterNotNull
1068 utilities.assert_equals(
1069 expect=main.TRUE,
1070 actual=rolesNotNull,
1071 onpass="Each device has a master",
1072 onfail="Some devices don't have a master assigned" )
1073
1074 main.step( "Check if switch roles are consistent across all nodes" )
1075 ONOS1Mastership = main.ONOScli1.roles()
1076 ONOS2Mastership = main.ONOScli2.roles()
1077 ONOS3Mastership = main.ONOScli3.roles()
1078 ONOS4Mastership = main.ONOScli4.roles()
1079 ONOS5Mastership = main.ONOScli5.roles()
1080 ONOS6Mastership = main.ONOScli6.roles()
1081 ONOS7Mastership = main.ONOScli7.roles()
1082 if "Error" in ONOS1Mastership or not ONOS1Mastership\
1083 or "Error" in ONOS2Mastership or not ONOS2Mastership\
1084 or "Error" in ONOS3Mastership or not ONOS3Mastership\
1085 or "Error" in ONOS4Mastership or not ONOS4Mastership\
1086 or "Error" in ONOS5Mastership or not ONOS5Mastership\
1087 or "Error" in ONOS6Mastership or not ONOS6Mastership\
1088 or "Error" in ONOS7Mastership or not ONOS7Mastership:
1089 main.log.error( "Error in getting ONOS mastership" )
1090 main.log.warn( "ONOS1 mastership response: " +
1091 repr( ONOS1Mastership ) )
1092 main.log.warn( "ONOS2 mastership response: " +
1093 repr( ONOS2Mastership ) )
1094 main.log.warn( "ONOS3 mastership response: " +
1095 repr( ONOS3Mastership ) )
1096 main.log.warn( "ONOS4 mastership response: " +
1097 repr( ONOS4Mastership ) )
1098 main.log.warn( "ONOS5 mastership response: " +
1099 repr( ONOS5Mastership ) )
1100 main.log.warn( "ONOS6 mastership response: " +
1101 repr( ONOS6Mastership ) )
1102 main.log.warn( "ONOS7 mastership response: " +
1103 repr( ONOS7Mastership ) )
1104 consistentMastership = main.FALSE
1105 elif ONOS1Mastership == ONOS2Mastership\
1106 and ONOS1Mastership == ONOS3Mastership\
1107 and ONOS1Mastership == ONOS4Mastership\
1108 and ONOS1Mastership == ONOS5Mastership\
1109 and ONOS1Mastership == ONOS6Mastership\
1110 and ONOS1Mastership == ONOS7Mastership:
1111 consistentMastership = main.TRUE
1112 main.log.report(
1113 "Switch roles are consistent across all ONOS nodes" )
1114 else:
1115 for i in range( 1, numControllers + 1 ):
1116 mastership = eval( "ONOS" + str( i ) + "Mastership" )
1117 main.log.warn( "ONOS" + str( i ) + " roles: " +
1118 json.dumps( json.loads( mastership ),
1119 sort_keys=True,
1120 indent=4,
1121 separators=( ',', ': ' ) ) )
1122 consistentMastership = main.FALSE
1123 utilities.assert_equals(
1124 expect=main.TRUE,
1125 actual=consistentMastership,
1126 onpass="Switch roles are consistent across all ONOS nodes",
1127 onfail="ONOS nodes have different views of switch roles" )
1128
1129 description2 = "Compare switch roles from before failure"
1130 main.step( description2 )
1131
1132 currentJson = json.loads( ONOS1Mastership )
1133 oldJson = json.loads( mastershipState )
1134 mastershipCheck = main.TRUE
1135 for i in range( 1, 29 ):
1136 switchDPID = str(
1137 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
1138
1139 current = [ switch[ 'master' ] for switch in currentJson
1140 if switchDPID in switch[ 'id' ] ]
1141 old = [ switch[ 'master' ] for switch in oldJson
1142 if switchDPID in switch[ 'id' ] ]
1143 if current == old:
1144 mastershipCheck = mastershipCheck and main.TRUE
1145 else:
1146 main.log.warn( "Mastership of switch %s changed" % switchDPID )
1147 mastershipCheck = main.FALSE
1148 if mastershipCheck == main.TRUE:
1149 main.log.report( "Mastership of Switches was not changed" )
1150 utilities.assert_equals(
1151 expect=main.TRUE,
1152 actual=mastershipCheck,
1153 onpass="Mastership of Switches was not changed",
1154 onfail="Mastership of some switches changed" )
1155 mastershipCheck = mastershipCheck and consistentMastership
1156
1157 main.step( "Get the intents and compare across all nodes" )
1158 ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
1159 ONOS2Intents = main.ONOScli2.intents( jsonFormat=True )
1160 ONOS3Intents = main.ONOScli3.intents( jsonFormat=True )
1161 ONOS4Intents = main.ONOScli4.intents( jsonFormat=True )
1162 ONOS5Intents = main.ONOScli5.intents( jsonFormat=True )
1163 ONOS6Intents = main.ONOScli6.intents( jsonFormat=True )
1164 ONOS7Intents = main.ONOScli7.intents( jsonFormat=True )
1165 intentCheck = main.FALSE
1166 if "Error" in ONOS1Intents or not ONOS1Intents\
1167 or "Error" in ONOS2Intents or not ONOS2Intents\
1168 or "Error" in ONOS3Intents or not ONOS3Intents\
1169 or "Error" in ONOS4Intents or not ONOS4Intents\
1170 or "Error" in ONOS5Intents or not ONOS5Intents\
1171 or "Error" in ONOS6Intents or not ONOS6Intents\
1172 or "Error" in ONOS7Intents or not ONOS7Intents:
1173 main.log.report( "Error in getting ONOS intents" )
1174 main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
1175 main.log.warn( "ONOS2 intents response: " + repr( ONOS2Intents ) )
1176 main.log.warn( "ONOS3 intents response: " + repr( ONOS3Intents ) )
1177 main.log.warn( "ONOS4 intents response: " + repr( ONOS4Intents ) )
1178 main.log.warn( "ONOS5 intents response: " + repr( ONOS5Intents ) )
1179 main.log.warn( "ONOS6 intents response: " + repr( ONOS6Intents ) )
1180 main.log.warn( "ONOS7 intents response: " + repr( ONOS7Intents ) )
1181 elif ONOS1Intents == ONOS2Intents\
1182 and ONOS1Intents == ONOS3Intents\
1183 and ONOS1Intents == ONOS4Intents\
1184 and ONOS1Intents == ONOS5Intents\
1185 and ONOS1Intents == ONOS6Intents\
1186 and ONOS1Intents == ONOS7Intents:
1187 intentCheck = main.TRUE
1188 main.log.report( "Intents are consistent across all ONOS nodes" )
1189 else:
1190 for i in range( 1, numControllers + 1 ):
1191 intents = eval( "ONOS" + str( i ) + "Intents" )
1192 main.log.warn( "ONOS" + str( i ) + " intents: " +
1193 json.dumps( json.loads( ONOS1Intents ),
1194 sort_keys=True,
1195 indent=4,
1196 separators=( ',', ': ' ) ) )
1197 utilities.assert_equals(
1198 expect=main.TRUE,
1199 actual=intentCheck,
1200 onpass="Intents are consistent across all ONOS nodes",
1201 onfail="ONOS nodes have different views of intents" )
1202 # Print the intent states
1203 intents = []
1204 intents.append( ONOS1Intents )
1205 intents.append( ONOS2Intents )
1206 intents.append( ONOS3Intents )
1207 intents.append( ONOS4Intents )
1208 intents.append( ONOS5Intents )
1209 intents.append( ONOS6Intents )
1210 intents.append( ONOS7Intents )
1211 intentStates = []
1212 for node in intents: # Iter through ONOS nodes
1213 nodeStates = []
1214 for intent in json.loads( node ): # Iter through intents of a node
1215 nodeStates.append( intent[ 'state' ] )
1216 intentStates.append( nodeStates )
1217 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1218 main.log.info( dict( out ) )
1219 # NOTE: Hazelcast has no durability, so intents are lost across system
1220 # restarts
1221 main.step( "Compare current intents with intents before the failure" )
1222 # NOTE: this requires case 5 to pass for intentState to be set.
1223 # maybe we should stop the test if that fails?
1224 sameIntents = main.TRUE
1225 if intentState and intentState == ONOS1Intents:
1226 sameIntents = main.TRUE
1227 main.log.report( "Intents are consistent with before failure" )
1228 # TODO: possibly the states have changed? we may need to figure out
1229 # what the aceptable states are
1230 else:
1231 try:
1232 main.log.warn( "ONOS1 intents: " )
1233 print json.dumps( json.loads( ONOS1Intents ),
1234 sort_keys=True, indent=4,
1235 separators=( ',', ': ' ) )
1236 except:
1237 pass
1238 sameIntents = main.FALSE
1239 utilities.assert_equals(
1240 expect=main.TRUE,
1241 actual=sameIntents,
1242 onpass="Intents are consistent with before failure",
1243 onfail="The Intents changed during failure" )
1244 intentCheck = intentCheck and sameIntents
1245
1246 main.step( "Get the OF Table entries and compare to before " +
1247 "component failure" )
1248 FlowTables = main.TRUE
1249 flows2 = []
1250 for i in range( 28 ):
1251 main.log.info( "Checking flow table on s" + str( i + 1 ) )
1252 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
1253 flows2.append( tmpFlows )
1254 tempResult = main.Mininet2.flowComp(
1255 flow1=flows[ i ],
1256 flow2=tmpFlows )
1257 FlowTables = FlowTables and tempResult
1258 if FlowTables == main.FALSE:
1259 main.log.info( "Differences in flow table for switch: s" +
1260 str( i + 1 ) )
1261 if FlowTables == main.TRUE:
1262 main.log.report( "No changes were found in the flow tables" )
1263 utilities.assert_equals(
1264 expect=main.TRUE,
1265 actual=FlowTables,
1266 onpass="No changes were found in the flow tables",
1267 onfail="Changes were found in the flow tables" )
1268
1269 main.step( "Check the continuous pings to ensure that no packets " +
1270 "were dropped during component failure" )
1271 # FIXME: This check is always failing. Investigate cause
1272 # NOTE: this may be something to do with file permsissions
1273 # or slight change in format
1274 main.Mininet2.pingKill(
1275 main.params[ 'TESTONUSER' ],
1276 main.params[ 'TESTONIP' ] )
1277 LossInPings = main.FALSE
1278 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
1279 for i in range( 8, 18 ):
1280 main.log.info(
1281 "Checking for a loss in pings along flow from s" +
1282 str( i ) )
1283 LossInPings = main.Mininet2.checkForLoss(
1284 "/tmp/ping.h" +
1285 str( i ) ) or LossInPings
1286 if LossInPings == main.TRUE:
1287 main.log.info( "Loss in ping detected" )
1288 elif LossInPings == main.ERROR:
1289 main.log.info( "There are multiple mininet process running" )
1290 elif LossInPings == main.FALSE:
1291 main.log.info( "No Loss in the pings" )
1292 main.log.report( "No loss of dataplane connectivity" )
1293 utilities.assert_equals(
1294 expect=main.FALSE,
1295 actual=LossInPings,
1296 onpass="No Loss of connectivity",
1297 onfail="Loss of dataplane connectivity detected" )
1298
1299 # Test of LeadershipElection
1300 # FIXME Update this for network partition case
1301 # NOTE: this only works for the sanity test. In case of failures,
1302 # leader will likely change
1303 leader = ONOS1Ip
1304 leaderResult = main.TRUE
1305 for controller in range( 1, numControllers + 1 ):
1306 # loop through ONOScli handlers
1307 node = getattr( main, ( 'ONOScli' + str( controller ) ) )
1308 leaderN = node.electionTestLeader()
1309 # verify leader is ONOS1
1310 if leaderN == leader:
1311 # all is well
1312 # NOTE: In failure scenario, this could be a new node, maybe
1313 # check != ONOS1
1314 pass
1315 elif leaderN == main.FALSE:
1316 # error in response
1317 main.log.report( "Something is wrong with " +
1318 "electionTestLeader function," +
1319 " check the error logs" )
1320 leaderResult = main.FALSE
1321 elif leader != leaderN:
1322 leaderResult = main.FALSE
1323 main.log.report( "ONOS" + str( controller ) + " sees " +
1324 str( leaderN ) +
1325 " as the leader of the election app. " +
1326 "Leader should be " + str( leader ) )
1327 if leaderResult:
1328 main.log.report( "Leadership election tests passed( consistent " +
1329 "view of leader across listeners and a new " +
1330 "leader was re-elected if applicable )" )
1331 utilities.assert_equals(
1332 expect=main.TRUE,
1333 actual=leaderResult,
1334 onpass="Leadership election passed",
1335 onfail="Something went wrong with Leadership election" )
1336
1337 result = mastershipCheck and intentCheck and FlowTables and\
1338 ( not LossInPings ) and rolesNotNull and leaderResult
1339 result = int( result )
1340 if result == main.TRUE:
1341 main.log.report( "Constant State Tests Passed" )
1342 utilities.assert_equals( expect=main.TRUE, actual=result,
1343 onpass="Constant State Tests Passed",
1344 onfail="Constant state tests failed" )
1345
1346 def CASE8( self, main ):
1347 """
1348 Compare topo
1349 """
1350 import sys
1351 # FIXME add this path to params
1352 sys.path.append( "/home/admin/sts" )
1353 # assumes that sts is already in you PYTHONPATH
1354 from sts.topology.teston_topology import TestONTopology
1355 import json
1356 import time
1357
1358 description = "Compare ONOS Topology view to Mininet topology"
1359 main.case( description )
1360 main.log.report( description )
1361 main.step( "Create TestONTopology object" )
1362 ctrls = []
1363 count = 1
1364 while True:
1365 temp = ()
1366 if ( 'ip' + str( count ) ) in main.params[ 'CTRL' ]:
1367 temp = temp + ( getattr( main, ( 'ONOS' + str( count ) ) ), )
1368 temp = temp + ( "ONOS" + str( count ), )
1369 temp = temp + ( main.params[ 'CTRL' ][ 'ip' + str( count ) ], )
1370 temp = temp + \
1371 ( eval( main.params[ 'CTRL' ][ 'port' + str( count ) ] ), )
1372 ctrls.append( temp )
1373 count = count + 1
1374 else:
1375 break
1376 MNTopo = TestONTopology(
1377 main.Mininet1,
1378 ctrls ) # can also add Intent API info for intent operations
1379
1380 main.step( "Comparing ONOS topology to MN" )
1381 devicesResults = main.TRUE
1382 portsResults = main.TRUE
1383 linksResults = main.TRUE
1384 topoResult = main.FALSE
1385 elapsed = 0
1386 count = 0
1387 main.step( "Collecting topology information from ONOS" )
1388 startTime = time.time()
1389 # Give time for Gossip to work
1390 while topoResult == main.FALSE and elapsed < 60:
1391 count = count + 1
1392 if count > 1:
1393 # TODO: Depricate STS usage
1394 MNTopo = TestONTopology(
1395 main.Mininet1,
1396 ctrls )
1397 cliStart = time.time()
1398 devices = []
1399 devices.append( main.ONOScli1.devices() )
1400 devices.append( main.ONOScli2.devices() )
1401 devices.append( main.ONOScli3.devices() )
1402 devices.append( main.ONOScli4.devices() )
1403 devices.append( main.ONOScli5.devices() )
1404 devices.append( main.ONOScli6.devices() )
1405 devices.append( main.ONOScli7.devices() )
1406 hosts = []
1407 hosts.append( json.loads( main.ONOScli1.hosts() ) )
1408 hosts.append( json.loads( main.ONOScli2.hosts() ) )
1409 hosts.append( json.loads( main.ONOScli3.hosts() ) )
1410 hosts.append( json.loads( main.ONOScli4.hosts() ) )
1411 hosts.append( json.loads( main.ONOScli5.hosts() ) )
1412 hosts.append( json.loads( main.ONOScli6.hosts() ) )
1413 hosts.append( json.loads( main.ONOScli7.hosts() ) )
1414 for controller in range( 0, len( hosts ) ):
1415 controllerStr = str( controller + 1 )
1416 for host in hosts[ controller ]:
1417 if host[ 'ips' ] == []:
1418 main.log.error(
1419 "DEBUG:Error with host ips on controller" +
1420 controllerStr + ": " + str( host ) )
1421 ports = []
1422 ports.append( main.ONOScli1.ports() )
1423 ports.append( main.ONOScli2.ports() )
1424 ports.append( main.ONOScli3.ports() )
1425 ports.append( main.ONOScli4.ports() )
1426 ports.append( main.ONOScli5.ports() )
1427 ports.append( main.ONOScli6.ports() )
1428 ports.append( main.ONOScli7.ports() )
1429 links = []
1430 links.append( main.ONOScli1.links() )
1431 links.append( main.ONOScli2.links() )
1432 links.append( main.ONOScli3.links() )
1433 links.append( main.ONOScli4.links() )
1434 links.append( main.ONOScli5.links() )
1435 links.append( main.ONOScli6.links() )
1436 links.append( main.ONOScli7.links() )
1437 clusters = []
1438 clusters.append( main.ONOScli1.clusters() )
1439 clusters.append( main.ONOScli2.clusters() )
1440 clusters.append( main.ONOScli3.clusters() )
1441 clusters.append( main.ONOScli4.clusters() )
1442 clusters.append( main.ONOScli5.clusters() )
1443 clusters.append( main.ONOScli6.clusters() )
1444 clusters.append( main.ONOScli7.clusters() )
1445
1446 elapsed = time.time() - startTime
1447 cliTime = time.time() - cliStart
1448 print "CLI time: " + str( cliTime )
1449
1450 for controller in range( numControllers ):
1451 controllerStr = str( controller + 1 )
1452 if devices[ controller ] or "Error" not in devices[
1453 controller ]:
1454 currentDevicesResult = main.Mininet1.compareSwitches(
1455 MNTopo,
1456 json.loads(
1457 devices[ controller ] ) )
1458 else:
1459 currentDevicesResult = main.FALSE
1460 utilities.assert_equals( expect=main.TRUE,
1461 actual=currentDevicesResult,
1462 onpass="ONOS" + controllerStr +
1463 " Switches view is correct",
1464 onfail="ONOS" + controllerStr +
1465 " Switches view is incorrect" )
1466
1467 if ports[ controller ] or "Error" not in ports[ controller ]:
1468 currentPortsResult = main.Mininet1.comparePorts(
1469 MNTopo,
1470 json.loads(
1471 ports[ controller ] ) )
1472 else:
1473 currentPortsResult = main.FALSE
1474 utilities.assert_equals( expect=main.TRUE,
1475 actual=currentPortsResult,
1476 onpass="ONOS" + controllerStr +
1477 " ports view is correct",
1478 onfail="ONOS" + controllerStr +
1479 " ports view is incorrect" )
1480
1481 if links[ controller ] or "Error" not in links[ controller ]:
1482 currentLinksResult = main.Mininet1.compareLinks(
1483 MNTopo,
1484 json.loads(
1485 links[ controller ] ) )
1486 else:
1487 currentLinksResult = main.FALSE
1488 utilities.assert_equals( expect=main.TRUE,
1489 actual=currentLinksResult,
1490 onpass="ONOS" + controllerStr +
1491 " links view is correct",
1492 onfail="ONOS" + controllerStr +
1493 " links view is incorrect" )
1494 devicesResults = devicesResults and currentDevicesResult
1495 portsResults = portsResults and currentPortsResult
1496 linksResults = linksResults and currentLinksResult
1497
1498 # Compare json objects for hosts and dataplane clusters
1499
1500 # hosts
1501 consistentHostsResult = main.TRUE
1502 for controller in range( len( hosts ) ):
1503 controllerStr = str( controller + 1 )
1504 if "Error" not in hosts[ controller ]:
1505 if hosts[ controller ] == hosts[ 0 ]:
1506 continue
1507 else: # hosts not consistent
1508 main.log.report( "hosts from ONOS" + controllerStr +
1509 " is inconsistent with ONOS1" )
1510 main.log.warn( repr( hosts[ controller ] ) )
1511 consistentHostsResult = main.FALSE
1512
1513 else:
1514 main.log.report( "Error in getting ONOS hosts from ONOS" +
1515 controllerStr )
1516 consistentHostsResult = main.FALSE
1517 main.log.warn( "ONOS" + controllerStr +
1518 " hosts response: " +
1519 repr( hosts[ controller ] ) )
1520 utilities.assert_equals(
1521 expect=main.TRUE,
1522 actual=consistentHostsResult,
1523 onpass="Hosts view is consistent across all ONOS nodes",
1524 onfail="ONOS nodes have different views of hosts" )
1525
1526 # Strongly connected clusters of devices
1527 consistentClustersResult = main.TRUE
1528 for controller in range( len( clusters ) ):
1529 controllerStr = str( controller + 1 )
1530 if "Error" not in clusters[ controller ]:
1531 if clusters[ controller ] == clusters[ 0 ]:
1532 continue
1533 else: # clusters not consistent
1534 main.log.report( "clusters from ONOS" +
1535 controllerStr +
1536 " is inconsistent with ONOS1" )
1537 consistentClustersResult = main.FALSE
1538
1539 else:
1540 main.log.report( "Error in getting dataplane clusters " +
1541 "from ONOS" + controllerStr )
1542 consistentClustersResult = main.FALSE
1543 main.log.warn( "ONOS" + controllerStr +
1544 " clusters response: " +
1545 repr( clusters[ controller ] ) )
1546 utilities.assert_equals(
1547 expect=main.TRUE,
1548 actual=consistentClustersResult,
1549 onpass="Clusters view is consistent across all ONOS nodes",
1550 onfail="ONOS nodes have different views of clusters" )
1551 # there should always only be one cluster
1552 numClusters = len( json.loads( clusters[ 0 ] ) )
1553 utilities.assert_equals(
1554 expect=1,
1555 actual=numClusters,
1556 onpass="ONOS shows 1 SCC",
1557 onfail="ONOS shows " +
1558 str( numClusters ) +
1559 " SCCs" )
1560
1561 topoResult = ( devicesResults and portsResults and linksResults
1562 and consistentHostsResult
1563 and consistentClustersResult )
1564
1565 topoResult = topoResult and int( count <= 2 )
1566 note = "note it takes about " + str( int( cliTime ) ) + \
1567 " seconds for the test to make all the cli calls to fetch " +\
1568 "the topology from each ONOS instance"
1569 main.log.info(
1570 "Very crass estimate for topology discovery/convergence( " +
1571 str( note ) + " ): " + str( elapsed ) + " seconds, " +
1572 str( count ) + " tries" )
1573 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
1574 onpass="Topology Check Test successful",
1575 onfail="Topology Check Test NOT successful" )
1576 if topoResult == main.TRUE:
1577 main.log.report( "ONOS topology view matches Mininet topology" )
1578
1579 def CASE9( self, main ):
1580 """
1581 Link s3-s28 down
1582 """
1583 import time
1584 # NOTE: You should probably run a topology check after this
1585
1586 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
1587
1588 description = "Turn off a link to ensure that Link Discovery " +\
1589 "is working properly"
1590 main.log.report( description )
1591 main.case( description )
1592
1593 main.step( "Kill Link between s3 and s28" )
1594 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
1595 main.log.info(
1596 "Waiting " +
1597 str( linkSleep ) +
1598 " seconds for link down to be discovered" )
1599 time.sleep( linkSleep )
1600 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
1601 onpass="Link down succesful",
1602 onfail="Failed to bring link down" )
1603 # TODO do some sort of check here
1604
1605 def CASE10( self, main ):
1606 """
1607 Link s3-s28 up
1608 """
1609 import time
1610 # NOTE: You should probably run a topology check after this
1611
1612 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
1613
1614 description = "Restore a link to ensure that Link Discovery is " + \
1615 "working properly"
1616 main.log.report( description )
1617 main.case( description )
1618
1619 main.step( "Bring link between s3 and s28 back up" )
1620 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
1621 main.log.info(
1622 "Waiting " +
1623 str( linkSleep ) +
1624 " seconds for link up to be discovered" )
1625 time.sleep( linkSleep )
1626 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
1627 onpass="Link up succesful",
1628 onfail="Failed to bring link up" )
1629 # TODO do some sort of check here
1630
1631 def CASE11( self, main ):
1632 """
1633 Switch Down
1634 """
1635 # NOTE: You should probably run a topology check after this
1636 import time
1637
1638 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
1639
1640 description = "Killing a switch to ensure it is discovered correctly"
1641 main.log.report( description )
1642 main.case( description )
1643 switch = main.params[ 'kill' ][ 'switch' ]
1644 switchDPID = main.params[ 'kill' ][ 'dpid' ]
1645
1646 # TODO: Make this switch parameterizable
1647 main.step( "Kill " + switch )
1648 main.log.report( "Deleting " + switch )
1649 main.Mininet1.delSwitch( switch )
1650 main.log.info( "Waiting " + str( switchSleep ) +
1651 " seconds for switch down to be discovered" )
1652 time.sleep( switchSleep )
1653 device = main.ONOScli1.getDevice( dpid=switchDPID )
1654 # Peek at the deleted switch
1655 main.log.warn( str( device ) )
1656 result = main.FALSE
1657 if device and device[ 'available' ] is False:
1658 result = main.TRUE
1659 utilities.assert_equals( expect=main.TRUE, actual=result,
1660 onpass="Kill switch succesful",
1661 onfail="Failed to kill switch?" )
1662
1663 def CASE12( self, main ):
1664 """
1665 Switch Up
1666 """
1667 # NOTE: You should probably run a topology check after this
1668 import time
1669
1670 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
1671 switch = main.params[ 'kill' ][ 'switch' ]
1672 switchDPID = main.params[ 'kill' ][ 'dpid' ]
1673 links = main.params[ 'kill' ][ 'links' ].split()
1674 description = "Adding a switch to ensure it is discovered correctly"
1675 main.log.report( description )
1676 main.case( description )
1677
1678 main.step( "Add back " + switch )
1679 main.log.report( "Adding back " + switch )
1680 main.Mininet1.addSwitch( switch, dpid=switchDPID )
1681 for peer in links:
1682 main.Mininet1.addLink( switch, peer )
1683 main.Mininet1.assignSwController(
1684 sw=switch.split( 's' )[ 1 ],
1685 count=numControllers,
1686 ip1=ONOS1Ip,
1687 port1=ONOS1Port,
1688 ip2=ONOS2Ip,
1689 port2=ONOS2Port,
1690 ip3=ONOS3Ip,
1691 port3=ONOS3Port,
1692 ip4=ONOS4Ip,
1693 port4=ONOS4Port,
1694 ip5=ONOS5Ip,
1695 port5=ONOS5Port,
1696 ip6=ONOS6Ip,
1697 port6=ONOS6Port,
1698 ip7=ONOS7Ip,
1699 port7=ONOS7Port )
1700 main.log.info(
1701 "Waiting " +
1702 str( switchSleep ) +
1703 " seconds for switch up to be discovered" )
1704 time.sleep( switchSleep )
1705 device = main.ONOScli1.getDevice( dpid=switchDPID )
1706 # Peek at the deleted switch
1707 main.log.warn( str( device ) )
1708 result = main.FALSE
1709 if device and device[ 'available' ]:
1710 result = main.TRUE
1711 utilities.assert_equals( expect=main.TRUE, actual=result,
1712 onpass="add switch succesful",
1713 onfail="Failed to add switch?" )
1714
1715 def CASE13( self, main ):
1716 """
1717 Clean up
1718 """
1719 import os
1720 import time
1721 # TODO: make use of this elsewhere
1722 ips = []
1723 ips.append( ONOS1Ip )
1724 ips.append( ONOS2Ip )
1725 ips.append( ONOS3Ip )
1726 ips.append( ONOS4Ip )
1727 ips.append( ONOS5Ip )
1728 ips.append( ONOS6Ip )
1729 ips.append( ONOS7Ip )
1730
1731 # printing colors to terminal
1732 colors = {}
1733 colors[ 'cyan' ] = '\033[96m'
1734 colors[ 'purple' ] = '\033[95m'
1735 colors[ 'blue' ] = '\033[94m'
1736 colors[ 'green' ] = '\033[92m'
1737 colors[ 'yellow' ] = '\033[93m'
1738 colors[ 'red' ] = '\033[91m'
1739 colors[ 'end' ] = '\033[0m'
1740 description = "Test Cleanup"
1741 main.log.report( description )
1742 main.case( description )
1743 main.step( "Killing tcpdumps" )
1744 main.Mininet2.stopTcpdump()
1745
1746 main.step( "Checking ONOS Logs for errors" )
1747 for i in range( 7 ):
1748 print colors[ 'purple' ] + "Checking logs for errors on " + \
1749 "ONOS" + str( i + 1 ) + ":" + colors[ 'end' ]
1750 print main.ONOSbench.checkLogs( ips[ i ] )
1751
1752 main.step( "Copying MN pcap and ONOS log files to test station" )
1753 testname = main.TEST
1754 teststationUser = main.params[ 'TESTONUSER' ]
1755 teststationIP = main.params[ 'TESTONIP' ]
1756 # NOTE: MN Pcap file is being saved to ~/packet_captures
1757 # scp this file as MN and TestON aren't necessarily the same vm
1758 # FIXME: scp
1759 # mn files
1760 # TODO: Load these from params
1761 # NOTE: must end in /
1762 logFolder = "/opt/onos/log/"
1763 logFiles = [ "karaf.log", "karaf.log.1" ]
1764 # NOTE: must end in /
1765 dstDir = "~/packet_captures/"
1766 for f in logFiles:
1767 for i in range( 7 ):
1768 main.ONOSbench.handle.sendline( "scp sdn@" + ips[ i ] + ":" +
1769 logFolder + f + " " +
1770 teststationUser + "@" +
1771 teststationIP + ":" +
1772 dstDir + str( testname ) +
1773 "-ONOS" + str( i + 1 ) + "-" +
1774 f )
1775 # std*.log's
1776 # NOTE: must end in /
1777 logFolder = "/opt/onos/var/"
1778 logFiles = [ "stderr.log", "stdout.log" ]
1779 # NOTE: must end in /
1780 dstDir = "~/packet_captures/"
1781 for f in logFiles:
1782 for i in range( 7 ):
1783 main.ONOSbench.handle.sendline( "scp sdn@" + ips[ i ] + ":" +
1784 logFolder + f + " " +
1785 teststationUser + "@" +
1786 teststationIP + ":" +
1787 dstDir + str( testname ) +
1788 "-ONOS" + str( i + 1 ) + "-" +
1789 f )
1790 # sleep so scp can finish
1791 time.sleep( 10 )
1792 main.step( "Packing and rotating pcap archives" )
1793 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
1794
1795 # TODO: actually check something here
1796 utilities.assert_equals( expect=main.TRUE, actual=main.TRUE,
1797 onpass="Test cleanup successful",
1798 onfail="Test cleanup NOT successful" )
1799
1800 def CASE14( self, main ):
1801 """
1802 start election app on all onos nodes
1803 """
1804 leaderResult = main.TRUE
1805 # install app on onos 1
1806 main.log.info( "Install leadership election app" )
1807 main.ONOScli1.featureInstall( "onos-app-election" )
1808 # wait for election
1809 # check for leader
1810 leader = main.ONOScli1.electionTestLeader()
1811 # verify leader is ONOS1
1812 if leader == ONOS1Ip:
1813 # all is well
1814 pass
1815 elif leader is None:
1816 # No leader elected
1817 main.log.report( "No leader was elected" )
1818 leaderResult = main.FALSE
1819 elif leader == main.FALSE:
1820 # error in response
1821 # TODO: add check for "Command not found:" in the driver, this
1822 # means the app isn't loaded
1823 main.log.report( "Something is wrong with electionTestLeader" +
1824 " function, check the error logs" )
1825 leaderResult = main.FALSE
1826 else:
1827 # error in response
1828 main.log.report(
1829 "Unexpected response from electionTestLeader function:'" +
1830 str( leader ) +
1831 "'" )
1832 leaderResult = main.FALSE
1833
1834 # install on other nodes and check for leader.
1835 # Should be onos1 and each app should show the same leader
1836 for controller in range( 2, numControllers + 1 ):
1837 # loop through ONOScli handlers
1838 node = getattr( main, ( 'ONOScli' + str( controller ) ) )
1839 node.featureInstall( "onos-app-election" )
1840 leaderN = node.electionTestLeader()
1841 # verify leader is ONOS1
1842 if leaderN == ONOS1Ip:
1843 # all is well
1844 pass
1845 elif leaderN == main.FALSE:
1846 # error in response
1847 # TODO: add check for "Command not found:" in the driver, this
1848 # means the app isn't loaded
1849 main.log.report( "Something is wrong with " +
1850 "electionTestLeader function, check the" +
1851 " error logs" )
1852 leaderResult = main.FALSE
1853 elif leader != leaderN:
1854 leaderResult = main.FALSE
1855 main.log.report( "ONOS" + str( controller ) + " sees " +
1856 str( leaderN ) +
1857 " as the leader of the election app. Leader" +
1858 " should be " +
1859 str( leader ) )
1860 if leaderResult:
1861 main.log.report( "Leadership election tests passed( consistent " +
1862 "view of leader across listeners and a leader " +
1863 "was elected )" )
1864 utilities.assert_equals(
1865 expect=main.TRUE,
1866 actual=leaderResult,
1867 onpass="Leadership election passed",
1868 onfail="Something went wrong with Leadership election" )
1869
1870 def CASE15( self, main ):
1871 """
1872 Check that Leadership Election is still functional
1873 """
1874 leaderResult = main.TRUE
1875 description = "Check that Leadership Election is still functional"
1876 main.log.report( description )
1877 main.case( description )
1878 main.step( "Find current leader and withdraw" )
1879 leader = main.ONOScli1.electionTestLeader()
1880 withdrawResult = main.FALSE
1881 if leader == ONOS1Ip:
1882 oldLeader = getattr( main, "ONOScli1" )
1883 elif leader == ONOS2Ip:
1884 oldLeader = getattr( main, "ONOScli2" )
1885 elif leader == ONOS3Ip:
1886 oldLeader = getattr( main, "ONOScli3" )
1887 elif leader == ONOS4Ip:
1888 oldLeader = getattr( main, "ONOScli4" )
1889 elif leader == ONOS5Ip:
1890 oldLeader = getattr( main, "ONOScli5" )
1891 elif leader == ONOS6Ip:
1892 oldLeader = getattr( main, "ONOScli6" )
1893 elif leader == ONOS7Ip:
1894 oldLeader = getattr( main, "ONOScli7" )
1895 elif leader is None or leader == main.FALSE:
1896 main.log.report(
1897 "Leader for the election app should be an ONOS node," +
1898 "instead got '" +
1899 str( leader ) +
1900 "'" )
1901 leaderResult = main.FALSE
1902 withdrawResult = oldLeader.electionTestWithdraw()
1903 utilities.assert_equals(
1904 expect=main.TRUE,
1905 actual=withdrawResult,
1906 onpass="App was withdrawn from election",
1907 onfail="App was not withdrawn from election" )
1908
1909 main.step( "Make sure new leader is elected" )
1910 leaderList = []
1911 for controller in range( 1, numControllers + 1 ):
1912 # loop through ONOScli handlers
1913 node = getattr( main, ( 'ONOScli' + str( controller ) ) )
1914 leaderList.append( node.electionTestLeader() )
1915 for leaderN in leaderList:
1916 if leaderN == leader:
1917 main.log.report(
1918 "ONOS" +
1919 str( controller ) +
1920 " still sees " +
1921 str( leader ) +
1922 " as leader after they withdrew" )
1923 leaderResult = main.FALSE
1924 elif leaderN == main.FALSE:
1925 # error in response
1926 # TODO: add check for "Command not found:" in the driver, this
1927 # means the app isn't loaded
1928 main.log.report( "Something is wrong with " +
1929 "electionTestLeader function, " +
1930 "check the error logs" )
1931 leaderResult = main.FALSE
1932 consistentLeader = main.FALSE
1933 if len( set( leaderList ) ) == 1:
1934 main.log.info( "Each Election-app sees '" +
1935 str( leaderList[ 0 ] ) +
1936 "' as the leader" )
1937 consistentLeader = main.TRUE
1938 else:
1939 main.log.report(
1940 "Inconsistent responses for leader of Election-app:" )
1941 for n in range( len( leaderList ) ):
1942 main.log.report( "ONOS" + str( n + 1 ) + " response: " +
1943 str( leaderList[ n ] ) )
1944 if leaderResult:
1945 main.log.report( "Leadership election tests passed( consistent " +
1946 "view of leader across listeners and a new " +
1947 "leader was elected when the old leader " +
1948 "resigned )" )
1949 utilities.assert_equals(
1950 expect=main.TRUE,
1951 actual=leaderResult,
1952 onpass="Leadership election passed",
1953 onfail="Something went wrong with Leadership election" )
1954
1955 main.step( "Run for election on old leader( just so everyone "
1956 "is in the hat )" )
1957 runResult = oldLeader.electionTestRun()
1958 utilities.assert_equals(
1959 expect=main.TRUE,
1960 actual=runResult,
1961 onpass="App re-ran for election",
1962 onfail="App failed to run for election" )
1963 if consistentLeader == main.TRUE:
1964 afterRun = main.ONOScli1.electionTestLeader()
1965 # verify leader didn't just change
1966 if afterRun == leaderList[ 0 ]:
1967 leaderResult = main.TRUE
1968 else:
1969 leaderResult = main.FALSE
1970 # TODO: assert on run and withdraw results?
1971
1972 utilities.assert_equals(
1973 expect=main.TRUE,
1974 actual=leaderResult,
1975 onpass="Leadership election passed",
1976 onfail="Something went wrong with Leadership election after " +
1977 "the old leader re-ran for election" )
1978 def CASE16( self ):
1979 """
1980 """
1981 main.ONOScli1.handle.sendline( "sudo iptables -F" )
1982 main.ONOScli1.handle.expect( "\$" )
1983 main.ONOScli2.handle.sendline( "sudo iptables -F" )
1984 main.ONOScli2.handle.expect( "\$" )
1985 main.ONOScli3.handle.sendline( "sudo iptables -F" )
1986 main.ONOScli3.handle.expect( "\$" )
1987 main.ONOScli4.handle.sendline( "sudo iptables -F" )
1988 main.ONOScli4.handle.expect( "\$" )
1989 main.ONOScli5.handle.sendline( "sudo iptables -F" )
1990 main.ONOScli5.handle.expect( "\$" )
1991 main.ONOScli6.handle.sendline( "sudo iptables -F" )
1992 main.ONOScli6.handle.expect( "\$" )
1993 main.ONOScli7.handle.sendline( "sudo iptables -F" )
1994 main.ONOScli7.handle.expect( "\$" )
1995