blob: ef237942fde3d258f780aee705bb409337ad8a24 [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 Hall48cf3ce2015-01-12 15:43:18 -080022class HATestSingleInstanceRestart:
Jon Hall73cf9cc2014-11-20 22:28:38 -080023
Jon Hall6aec96b2015-01-19 14:49:31 -080024 def __init__( self ):
Jon Hall73cf9cc2014-11-20 22:28:38 -080025 self.default = ''
26
Jon Hall6aec96b2015-01-19 14:49:31 -080027 def CASE1( self, main ):
28 """
Jon Hall73cf9cc2014-11-20 22:28:38 -080029 CASE1 is to compile ONOS and push it to the test machines
30
31 Startup sequence:
32 git pull
33 mvn clean install
34 onos-package
35 cell <name>
36 onos-verify-cell
37 NOTE: temporary - onos-remove-raft-logs
38 onos-install -f
39 onos-wait-for-start
Jon Hall6aec96b2015-01-19 14:49:31 -080040 """
41 main.log.report( "ONOS Single node cluster restart " +
42 "HA test - initialization" )
43 main.case( "Setting up test environment" )
44 # TODO: save all the timers and output them for plotting
Jon Hall73cf9cc2014-11-20 22:28:38 -080045
46 # load some vairables from the params file
47 PULL_CODE = False
Jon Hall6aec96b2015-01-19 14:49:31 -080048 if main.params[ 'Git' ] == 'True':
Jon Hall73cf9cc2014-11-20 22:28:38 -080049 PULL_CODE = True
Jon Hall73cf9cc2014-11-20 22:28:38 -080050
Jon Hall6aec96b2015-01-19 14:49:31 -080051 cell_name = main.params[ 'ENV' ][ 'cellName' ]
52
53 # set global variables
Jon Hall73cf9cc2014-11-20 22:28:38 -080054 global ONOS1_ip
55 global ONOS1_port
56 global ONOS2_ip
57 global ONOS2_port
58 global ONOS3_ip
59 global ONOS3_port
60 global ONOS4_ip
61 global ONOS4_port
62 global ONOS5_ip
63 global ONOS5_port
64 global ONOS6_ip
65 global ONOS6_port
66 global ONOS7_ip
67 global ONOS7_port
Jon Hall669173b2014-12-17 11:36:30 -080068 global num_controllers
Jon Hall73cf9cc2014-11-20 22:28:38 -080069
Jon Hall6aec96b2015-01-19 14:49:31 -080070 ONOS1_ip = main.params[ 'CTRL' ][ 'ip1' ]
71 ONOS1_port = main.params[ 'CTRL' ][ 'port1' ]
72 ONOS2_ip = main.params[ 'CTRL' ][ 'ip2' ]
73 ONOS2_port = main.params[ 'CTRL' ][ 'port2' ]
74 ONOS3_ip = main.params[ 'CTRL' ][ 'ip3' ]
75 ONOS3_port = main.params[ 'CTRL' ][ 'port3' ]
76 ONOS4_ip = main.params[ 'CTRL' ][ 'ip4' ]
77 ONOS4_port = main.params[ 'CTRL' ][ 'port4' ]
78 ONOS5_ip = main.params[ 'CTRL' ][ 'ip5' ]
79 ONOS5_port = main.params[ 'CTRL' ][ 'port5' ]
80 ONOS6_ip = main.params[ 'CTRL' ][ 'ip6' ]
81 ONOS6_port = main.params[ 'CTRL' ][ 'port6' ]
82 ONOS7_ip = main.params[ 'CTRL' ][ 'ip7' ]
83 ONOS7_port = main.params[ 'CTRL' ][ 'port7' ]
84 num_controllers = int( main.params[ 'num_controllers' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -080085
Jon Hall6aec96b2015-01-19 14:49:31 -080086 main.step( "Applying cell variable to environment" )
87 cell_result = main.ONOSbench.set_cell( cell_name )
Jon Hall73cf9cc2014-11-20 22:28:38 -080088 verify_result = main.ONOSbench.verify_cell()
89
Jon Hall6aec96b2015-01-19 14:49:31 -080090 # FIXME:this is short term fix
91 main.log.report( "Removing raft logs" )
Jon Hall73cf9cc2014-11-20 22:28:38 -080092 main.ONOSbench.onos_remove_raft_logs()
Jon Hall6aec96b2015-01-19 14:49:31 -080093 main.log.report( "Uninstalling ONOS" )
94 main.ONOSbench.onos_uninstall( ONOS1_ip )
95 main.ONOSbench.onos_uninstall( ONOS2_ip )
96 main.ONOSbench.onos_uninstall( ONOS3_ip )
97 main.ONOSbench.onos_uninstall( ONOS4_ip )
98 main.ONOSbench.onos_uninstall( ONOS5_ip )
99 main.ONOSbench.onos_uninstall( ONOS6_ip )
100 main.ONOSbench.onos_uninstall( ONOS7_ip )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800101
102 clean_install_result = main.TRUE
103 git_pull_result = main.TRUE
104
Jon Hall6aec96b2015-01-19 14:49:31 -0800105 main.step( "Compiling the latest version of ONOS" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800106 if PULL_CODE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800107 # TODO Configure branch in params
108 main.step( "Git checkout and pull master" )
109 main.ONOSbench.git_checkout( "master" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800110 git_pull_result = main.ONOSbench.git_pull()
111
Jon Hall6aec96b2015-01-19 14:49:31 -0800112 main.step( "Using mvn clean & install" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800113 clean_install_result = main.TRUE
114 if git_pull_result == main.TRUE:
115 clean_install_result = main.ONOSbench.clean_install()
116 else:
Jon Hall6aec96b2015-01-19 14:49:31 -0800117 main.log.warn( "Did not pull new code so skipping mvn " +
118 "clean install" )
119 main.ONOSbench.get_version( report=True )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800120
Jon Hall6aec96b2015-01-19 14:49:31 -0800121 cell_result = main.ONOSbench.set_cell( "SingleHA" )
Jon Hall94fd0472014-12-08 11:52:42 -0800122 verify_result = main.ONOSbench.verify_cell()
Jon Hall6aec96b2015-01-19 14:49:31 -0800123 main.step( "Creating ONOS package" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800124 package_result = main.ONOSbench.onos_package()
125
Jon Hall6aec96b2015-01-19 14:49:31 -0800126 main.step( "Installing ONOS package" )
127 onos1_install_result = main.ONOSbench.onos_install( options="-f",
128 node=ONOS1_ip )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800129
Jon Hall6aec96b2015-01-19 14:49:31 -0800130 main.step( "Checking if ONOS is up yet" )
131 # TODO check bundle:list?
132 for i in range( 2 ):
133 onos1_isup = main.ONOSbench.isup( ONOS1_ip )
Jon Hall94fd0472014-12-08 11:52:42 -0800134 if onos1_isup:
135 break
Jon Hall73cf9cc2014-11-20 22:28:38 -0800136 if not onos1_isup:
Jon Hall6aec96b2015-01-19 14:49:31 -0800137 main.log.report( "ONOS1 didn't start!" )
Jon Hall94fd0472014-12-08 11:52:42 -0800138
Jon Hall6aec96b2015-01-19 14:49:31 -0800139 cli_result = main.ONOScli1.start_onos_cli( ONOS1_ip )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800140
Jon Hall6aec96b2015-01-19 14:49:31 -0800141 main.step( "Start Packet Capture MN" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800142 main.Mininet2.start_tcpdump(
Jon Hall6aec96b2015-01-19 14:49:31 -0800143 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
144 + "-MN.pcap",
145 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
146 port=main.params[ 'MNtcpdump' ][ 'port' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800147
Jon Hall6aec96b2015-01-19 14:49:31 -0800148 case1_result = ( clean_install_result and package_result and
149 cell_result and verify_result and onos1_install_result
150 and onos1_isup and cli_result )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800151
Jon Hall6aec96b2015-01-19 14:49:31 -0800152 utilities.assert_equals( expect=main.TRUE, actual=case1_result,
153 onpass="Test startup successful",
154 onfail="Test startup NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800155
Jon Hall6aec96b2015-01-19 14:49:31 -0800156 if case1_result == main.FALSE:
Jon Hall73cf9cc2014-11-20 22:28:38 -0800157 main.cleanup()
158 main.exit()
159
Jon Hall6aec96b2015-01-19 14:49:31 -0800160 def CASE2( self, main ):
161 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800162 Assign mastership to controllers
Jon Hall6aec96b2015-01-19 14:49:31 -0800163 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800164 import re
165
Jon Hall6aec96b2015-01-19 14:49:31 -0800166 main.log.report( "Assigning switches to controllers" )
167 main.case( "Assigning Controllers" )
168 main.step( "Assign switches to controllers" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800169
Jon Hall6aec96b2015-01-19 14:49:31 -0800170 for i in range( 1, 29 ):
171 main.Mininet1.assign_sw_controller(
172 sw=str( i ),
173 ip1=ONOS1_ip, port1=ONOS1_port )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800174
175 mastership_check = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800176 for i in range( 1, 29 ):
177 response = main.Mininet1.get_sw_controller( "s" + str( i ) )
Jon Hallffb386d2014-11-21 13:43:38 -0800178 try:
Jon Hall6aec96b2015-01-19 14:49:31 -0800179 main.log.info( str( response ) )
Jon Hallffb386d2014-11-21 13:43:38 -0800180 except:
Jon Hall6aec96b2015-01-19 14:49:31 -0800181 main.log.info( repr( response ) )
182 if re.search( "tcp:" + ONOS1_ip, response ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800183 mastership_check = mastership_check and main.TRUE
184 else:
185 mastership_check = main.FALSE
186 if mastership_check == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800187 main.log.report( "Switch mastership assigned correctly" )
188 utilities.assert_equals(
189 expect=main.TRUE,
190 actual=mastership_check,
191 onpass="Switch mastership assigned correctly",
192 onfail="Switches not assigned correctly to controllers" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800193
Jon Hall6aec96b2015-01-19 14:49:31 -0800194 def CASE3( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800195 """
196 Assign intents
197
198 """
Jon Hall6aec96b2015-01-19 14:49:31 -0800199 # FIXME: we must reinstall intents until we have a persistant
200 # datastore!
Jon Hall73cf9cc2014-11-20 22:28:38 -0800201 import time
Jon Hall6aec96b2015-01-19 14:49:31 -0800202 main.log.report( "Adding host intents" )
203 main.case( "Adding host Intents" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800204
Jon Hall6aec96b2015-01-19 14:49:31 -0800205 main.step( "Discovering Hosts( Via pingall for now)" )
206 # FIXME: Once we have a host discovery mechanism, use that instead
Jon Hall73cf9cc2014-11-20 22:28:38 -0800207
Jon Hall6aec96b2015-01-19 14:49:31 -0800208 # install onos-app-fwd
209 main.log.info( "Install reactive forwarding app" )
210 main.ONOScli1.feature_install( "onos-app-fwd" )
Jon Hall94fd0472014-12-08 11:52:42 -0800211
Jon Hall6aec96b2015-01-19 14:49:31 -0800212 # REACTIVE FWD test
Jon Hall73cf9cc2014-11-20 22:28:38 -0800213 ping_result = main.FALSE
214 time1 = time.time()
215 ping_result = main.Mininet1.pingall()
216 time2 = time.time()
Jon Hall6aec96b2015-01-19 14:49:31 -0800217 main.log.info( "Time for pingall: %2f seconds" % ( time2 - time1 ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800218
Jon Hall6aec96b2015-01-19 14:49:31 -0800219 # uninstall onos-app-fwd
220 main.log.info( "Uninstall reactive forwarding app" )
221 main.ONOScli1.feature_uninstall( "onos-app-fwd" )
222 # timeout for fwd flows
223 time.sleep( 10 )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800224
Jon Hall6aec96b2015-01-19 14:49:31 -0800225 main.step( "Add host intents" )
226 # TODO: move the host numbers to params
Jon Hall94fd0472014-12-08 11:52:42 -0800227 intent_add_result = True
Jon Hall6aec96b2015-01-19 14:49:31 -0800228 for i in range( 8, 18 ):
229 main.log.info( "Adding host intent between h" + str( i ) +
230 " and h" + str( i + 10 ) )
231 host1 = "00:00:00:00:00:" + \
232 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
233 host2 = "00:00:00:00:00:" + \
234 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
235 host1_id = main.ONOScli1.get_host( host1 )[ 'id' ]
236 host2_id = main.ONOScli1.get_host( host2 )[ 'id' ]
237 # NOTE: get host can return None
Jon Hall669173b2014-12-17 11:36:30 -0800238 if host1_id and host2_id:
Jon Hall6aec96b2015-01-19 14:49:31 -0800239 tmp_result = main.ONOScli1.add_host_intent(
240 host1_id,
241 host2_id )
Jon Hall669173b2014-12-17 11:36:30 -0800242 else:
Jon Hall6aec96b2015-01-19 14:49:31 -0800243 main.log.error( "Error, get_host() failed" )
Jon Hall669173b2014-12-17 11:36:30 -0800244 tmp_result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800245 intent_add_result = bool( ping_result and intent_add_result
246 and tmp_result )
247 utilities.assert_equals(
248 expect=True,
249 actual=intent_add_result,
250 onpass="Switch mastership correctly assigned",
251 onfail="Error in (re)assigning switch mastership" )
252 # TODO Check if intents all exist in datastore
Jon Hall73cf9cc2014-11-20 22:28:38 -0800253
Jon Hall6aec96b2015-01-19 14:49:31 -0800254 def CASE4( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800255 """
256 Ping across added host intents
257 """
258 description = " Ping across added host intents"
Jon Hall6aec96b2015-01-19 14:49:31 -0800259 main.log.report( description )
260 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800261 Ping_Result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800262 for i in range( 8, 18 ):
263 ping = main.Mininet1.pingHost(
264 src="h" + str( i ), target="h" + str( i + 10 ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800265 Ping_Result = Ping_Result and ping
Jon Hall6aec96b2015-01-19 14:49:31 -0800266 if ping == main.FALSE:
267 main.log.warn( "Ping failed between h" + str( i ) +
268 " and h" + str( i + 10 ) )
269 elif ping == main.TRUE:
270 main.log.info( "Ping test passed!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800271 Ping_Result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800272 if Ping_Result == main.FALSE:
273 main.log.report(
274 "Intents have not been installed correctly, pings failed." )
275 if Ping_Result == main.TRUE:
276 main.log.report(
277 "Intents have been installed correctly and verified by pings" )
278 utilities.assert_equals(
279 expect=main.TRUE,
280 actual=Ping_Result,
281 onpass="Intents have been installed correctly and pings work",
282 onfail="Intents have not been installed correctly, pings failed." )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800283
Jon Hall6aec96b2015-01-19 14:49:31 -0800284 def CASE5( self, main ):
285 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800286 Reading state of ONOS
Jon Hall6aec96b2015-01-19 14:49:31 -0800287 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800288 import json
Jon Hall6aec96b2015-01-19 14:49:31 -0800289 # assumes that sts is already in you PYTHONPATH
290 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -0800291
Jon Hall6aec96b2015-01-19 14:49:31 -0800292 main.log.report( "Setting up and gathering data for current state" )
293 main.case( "Setting up and gathering data for current state" )
294 # The general idea for this test case is to pull the state of
295 # ( intents,flows, topology,... ) from each ONOS node
296 # We can then compare them with eachother and also with past states
Jon Hall73cf9cc2014-11-20 22:28:38 -0800297
Jon Hall6aec96b2015-01-19 14:49:31 -0800298 main.step( "Get the Mastership of each switch from each controller" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800299 global mastership_state
Jon Hall94fd0472014-12-08 11:52:42 -0800300 mastership_state = []
301
Jon Hall6aec96b2015-01-19 14:49:31 -0800302 # Assert that each device has a master
Jon Hall94fd0472014-12-08 11:52:42 -0800303 roles_not_null = main.ONOScli1.roles_not_null()
Jon Hall6aec96b2015-01-19 14:49:31 -0800304 utilities.assert_equals(
305 expect=main.TRUE,
306 actual=roles_not_null,
307 onpass="Each device has a master",
308 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -0800309
Jon Hall73cf9cc2014-11-20 22:28:38 -0800310 ONOS1_mastership = main.ONOScli1.roles()
Jon Hall6aec96b2015-01-19 14:49:31 -0800311 # TODO: Make this a meaningful check
Jon Hall73cf9cc2014-11-20 22:28:38 -0800312 if "Error" in ONOS1_mastership or not ONOS1_mastership:
Jon Hall6aec96b2015-01-19 14:49:31 -0800313 main.log.report( "Error in getting ONOS roles" )
314 main.log.warn(
315 "ONOS1 mastership response: " +
316 repr( ONOS1_mastership ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800317 consistent_mastership = main.FALSE
318 else:
319 mastership_state = ONOS1_mastership
320 consistent_mastership = main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800321
Jon Hall6aec96b2015-01-19 14:49:31 -0800322 main.step( "Get the intents from each controller" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800323 global intent_state
Jon Hall94fd0472014-12-08 11:52:42 -0800324 intent_state = []
Jon Hall73cf9cc2014-11-20 22:28:38 -0800325 ONOS1_intents = main.ONOScli1.intents( json_format=True )
326 intent_check = main.FALSE
327 if "Error" in ONOS1_intents or not ONOS1_intents:
Jon Hall6aec96b2015-01-19 14:49:31 -0800328 main.log.report( "Error in getting ONOS intents" )
329 main.log.warn( "ONOS1 intents response: " + repr( ONOS1_intents ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800330 else:
331 intent_check = main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800332
Jon Hall6aec96b2015-01-19 14:49:31 -0800333 main.step( "Get the flows from each controller" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800334 global flow_state
Jon Hall94fd0472014-12-08 11:52:42 -0800335 flow_state = []
Jon Hall73cf9cc2014-11-20 22:28:38 -0800336 ONOS1_flows = main.ONOScli1.flows( json_format=True )
337 flow_check = main.FALSE
338 if "Error" in ONOS1_flows or not ONOS1_flows:
Jon Hall6aec96b2015-01-19 14:49:31 -0800339 main.log.report( "Error in getting ONOS intents" )
340 main.log.warn( "ONOS1 flows repsponse: " + ONOS1_flows )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800341 else:
Jon Hall6aec96b2015-01-19 14:49:31 -0800342 # TODO: Do a better check, maybe compare flows on switches?
Jon Hall73cf9cc2014-11-20 22:28:38 -0800343 flow_state = ONOS1_flows
344 flow_check = main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800345
Jon Hall6aec96b2015-01-19 14:49:31 -0800346 main.step( "Get the OF Table entries" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800347 global flows
Jon Hall6aec96b2015-01-19 14:49:31 -0800348 flows = []
349 for i in range( 1, 29 ):
350 flows.append( main.Mininet2.get_flowTable( 1.3, "s" + str( i ) ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800351
Jon Hall6aec96b2015-01-19 14:49:31 -0800352 # TODO: Compare switch flow tables with ONOS flow tables
Jon Hall73cf9cc2014-11-20 22:28:38 -0800353
Jon Hall6aec96b2015-01-19 14:49:31 -0800354 main.step( "Create TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800355 ctrls = []
356 count = 1
357 temp = ()
Jon Hall6aec96b2015-01-19 14:49:31 -0800358 temp = temp + ( getattr( main, ( 'ONOS' + str( count ) ) ), )
359 temp = temp + ( "ONOS" + str( count ), )
360 temp = temp + ( main.params[ 'CTRL' ][ 'ip' + str( count ) ], )
361 temp = temp + \
362 ( eval( main.params[ 'CTRL' ][ 'port' + str( count ) ] ), )
363 ctrls.append( temp )
364 MNTopo = TestONTopology(
365 main.Mininet1,
366 ctrls ) # can also add Intent API info for intent operations
Jon Hall73cf9cc2014-11-20 22:28:38 -0800367
Jon Hall6aec96b2015-01-19 14:49:31 -0800368 main.step( "Collecting topology information from ONOS" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800369 devices = []
370 devices.append( main.ONOScli1.devices() )
Jon Hall6aec96b2015-01-19 14:49:31 -0800371 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800372 hosts = []
373 hosts.append( main.ONOScli1.hosts() )
Jon Hall6aec96b2015-01-19 14:49:31 -0800374 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800375 ports = []
376 ports.append( main.ONOScli1.ports() )
377 links = []
378 links.append( main.ONOScli1.links() )
379
Jon Hall6aec96b2015-01-19 14:49:31 -0800380 main.step( "Comparing ONOS topology to MN" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800381 devices_results = main.TRUE
382 ports_results = main.TRUE
383 links_results = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800384 for controller in range( num_controllers ):
385 controller_str = str( controller + 1 )
386 if devices[ controller ] or "Error" not in devices[ controller ]:
387 current_devices_result = main.Mininet1.compare_switches(
388 MNTopo,
389 json.loads(
390 devices[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800391 else:
392 current_devices_result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800393 utilities.assert_equals( expect=main.TRUE,
394 actual=current_devices_result,
395 onpass="ONOS" + controller_str +
396 " Switches view is correct",
397 onfail="ONOS" + controller_str +
398 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800399
Jon Hall6aec96b2015-01-19 14:49:31 -0800400 if ports[ controller ] or "Error" not in ports[ controller ]:
401 current_ports_result = main.Mininet1.compare_ports(
402 MNTopo,
403 json.loads(
404 ports[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800405 else:
406 current_ports_result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800407 utilities.assert_equals( expect=main.TRUE,
408 actual=current_ports_result,
409 onpass="ONOS" + controller_str +
410 " ports view is correct",
411 onfail="ONOS" + controller_str +
412 " ports view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800413
Jon Hall6aec96b2015-01-19 14:49:31 -0800414 if links[ controller ] or "Error" not in links[ controller ]:
415 current_links_result = main.Mininet1.compare_links(
416 MNTopo,
417 json.loads(
418 links[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800419 else:
420 current_links_result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800421 utilities.assert_equals( expect=main.TRUE,
422 actual=current_links_result,
423 onpass="ONOS" + controller_str +
424 " links view is correct",
425 onfail="ONOS" + controller_str +
426 " links view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800427
428 devices_results = devices_results and current_devices_result
429 ports_results = ports_results and current_ports_result
430 links_results = links_results and current_links_result
431
432 topo_result = devices_results and ports_results and links_results
Jon Hall6aec96b2015-01-19 14:49:31 -0800433 utilities.assert_equals( expect=main.TRUE, actual=topo_result,
434 onpass="Topology Check Test successful",
435 onfail="Topology Check Test NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800436
437 final_assert = main.TRUE
438 final_assert = final_assert and topo_result and flow_check \
Jon Hall6aec96b2015-01-19 14:49:31 -0800439 and intent_check and consistent_mastership and roles_not_null
440 utilities.assert_equals( expect=main.TRUE, actual=final_assert,
441 onpass="State check successful",
442 onfail="State check NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800443
Jon Hall6aec96b2015-01-19 14:49:31 -0800444 def CASE6( self, main ):
445 """
Jon Hallffb386d2014-11-21 13:43:38 -0800446 The Failure case.
Jon Hall6aec96b2015-01-19 14:49:31 -0800447 """
Jon Hallffb386d2014-11-21 13:43:38 -0800448 import time
Jon Hall73cf9cc2014-11-20 22:28:38 -0800449
Jon Hall6aec96b2015-01-19 14:49:31 -0800450 main.log.report( "Restart ONOS node" )
451 main.log.case( "Restart ONOS node" )
452 main.ONOSbench.onos_kill( ONOS1_ip )
Jon Hallffb386d2014-11-21 13:43:38 -0800453 start = time.time()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800454
Jon Hall6aec96b2015-01-19 14:49:31 -0800455 main.step( "Checking if ONOS is up yet" )
Jon Hallffb386d2014-11-21 13:43:38 -0800456 count = 0
Jon Hall94fd0472014-12-08 11:52:42 -0800457 while count < 10:
Jon Hall6aec96b2015-01-19 14:49:31 -0800458 onos1_isup = main.ONOSbench.isup( ONOS1_ip )
Jon Hallffb386d2014-11-21 13:43:38 -0800459 if onos1_isup == main.TRUE:
460 elapsed = time.time() - start
461 break
462 else:
463 count = count + 1
Jon Hall73cf9cc2014-11-20 22:28:38 -0800464
Jon Hall6aec96b2015-01-19 14:49:31 -0800465 cli_result = main.ONOScli1.start_onos_cli( ONOS1_ip )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800466
Jon Hall94fd0472014-12-08 11:52:42 -0800467 case_results = main.TRUE and onos1_isup and cli_result
Jon Hall6aec96b2015-01-19 14:49:31 -0800468 utilities.assert_equals( expect=main.TRUE, actual=case_results,
469 onpass="ONOS restart successful",
470 onfail="ONOS restart NOT successful" )
471 main.log.info(
472 "ESTIMATE: ONOS took %s seconds to restart" %
473 str( elapsed ) )
474 time.sleep( 5 )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800475
Jon Hall6aec96b2015-01-19 14:49:31 -0800476 def CASE7( self, main ):
477 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800478 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -0800479 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800480 import json
Jon Hall6aec96b2015-01-19 14:49:31 -0800481 main.case( "Running ONOS Constant State Tests" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800482
Jon Hall6aec96b2015-01-19 14:49:31 -0800483 # Assert that each device has a master
Jon Hall94fd0472014-12-08 11:52:42 -0800484 roles_not_null = main.ONOScli1.roles_not_null()
Jon Hall6aec96b2015-01-19 14:49:31 -0800485 utilities.assert_equals(
486 expect=main.TRUE,
487 actual=roles_not_null,
488 onpass="Each device has a master",
489 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -0800490
Jon Hall6aec96b2015-01-19 14:49:31 -0800491 main.step( "Check if switch roles are consistent across all nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800492 ONOS1_mastership = main.ONOScli1.roles()
Jon Hall6aec96b2015-01-19 14:49:31 -0800493 # FIXME: Refactor this whole case for single instance
Jon Hall73cf9cc2014-11-20 22:28:38 -0800494 if "Error" in ONOS1_mastership or not ONOS1_mastership:
Jon Hall6aec96b2015-01-19 14:49:31 -0800495 main.log.report( "Error in getting ONOS mastership" )
496 main.log.warn(
497 "ONOS1 mastership response: " +
498 repr( ONOS1_mastership ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800499 consistent_mastership = main.FALSE
500 else:
501 consistent_mastership = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800502 main.log.report(
503 "Switch roles are consistent across all ONOS nodes" )
504 utilities.assert_equals(
505 expect=main.TRUE,
506 actual=consistent_mastership,
507 onpass="Switch roles are consistent across all ONOS nodes",
508 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800509
510 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -0800511 main.step( description2 )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800512
Jon Hall6aec96b2015-01-19 14:49:31 -0800513 current_json = json.loads( ONOS1_mastership )
514 old_json = json.loads( mastership_state )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800515 mastership_check = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800516 for i in range( 1, 29 ):
517 switchDPID = str(
518 main.Mininet1.getSwitchDPID(
519 switch="s" +
520 str( i ) ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800521
Jon Hall6aec96b2015-01-19 14:49:31 -0800522 current = [ switch[ 'master' ] for switch in current_json
523 if switchDPID in switch[ 'id' ] ]
524 old = [ switch[ 'master' ] for switch in old_json
525 if switchDPID in switch[ 'id' ] ]
Jon Hall73cf9cc2014-11-20 22:28:38 -0800526 if current == old:
527 mastership_check = mastership_check and main.TRUE
528 else:
Jon Hall6aec96b2015-01-19 14:49:31 -0800529 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800530 mastership_check = main.FALSE
531 if mastership_check == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800532 main.log.report( "Mastership of Switches was not changed" )
533 utilities.assert_equals(
534 expect=main.TRUE,
535 actual=mastership_check,
536 onpass="Mastership of Switches was not changed",
537 onfail="Mastership of some switches changed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800538 mastership_check = mastership_check and consistent_mastership
539
Jon Hall6aec96b2015-01-19 14:49:31 -0800540 main.step( "Get the intents and compare across all nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800541 ONOS1_intents = main.ONOScli1.intents( json_format=True )
542 intent_check = main.FALSE
543 if "Error" in ONOS1_intents or not ONOS1_intents:
Jon Hall6aec96b2015-01-19 14:49:31 -0800544 main.log.report( "Error in getting ONOS intents" )
545 main.log.warn( "ONOS1 intents response: " + repr( ONOS1_intents ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800546 else:
Jon Hall73cf9cc2014-11-20 22:28:38 -0800547 intent_check = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800548 main.log.report( "Intents are consistent across all ONOS nodes" )
549 utilities.assert_equals(
550 expect=main.TRUE,
551 actual=intent_check,
552 onpass="Intents are consistent across all ONOS nodes",
553 onfail="ONOS nodes have different views of intents" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800554
Jon Hall6aec96b2015-01-19 14:49:31 -0800555 # NOTE: Hazelcast has no durability, so intents are lost across system
556 # restarts
557 """
558 main.step( "Compare current intents with intents before the failure" )
559 # NOTE: this requires case 5 to pass for intent_state to be set.
560 # maybe we should stop the test if that fails?
Jon Hall73cf9cc2014-11-20 22:28:38 -0800561 if intent_state == ONOS1_intents:
562 same_intents = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800563 main.log.report( "Intents are consistent with before failure" )
564 # TODO: possibly the states have changed? we may need to figure out
565 # what the aceptable states are
Jon Hall73cf9cc2014-11-20 22:28:38 -0800566 else:
Jon Hall6aec96b2015-01-19 14:49:31 -0800567 try:
568 main.log.warn( "ONOS1 intents: " )
569 print json.dumps( json.loads( ONOS1_intents ),
570 sort_keys=True, indent=4,
571 separators=( ',', ': ' ) )
572 except:
573 pass
Jon Hall73cf9cc2014-11-20 22:28:38 -0800574 same_intents = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800575 utilities.assert_equals(
576 expect=main.TRUE,
577 actual=same_intents,
578 onpass="Intents are consistent with before failure",
579 onfail="The Intents changed during failure" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800580 intent_check = intent_check and same_intents
Jon Hall6aec96b2015-01-19 14:49:31 -0800581 """
582 main.step( "Get the OF Table entries and compare to before " +
583 "component failure" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800584 Flow_Tables = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800585 flows2 = []
586 for i in range( 28 ):
587 main.log.info( "Checking flow table on s" + str( i + 1 ) )
588 tmp_flows = main.Mininet2.get_flowTable( 1.3, "s" + str( i + 1 ) )
589 flows2.append( tmp_flows )
590 temp_result = main.Mininet2.flow_comp(
591 flow1=flows[ i ],
592 flow2=tmp_flows )
Jon Hall94fd0472014-12-08 11:52:42 -0800593 Flow_Tables = Flow_Tables and temp_result
Jon Hall73cf9cc2014-11-20 22:28:38 -0800594 if Flow_Tables == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800595 main.log.info( "Differences in flow table for switch: s" +
596 str( i + 1 ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800597 if Flow_Tables == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800598 main.log.report( "No changes were found in the flow tables" )
599 utilities.assert_equals(
600 expect=main.TRUE,
601 actual=Flow_Tables,
602 onpass="No changes were found in the flow tables",
603 onfail="Changes were found in the flow tables" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800604
Jon Hall6aec96b2015-01-19 14:49:31 -0800605 # Test of LeadershipElection
Jon Hall669173b2014-12-17 11:36:30 -0800606
607 leader = ONOS1_ip
608 leader_result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800609 for controller in range( 1, num_controllers + 1 ):
610 # loop through ONOScli handlers
611 node = getattr( main, ( 'ONOScli' + str( controller ) ) )
Jon Hall669173b2014-12-17 11:36:30 -0800612 leaderN = node.election_test_leader()
Jon Hall6aec96b2015-01-19 14:49:31 -0800613 # verify leader is ONOS1
614 # NOTE even though we restarted ONOS, it is the only one so onos 1
615 # must be leader
Jon Hall669173b2014-12-17 11:36:30 -0800616 if leaderN == leader:
Jon Hall6aec96b2015-01-19 14:49:31 -0800617 # all is well
Jon Hall669173b2014-12-17 11:36:30 -0800618 pass
619 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800620 # error in response
621 main.log.report( "Something is wrong with " +
622 "election_test_leader function, check the" +
623 " error logs" )
Jon Hall669173b2014-12-17 11:36:30 -0800624 leader_result = main.FALSE
625 elif leader != leaderN:
626 leader_result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800627 main.log.report( "ONOS" + str( controller ) +
628 " sees " + str( leaderN ) +
629 " as the leader of the election app." +
630 " Leader should be " + str( leader ) )
Jon Hall669173b2014-12-17 11:36:30 -0800631 if leader_result:
Jon Hall6aec96b2015-01-19 14:49:31 -0800632 main.log.report( "Leadership election tests passed(consistent " +
633 "view of leader across listeners and a new " +
634 "leader was re-elected if applicable)" )
635 utilities.assert_equals(
636 expect=main.TRUE,
637 actual=leader_result,
638 onpass="Leadership election passed",
639 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -0800640
Jon Hall6aec96b2015-01-19 14:49:31 -0800641 result = ( mastership_check and intent_check and Flow_Tables and
642 roles_not_null and leader_result )
643 result = int( result )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800644 if result == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800645 main.log.report( "Constant State Tests Passed" )
646 utilities.assert_equals( expect=main.TRUE, actual=result,
647 onpass="Constant State Tests Passed",
648 onfail="Constant state tests failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800649
Jon Hall6aec96b2015-01-19 14:49:31 -0800650 def CASE8( self, main ):
651 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800652 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -0800653 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800654 import sys
Jon Hall6aec96b2015-01-19 14:49:31 -0800655 # FIXME add this path to params
656 sys.path.append( "/home/admin/sts" )
657 # assumes that sts is already in you PYTHONPATH
658 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -0800659 import json
660 import time
661
Jon Hall6aec96b2015-01-19 14:49:31 -0800662 description = "Compare ONOS Topology view to Mininet topology"
663 main.case( description )
664 main.log.report( description )
665 main.step( "Create TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800666 ctrls = []
667 count = 1
668 temp = ()
Jon Hall6aec96b2015-01-19 14:49:31 -0800669 temp = temp + ( getattr( main, ( 'ONOS' + str( count ) ) ), )
670 temp = temp + ( "ONOS" + str( count ), )
671 temp = temp + ( main.params[ 'CTRL' ][ 'ip' + str( count ) ], )
672 temp = temp + \
673 ( eval( main.params[ 'CTRL' ][ 'port' + str( count ) ] ), )
674 ctrls.append( temp )
675 MNTopo = TestONTopology(
676 main.Mininet1,
677 ctrls ) # can also add Intent API info for intent operations
Jon Hall73cf9cc2014-11-20 22:28:38 -0800678
Jon Hall6aec96b2015-01-19 14:49:31 -0800679 main.step( "Comparing ONOS topology to MN" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800680 devices_results = main.TRUE
681 ports_results = main.TRUE
682 links_results = main.TRUE
683 topo_result = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800684 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -0800685 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -0800686 main.step( "Collecting topology information from ONOS" )
Jon Hall94fd0472014-12-08 11:52:42 -0800687 start_time = time.time()
688 while topo_result == main.FALSE and elapsed < 60:
Jon Hallffb386d2014-11-21 13:43:38 -0800689 count = count + 1
Jon Hall94fd0472014-12-08 11:52:42 -0800690 if count > 1:
Jon Hall6aec96b2015-01-19 14:49:31 -0800691 MNTopo = TestONTopology(
692 main.Mininet1,
693 ctrls )
Jon Hall94fd0472014-12-08 11:52:42 -0800694 cli_start = time.time()
695 devices = []
696 devices.append( main.ONOScli1.devices() )
Jon Hall6aec96b2015-01-19 14:49:31 -0800697 """
Jon Hall94fd0472014-12-08 11:52:42 -0800698 hosts = []
699 hosts.append( main.ONOScli1.hosts() )
Jon Hall6aec96b2015-01-19 14:49:31 -0800700 """
Jon Hall94fd0472014-12-08 11:52:42 -0800701 ports = []
702 ports.append( main.ONOScli1.ports() )
703 links = []
704 links.append( main.ONOScli1.links() )
705 elapsed = time.time() - start_time
Jon Hall6aec96b2015-01-19 14:49:31 -0800706 cli_time = time.time() - cli_start
707 print "CLI time: " + str( cli_time )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800708
Jon Hall6aec96b2015-01-19 14:49:31 -0800709 for controller in range( num_controllers ):
710 controller_str = str( controller + 1 )
711 if devices[ controller ] or "Error" not in devices[
712 controller ]:
713 current_devices_result = main.Mininet1.compare_switches(
714 MNTopo,
715 json.loads(
716 devices[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800717 else:
718 current_devices_result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800719 utilities.assert_equals( expect=main.TRUE,
720 actual=current_devices_result,
721 onpass="ONOS" + controller_str +
722 " Switches view is correct",
723 onfail="ONOS" + controller_str +
724 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800725
Jon Hall6aec96b2015-01-19 14:49:31 -0800726 if ports[ controller ] or "Error" not in ports[ controller ]:
727 current_ports_result = main.Mininet1.compare_ports(
728 MNTopo,
729 json.loads(
730 ports[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800731 else:
732 current_ports_result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800733 utilities.assert_equals( expect=main.TRUE,
734 actual=current_ports_result,
735 onpass="ONOS" + controller_str +
736 " ports view is correct",
737 onfail="ONOS" + controller_str +
738 " ports view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800739
Jon Hall6aec96b2015-01-19 14:49:31 -0800740 if links[ controller ] or "Error" not in links[ controller ]:
741 current_links_result = main.Mininet1.compare_links(
742 MNTopo,
743 json.loads(
744 links[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800745 else:
746 current_links_result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800747 utilities.assert_equals( expect=main.TRUE,
748 actual=current_links_result,
749 onpass="ONOS" + controller_str +
750 " links view is correct",
751 onfail="ONOS" + controller_str +
752 " links view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800753 devices_results = devices_results and current_devices_result
754 ports_results = ports_results and current_ports_result
755 links_results = links_results and current_links_result
Jon Hall94fd0472014-12-08 11:52:42 -0800756 topo_result = devices_results and ports_results and links_results
757
Jon Hall6aec96b2015-01-19 14:49:31 -0800758 topo_result = topo_result and int( count <= 2 )
759 note = "note it takes about " + str( int( cli_time ) ) + \
760 " seconds for the test to make all the cli calls to fetch " +\
761 "the topology from each ONOS instance"
762 main.log.report(
763 "Very crass estimate for topology discovery/convergence(" +
764 str( note ) + "): " + str( elapsed ) + " seconds, " +
765 str( count ) + " tries" )
Jon Hall94fd0472014-12-08 11:52:42 -0800766 if elapsed > 60:
Jon Hall6aec96b2015-01-19 14:49:31 -0800767 main.log.report( "Giving up on topology convergence" )
768 utilities.assert_equals( expect=main.TRUE, actual=topo_result,
769 onpass="Topology Check Test successful",
770 onfail="Topology Check Test NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800771 if topo_result == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800772 main.log.report( "ONOS topology view matches Mininet topology" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800773
Jon Hall6aec96b2015-01-19 14:49:31 -0800774 def CASE9( self, main ):
775 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800776 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -0800777 """
778 import time
779 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -0800780
Jon Hall6aec96b2015-01-19 14:49:31 -0800781 link_sleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800782
Jon Hall6aec96b2015-01-19 14:49:31 -0800783 description = "Turn off a link to ensure that Link Discovery " +\
784 "is working properly"
785 main.log.report( description )
786 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800787
Jon Hall6aec96b2015-01-19 14:49:31 -0800788 main.step( "Kill Link between s3 and s28" )
789 Link_Down = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
790 main.log.info(
791 "Waiting " +
792 str( link_sleep ) +
793 " seconds for link down to be discovered" )
794 time.sleep( link_sleep )
795 utilities.assert_equals( expect=main.TRUE, actual=Link_Down,
796 onpass="Link down succesful",
797 onfail="Failed to bring link down" )
798 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -0800799
Jon Hall6aec96b2015-01-19 14:49:31 -0800800 def CASE10( self, main ):
801 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800802 Link s3-s28 up
Jon Hall6aec96b2015-01-19 14:49:31 -0800803 """
804 import time
805 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -0800806
Jon Hall6aec96b2015-01-19 14:49:31 -0800807 link_sleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800808
Jon Hall6aec96b2015-01-19 14:49:31 -0800809 description = "Restore a link to ensure that Link Discovery is " + \
810 "working properly"
811 main.log.report( description )
812 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800813
Jon Hall6aec96b2015-01-19 14:49:31 -0800814 main.step( "Bring link between s3 and s28 back up" )
815 Link_Up = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
816 main.log.info(
817 "Waiting " +
818 str( link_sleep ) +
819 " seconds for link up to be discovered" )
820 time.sleep( link_sleep )
821 utilities.assert_equals( expect=main.TRUE, actual=Link_Up,
822 onpass="Link up succesful",
823 onfail="Failed to bring link up" )
824 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -0800825
Jon Hall6aec96b2015-01-19 14:49:31 -0800826 def CASE11( self, main ):
827 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800828 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -0800829 """
830 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -0800831 import time
832
Jon Hall6aec96b2015-01-19 14:49:31 -0800833 switch_sleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800834
835 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -0800836 main.log.report( description )
837 main.case( description )
838 switch = main.params[ 'kill' ][ 'switch' ]
839 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hall73cf9cc2014-11-20 22:28:38 -0800840
Jon Hall6aec96b2015-01-19 14:49:31 -0800841 # TODO: Make this switch parameterizable
842 main.step( "Kill " + switch )
843 main.log.report( "Deleting " + switch )
844 main.Mininet1.del_switch( switch )
845 main.log.info( "Waiting " + str( switch_sleep ) +
846 " seconds for switch down to be discovered" )
847 time.sleep( switch_sleep )
848 device = main.ONOScli1.get_device( dpid=switchDPID )
849 # Peek at the deleted switch
850 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800851 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800852 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -0800853 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800854 utilities.assert_equals( expect=main.TRUE, actual=result,
855 onpass="Kill switch succesful",
856 onfail="Failed to kill switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800857
Jon Hall6aec96b2015-01-19 14:49:31 -0800858 def CASE12( self, main ):
859 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800860 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -0800861 """
862 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -0800863 import time
Jon Hall669173b2014-12-17 11:36:30 -0800864
Jon Hall6aec96b2015-01-19 14:49:31 -0800865 switch_sleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
866 switch = main.params[ 'kill' ][ 'switch' ]
867 switchDPID = main.params[ 'kill' ][ 'dpid' ]
868 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800869 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -0800870 main.log.report( description )
871 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800872
Jon Hall6aec96b2015-01-19 14:49:31 -0800873 main.step( "Add back " + switch )
874 main.log.report( "Adding back " + switch )
875 main.Mininet1.add_switch( switch, dpid=switchDPID )
876 # TODO: New dpid or same? Ask Thomas?
877 for peer in links:
878 main.Mininet1.add_link( switch, peer )
879 main.Mininet1.assign_sw_controller( sw=switch.split( 's' )[ 1 ],
880 ip1=ONOS1_ip, port1=ONOS1_port )
881 main.log.info(
882 "Waiting " +
883 str( switch_sleep ) +
884 " seconds for switch up to be discovered" )
885 time.sleep( switch_sleep )
886 device = main.ONOScli1.get_device( dpid=switchDPID )
887 # Peek at the deleted switch
888 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -0800889 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800890 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -0800891 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800892 utilities.assert_equals( expect=main.TRUE, actual=result,
893 onpass="add switch succesful",
894 onfail="Failed to add switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800895
Jon Hall6aec96b2015-01-19 14:49:31 -0800896 def CASE13( self, main ):
897 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800898 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -0800899 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800900 import os
901 import time
Jon Hall6aec96b2015-01-19 14:49:31 -0800902 # printing colors to terminal
Jon Hall669173b2014-12-17 11:36:30 -0800903 colors = {}
Jon Hall6aec96b2015-01-19 14:49:31 -0800904 colors[ 'cyan' ] = '\033[96m'
905 colors[ 'purple' ] = '\033[95m'
906 colors[ 'blue' ] = '\033[94m'
907 colors[ 'green' ] = '\033[92m'
908 colors[ 'yellow' ] = '\033[93m'
909 colors[ 'red' ] = '\033[91m'
910 colors[ 'end' ] = '\033[0m'
Jon Hall73cf9cc2014-11-20 22:28:38 -0800911 description = "Test Cleanup"
Jon Hall6aec96b2015-01-19 14:49:31 -0800912 main.log.report( description )
913 main.case( description )
914 main.step( "Killing tcpdumps" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800915 main.Mininet2.stop_tcpdump()
916
Jon Hall6aec96b2015-01-19 14:49:31 -0800917 main.step( "Checking ONOS Logs for errors" )
918 print colors[ 'purple' ] + "Checking logs for errors on ONOS1:" + \
919 colors[ 'end' ]
920 print main.ONOSbench.check_logs( ONOS1_ip )
921 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800922 testname = main.TEST
Jon Hall6aec96b2015-01-19 14:49:31 -0800923 teststation_user = main.params[ 'TESTONUSER' ]
924 teststation_IP = main.params[ 'TESTONIP' ]
925 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -0800926 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -0800927 # FIXME: scp
928 # mn files
929 # TODO: Load these from params
930 # NOTE: must end in /
Jon Hall73cf9cc2014-11-20 22:28:38 -0800931 log_folder = "/opt/onos/log/"
Jon Hall6aec96b2015-01-19 14:49:31 -0800932 log_files = [ "karaf.log", "karaf.log.1" ]
933 # NOTE: must end in /
Jon Hall73cf9cc2014-11-20 22:28:38 -0800934 dst_dir = "~/packet_captures/"
935 for f in log_files:
Jon Hall6aec96b2015-01-19 14:49:31 -0800936 main.ONOSbench.handle.sendline( "scp sdn@" + ONOS1_ip + ":" +
937 log_folder + f + " " +
938 teststation_user + "@" +
939 teststation_IP + ":" + dst_dir +
940 str( testname ) + "-ONOS1-" + f )
941 main.ONOSbench.handle.expect( "\$" )
Jon Hall94fd0472014-12-08 11:52:42 -0800942 print main.ONOSbench.handle.before
Jon Hall73cf9cc2014-11-20 22:28:38 -0800943
Jon Hall6aec96b2015-01-19 14:49:31 -0800944 # std*.log's
945 # NOTE: must end in /
Jon Hall73cf9cc2014-11-20 22:28:38 -0800946 log_folder = "/opt/onos/var/"
Jon Hall6aec96b2015-01-19 14:49:31 -0800947 log_files = [ "stderr.log", "stdout.log" ]
948 # NOTE: must end in /
Jon Hall73cf9cc2014-11-20 22:28:38 -0800949 dst_dir = "~/packet_captures/"
950 for f in log_files:
Jon Hall6aec96b2015-01-19 14:49:31 -0800951 main.ONOSbench.handle.sendline( "scp sdn@" + ONOS1_ip + ":" +
952 log_folder + f + " " +
953 teststation_user + "@" +
954 teststation_IP + ":" + dst_dir +
955 str( testname ) + "-ONOS1-" + f )
956 # sleep so scp can finish
957 time.sleep( 10 )
958 main.step( "Packing and rotating pcap archives" )
959 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800960
Jon Hall6aec96b2015-01-19 14:49:31 -0800961 # TODO: actually check something here
962 utilities.assert_equals( expect=main.TRUE, actual=main.TRUE,
963 onpass="Test cleanup successful",
964 onfail="Test cleanup NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800965
Jon Hall6aec96b2015-01-19 14:49:31 -0800966 def CASE14( self, main ):
967 """
Jon Hall669173b2014-12-17 11:36:30 -0800968 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -0800969 """
Jon Hall669173b2014-12-17 11:36:30 -0800970 leader_result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800971 # install app on onos 1
972 main.log.info( "Install leadership election app" )
973 main.ONOScli1.feature_install( "onos-app-election" )
974 # wait for election
975 # check for leader
Jon Hall669173b2014-12-17 11:36:30 -0800976 leader = main.ONOScli1.election_test_leader()
Jon Hall6aec96b2015-01-19 14:49:31 -0800977 # verify leader is ONOS1
Jon Hall669173b2014-12-17 11:36:30 -0800978 if leader == ONOS1_ip:
Jon Hall6aec96b2015-01-19 14:49:31 -0800979 # all is well
Jon Hall669173b2014-12-17 11:36:30 -0800980 pass
Jon Hall6aec96b2015-01-19 14:49:31 -0800981 elif leader is None:
982 # No leader elected
983 main.log.report( "No leader was elected" )
Jon Hall669173b2014-12-17 11:36:30 -0800984 leader_result = main.FALSE
985 elif leader == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800986 # error in response
987 # TODO: add check for "Command not found:" in the driver, this
988 # means the app isn't loaded
989 main.log.report( "Something is wrong with election_test_leader" +
990 " function, check the error logs" )
Jon Hall669173b2014-12-17 11:36:30 -0800991 leader_result = main.FALSE
992 else:
Jon Hall6aec96b2015-01-19 14:49:31 -0800993 # error in response
994 main.log.report(
995 "Unexpected response from election_test_leader function:'" +
996 str(leader) +
997 "'" )
Jon Hall669173b2014-12-17 11:36:30 -0800998 leader_result = main.FALSE
999
Jon Hall6aec96b2015-01-19 14:49:31 -08001000 # install on other nodes and check for leader.
1001 # Should be onos1 and each app should show the same leader
1002 for controller in range( 2, num_controllers + 1 ):
1003 # loop through ONOScli handlers
1004 node = getattr( main, ( 'ONOScli' + str( controller ) ) )
1005 node.feature_install( "onos-app-election" )
Jon Hall669173b2014-12-17 11:36:30 -08001006 leaderN = node.election_test_leader()
Jon Hall6aec96b2015-01-19 14:49:31 -08001007 # verify leader is ONOS1
Jon Hall669173b2014-12-17 11:36:30 -08001008 if leaderN == ONOS1_ip:
Jon Hall6aec96b2015-01-19 14:49:31 -08001009 # all is well
Jon Hall669173b2014-12-17 11:36:30 -08001010 pass
1011 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001012 # error in response
1013 # TODO: add check for "Command not found:" in the driver, this
1014 # means the app isn't loaded
1015 main.log.report( "Something is wrong with " +
1016 "election_test_leader function, check the" +
1017 " error logs" )
Jon Hall669173b2014-12-17 11:36:30 -08001018 leader_result = main.FALSE
1019 elif leader != leaderN:
1020 leader_result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001021 main.log.report( "ONOS" + str( controller ) + " sees " +
1022 str( leaderN ) +
1023 " as the leader of the election app. Leader" +
1024 " should be " +
1025 str( leader ) )
Jon Hall669173b2014-12-17 11:36:30 -08001026 if leader_result:
Jon Hall6aec96b2015-01-19 14:49:31 -08001027 main.log.report( "Leadership election tests passed( consistent " +
1028 "view of leader across listeners and a leader " +
1029 "was elected)" )
1030 utilities.assert_equals(
1031 expect=main.TRUE,
1032 actual=leader_result,
1033 onpass="Leadership election passed",
1034 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08001035
Jon Hall6aec96b2015-01-19 14:49:31 -08001036 def CASE15( self, main ):
1037 """
Jon Hall669173b2014-12-17 11:36:30 -08001038 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08001039 """
Jon Hall669173b2014-12-17 11:36:30 -08001040 leader_result = main.TRUE
1041 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08001042 main.log.report( description )
1043 main.case( description )
1044 main.step( "Find current leader and withdraw" )
Jon Hall669173b2014-12-17 11:36:30 -08001045 leader = main.ONOScli1.election_test_leader()
Jon Hall6aec96b2015-01-19 14:49:31 -08001046 # TODO: do some sanity checking on leader before using it
Jon Hall669173b2014-12-17 11:36:30 -08001047 withdraw_result = main.FALSE
1048 if leader == ONOS1_ip:
1049 old_leader = getattr( main, "ONOScli1" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001050 elif leader is None or leader == main.FALSE:
1051 main.log.report(
1052 "Leader for the election app should be an ONOS node," +
1053 "instead got '" +
1054 str(leader) +
1055 "'" )
Jon Hall669173b2014-12-17 11:36:30 -08001056 leader_result = main.FALSE
1057 withdraw_result = old_leader.election_test_withdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08001058 utilities.assert_equals(
1059 expect=main.TRUE,
1060 actual=withdraw_result,
1061 onpass="App was withdrawn from election",
1062 onfail="App was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08001063
Jon Hall6aec96b2015-01-19 14:49:31 -08001064 main.step( "Make sure new leader is elected" )
Jon Hall669173b2014-12-17 11:36:30 -08001065 leader_list = []
Jon Hall6aec96b2015-01-19 14:49:31 -08001066 leaderN = main.ONOScli1.election_test_leader()
Jon Hall669173b2014-12-17 11:36:30 -08001067 if leaderN == leader:
Jon Hall6aec96b2015-01-19 14:49:31 -08001068 main.log.report( "ONOS still sees " + str( leaderN ) +
1069 " as leader after they withdrew" )
Jon Hall669173b2014-12-17 11:36:30 -08001070 leader_result = main.FALSE
1071 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001072 # error in response
1073 # TODO: add check for "Command not found:" in the driver, this
1074 # means the app isn't loaded
1075 main.log.report( "Something is wrong with election_test_leader " +
1076 "function, check the error logs" )
Jon Hall669173b2014-12-17 11:36:30 -08001077 leader_result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001078 elif leaderN is None:
1079 main.log.info(
1080 "There is no leader after the app withdrew from election" )
Jon Hall669173b2014-12-17 11:36:30 -08001081 if leader_result:
Jon Hall6aec96b2015-01-19 14:49:31 -08001082 main.log.report( "Leadership election tests passed(There is no " +
1083 "leader after the old leader resigned)" )
1084 utilities.assert_equals(
1085 expect=main.TRUE,
1086 actual=leader_result,
1087 onpass="Leadership election passed",
1088 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08001089
Jon Hall6aec96b2015-01-19 14:49:31 -08001090 main.step(
1091 "Run for election on old leader(just so everyone is in the hat)" )
Jon Hall669173b2014-12-17 11:36:30 -08001092 run_result = old_leader.election_test_run()
Jon Hall6aec96b2015-01-19 14:49:31 -08001093 utilities.assert_equals(
1094 expect=main.TRUE,
1095 actual=run_result,
1096 onpass="App re-ran for election",
1097 onfail="App failed to run for election" )
Jon Hall669173b2014-12-17 11:36:30 -08001098 leader = main.ONOScli1.election_test_leader()
Jon Hall6aec96b2015-01-19 14:49:31 -08001099 # verify leader is ONOS1
Jon Hall669173b2014-12-17 11:36:30 -08001100 if leader == ONOS1_ip:
1101 leader_result = main.TRUE
1102 else:
1103 leader_result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001104 # TODO: assert on run and withdraw results?
Jon Hall669173b2014-12-17 11:36:30 -08001105
Jon Hall6aec96b2015-01-19 14:49:31 -08001106 utilities.assert_equals(
1107 expect=main.TRUE,
1108 actual=leader_result,
1109 onpass="Leadership election passed",
1110 onfail="ONOS1's election app was not leader after it re-ran " +
1111 "for election" )