blob: 81b3afd111f1481f94edcb7fe854be734d3b8054 [file] [log] [blame]
Jon Hall6aec96b2015-01-19 14:49:31 -08001"""
Jon Hall73cf9cc2014-11-20 22:28:38 -08002Description: 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 mastership to controllers
8CASE3: Assign intents
9CASE4: Ping across added host intents
10CASE5: Reading state of ONOS
11CASE6: The Failure case. Since this is the Sanity test, we do nothing.
12CASE7: Check state after control plane failure
13CASE8: Compare topo
14CASE9: Link s3-s28 down
15CASE10: Link s3-s28 up
16CASE11: Switch down
17CASE12: Switch up
18CASE13: Clean up
Jon Hall669173b2014-12-17 11:36:30 -080019CASE14: start election app on all onos nodes
20CASE15: Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -080021"""
Jon Hall8f89dda2015-01-22 16:03:33 -080022
23
Jon Hall48cf3ce2015-01-12 15:43:18 -080024class HATestSingleInstanceRestart:
Jon Hall73cf9cc2014-11-20 22:28:38 -080025
Jon Hall6aec96b2015-01-19 14:49:31 -080026 def __init__( self ):
Jon Hall73cf9cc2014-11-20 22:28:38 -080027 self.default = ''
28
Jon Hall6aec96b2015-01-19 14:49:31 -080029 def CASE1( self, main ):
30 """
Jon Hall73cf9cc2014-11-20 22:28:38 -080031 CASE1 is to compile ONOS and push it to the test machines
32
33 Startup sequence:
34 git pull
35 mvn clean install
36 onos-package
37 cell <name>
38 onos-verify-cell
39 NOTE: temporary - onos-remove-raft-logs
40 onos-install -f
41 onos-wait-for-start
Jon Hall6aec96b2015-01-19 14:49:31 -080042 """
43 main.log.report( "ONOS Single node cluster restart " +
44 "HA test - initialization" )
45 main.case( "Setting up test environment" )
46 # TODO: save all the timers and output them for plotting
Jon Hall73cf9cc2014-11-20 22:28:38 -080047
48 # load some vairables from the params file
Jon Hall8f89dda2015-01-22 16:03:33 -080049 PULLCODE = False
Jon Hall6aec96b2015-01-19 14:49:31 -080050 if main.params[ 'Git' ] == 'True':
Jon Hall8f89dda2015-01-22 16:03:33 -080051 PULLCODE = True
Jon Hall529a37f2015-01-28 10:02:00 -080052 gitBranch = main.params[ 'branch' ]
Jon Hall8f89dda2015-01-22 16:03:33 -080053 cellName = main.params[ 'ENV' ][ 'cellName' ]
Jon Hall6aec96b2015-01-19 14:49:31 -080054
55 # set global variables
Jon Hall8f89dda2015-01-22 16:03:33 -080056 global ONOS1Ip
57 global ONOS1Port
58 global ONOS2Ip
59 global ONOS2Port
60 global ONOS3Ip
61 global ONOS3Port
62 global ONOS4Ip
63 global ONOS4Port
64 global ONOS5Ip
65 global ONOS5Port
66 global ONOS6Ip
67 global ONOS6Port
68 global ONOS7Ip
69 global ONOS7Port
70 global numControllers
Jon Hall73cf9cc2014-11-20 22:28:38 -080071
Jon Hall8f89dda2015-01-22 16:03:33 -080072 ONOS1Ip = main.params[ 'CTRL' ][ 'ip1' ]
73 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
74 ONOS2Ip = main.params[ 'CTRL' ][ 'ip2' ]
75 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
76 ONOS3Ip = main.params[ 'CTRL' ][ 'ip3' ]
77 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
78 ONOS4Ip = main.params[ 'CTRL' ][ 'ip4' ]
79 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
80 ONOS5Ip = main.params[ 'CTRL' ][ 'ip5' ]
81 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
82 ONOS6Ip = main.params[ 'CTRL' ][ 'ip6' ]
83 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
84 ONOS7Ip = main.params[ 'CTRL' ][ 'ip7' ]
85 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
86 numControllers = int( main.params[ 'num_controllers' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -080087
Jon Hall6aec96b2015-01-19 14:49:31 -080088 main.step( "Applying cell variable to environment" )
Jon Hall8f89dda2015-01-22 16:03:33 -080089 cellResult = main.ONOSbench.setCell( cellName )
90 verifyResult = main.ONOSbench.verifyCell()
Jon Hall73cf9cc2014-11-20 22:28:38 -080091
Jon Hall6aec96b2015-01-19 14:49:31 -080092 # FIXME:this is short term fix
93 main.log.report( "Removing raft logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -080094 main.ONOSbench.onosRemoveRaftLogs()
Jon Hall6aec96b2015-01-19 14:49:31 -080095 main.log.report( "Uninstalling ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -080096 main.ONOSbench.onosUninstall( ONOS1Ip )
97 main.ONOSbench.onosUninstall( ONOS2Ip )
98 main.ONOSbench.onosUninstall( ONOS3Ip )
99 main.ONOSbench.onosUninstall( ONOS4Ip )
100 main.ONOSbench.onosUninstall( ONOS5Ip )
101 main.ONOSbench.onosUninstall( ONOS6Ip )
102 main.ONOSbench.onosUninstall( ONOS7Ip )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800103
Jon Hall8f89dda2015-01-22 16:03:33 -0800104 cleanInstallResult = main.TRUE
105 gitPullResult = main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800106
Jon Hall97f31752015-02-04 12:01:04 -0800107 main.step( "Starting Mininet" )
108 main.Mininet1.startNet( )
109
Jon Hall6aec96b2015-01-19 14:49:31 -0800110 main.step( "Compiling the latest version of ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800111 if PULLCODE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800112 # TODO Configure branch in params
113 main.step( "Git checkout and pull master" )
Jon Hall529a37f2015-01-28 10:02:00 -0800114 main.ONOSbench.gitCheckout( gitBranch )
Jon Hall8f89dda2015-01-22 16:03:33 -0800115 gitPullResult = main.ONOSbench.gitPull()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800116
Jon Hall6aec96b2015-01-19 14:49:31 -0800117 main.step( "Using mvn clean & install" )
Jon Hall529a37f2015-01-28 10:02:00 -0800118 cleanInstallResult = main.ONOSbench.cleanInstall()
119 else:
120 main.log.warn( "Did not pull new code so skipping mvn " +
121 "clean install" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800122 main.ONOSbench.getVersion( report=True )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800123
Jon Hall8f89dda2015-01-22 16:03:33 -0800124 cellResult = main.ONOSbench.setCell( "SingleHA" )
125 verifyResult = main.ONOSbench.verifyCell()
Jon Hall6aec96b2015-01-19 14:49:31 -0800126 main.step( "Creating ONOS package" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800127 packageResult = main.ONOSbench.onosPackage()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800128
Jon Hall6aec96b2015-01-19 14:49:31 -0800129 main.step( "Installing ONOS package" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800130 onos1InstallResult = main.ONOSbench.onosInstall( options="-f",
131 node=ONOS1Ip )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800132
Jon Hall6aec96b2015-01-19 14:49:31 -0800133 main.step( "Checking if ONOS is up yet" )
134 # TODO check bundle:list?
135 for i in range( 2 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800136 onos1Isup = main.ONOSbench.isup( ONOS1Ip )
137 if onos1Isup:
Jon Hall94fd0472014-12-08 11:52:42 -0800138 break
Jon Hall8f89dda2015-01-22 16:03:33 -0800139 if not onos1Isup:
Jon Hall6aec96b2015-01-19 14:49:31 -0800140 main.log.report( "ONOS1 didn't start!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800141
Jon Hall8f89dda2015-01-22 16:03:33 -0800142 cliResult = main.ONOScli1.startOnosCli( ONOS1Ip )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800143
Jon Hall6aec96b2015-01-19 14:49:31 -0800144 main.step( "Start Packet Capture MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800145 main.Mininet2.startTcpdump(
Jon Hall6aec96b2015-01-19 14:49:31 -0800146 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
147 + "-MN.pcap",
148 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
149 port=main.params[ 'MNtcpdump' ][ 'port' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800150
Jon Hall8f89dda2015-01-22 16:03:33 -0800151 case1Result = ( cleanInstallResult and packageResult and
152 cellResult and verifyResult and onos1InstallResult
153 and onos1Isup and cliResult )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800154
Jon Hall8f89dda2015-01-22 16:03:33 -0800155 utilities.assert_equals( expect=main.TRUE, actual=case1Result,
156 onpass="Test startup successful",
157 onfail="Test startup NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800158
Jon Hall8f89dda2015-01-22 16:03:33 -0800159 if case1Result == main.FALSE:
Jon Hall73cf9cc2014-11-20 22:28:38 -0800160 main.cleanup()
161 main.exit()
162
Jon Hall6aec96b2015-01-19 14:49:31 -0800163 def CASE2( self, main ):
164 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800165 Assign mastership to controllers
Jon Hall6aec96b2015-01-19 14:49:31 -0800166 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800167 import re
168
Jon Hall6aec96b2015-01-19 14:49:31 -0800169 main.log.report( "Assigning switches to controllers" )
170 main.case( "Assigning Controllers" )
171 main.step( "Assign switches to controllers" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800172
Jon Hall6aec96b2015-01-19 14:49:31 -0800173 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800174 main.Mininet1.assignSwController(
Jon Hall6aec96b2015-01-19 14:49:31 -0800175 sw=str( i ),
Jon Hall8f89dda2015-01-22 16:03:33 -0800176 ip1=ONOS1Ip, port1=ONOS1Port )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800177
Jon Hall8f89dda2015-01-22 16:03:33 -0800178 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800179 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800180 response = main.Mininet1.getSwController( "s" + str( i ) )
Jon Hallffb386d2014-11-21 13:43:38 -0800181 try:
Jon Hall6aec96b2015-01-19 14:49:31 -0800182 main.log.info( str( response ) )
Jon Hallfebb1c72015-03-05 13:30:09 -0800183 except Exception:
Jon Hall6aec96b2015-01-19 14:49:31 -0800184 main.log.info( repr( response ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800185 if re.search( "tcp:" + ONOS1Ip, response ):
186 mastershipCheck = mastershipCheck and main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800187 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800188 mastershipCheck = main.FALSE
189 if mastershipCheck == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800190 main.log.report( "Switch mastership assigned correctly" )
191 utilities.assert_equals(
192 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800193 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800194 onpass="Switch mastership assigned correctly",
195 onfail="Switches not assigned correctly to controllers" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800196
Jon Hall6aec96b2015-01-19 14:49:31 -0800197 def CASE3( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800198 """
199 Assign intents
Jon Hall73cf9cc2014-11-20 22:28:38 -0800200 """
Jon Hallfebb1c72015-03-05 13:30:09 -0800201 import json
Jon Hall6aec96b2015-01-19 14:49:31 -0800202 # FIXME: we must reinstall intents until we have a persistant
203 # datastore!
Jon Hall73cf9cc2014-11-20 22:28:38 -0800204 import time
Jon Hall6aec96b2015-01-19 14:49:31 -0800205 main.log.report( "Adding host intents" )
206 main.case( "Adding host Intents" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800207
Jon Hall8f89dda2015-01-22 16:03:33 -0800208 main.step( "Discovering Hosts( Via pingall for now )" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800209 # FIXME: Once we have a host discovery mechanism, use that instead
Jon Hall73cf9cc2014-11-20 22:28:38 -0800210
Jon Hall6aec96b2015-01-19 14:49:31 -0800211 # install onos-app-fwd
212 main.log.info( "Install reactive forwarding app" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800213 main.ONOScli1.featureInstall( "onos-app-fwd" )
Jon Hall94fd0472014-12-08 11:52:42 -0800214
Jon Hall6aec96b2015-01-19 14:49:31 -0800215 # REACTIVE FWD test
Jon Hall8f89dda2015-01-22 16:03:33 -0800216 pingResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800217 time1 = time.time()
Jon Hall8f89dda2015-01-22 16:03:33 -0800218 pingResult = main.Mininet1.pingall()
Jon Hall529a37f2015-01-28 10:02:00 -0800219 utilities.assert_equals(
220 expect=main.TRUE,
221 actual=pingResult,
222 onpass="Reactive Pingall test passed",
223 onfail="Reactive Pingall failed, one or more ping pairs failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800224 time2 = time.time()
Jon Hall6aec96b2015-01-19 14:49:31 -0800225 main.log.info( "Time for pingall: %2f seconds" % ( time2 - time1 ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800226
Jon Hall6aec96b2015-01-19 14:49:31 -0800227 # uninstall onos-app-fwd
228 main.log.info( "Uninstall reactive forwarding app" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800229 main.ONOScli1.featureUninstall( "onos-app-fwd" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800230 # timeout for fwd flows
231 time.sleep( 10 )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800232
Jon Hall6aec96b2015-01-19 14:49:31 -0800233 main.step( "Add host intents" )
234 # TODO: move the host numbers to params
Jon Hall8f89dda2015-01-22 16:03:33 -0800235 intentAddResult = True
Jon Hall6aec96b2015-01-19 14:49:31 -0800236 for i in range( 8, 18 ):
237 main.log.info( "Adding host intent between h" + str( i ) +
238 " and h" + str( i + 10 ) )
239 host1 = "00:00:00:00:00:" + \
240 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
241 host2 = "00:00:00:00:00:" + \
242 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800243 # NOTE: getHost can return None
244 host1Dict = main.ONOScli1.getHost( host1 )
245 host2Dict = main.ONOScli1.getHost( host2 )
246 host1Id = None
247 host2Id = None
248 if host1Dict and host2Dict:
249 host1Id = host1Dict.get( 'id', None )
250 host2Id = host2Dict.get( 'id', None )
Jon Hall8f89dda2015-01-22 16:03:33 -0800251 if host1Id and host2Id:
252 tmpResult = main.ONOScli1.addHostIntent(
253 host1Id,
254 host2Id )
Jon Hall669173b2014-12-17 11:36:30 -0800255 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800256 main.log.error( "Error, getHost() failed" )
Jon Hall1b8f54a2015-02-04 13:24:20 -0800257 main.log.warn( json.dumps( json.loads( main.ONOScli1.hosts() ),
258 sort_keys=True,
259 indent=4,
260 separators=( ',', ': ' ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800261 tmpResult = main.FALSE
262 intentAddResult = bool( pingResult and intentAddResult
263 and tmpResult )
Jon Hall529a37f2015-01-28 10:02:00 -0800264 # TODO Check that intents were added?
Jon Hall1b8f54a2015-02-04 13:24:20 -0800265 # Print the intent states
266 intents = main.ONOScli1.intents( )
267 intentStates = []
268 for intent in json.loads( intents ): # Iter through intents of a node
269 intentStates.append( intent.get( 'state', None ) )
270 out = [ (i, intentStates.count( i ) ) for i in set( intentStates ) ]
271 main.log.info( dict( out ) )
272
Jon Hall6aec96b2015-01-19 14:49:31 -0800273 utilities.assert_equals(
274 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -0800275 actual=intentAddResult,
Jon Hall529a37f2015-01-28 10:02:00 -0800276 onpass="Pushed host intents to ONOS",
277 onfail="Error in pushing host intents to ONOS" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800278 # TODO Check if intents all exist in datastore
Jon Hall73cf9cc2014-11-20 22:28:38 -0800279
Jon Hall6aec96b2015-01-19 14:49:31 -0800280 def CASE4( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800281 """
282 Ping across added host intents
283 """
Jon Hallfebb1c72015-03-05 13:30:09 -0800284 import json
Jon Hall73cf9cc2014-11-20 22:28:38 -0800285 description = " Ping across added host intents"
Jon Hall6aec96b2015-01-19 14:49:31 -0800286 main.log.report( description )
287 main.case( description )
Jon Hall8f89dda2015-01-22 16:03:33 -0800288 PingResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800289 for i in range( 8, 18 ):
290 ping = main.Mininet1.pingHost(
291 src="h" + str( i ), target="h" + str( i + 10 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800292 PingResult = PingResult and ping
Jon Hall6aec96b2015-01-19 14:49:31 -0800293 if ping == main.FALSE:
294 main.log.warn( "Ping failed between h" + str( i ) +
295 " and h" + str( i + 10 ) )
296 elif ping == main.TRUE:
297 main.log.info( "Ping test passed!" )
Jon Hall21270ac2015-02-16 17:59:55 -0800298 # Don't set PingResult or you'd override failures
Jon Hall8f89dda2015-01-22 16:03:33 -0800299 if PingResult == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800300 main.log.report(
301 "Intents have not been installed correctly, pings failed." )
Jon Hall529a37f2015-01-28 10:02:00 -0800302 #TODO: pretty print
303 main.log.warn( "ONSO1 intents: " )
304 main.log.warn( json.dumps( json.loads( main.ONOScli1.intents() ),
305 sort_keys=True,
306 indent=4,
307 separators=( ',', ': ' ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800308 if PingResult == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800309 main.log.report(
310 "Intents have been installed correctly and verified by pings" )
311 utilities.assert_equals(
312 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800313 actual=PingResult,
Jon Hall6aec96b2015-01-19 14:49:31 -0800314 onpass="Intents have been installed correctly and pings work",
315 onfail="Intents have not been installed correctly, pings failed." )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800316
Jon Hall6aec96b2015-01-19 14:49:31 -0800317 def CASE5( self, main ):
318 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800319 Reading state of ONOS
Jon Hall6aec96b2015-01-19 14:49:31 -0800320 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800321 import json
Jon Hall6aec96b2015-01-19 14:49:31 -0800322 # assumes that sts is already in you PYTHONPATH
323 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -0800324
Jon Hall6aec96b2015-01-19 14:49:31 -0800325 main.log.report( "Setting up and gathering data for current state" )
326 main.case( "Setting up and gathering data for current state" )
327 # The general idea for this test case is to pull the state of
328 # ( intents,flows, topology,... ) from each ONOS node
329 # We can then compare them with eachother and also with past states
Jon Hall73cf9cc2014-11-20 22:28:38 -0800330
Jon Hall6aec96b2015-01-19 14:49:31 -0800331 main.step( "Get the Mastership of each switch from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800332 global mastershipState
333 mastershipState = []
Jon Hall94fd0472014-12-08 11:52:42 -0800334
Jon Hall6aec96b2015-01-19 14:49:31 -0800335 # Assert that each device has a master
Jon Hall8f89dda2015-01-22 16:03:33 -0800336 rolesNotNull = main.ONOScli1.rolesNotNull()
Jon Hall6aec96b2015-01-19 14:49:31 -0800337 utilities.assert_equals(
338 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800339 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -0800340 onpass="Each device has a master",
341 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -0800342
Jon Hall8f89dda2015-01-22 16:03:33 -0800343 ONOS1Mastership = main.ONOScli1.roles()
Jon Hall6aec96b2015-01-19 14:49:31 -0800344 # TODO: Make this a meaningful check
Jon Hall8f89dda2015-01-22 16:03:33 -0800345 if "Error" in ONOS1Mastership or not ONOS1Mastership:
Jon Hall6aec96b2015-01-19 14:49:31 -0800346 main.log.report( "Error in getting ONOS roles" )
347 main.log.warn(
348 "ONOS1 mastership response: " +
Jon Hall8f89dda2015-01-22 16:03:33 -0800349 repr( ONOS1Mastership ) )
350 consistentMastership = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800351 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800352 mastershipState = ONOS1Mastership
353 consistentMastership = main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800354
Jon Hall6aec96b2015-01-19 14:49:31 -0800355 main.step( "Get the intents from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800356 global intentState
357 intentState = []
358 ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
359 intentCheck = main.FALSE
360 if "Error" in ONOS1Intents or not ONOS1Intents:
Jon Hall6aec96b2015-01-19 14:49:31 -0800361 main.log.report( "Error in getting ONOS intents" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800362 main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800363 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800364 intentCheck = main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800365
Jon Hall6aec96b2015-01-19 14:49:31 -0800366 main.step( "Get the flows from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800367 global flowState
368 flowState = []
369 ONOS1Flows = main.ONOScli1.flows( jsonFormat=True )
370 flowCheck = main.FALSE
371 if "Error" in ONOS1Flows or not ONOS1Flows:
Jon Hall6aec96b2015-01-19 14:49:31 -0800372 main.log.report( "Error in getting ONOS intents" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800373 main.log.warn( "ONOS1 flows repsponse: " + ONOS1Flows )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800374 else:
Jon Hall6aec96b2015-01-19 14:49:31 -0800375 # TODO: Do a better check, maybe compare flows on switches?
Jon Hall8f89dda2015-01-22 16:03:33 -0800376 flowState = ONOS1Flows
377 flowCheck = main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800378
Jon Hall6aec96b2015-01-19 14:49:31 -0800379 main.step( "Get the OF Table entries" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800380 global flows
Jon Hall6aec96b2015-01-19 14:49:31 -0800381 flows = []
382 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800383 flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800384
Jon Hall6aec96b2015-01-19 14:49:31 -0800385 # TODO: Compare switch flow tables with ONOS flow tables
Jon Hall73cf9cc2014-11-20 22:28:38 -0800386
Jon Hall6aec96b2015-01-19 14:49:31 -0800387 main.step( "Create TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800388 ctrls = []
389 count = 1
390 temp = ()
Jon Hall6aec96b2015-01-19 14:49:31 -0800391 temp = temp + ( getattr( main, ( 'ONOS' + str( count ) ) ), )
392 temp = temp + ( "ONOS" + str( count ), )
393 temp = temp + ( main.params[ 'CTRL' ][ 'ip' + str( count ) ], )
394 temp = temp + \
395 ( eval( main.params[ 'CTRL' ][ 'port' + str( count ) ] ), )
396 ctrls.append( temp )
397 MNTopo = TestONTopology(
398 main.Mininet1,
399 ctrls ) # can also add Intent API info for intent operations
Jon Hall73cf9cc2014-11-20 22:28:38 -0800400
Jon Hall6aec96b2015-01-19 14:49:31 -0800401 main.step( "Collecting topology information from ONOS" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800402 devices = []
403 devices.append( main.ONOScli1.devices() )
Jon Hall6aec96b2015-01-19 14:49:31 -0800404 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800405 hosts = []
406 hosts.append( main.ONOScli1.hosts() )
Jon Hall6aec96b2015-01-19 14:49:31 -0800407 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800408 ports = []
409 ports.append( main.ONOScli1.ports() )
410 links = []
411 links.append( main.ONOScli1.links() )
412
Jon Hall6aec96b2015-01-19 14:49:31 -0800413 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800414 devicesResults = main.TRUE
415 portsResults = main.TRUE
416 linksResults = main.TRUE
417 for controller in range( numControllers ):
418 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -0800419 if devices[ controller ] or "Error" not in devices[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -0800420 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -0800421 MNTopo,
422 json.loads(
423 devices[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800424 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800425 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800426 utilities.assert_equals( expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800427 actual=currentDevicesResult,
428 onpass="ONOS" + controllerStr +
429 " Switches view is correct",
430 onfail="ONOS" + controllerStr +
431 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800432
Jon Hall6aec96b2015-01-19 14:49:31 -0800433 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -0800434 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -0800435 MNTopo,
436 json.loads(
437 ports[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800438 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800439 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800440 utilities.assert_equals( expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800441 actual=currentPortsResult,
442 onpass="ONOS" + controllerStr +
443 " ports view is correct",
444 onfail="ONOS" + controllerStr +
445 " ports view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800446
Jon Hall6aec96b2015-01-19 14:49:31 -0800447 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -0800448 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -0800449 MNTopo,
450 json.loads(
451 links[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800452 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800453 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800454 utilities.assert_equals( expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800455 actual=currentLinksResult,
456 onpass="ONOS" + controllerStr +
457 " links view is correct",
458 onfail="ONOS" + controllerStr +
459 " links view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800460
Jon Hall8f89dda2015-01-22 16:03:33 -0800461 devicesResults = devicesResults and currentDevicesResult
462 portsResults = portsResults and currentPortsResult
463 linksResults = linksResults and currentLinksResult
Jon Hall73cf9cc2014-11-20 22:28:38 -0800464
Jon Hall8f89dda2015-01-22 16:03:33 -0800465 topoResult = devicesResults and portsResults and linksResults
466 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
467 onpass="Topology Check Test successful",
468 onfail="Topology Check Test NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800469
Jon Hall8f89dda2015-01-22 16:03:33 -0800470 finalAssert = main.TRUE
471 finalAssert = finalAssert and topoResult and flowCheck \
472 and intentCheck and consistentMastership and rolesNotNull
473 utilities.assert_equals( expect=main.TRUE, actual=finalAssert,
474 onpass="State check successful",
475 onfail="State check NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800476
Jon Hall6aec96b2015-01-19 14:49:31 -0800477 def CASE6( self, main ):
478 """
Jon Hallffb386d2014-11-21 13:43:38 -0800479 The Failure case.
Jon Hall6aec96b2015-01-19 14:49:31 -0800480 """
Jon Hallffb386d2014-11-21 13:43:38 -0800481 import time
Jon Hall73cf9cc2014-11-20 22:28:38 -0800482
Jon Hall6aec96b2015-01-19 14:49:31 -0800483 main.log.report( "Restart ONOS node" )
484 main.log.case( "Restart ONOS node" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800485 main.ONOSbench.onosKill( ONOS1Ip )
Jon Hallffb386d2014-11-21 13:43:38 -0800486 start = time.time()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800487
Jon Hall6aec96b2015-01-19 14:49:31 -0800488 main.step( "Checking if ONOS is up yet" )
Jon Hallffb386d2014-11-21 13:43:38 -0800489 count = 0
Jon Hall94fd0472014-12-08 11:52:42 -0800490 while count < 10:
Jon Hall8f89dda2015-01-22 16:03:33 -0800491 onos1Isup = main.ONOSbench.isup( ONOS1Ip )
492 if onos1Isup == main.TRUE:
Jon Hallffb386d2014-11-21 13:43:38 -0800493 elapsed = time.time() - start
494 break
495 else:
496 count = count + 1
Jon Hall73cf9cc2014-11-20 22:28:38 -0800497
Jon Hall8f89dda2015-01-22 16:03:33 -0800498 cliResult = main.ONOScli1.startOnosCli( ONOS1Ip )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800499
Jon Hall8f89dda2015-01-22 16:03:33 -0800500 caseResults = main.TRUE and onos1Isup and cliResult
501 utilities.assert_equals( expect=main.TRUE, actual=caseResults,
502 onpass="ONOS restart successful",
503 onfail="ONOS restart NOT successful" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800504 if elapsed:
505 main.log.info( "ESTIMATE: ONOS took %s seconds to restart" %
506 str( elapsed ) )
Jon Hall6aec96b2015-01-19 14:49:31 -0800507 time.sleep( 5 )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800508
Jon Hall6aec96b2015-01-19 14:49:31 -0800509 def CASE7( self, main ):
510 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800511 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -0800512 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800513 import json
Jon Hall6aec96b2015-01-19 14:49:31 -0800514 main.case( "Running ONOS Constant State Tests" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800515
Jon Hall6aec96b2015-01-19 14:49:31 -0800516 # Assert that each device has a master
Jon Hall8f89dda2015-01-22 16:03:33 -0800517 rolesNotNull = main.ONOScli1.rolesNotNull()
Jon Hall6aec96b2015-01-19 14:49:31 -0800518 utilities.assert_equals(
519 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800520 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -0800521 onpass="Each device has a master",
522 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -0800523
Jon Hall6aec96b2015-01-19 14:49:31 -0800524 main.step( "Check if switch roles are consistent across all nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800525 ONOS1Mastership = main.ONOScli1.roles()
Jon Hall6aec96b2015-01-19 14:49:31 -0800526 # FIXME: Refactor this whole case for single instance
Jon Hall8f89dda2015-01-22 16:03:33 -0800527 if "Error" in ONOS1Mastership or not ONOS1Mastership:
Jon Hall6aec96b2015-01-19 14:49:31 -0800528 main.log.report( "Error in getting ONOS mastership" )
529 main.log.warn(
530 "ONOS1 mastership response: " +
Jon Hall8f89dda2015-01-22 16:03:33 -0800531 repr( ONOS1Mastership ) )
532 consistentMastership = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800533 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800534 consistentMastership = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800535 main.log.report(
536 "Switch roles are consistent across all ONOS nodes" )
537 utilities.assert_equals(
538 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800539 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -0800540 onpass="Switch roles are consistent across all ONOS nodes",
541 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800542
543 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -0800544 main.step( description2 )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800545
Jon Hall8f89dda2015-01-22 16:03:33 -0800546 currentJson = json.loads( ONOS1Mastership )
547 oldJson = json.loads( mastershipState )
548 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800549 for i in range( 1, 29 ):
550 switchDPID = str(
551 main.Mininet1.getSwitchDPID(
552 switch="s" +
553 str( i ) ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800554
Jon Hall8f89dda2015-01-22 16:03:33 -0800555 current = [ switch[ 'master' ] for switch in currentJson
Jon Hall6aec96b2015-01-19 14:49:31 -0800556 if switchDPID in switch[ 'id' ] ]
Jon Hall8f89dda2015-01-22 16:03:33 -0800557 old = [ switch[ 'master' ] for switch in oldJson
Jon Hall6aec96b2015-01-19 14:49:31 -0800558 if switchDPID in switch[ 'id' ] ]
Jon Hall73cf9cc2014-11-20 22:28:38 -0800559 if current == old:
Jon Hall8f89dda2015-01-22 16:03:33 -0800560 mastershipCheck = mastershipCheck and main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800561 else:
Jon Hall6aec96b2015-01-19 14:49:31 -0800562 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall8f89dda2015-01-22 16:03:33 -0800563 mastershipCheck = main.FALSE
564 if mastershipCheck == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800565 main.log.report( "Mastership of Switches was not changed" )
566 utilities.assert_equals(
567 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800568 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800569 onpass="Mastership of Switches was not changed",
570 onfail="Mastership of some switches changed" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800571 mastershipCheck = mastershipCheck and consistentMastership
Jon Hall73cf9cc2014-11-20 22:28:38 -0800572
Jon Hall6aec96b2015-01-19 14:49:31 -0800573 main.step( "Get the intents and compare across all nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800574 ONOS1Intents = main.ONOScli1.intents( jsonFormat=True )
575 intentCheck = main.FALSE
576 if "Error" in ONOS1Intents or not ONOS1Intents:
Jon Hall6aec96b2015-01-19 14:49:31 -0800577 main.log.report( "Error in getting ONOS intents" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800578 main.log.warn( "ONOS1 intents response: " + repr( ONOS1Intents ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800579 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800580 intentCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800581 main.log.report( "Intents are consistent across all ONOS nodes" )
582 utilities.assert_equals(
583 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800584 actual=intentCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800585 onpass="Intents are consistent across all ONOS nodes",
586 onfail="ONOS nodes have different views of intents" )
Jon Hall1b8f54a2015-02-04 13:24:20 -0800587 # Print the intent states
588 intents = []
589 intents.append( ONOS1Intents )
590 intentStates = []
591 for node in intents: # Iter through ONOS nodes
592 nodeStates = []
593 for intent in json.loads( node ): # Iter through intents of a node
594 nodeStates.append( intent[ 'state' ] )
595 intentStates.append( nodeStates )
596 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
597 main.log.info( dict( out ) )
598
Jon Hall73cf9cc2014-11-20 22:28:38 -0800599
Jon Hall6aec96b2015-01-19 14:49:31 -0800600 # NOTE: Hazelcast has no durability, so intents are lost across system
601 # restarts
602 """
603 main.step( "Compare current intents with intents before the failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800604 # NOTE: this requires case 5 to pass for intentState to be set.
Jon Hall6aec96b2015-01-19 14:49:31 -0800605 # maybe we should stop the test if that fails?
Jon Hall1b8f54a2015-02-04 13:24:20 -0800606 sameIntents = main.TRUE
607 if intentState and intentState == ONOS1Intents:
Jon Hall8f89dda2015-01-22 16:03:33 -0800608 sameIntents = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800609 main.log.report( "Intents are consistent with before failure" )
610 # TODO: possibly the states have changed? we may need to figure out
611 # what the aceptable states are
Jon Hall73cf9cc2014-11-20 22:28:38 -0800612 else:
Jon Hall6aec96b2015-01-19 14:49:31 -0800613 try:
614 main.log.warn( "ONOS1 intents: " )
Jon Hall8f89dda2015-01-22 16:03:33 -0800615 print json.dumps( json.loads( ONOS1Intents ),
Jon Hall6aec96b2015-01-19 14:49:31 -0800616 sort_keys=True, indent=4,
617 separators=( ',', ': ' ) )
Jon Hallfebb1c72015-03-05 13:30:09 -0800618 except Exception:
Jon Hall6aec96b2015-01-19 14:49:31 -0800619 pass
Jon Hall8f89dda2015-01-22 16:03:33 -0800620 sameIntents = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800621 utilities.assert_equals(
622 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800623 actual=sameIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -0800624 onpass="Intents are consistent with before failure",
625 onfail="The Intents changed during failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800626 intentCheck = intentCheck and sameIntents
Jon Hall6aec96b2015-01-19 14:49:31 -0800627 """
628 main.step( "Get the OF Table entries and compare to before " +
629 "component failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800630 FlowTables = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800631 flows2 = []
632 for i in range( 28 ):
633 main.log.info( "Checking flow table on s" + str( i + 1 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800634 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
635 flows2.append( tmpFlows )
636 tempResult = main.Mininet2.flowComp(
Jon Hall6aec96b2015-01-19 14:49:31 -0800637 flow1=flows[ i ],
Jon Hall8f89dda2015-01-22 16:03:33 -0800638 flow2=tmpFlows )
639 FlowTables = FlowTables and tempResult
640 if FlowTables == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800641 main.log.info( "Differences in flow table for switch: s" +
642 str( i + 1 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800643 if FlowTables == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800644 main.log.report( "No changes were found in the flow tables" )
645 utilities.assert_equals(
646 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800647 actual=FlowTables,
Jon Hall6aec96b2015-01-19 14:49:31 -0800648 onpass="No changes were found in the flow tables",
649 onfail="Changes were found in the flow tables" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800650
Jon Hall6aec96b2015-01-19 14:49:31 -0800651 # Test of LeadershipElection
Jon Hall669173b2014-12-17 11:36:30 -0800652
Jon Hall8f89dda2015-01-22 16:03:33 -0800653 leader = ONOS1Ip
654 leaderResult = main.TRUE
655 for controller in range( 1, numControllers + 1 ):
Jon Hall6aec96b2015-01-19 14:49:31 -0800656 # loop through ONOScli handlers
657 node = getattr( main, ( 'ONOScli' + str( controller ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800658 leaderN = node.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -0800659 # verify leader is ONOS1
660 # NOTE even though we restarted ONOS, it is the only one so onos 1
661 # must be leader
Jon Hall669173b2014-12-17 11:36:30 -0800662 if leaderN == leader:
Jon Hall6aec96b2015-01-19 14:49:31 -0800663 # all is well
Jon Hall669173b2014-12-17 11:36:30 -0800664 pass
665 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800666 # error in response
667 main.log.report( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -0800668 "electionTestLeader function, check the" +
Jon Hall6aec96b2015-01-19 14:49:31 -0800669 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800670 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -0800671 elif leader != leaderN:
Jon Hall8f89dda2015-01-22 16:03:33 -0800672 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800673 main.log.report( "ONOS" + str( controller ) +
674 " sees " + str( leaderN ) +
675 " as the leader of the election app." +
676 " Leader should be " + str( leader ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800677 if leaderResult:
678 main.log.report( "Leadership election tests passed( consistent " +
Jon Hall6aec96b2015-01-19 14:49:31 -0800679 "view of leader across listeners and a new " +
Jon Hall8f89dda2015-01-22 16:03:33 -0800680 "leader was re-elected if applicable )" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800681 utilities.assert_equals(
682 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800683 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -0800684 onpass="Leadership election passed",
685 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -0800686
Jon Hall8f89dda2015-01-22 16:03:33 -0800687 result = ( mastershipCheck and intentCheck and FlowTables and
688 rolesNotNull and leaderResult )
Jon Hall6aec96b2015-01-19 14:49:31 -0800689 result = int( result )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800690 if result == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800691 main.log.report( "Constant State Tests Passed" )
692 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall8f89dda2015-01-22 16:03:33 -0800693 onpass="Constant State Tests Passed",
694 onfail="Constant state tests failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800695
Jon Hall6aec96b2015-01-19 14:49:31 -0800696 def CASE8( self, main ):
697 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800698 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -0800699 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800700 import sys
Jon Hall6aec96b2015-01-19 14:49:31 -0800701 # FIXME add this path to params
702 sys.path.append( "/home/admin/sts" )
703 # assumes that sts is already in you PYTHONPATH
704 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -0800705 import json
706 import time
707
Jon Hall6aec96b2015-01-19 14:49:31 -0800708 description = "Compare ONOS Topology view to Mininet topology"
709 main.case( description )
710 main.log.report( description )
711 main.step( "Create TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800712 ctrls = []
713 count = 1
714 temp = ()
Jon Hall6aec96b2015-01-19 14:49:31 -0800715 temp = temp + ( getattr( main, ( 'ONOS' + str( count ) ) ), )
716 temp = temp + ( "ONOS" + str( count ), )
717 temp = temp + ( main.params[ 'CTRL' ][ 'ip' + str( count ) ], )
718 temp = temp + \
719 ( eval( main.params[ 'CTRL' ][ 'port' + str( count ) ] ), )
720 ctrls.append( temp )
721 MNTopo = TestONTopology(
722 main.Mininet1,
723 ctrls ) # can also add Intent API info for intent operations
Jon Hall73cf9cc2014-11-20 22:28:38 -0800724
Jon Hall6aec96b2015-01-19 14:49:31 -0800725 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800726 devicesResults = main.TRUE
727 portsResults = main.TRUE
728 linksResults = main.TRUE
729 topoResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800730 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -0800731 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -0800732 main.step( "Collecting topology information from ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800733 startTime = time.time()
734 while topoResult == main.FALSE and elapsed < 60:
Jon Hallffb386d2014-11-21 13:43:38 -0800735 count = count + 1
Jon Hall94fd0472014-12-08 11:52:42 -0800736 if count > 1:
Jon Hall6aec96b2015-01-19 14:49:31 -0800737 MNTopo = TestONTopology(
738 main.Mininet1,
739 ctrls )
Jon Hall8f89dda2015-01-22 16:03:33 -0800740 cliStart = time.time()
Jon Hall94fd0472014-12-08 11:52:42 -0800741 devices = []
742 devices.append( main.ONOScli1.devices() )
Jon Hall6aec96b2015-01-19 14:49:31 -0800743 """
Jon Hall94fd0472014-12-08 11:52:42 -0800744 hosts = []
745 hosts.append( main.ONOScli1.hosts() )
Jon Hall6aec96b2015-01-19 14:49:31 -0800746 """
Jon Hall94fd0472014-12-08 11:52:42 -0800747 ports = []
748 ports.append( main.ONOScli1.ports() )
749 links = []
750 links.append( main.ONOScli1.links() )
Jon Hall8f89dda2015-01-22 16:03:33 -0800751 elapsed = time.time() - startTime
752 cliTime = time.time() - cliStart
753 print "CLI time: " + str( cliTime )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800754
Jon Hall8f89dda2015-01-22 16:03:33 -0800755 for controller in range( numControllers ):
756 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -0800757 if devices[ controller ] or "Error" not in devices[
758 controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -0800759 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -0800760 MNTopo,
761 json.loads(
762 devices[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800763 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800764 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800765 utilities.assert_equals( expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800766 actual=currentDevicesResult,
767 onpass="ONOS" + controllerStr +
768 " Switches view is correct",
769 onfail="ONOS" + controllerStr +
770 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800771
Jon Hall6aec96b2015-01-19 14:49:31 -0800772 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -0800773 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -0800774 MNTopo,
775 json.loads(
776 ports[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800777 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800778 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800779 utilities.assert_equals( expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800780 actual=currentPortsResult,
781 onpass="ONOS" + controllerStr +
782 " ports view is correct",
783 onfail="ONOS" + controllerStr +
784 " ports view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800785
Jon Hall6aec96b2015-01-19 14:49:31 -0800786 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -0800787 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -0800788 MNTopo,
789 json.loads(
790 links[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800791 else:
Jon Hall8f89dda2015-01-22 16:03:33 -0800792 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800793 utilities.assert_equals( expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800794 actual=currentLinksResult,
795 onpass="ONOS" + controllerStr +
796 " links view is correct",
797 onfail="ONOS" + controllerStr +
798 " links view is incorrect" )
799 devicesResults = devicesResults and currentDevicesResult
800 portsResults = portsResults and currentPortsResult
801 linksResults = linksResults and currentLinksResult
802 topoResult = devicesResults and portsResults and linksResults
Jon Hall94fd0472014-12-08 11:52:42 -0800803
Jon Hall8f89dda2015-01-22 16:03:33 -0800804 topoResult = topoResult and int( count <= 2 )
805 note = "note it takes about " + str( int( cliTime ) ) + \
806 " seconds for the test to make all the cli calls to fetch " +\
807 "the topology from each ONOS instance"
Jon Hall1b8f54a2015-02-04 13:24:20 -0800808 main.log.info(
Jon Hall8f89dda2015-01-22 16:03:33 -0800809 "Very crass estimate for topology discovery/convergence( " +
810 str( note ) + " ): " + str( elapsed ) + " seconds, " +
Jon Hall6aec96b2015-01-19 14:49:31 -0800811 str( count ) + " tries" )
Jon Hall94fd0472014-12-08 11:52:42 -0800812 if elapsed > 60:
Jon Hall6aec96b2015-01-19 14:49:31 -0800813 main.log.report( "Giving up on topology convergence" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800814 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
815 onpass="Topology Check Test successful",
816 onfail="Topology Check Test NOT successful" )
817 if topoResult == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800818 main.log.report( "ONOS topology view matches Mininet topology" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800819
Jon Hall6aec96b2015-01-19 14:49:31 -0800820 def CASE9( self, main ):
821 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800822 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -0800823 """
824 import time
825 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -0800826
Jon Hall8f89dda2015-01-22 16:03:33 -0800827 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800828
Jon Hall6aec96b2015-01-19 14:49:31 -0800829 description = "Turn off a link to ensure that Link Discovery " +\
Jon Hall8f89dda2015-01-22 16:03:33 -0800830 "is working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -0800831 main.log.report( description )
832 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800833
Jon Hall6aec96b2015-01-19 14:49:31 -0800834 main.step( "Kill Link between s3 and s28" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800835 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800836 main.log.info(
837 "Waiting " +
Jon Hall8f89dda2015-01-22 16:03:33 -0800838 str( linkSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -0800839 " seconds for link down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800840 time.sleep( linkSleep )
841 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
842 onpass="Link down succesful",
843 onfail="Failed to bring link down" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800844 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -0800845
Jon Hall6aec96b2015-01-19 14:49:31 -0800846 def CASE10( self, main ):
847 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800848 Link s3-s28 up
Jon Hall6aec96b2015-01-19 14:49:31 -0800849 """
850 import time
851 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -0800852
Jon Hall8f89dda2015-01-22 16:03:33 -0800853 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800854
Jon Hall6aec96b2015-01-19 14:49:31 -0800855 description = "Restore a link to ensure that Link Discovery is " + \
Jon Hall8f89dda2015-01-22 16:03:33 -0800856 "working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -0800857 main.log.report( description )
858 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800859
Jon Hall6aec96b2015-01-19 14:49:31 -0800860 main.step( "Bring link between s3 and s28 back up" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800861 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800862 main.log.info(
863 "Waiting " +
Jon Hall8f89dda2015-01-22 16:03:33 -0800864 str( linkSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -0800865 " seconds for link up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800866 time.sleep( linkSleep )
867 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
868 onpass="Link up succesful",
869 onfail="Failed to bring link up" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800870 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -0800871
Jon Hall6aec96b2015-01-19 14:49:31 -0800872 def CASE11( self, main ):
873 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800874 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -0800875 """
876 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -0800877 import time
878
Jon Hall8f89dda2015-01-22 16:03:33 -0800879 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800880
881 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -0800882 main.log.report( description )
883 main.case( description )
884 switch = main.params[ 'kill' ][ 'switch' ]
885 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hall73cf9cc2014-11-20 22:28:38 -0800886
Jon Hall6aec96b2015-01-19 14:49:31 -0800887 # TODO: Make this switch parameterizable
888 main.step( "Kill " + switch )
889 main.log.report( "Deleting " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -0800890 main.Mininet1.delSwitch( switch )
891 main.log.info( "Waiting " + str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -0800892 " seconds for switch down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800893 time.sleep( switchSleep )
894 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -0800895 # Peek at the deleted switch
896 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800897 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800898 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -0800899 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800900 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall8f89dda2015-01-22 16:03:33 -0800901 onpass="Kill switch succesful",
902 onfail="Failed to kill switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800903
Jon Hall6aec96b2015-01-19 14:49:31 -0800904 def CASE12( self, main ):
905 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800906 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -0800907 """
908 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -0800909 import time
Jon Hall669173b2014-12-17 11:36:30 -0800910
Jon Hall8f89dda2015-01-22 16:03:33 -0800911 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall6aec96b2015-01-19 14:49:31 -0800912 switch = main.params[ 'kill' ][ 'switch' ]
913 switchDPID = main.params[ 'kill' ][ 'dpid' ]
914 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800915 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -0800916 main.log.report( description )
917 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800918
Jon Hall6aec96b2015-01-19 14:49:31 -0800919 main.step( "Add back " + switch )
920 main.log.report( "Adding back " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -0800921 main.Mininet1.addSwitch( switch, dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -0800922 # TODO: New dpid or same? Ask Thomas?
923 for peer in links:
Jon Hall8f89dda2015-01-22 16:03:33 -0800924 main.Mininet1.addLink( switch, peer )
925 main.Mininet1.assignSwController( sw=switch.split( 's' )[ 1 ],
926 ip1=ONOS1Ip, port1=ONOS1Port )
Jon Hall6aec96b2015-01-19 14:49:31 -0800927 main.log.info(
928 "Waiting " +
Jon Hall8f89dda2015-01-22 16:03:33 -0800929 str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -0800930 " seconds for switch up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800931 time.sleep( switchSleep )
932 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -0800933 # Peek at the deleted switch
934 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800935 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800936 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -0800937 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800938 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall8f89dda2015-01-22 16:03:33 -0800939 onpass="add switch succesful",
940 onfail="Failed to add switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800941
Jon Hall6aec96b2015-01-19 14:49:31 -0800942 def CASE13( self, main ):
943 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800944 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -0800945 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800946 import os
947 import time
Jon Hall6aec96b2015-01-19 14:49:31 -0800948 # printing colors to terminal
Jon Hall669173b2014-12-17 11:36:30 -0800949 colors = {}
Jon Hall6aec96b2015-01-19 14:49:31 -0800950 colors[ 'cyan' ] = '\033[96m'
951 colors[ 'purple' ] = '\033[95m'
952 colors[ 'blue' ] = '\033[94m'
953 colors[ 'green' ] = '\033[92m'
954 colors[ 'yellow' ] = '\033[93m'
955 colors[ 'red' ] = '\033[91m'
956 colors[ 'end' ] = '\033[0m'
Jon Hall73cf9cc2014-11-20 22:28:38 -0800957 description = "Test Cleanup"
Jon Hall6aec96b2015-01-19 14:49:31 -0800958 main.log.report( description )
959 main.case( description )
960 main.step( "Killing tcpdumps" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800961 main.Mininet2.stopTcpdump()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800962
Jon Hall6aec96b2015-01-19 14:49:31 -0800963 main.step( "Checking ONOS Logs for errors" )
964 print colors[ 'purple' ] + "Checking logs for errors on ONOS1:" + \
Jon Hall8f89dda2015-01-22 16:03:33 -0800965 colors[ 'end' ]
966 print main.ONOSbench.checkLogs( ONOS1Ip )
Jon Hall6aec96b2015-01-19 14:49:31 -0800967 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800968 testname = main.TEST
Jon Hall8f89dda2015-01-22 16:03:33 -0800969 teststationUser = main.params[ 'TESTONUSER' ]
970 teststationIP = main.params[ 'TESTONIP' ]
Jon Hall6aec96b2015-01-19 14:49:31 -0800971 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -0800972 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -0800973 # FIXME: scp
974 # mn files
975 # TODO: Load these from params
976 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -0800977 logFolder = "/opt/onos/log/"
978 logFiles = [ "karaf.log", "karaf.log.1" ]
Jon Hall6aec96b2015-01-19 14:49:31 -0800979 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -0800980 dstDir = "~/packet_captures/"
981 for f in logFiles:
982 main.ONOSbench.handle.sendline( "scp sdn@" + ONOS1Ip + ":" +
983 logFolder + f + " " +
984 teststationUser + "@" +
985 teststationIP + ":" + dstDir +
Jon Hall6aec96b2015-01-19 14:49:31 -0800986 str( testname ) + "-ONOS1-" + f )
987 main.ONOSbench.handle.expect( "\$" )
Jon Hall94fd0472014-12-08 11:52:42 -0800988 print main.ONOSbench.handle.before
Jon Hall73cf9cc2014-11-20 22:28:38 -0800989
Jon Hall6aec96b2015-01-19 14:49:31 -0800990 # std*.log's
991 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -0800992 logFolder = "/opt/onos/var/"
993 logFiles = [ "stderr.log", "stdout.log" ]
Jon Hall6aec96b2015-01-19 14:49:31 -0800994 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -0800995 dstDir = "~/packet_captures/"
996 for f in logFiles:
997 main.ONOSbench.handle.sendline( "scp sdn@" + ONOS1Ip + ":" +
998 logFolder + f + " " +
999 teststationUser + "@" +
1000 teststationIP + ":" + dstDir +
Jon Hall6aec96b2015-01-19 14:49:31 -08001001 str( testname ) + "-ONOS1-" + f )
1002 # sleep so scp can finish
1003 time.sleep( 10 )
1004 main.step( "Packing and rotating pcap archives" )
1005 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001006
Jon Hall6aec96b2015-01-19 14:49:31 -08001007 # TODO: actually check something here
1008 utilities.assert_equals( expect=main.TRUE, actual=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001009 onpass="Test cleanup successful",
1010 onfail="Test cleanup NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001011
Jon Hall6aec96b2015-01-19 14:49:31 -08001012 def CASE14( self, main ):
1013 """
Jon Hall669173b2014-12-17 11:36:30 -08001014 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -08001015 """
Jon Hall8f89dda2015-01-22 16:03:33 -08001016 leaderResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001017 # install app on onos 1
1018 main.log.info( "Install leadership election app" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001019 main.ONOScli1.featureInstall( "onos-app-election" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001020 # wait for election
1021 # check for leader
Jon Hall8f89dda2015-01-22 16:03:33 -08001022 leader = main.ONOScli1.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08001023 # verify leader is ONOS1
Jon Hall8f89dda2015-01-22 16:03:33 -08001024 if leader == ONOS1Ip:
Jon Hall6aec96b2015-01-19 14:49:31 -08001025 # all is well
Jon Hall669173b2014-12-17 11:36:30 -08001026 pass
Jon Hall6aec96b2015-01-19 14:49:31 -08001027 elif leader is None:
1028 # No leader elected
1029 main.log.report( "No leader was elected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001030 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08001031 elif leader == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001032 # error in response
1033 # TODO: add check for "Command not found:" in the driver, this
1034 # means the app isn't loaded
Jon Hall8f89dda2015-01-22 16:03:33 -08001035 main.log.report( "Something is wrong with electionTestLeader" +
Jon Hall6aec96b2015-01-19 14:49:31 -08001036 " function, check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001037 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08001038 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001039 # error in response
1040 main.log.report(
Jon Hall8f89dda2015-01-22 16:03:33 -08001041 "Unexpected response from electionTestLeader function:'" +
1042 str( leader ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08001043 "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001044 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08001045
Jon Hall6aec96b2015-01-19 14:49:31 -08001046 # install on other nodes and check for leader.
1047 # Should be onos1 and each app should show the same leader
Jon Hall8f89dda2015-01-22 16:03:33 -08001048 for controller in range( 2, numControllers + 1 ):
Jon Hall6aec96b2015-01-19 14:49:31 -08001049 # loop through ONOScli handlers
1050 node = getattr( main, ( 'ONOScli' + str( controller ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001051 node.featureInstall( "onos-app-election" )
1052 leaderN = node.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08001053 # verify leader is ONOS1
Jon Hall8f89dda2015-01-22 16:03:33 -08001054 if leaderN == ONOS1Ip:
Jon Hall6aec96b2015-01-19 14:49:31 -08001055 # all is well
Jon Hall669173b2014-12-17 11:36:30 -08001056 pass
1057 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001058 # error in response
1059 # TODO: add check for "Command not found:" in the driver, this
1060 # means the app isn't loaded
1061 main.log.report( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001062 "electionTestLeader function, check the" +
Jon Hall6aec96b2015-01-19 14:49:31 -08001063 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001064 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08001065 elif leader != leaderN:
Jon Hall8f89dda2015-01-22 16:03:33 -08001066 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001067 main.log.report( "ONOS" + str( controller ) + " sees " +
1068 str( leaderN ) +
1069 " as the leader of the election app. Leader" +
1070 " should be " +
1071 str( leader ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001072 if leaderResult:
Jon Hall6aec96b2015-01-19 14:49:31 -08001073 main.log.report( "Leadership election tests passed( consistent " +
1074 "view of leader across listeners and a leader " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001075 "was elected )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001076 utilities.assert_equals(
1077 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001078 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001079 onpass="Leadership election passed",
1080 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08001081
Jon Hall6aec96b2015-01-19 14:49:31 -08001082 def CASE15( self, main ):
1083 """
Jon Hall669173b2014-12-17 11:36:30 -08001084 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08001085 """
Jon Hall8f89dda2015-01-22 16:03:33 -08001086 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08001087 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08001088 main.log.report( description )
1089 main.case( description )
1090 main.step( "Find current leader and withdraw" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001091 leader = main.ONOScli1.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08001092 # TODO: do some sanity checking on leader before using it
Jon Hall8f89dda2015-01-22 16:03:33 -08001093 withdrawResult = main.FALSE
1094 if leader == ONOS1Ip:
1095 oldLeader = getattr( main, "ONOScli1" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001096 elif leader is None or leader == main.FALSE:
1097 main.log.report(
1098 "Leader for the election app should be an ONOS node," +
1099 "instead got '" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001100 str( leader ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08001101 "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001102 leaderResult = main.FALSE
1103 withdrawResult = oldLeader.electionTestWithdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08001104 utilities.assert_equals(
1105 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001106 actual=withdrawResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001107 onpass="App was withdrawn from election",
1108 onfail="App was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08001109
Jon Hall6aec96b2015-01-19 14:49:31 -08001110 main.step( "Make sure new leader is elected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001111 leaderList = []
1112 leaderN = main.ONOScli1.electionTestLeader()
Jon Hall669173b2014-12-17 11:36:30 -08001113 if leaderN == leader:
Jon Hall6aec96b2015-01-19 14:49:31 -08001114 main.log.report( "ONOS still sees " + str( leaderN ) +
1115 " as leader after they withdrew" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001116 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08001117 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001118 # error in response
1119 # TODO: add check for "Command not found:" in the driver, this
1120 # means the app isn't loaded
Jon Hall8f89dda2015-01-22 16:03:33 -08001121 main.log.report( "Something is wrong with electionTestLeader " +
Jon Hall6aec96b2015-01-19 14:49:31 -08001122 "function, check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001123 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001124 elif leaderN is None:
1125 main.log.info(
1126 "There is no leader after the app withdrew from election" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001127 if leaderResult:
1128 main.log.report( "Leadership election tests passed( There is no " +
1129 "leader after the old leader resigned )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001130 utilities.assert_equals(
1131 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001132 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001133 onpass="Leadership election passed",
1134 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08001135
Jon Hall6aec96b2015-01-19 14:49:31 -08001136 main.step(
Jon Hall8f89dda2015-01-22 16:03:33 -08001137 "Run for election on old leader( just so everyone is in the hat )" )
1138 runResult = oldLeader.electionTestRun()
Jon Hall6aec96b2015-01-19 14:49:31 -08001139 utilities.assert_equals(
1140 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001141 actual=runResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001142 onpass="App re-ran for election",
1143 onfail="App failed to run for election" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001144 leader = main.ONOScli1.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08001145 # verify leader is ONOS1
Jon Hall8f89dda2015-01-22 16:03:33 -08001146 if leader == ONOS1Ip:
1147 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08001148 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001149 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001150 # TODO: assert on run and withdraw results?
Jon Hall669173b2014-12-17 11:36:30 -08001151
Jon Hall6aec96b2015-01-19 14:49:31 -08001152 utilities.assert_equals(
1153 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001154 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001155 onpass="Leadership election passed",
1156 onfail="ONOS1's election app was not leader after it re-ran " +
1157 "for election" )