blob: 1205b11a21e1bf555c66d731872b1544b3f23e63 [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 ONOS can handle
3 all of it's nodes restarting
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.
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 Hall73cf9cc2014-11-20 22:28:38 -080024class HATestClusterRestart:
25
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:
Jon Hall73cf9cc2014-11-20 22:28:38 -080034 cell <name>
35 onos-verify-cell
36 NOTE: temporary - onos-remove-raft-logs
Jon Hall58c76b72015-02-23 11:09:24 -080037 onos-uninstall
38 start mininet
39 git pull
40 mvn clean install
41 onos-package
Jon Hall73cf9cc2014-11-20 22:28:38 -080042 onos-install -f
43 onos-wait-for-start
Jon Hall58c76b72015-02-23 11:09:24 -080044 start cli sessions
45 start tcpdump
Jon Hall6aec96b2015-01-19 14:49:31 -080046 """
47 main.log.report( "ONOS HA test: Restart all ONOS nodes - " +
48 "initialization" )
49 main.case( "Setting up test environment" )
50 # TODO: save all the timers and output them for plotting
Jon Hall73cf9cc2014-11-20 22:28:38 -080051
Jon Hall5cfd23c2015-03-19 11:40:57 -070052 # load some variables from the params file
Jon Hall8f89dda2015-01-22 16:03:33 -080053 PULLCODE = False
Jon Hall6aec96b2015-01-19 14:49:31 -080054 if main.params[ 'Git' ] == 'True':
Jon Hall8f89dda2015-01-22 16:03:33 -080055 PULLCODE = True
Jon Hall529a37f2015-01-28 10:02:00 -080056 gitBranch = main.params[ 'branch' ]
Jon Hall8f89dda2015-01-22 16:03:33 -080057 cellName = main.params[ 'ENV' ][ 'cellName' ]
Jon Hall6aec96b2015-01-19 14:49:31 -080058
59 # set global variables
Jon Hall8f89dda2015-01-22 16:03:33 -080060 global ONOS1Port
Jon Hall8f89dda2015-01-22 16:03:33 -080061 global ONOS2Port
Jon Hall8f89dda2015-01-22 16:03:33 -080062 global ONOS3Port
Jon Hall8f89dda2015-01-22 16:03:33 -080063 global ONOS4Port
Jon Hall8f89dda2015-01-22 16:03:33 -080064 global ONOS5Port
Jon Hall8f89dda2015-01-22 16:03:33 -080065 global ONOS6Port
Jon Hall8f89dda2015-01-22 16:03:33 -080066 global ONOS7Port
67 global numControllers
Jon Hall8f89dda2015-01-22 16:03:33 -080068 numControllers = int( main.params[ 'num_controllers' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -080069
Jon Hall5cfd23c2015-03-19 11:40:57 -070070 # FIXME: just get controller port from params?
71 # TODO: do we really need all these?
72 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
73 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
74 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
75 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
76 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
77 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
78 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
79
80 global CLIs
81 CLIs = []
82 global nodes
83 nodes = []
84 for i in range( 1, numControllers + 1 ):
85 CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
86 nodes.append( getattr( main, 'ONOS' + str( i ) ) )
87
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 Hall5cfd23c2015-03-19 11:40:57 -070095
Jon Hall6aec96b2015-01-19 14:49:31 -080096 main.log.report( "Uninstalling ONOS" )
Jon Hall5cfd23c2015-03-19 11:40:57 -070097 for node in nodes:
98 main.ONOSbench.onosUninstall( node.ip_address )
Jon Hall73cf9cc2014-11-20 22:28:38 -080099
Jon Hall8f89dda2015-01-22 16:03:33 -0800100 cleanInstallResult = main.TRUE
101 gitPullResult = main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800102
Jon Hall97f31752015-02-04 12:01:04 -0800103 main.step( "Starting Mininet" )
104 main.Mininet1.startNet( )
105
Jon Hall6aec96b2015-01-19 14:49:31 -0800106 main.step( "Compiling the latest version of ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800107 if PULLCODE:
Jon Hall58c76b72015-02-23 11:09:24 -0800108 main.step( "Git checkout and pull " + gitBranch )
Jon Hall529a37f2015-01-28 10:02:00 -0800109 main.ONOSbench.gitCheckout( gitBranch )
Jon Hall8f89dda2015-01-22 16:03:33 -0800110 gitPullResult = main.ONOSbench.gitPull()
Jon Hall5cfd23c2015-03-19 11:40:57 -0700111 if gitPullResult == main.ERROR:
112 main.log.error( "Error pulling git branch" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800113
Jon Hall6aec96b2015-01-19 14:49:31 -0800114 main.step( "Using mvn clean & install" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800115 cleanInstallResult = main.ONOSbench.cleanInstall()
Jon Hall6aec96b2015-01-19 14:49:31 -0800116 else:
117 main.log.warn( "Did not pull new code so skipping mvn " +
118 "clean install" )
Jon Hall1b8f54a2015-02-04 13:24:20 -0800119 main.ONOSbench.getVersion( report=True )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800120
Jon Hall6aec96b2015-01-19 14:49:31 -0800121 main.step( "Creating ONOS package" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800122 packageResult = main.ONOSbench.onosPackage()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800123
Jon Hall6aec96b2015-01-19 14:49:31 -0800124 main.step( "Installing ONOS package" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700125 onosInstallResult = main.TRUE
126 for node in nodes:
127 tmpResult = main.ONOSbench.onosInstall( options="-f",
128 node=node.ip_address )
129 onosInstallResult = onosInstallResult and tmpResult
Jon Hall73cf9cc2014-11-20 22:28:38 -0800130
Jon Hall6aec96b2015-01-19 14:49:31 -0800131 main.step( "Checking if ONOS is up yet" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800132 for i in range( 2 ):
Jon Hall5cfd23c2015-03-19 11:40:57 -0700133 onosIsupResult = main.TRUE
134 for node in nodes:
135 started = main.ONOSbench.isup( node.ip_address )
136 if not started:
137 main.log.report( node.name + " didn't start!" )
138 main.ONOSbench.onosStop( node.ip_address )
139 main.ONOSbench.onosStart( node.ip_address )
140 onosIsupResult = onosIsupResult and started
Jon Hall8f89dda2015-01-22 16:03:33 -0800141 if onosIsupResult == main.TRUE:
Jon Hall94fd0472014-12-08 11:52:42 -0800142 break
Jon Hall73cf9cc2014-11-20 22:28:38 -0800143
Jon Hall5cfd23c2015-03-19 11:40:57 -0700144 main.log.step( "Starting ONOS CLI sessions" )
145 cliResults = main.TRUE
146 threads = []
147 for i in range( numControllers ):
148 t = main.Thread( target=CLIs[i].startOnosCli,
149 name="startOnosCli-" + str( i ),
150 args=[nodes[i].ip_address] )
151 threads.append( t )
152 t.start()
153
154 for t in threads:
155 t.join()
156 cliResults = cliResults and t.result
Jon Hall73cf9cc2014-11-20 22:28:38 -0800157
Jon Hall6aec96b2015-01-19 14:49:31 -0800158 main.step( "Start Packet Capture MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800159 main.Mininet2.startTcpdump(
Jon Hall6aec96b2015-01-19 14:49:31 -0800160 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
161 + "-MN.pcap",
162 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
163 port=main.params[ 'MNtcpdump' ][ 'port' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800164
Jon Halla9d26da2015-03-30 16:45:32 -0700165 appCheck = main.TRUE
166 threads = []
167 for i in range( numControllers ):
168 t = main.Thread( target=CLIs[i].appToIDCheck,
169 name="appToIDCheck-" + str( i ),
170 args=[] )
171 threads.append( t )
172 t.start()
173
174 for t in threads:
175 t.join()
176 appCheck = appCheck and t.result
177 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
178 onpass="App Ids seem to be correct",
179 onfail="Something is wrong with app Ids" )
180 if appCheck != main.TRUE:
181 main.log.warn( CLIs[0].apps() )
182 main.log.warn( CLIs[0].appIDs() )
183
Jon Hall8f89dda2015-01-22 16:03:33 -0800184 case1Result = ( cleanInstallResult and packageResult and
185 cellResult and verifyResult and onosInstallResult
Jon Halla9d26da2015-03-30 16:45:32 -0700186 and onosIsupResult and cliResults and appCheck)
Jon Hall73cf9cc2014-11-20 22:28:38 -0800187
Jon Hall8f89dda2015-01-22 16:03:33 -0800188 utilities.assert_equals( expect=main.TRUE, actual=case1Result,
Jon Hall58c76b72015-02-23 11:09:24 -0800189 onpass="Test startup successful",
190 onfail="Test startup NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800191
Jon Hall8f89dda2015-01-22 16:03:33 -0800192 if case1Result == main.FALSE:
Jon Hall94fd0472014-12-08 11:52:42 -0800193 main.cleanup()
194 main.exit()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800195
Jon Hall6aec96b2015-01-19 14:49:31 -0800196 def CASE2( self, main ):
197 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800198 Assign mastership to controllers
Jon Hall6aec96b2015-01-19 14:49:31 -0800199 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800200 import re
Jon Hall5cfd23c2015-03-19 11:40:57 -0700201 assert numControllers, "numControllers not defined"
202 assert main, "main not defined"
203 assert utilities.assert_equals, "utilities.assert_equals not defined"
204 assert CLIs, "CLIs not defined"
205 assert nodes, "nodes not defined"
206 assert ONOS1Port, "ONOS1Port not defined"
207 assert ONOS2Port, "ONOS2Port not defined"
208 assert ONOS3Port, "ONOS3Port not defined"
209 assert ONOS4Port, "ONOS4Port not defined"
210 assert ONOS5Port, "ONOS5Port not defined"
211 assert ONOS6Port, "ONOS6Port not defined"
212 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -0800213
Jon Hall6aec96b2015-01-19 14:49:31 -0800214 main.log.report( "Assigning switches to controllers" )
215 main.case( "Assigning Controllers" )
216 main.step( "Assign switches to controllers" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800217
Jon Hall5cfd23c2015-03-19 11:40:57 -0700218 # TODO: rewrite this function to take lists of ips and ports?
219 # or list of tuples?
Jon Hall6aec96b2015-01-19 14:49:31 -0800220 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800221 main.Mininet1.assignSwController(
Jon Hall6aec96b2015-01-19 14:49:31 -0800222 sw=str( i ),
Jon Hall8f89dda2015-01-22 16:03:33 -0800223 count=numControllers,
Jon Hall5cfd23c2015-03-19 11:40:57 -0700224 ip1=nodes[ 0 ].ip_address, port1=ONOS1Port,
225 ip2=nodes[ 1 ].ip_address, port2=ONOS2Port,
226 ip3=nodes[ 2 ].ip_address, port3=ONOS3Port,
227 ip4=nodes[ 3 ].ip_address, port4=ONOS4Port,
228 ip5=nodes[ 4 ].ip_address, port5=ONOS5Port,
229 ip6=nodes[ 5 ].ip_address, port6=ONOS6Port,
230 ip7=nodes[ 6 ].ip_address, port7=ONOS7Port )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800231
Jon Hall8f89dda2015-01-22 16:03:33 -0800232 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800233 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800234 response = main.Mininet1.getSwController( "s" + str( i ) )
Jon Hallffb386d2014-11-21 13:43:38 -0800235 try:
Jon Hall6aec96b2015-01-19 14:49:31 -0800236 main.log.info( str( response ) )
Jon Hallfebb1c72015-03-05 13:30:09 -0800237 except Exception:
Jon Hall6aec96b2015-01-19 14:49:31 -0800238 main.log.info( repr( response ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700239 for node in nodes:
240 if re.search( "tcp:" + node.ip_address, response ):
241 mastershipCheck = mastershipCheck and main.TRUE
242 else:
Jon Halla9d26da2015-03-30 16:45:32 -0700243 main.log.error( "Error, node " + node.ip_address + " is " +
244 "not in the list of controllers s" +
245 str( i ) + " is connecting to." )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700246 mastershipCheck = main.FALSE
Jon Hall8f89dda2015-01-22 16:03:33 -0800247 if mastershipCheck == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800248 main.log.report( "Switch mastership assigned correctly" )
249 utilities.assert_equals(
250 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800251 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800252 onpass="Switch mastership assigned correctly",
253 onfail="Switches not assigned correctly to controllers" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800254 # Manually assign mastership to the controller we want
Jon Hall8f89dda2015-01-22 16:03:33 -0800255 roleCall = main.TRUE
256 roleCheck = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -0800257 try:
Jon Halla9d26da2015-03-30 16:45:32 -0700258 for i in range( 1, 29 ): # switches 1 through 28
259 # set up correct variables:
260 if i == 1:
261 ip = nodes[ 0 ].ip_address # ONOS1
262 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
263 elif i == 2:
264 ip = nodes[ 1 ].ip_address # ONOS2
265 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
266 elif i == 3:
267 ip = nodes[ 1 ].ip_address # ONOS2
268 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
269 elif i == 4:
270 ip = nodes[ 3 ].ip_address # ONOS4
271 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
272 elif i == 5:
273 ip = nodes[ 2 ].ip_address # ONOS3
274 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
275 elif i == 6:
276 ip = nodes[ 2 ].ip_address # ONOS3
277 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
278 elif i == 7:
279 ip = nodes[ 5 ].ip_address # ONOS6
280 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
281 elif i >= 8 and i <= 17:
282 ip = nodes[ 4 ].ip_address # ONOS5
283 dpid = '3' + str( i ).zfill( 3 )
284 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
285 elif i >= 18 and i <= 27:
286 ip = nodes[ 6 ].ip_address # ONOS7
287 dpid = '6' + str( i ).zfill( 3 )
288 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
289 elif i == 28:
290 ip = nodes[ 0 ].ip_address # ONOS1
291 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
292 else:
293 main.log.error( "You didn't write an else statement for " +
294 "switch s" + str( i ) )
295 # Assign switch
296 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
297 # TODO: make this controller dynamic
298 roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
299 ip )
Jon Hall58c76b72015-02-23 11:09:24 -0800300 # Check assignment
Jon Hall678f4512015-03-31 09:48:31 -0700301 master = main.ONOScli1.getRole( deviceId ).get( 'master' )
302 if ip in master:
Jon Hall58c76b72015-02-23 11:09:24 -0800303 roleCheck = roleCheck and main.TRUE
304 else:
305 roleCheck = roleCheck and main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -0700306 main.log.error( "Error, controller " + ip + " is not" +
307 " master " + "of device " +
Jon Hall678f4512015-03-31 09:48:31 -0700308 str( deviceId ) + ". Master is " +
309 repr( master ) + "." )
Jon Hall58c76b72015-02-23 11:09:24 -0800310 except ( AttributeError, AssertionError ):
311 main.log.exception( "Something is wrong with ONOS device view" )
312 main.log.info( main.ONOScli1.devices() )
Jon Hall6aec96b2015-01-19 14:49:31 -0800313 utilities.assert_equals(
314 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800315 actual=roleCall,
Jon Hall6aec96b2015-01-19 14:49:31 -0800316 onpass="Re-assigned switch mastership to designated controller",
Jon Hall8f89dda2015-01-22 16:03:33 -0800317 onfail="Something wrong with deviceRole calls" )
Jon Hall94fd0472014-12-08 11:52:42 -0800318
Jon Hall6aec96b2015-01-19 14:49:31 -0800319 utilities.assert_equals(
320 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800321 actual=roleCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800322 onpass="Switches were successfully reassigned to designated " +
323 "controller",
324 onfail="Switches were not successfully reassigned" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800325 mastershipCheck = mastershipCheck and roleCall and roleCheck
326 utilities.assert_equals( expect=main.TRUE, actual=mastershipCheck,
Jon Hall21270ac2015-02-16 17:59:55 -0800327 onpass="Switch mastership correctly assigned",
328 onfail="Error in (re)assigning switch" +
329 " mastership" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800330
Jon Hall6aec96b2015-01-19 14:49:31 -0800331 def CASE3( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800332 """
333 Assign intents
Jon Hall73cf9cc2014-11-20 22:28:38 -0800334 """
Jon Hall6aec96b2015-01-19 14:49:31 -0800335 # FIXME: we must reinstall intents until we have a persistant
336 # datastore!
Jon Hall73cf9cc2014-11-20 22:28:38 -0800337 import time
Jon Hall58c76b72015-02-23 11:09:24 -0800338 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700339 assert numControllers, "numControllers not defined"
340 assert main, "main not defined"
341 assert utilities.assert_equals, "utilities.assert_equals not defined"
342 assert CLIs, "CLIs not defined"
343 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -0800344 main.log.report( "Adding host intents" )
345 main.case( "Adding host Intents" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800346
Jon Hall8f89dda2015-01-22 16:03:33 -0800347 main.step( "Discovering Hosts( Via pingall for now )" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800348 # FIXME: Once we have a host discovery mechanism, use that instead
Jon Hall73cf9cc2014-11-20 22:28:38 -0800349
Jon Hall6aec96b2015-01-19 14:49:31 -0800350 # install onos-app-fwd
351 main.log.info( "Install reactive forwarding app" )
Jon Halla9d26da2015-03-30 16:45:32 -0700352 appResults = CLIs[0].activateApp( "org.onosproject.fwd" )
353
354 # FIXME: add this to asserts
355 appCheck = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700356 threads = []
357 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700358 t = main.Thread( target=CLIs[i].appToIDCheck,
359 name="appToIDCheck-" + str( i ),
360 args=[] )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700361 threads.append( t )
362 t.start()
363
364 for t in threads:
365 t.join()
Jon Halla9d26da2015-03-30 16:45:32 -0700366 appCheck = appCheck and t.result
367 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
368 onpass="App Ids seem to be correct",
369 onfail="Something is wrong with app Ids" )
370 if appCheck != main.TRUE:
371 main.log.warn( CLIs[0].apps() )
372 main.log.warn( CLIs[0].appIDs() )
Jon Hall94fd0472014-12-08 11:52:42 -0800373
Jon Hall6aec96b2015-01-19 14:49:31 -0800374 # REACTIVE FWD test
Jon Hall8f89dda2015-01-22 16:03:33 -0800375 pingResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700376 for i in range(2): # Retry if pingall fails first time
377 time1 = time.time()
378 pingResult = main.Mininet1.pingall()
379 utilities.assert_equals(
380 expect=main.TRUE,
381 actual=pingResult,
382 onpass="Reactive Pingall test passed",
383 onfail="Reactive Pingall failed, one or more ping pairs failed" )
384 time2 = time.time()
385 main.log.info( "Time for pingall: %2f seconds" % ( time2 - time1 ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800386
Jon Hall6aec96b2015-01-19 14:49:31 -0800387 # uninstall onos-app-fwd
388 main.log.info( "Uninstall reactive forwarding app" )
Jon Halla9d26da2015-03-30 16:45:32 -0700389 appResults = appResults and CLIs[0].deactivateApp( "org.onosproject.fwd" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700390 threads = []
391 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700392 t = main.Thread( target=CLIs[i].appToIDCheck,
393 name="appToIDCheck-" + str( i ),
394 args=[] )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700395 threads.append( t )
396 t.start()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800397
Jon Hall5cfd23c2015-03-19 11:40:57 -0700398 for t in threads:
399 t.join()
Jon Halla9d26da2015-03-30 16:45:32 -0700400 appCheck = appCheck and t.result
401 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
402 onpass="App Ids seem to be correct",
403 onfail="Something is wrong with app Ids" )
404 if appCheck != main.TRUE:
405 main.log.warn( CLIs[0].apps() )
406 main.log.warn( CLIs[0].appIDs() )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700407
408 # timeout for fwd flows
409 time.sleep( 11 )
410
411 main.step( "Add host intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800412 intentIds = []
Jon Hall6aec96b2015-01-19 14:49:31 -0800413 # TODO: move the host numbers to params
Jon Hall58c76b72015-02-23 11:09:24 -0800414 # Maybe look at all the paths we ping?
Jon Hall8f89dda2015-01-22 16:03:33 -0800415 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800416 hostResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800417 for i in range( 8, 18 ):
418 main.log.info( "Adding host intent between h" + str( i ) +
419 " and h" + str( i + 10 ) )
420 host1 = "00:00:00:00:00:" + \
421 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
422 host2 = "00:00:00:00:00:" + \
423 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800424 # NOTE: getHost can return None
425 host1Dict = main.ONOScli1.getHost( host1 )
426 host2Dict = main.ONOScli1.getHost( host2 )
427 host1Id = None
428 host2Id = None
429 if host1Dict and host2Dict:
430 host1Id = host1Dict.get( 'id', None )
431 host2Id = host2Dict.get( 'id', None )
Jon Hall8f89dda2015-01-22 16:03:33 -0800432 if host1Id and host2Id:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700433 nodeNum = ( i % 7 )
434 tmpId = CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
Jon Hall63604932015-02-26 17:09:50 -0800435 if tmpId:
436 main.log.info( "Added intent with id: " + tmpId )
437 intentIds.append( tmpId )
438 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700439 main.log.error( "addHostIntent returned: " +
440 repr( tmpId ) )
Jon Hall669173b2014-12-17 11:36:30 -0800441 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700442 main.log.error( "Error, getHost() failed for h" + str( i ) +
443 " and/or h" + str( i + 10 ) )
444 hosts = CLIs[ 0 ].hosts()
445 main.log.warn( "Hosts output: " )
446 try:
447 main.log.warn( json.dumps( json.loads( hosts ),
448 sort_keys=True,
449 indent=4,
450 separators=( ',', ': ' ) ) )
451 except ( ValueError, TypeError ):
452 main.log.warn( repr( hosts ) )
Jon Hall58c76b72015-02-23 11:09:24 -0800453 hostResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -0700454 # FIXME: DEBUG
455 intentStart = time.time()
Jon Hall58c76b72015-02-23 11:09:24 -0800456 onosIds = main.ONOScli1.getAllIntentsId()
457 main.log.info( "Submitted intents: " + str( intentIds ) )
458 main.log.info( "Intents in ONOS: " + str( onosIds ) )
459 for intent in intentIds:
460 if intent in onosIds:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700461 pass # intent submitted is in onos
Jon Hall58c76b72015-02-23 11:09:24 -0800462 else:
463 intentAddResult = False
Jon Halla9d26da2015-03-30 16:45:32 -0700464 # FIXME: DEBUG
465 if intentAddResult:
466 intentStop = time.time()
467 else:
468 intentStop = None
Jon Hall1b8f54a2015-02-04 13:24:20 -0800469 # Print the intent states
Jon Hall58c76b72015-02-23 11:09:24 -0800470 intents = main.ONOScli1.intents()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800471 intentStates = []
Jon Hall63604932015-02-26 17:09:50 -0800472 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800473 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
474 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700475 try:
476 for intent in json.loads( intents ):
477 state = intent.get( 'state', None )
478 if "INSTALLED" not in state:
479 installedCheck = False
480 intentId = intent.get( 'id', None )
481 intentStates.append( ( intentId, state ) )
482 except ( ValueError, TypeError ):
483 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800484 # add submitted intents not in the store
485 tmplist = [ i for i, s in intentStates ]
486 missingIntents = False
487 for i in intentIds:
488 if i not in tmplist:
489 intentStates.append( ( i, " - " ) )
490 missingIntents = True
491 intentStates.sort()
492 for i, s in intentStates:
493 count += 1
494 main.log.info( "%-6s%-15s%-15s" %
495 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700496 leaders = main.ONOScli1.leaders()
497 try:
498 if leaders:
499 parsedLeaders = json.loads( leaders )
500 main.log.warn( json.dumps( parsedLeaders,
501 sort_keys=True,
502 indent=4,
503 separators=( ',', ': ' ) ) )
504 # check for all intent partitions
Jon Hall5cfd23c2015-03-19 11:40:57 -0700505 topics = []
506 for i in range( 14 ):
507 topics.append( "intent-partition-" + str( i ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700508 main.log.debug( topics )
509 ONOStopics = [ j['topic'] for j in parsedLeaders ]
510 for topic in topics:
511 if topic not in ONOStopics:
512 main.log.error( "Error: " + topic +
513 " not in leaders" )
514 else:
515 main.log.error( "leaders() returned None" )
516 except ( ValueError, TypeError ):
517 main.log.exception( "Error parsing leaders" )
518 main.log.error( repr( leaders ) )
519 partitions = main.ONOScli1.partitions()
520 try:
521 if partitions :
522 parsedPartitions = json.loads( partitions )
523 main.log.warn( json.dumps( parsedPartitions,
524 sort_keys=True,
525 indent=4,
526 separators=( ',', ': ' ) ) )
527 # TODO check for a leader in all paritions
528 # TODO check for consistency among nodes
529 else:
530 main.log.error( "partitions() returned None" )
531 except ( ValueError, TypeError ):
532 main.log.exception( "Error parsing partitions" )
533 main.log.error( repr( partitions ) )
Jon Hall63604932015-02-26 17:09:50 -0800534 pendingMap = main.ONOScli1.pendingMap()
Jon Hall5cfd23c2015-03-19 11:40:57 -0700535 try:
536 if pendingMap :
537 parsedPending = json.loads( pendingMap )
538 main.log.warn( json.dumps( parsedPending,
539 sort_keys=True,
540 indent=4,
541 separators=( ',', ': ' ) ) )
542 # TODO check something here?
543 else:
544 main.log.error( "pendingMap() returned None" )
545 except ( ValueError, TypeError ):
546 main.log.exception( "Error parsing pending map" )
547 main.log.error( repr( pendingMap ) )
548
Jon Hall58c76b72015-02-23 11:09:24 -0800549 intentAddResult = bool( pingResult and hostResult and intentAddResult
Jon Hall63604932015-02-26 17:09:50 -0800550 and not missingIntents and installedCheck )
Jon Hall6aec96b2015-01-19 14:49:31 -0800551 utilities.assert_equals(
552 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -0800553 actual=intentAddResult,
Jon Hall529a37f2015-01-28 10:02:00 -0800554 onpass="Pushed host intents to ONOS",
555 onfail="Error in pushing host intents to ONOS" )
Jon Halla9d26da2015-03-30 16:45:32 -0700556 for i in range(100):
557 onosIds = main.ONOScli1.getAllIntentsId()
558 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
559 main.log.info( "Intents in ONOS: " + str( sorted( onosIds ) ) )
560 if sorted(onosIds) == sorted(intentIds):
561 break
562 else:
563 time.sleep(1)
564 # FIXME: DEBUG
565 if not intentStop:
566 intentStop = time.time()
567 gossipTime = intentStop - intentStart
568 main.log.info( "It took about " + str( gossipTime ) +
569 " seconds for all intents to appear on ONOS1" )
570 # FIXME: make this time configurable/calculate based off of number of
571 # nodes and gossip rounds
572 utilities.assert_greater_equals(
573 expect=30, actual=gossipTime,
574 onpass="ECM anti-entropy for intents worked within " +
575 "expected time",
576 onfail="Intent ECM anti-entropy took too long" )
Jon Hall678f4512015-03-31 09:48:31 -0700577 if gossipTime <= 30:
578 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800579
Jon Hall63604932015-02-26 17:09:50 -0800580 if not intentAddResult or "key" in pendingMap:
Jon Hall58c76b72015-02-23 11:09:24 -0800581 import time
Jon Hall63604932015-02-26 17:09:50 -0800582 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800583 main.log.info( "Sleeping 60 seconds to see if intents are found" )
584 time.sleep( 60 )
585 onosIds = main.ONOScli1.getAllIntentsId()
586 main.log.info( "Submitted intents: " + str( intentIds ) )
587 main.log.info( "Intents in ONOS: " + str( onosIds ) )
588 # Print the intent states
589 intents = main.ONOScli1.intents()
590 intentStates = []
591 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
592 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700593 try:
594 for intent in json.loads( intents ):
595 # Iter through intents of a node
596 state = intent.get( 'state', None )
597 if "INSTALLED" not in state:
598 installedCheck = False
599 intentId = intent.get( 'id', None )
600 intentStates.append( ( intentId, state ) )
601 except ( ValueError, TypeError ):
602 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800603 # add submitted intents not in the store
604 tmplist = [ i for i, s in intentStates ]
605 for i in intentIds:
606 if i not in tmplist:
607 intentStates.append( ( i, " - " ) )
608 intentStates.sort()
609 for i, s in intentStates:
610 count += 1
611 main.log.info( "%-6s%-15s%-15s" %
612 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700613 leaders = main.ONOScli1.leaders()
614 try:
615 if leaders:
616 parsedLeaders = json.loads( leaders )
617 main.log.warn( json.dumps( parsedLeaders,
618 sort_keys=True,
619 indent=4,
620 separators=( ',', ': ' ) ) )
621 # check for all intent partitions
622 # check for election
623 topics = []
624 for i in range( 14 ):
625 topics.append( "intent-partition-" + str( i ) )
626 # FIXME: this should only be after we start the app
627 topics.append( "org.onosproject.election" )
628 main.log.debug( topics )
629 ONOStopics = [ j['topic'] for j in parsedLeaders ]
630 for topic in topics:
631 if topic not in ONOStopics:
632 main.log.error( "Error: " + topic +
633 " not in leaders" )
634 else:
635 main.log.error( "leaders() returned None" )
636 except ( ValueError, TypeError ):
637 main.log.exception( "Error parsing leaders" )
638 main.log.error( repr( leaders ) )
639 partitions = main.ONOScli1.partitions()
640 try:
641 if partitions :
642 parsedPartitions = json.loads( partitions )
643 main.log.warn( json.dumps( parsedPartitions,
644 sort_keys=True,
645 indent=4,
646 separators=( ',', ': ' ) ) )
647 # TODO check for a leader in all paritions
648 # TODO check for consistency among nodes
649 else:
650 main.log.error( "partitions() returned None" )
651 except ( ValueError, TypeError ):
652 main.log.exception( "Error parsing partitions" )
653 main.log.error( repr( partitions ) )
654 pendingMap = main.ONOScli1.pendingMap()
655 try:
656 if pendingMap :
657 parsedPending = json.loads( pendingMap )
658 main.log.warn( json.dumps( parsedPending,
659 sort_keys=True,
660 indent=4,
661 separators=( ',', ': ' ) ) )
662 # TODO check something here?
663 else:
664 main.log.error( "pendingMap() returned None" )
665 except ( ValueError, TypeError ):
666 main.log.exception( "Error parsing pending map" )
667 main.log.error( repr( pendingMap ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800668
Jon Hall6aec96b2015-01-19 14:49:31 -0800669 def CASE4( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800670 """
671 Ping across added host intents
672 """
Jon Hall58c76b72015-02-23 11:09:24 -0800673 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700674 import time
675 assert numControllers, "numControllers not defined"
676 assert main, "main not defined"
677 assert utilities.assert_equals, "utilities.assert_equals not defined"
678 assert CLIs, "CLIs not defined"
679 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -0800680 description = " Ping across added host intents"
Jon Hall6aec96b2015-01-19 14:49:31 -0800681 main.log.report( description )
682 main.case( description )
Jon Hall8f89dda2015-01-22 16:03:33 -0800683 PingResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800684 for i in range( 8, 18 ):
Jon Hall58c76b72015-02-23 11:09:24 -0800685 ping = main.Mininet1.pingHost( src="h" + str( i ),
686 target="h" + str( i + 10 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800687 PingResult = PingResult and ping
Jon Hall6aec96b2015-01-19 14:49:31 -0800688 if ping == main.FALSE:
689 main.log.warn( "Ping failed between h" + str( i ) +
690 " and h" + str( i + 10 ) )
691 elif ping == main.TRUE:
692 main.log.info( "Ping test passed!" )
Jon Hall21270ac2015-02-16 17:59:55 -0800693 # Don't set PingResult or you'd override failures
Jon Hall8f89dda2015-01-22 16:03:33 -0800694 if PingResult == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800695 main.log.report(
696 "Intents have not been installed correctly, pings failed." )
Jon Hall58c76b72015-02-23 11:09:24 -0800697 # TODO: pretty print
Jon Hall5cfd23c2015-03-19 11:40:57 -0700698 main.log.warn( "ONOS1 intents: " )
699 try:
700 tmpIntents = main.ONOScli1.intents()
701 main.log.warn( json.dumps( json.loads( tmpIntents ),
702 sort_keys=True,
703 indent=4,
704 separators=( ',', ': ' ) ) )
705 except ( ValueError, TypeError ):
706 main.log.warn( repr( tmpIntents ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800707 if PingResult == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800708 main.log.report(
709 "Intents have been installed correctly and verified by pings" )
710 utilities.assert_equals(
711 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800712 actual=PingResult,
Jon Hall6aec96b2015-01-19 14:49:31 -0800713 onpass="Intents have been installed correctly and pings work",
714 onfail="Intents have not been installed correctly, pings failed." )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800715
Jon Hall63604932015-02-26 17:09:50 -0800716 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800717 if PingResult is not main.TRUE:
718 # Print the intent states
719 intents = main.ONOScli1.intents()
720 intentStates = []
721 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
722 count = 0
723 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700724 try:
725 for intent in json.loads( intents ):
726 state = intent.get( 'state', None )
727 if "INSTALLED" not in state:
728 installedCheck = False
729 intentId = intent.get( 'id', None )
730 intentStates.append( ( intentId, state ) )
731 except ( ValueError, TypeError ):
732 main.log.exception( "Error parsing intents." )
Jon Hall58c76b72015-02-23 11:09:24 -0800733 intentStates.sort()
734 for i, s in intentStates:
735 count += 1
736 main.log.info( "%-6s%-15s%-15s" %
737 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700738 leaders = main.ONOScli1.leaders()
739 try:
740 if leaders:
741 parsedLeaders = json.loads( leaders )
742 main.log.warn( json.dumps( parsedLeaders,
743 sort_keys=True,
744 indent=4,
745 separators=( ',', ': ' ) ) )
746 # check for all intent partitions
747 # check for election
748 topics = []
749 for i in range( 14 ):
750 topics.append( "intent-partition-" + str( i ) )
751 # FIXME: this should only be after we start the app
752 topics.append( "org.onosproject.election" )
753 main.log.debug( topics )
754 ONOStopics = [ j['topic'] for j in parsedLeaders ]
755 for topic in topics:
756 if topic not in ONOStopics:
757 main.log.error( "Error: " + topic +
758 " not in leaders" )
759 else:
760 main.log.error( "leaders() returned None" )
761 except ( ValueError, TypeError ):
762 main.log.exception( "Error parsing leaders" )
763 main.log.error( repr( leaders ) )
764 partitions = main.ONOScli1.partitions()
765 try:
766 if partitions :
767 parsedPartitions = json.loads( partitions )
768 main.log.warn( json.dumps( parsedPartitions,
769 sort_keys=True,
770 indent=4,
771 separators=( ',', ': ' ) ) )
772 # TODO check for a leader in all paritions
773 # TODO check for consistency among nodes
774 else:
775 main.log.error( "partitions() returned None" )
776 except ( ValueError, TypeError ):
777 main.log.exception( "Error parsing partitions" )
778 main.log.error( repr( partitions ) )
779 pendingMap = main.ONOScli1.pendingMap()
780 try:
781 if pendingMap :
782 parsedPending = json.loads( pendingMap )
783 main.log.warn( json.dumps( parsedPending,
784 sort_keys=True,
785 indent=4,
786 separators=( ',', ': ' ) ) )
787 # TODO check something here?
788 else:
789 main.log.error( "pendingMap() returned None" )
790 except ( ValueError, TypeError ):
791 main.log.exception( "Error parsing pending map" )
792 main.log.error( repr( pendingMap ) )
793
Jon Hall63604932015-02-26 17:09:50 -0800794 if not installedCheck:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700795 main.log.info( "Waiting 60 seconds to see if the state of " +
796 "intents change" )
Jon Hall63604932015-02-26 17:09:50 -0800797 time.sleep( 60 )
798 # Print the intent states
799 intents = main.ONOScli1.intents()
800 intentStates = []
801 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
802 count = 0
803 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700804 try:
805 for intent in json.loads( intents ):
806 state = intent.get( 'state', None )
807 if "INSTALLED" not in state:
808 installedCheck = False
809 intentId = intent.get( 'id', None )
810 intentStates.append( ( intentId, state ) )
811 except ( ValueError, TypeError ):
812 main.log.exception( "Error parsing intents." )
Jon Hall63604932015-02-26 17:09:50 -0800813 intentStates.sort()
814 for i, s in intentStates:
815 count += 1
816 main.log.info( "%-6s%-15s%-15s" %
817 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700818 leaders = main.ONOScli1.leaders()
819 try:
820 if leaders:
821 parsedLeaders = json.loads( leaders )
822 main.log.warn( json.dumps( parsedLeaders,
823 sort_keys=True,
824 indent=4,
825 separators=( ',', ': ' ) ) )
826 # check for all intent partitions
827 # check for election
828 topics = []
829 for i in range( 14 ):
830 topics.append( "intent-partition-" + str( i ) )
831 # FIXME: this should only be after we start the app
832 topics.append( "org.onosproject.election" )
833 main.log.debug( topics )
834 ONOStopics = [ j['topic'] for j in parsedLeaders ]
835 for topic in topics:
836 if topic not in ONOStopics:
837 main.log.error( "Error: " + topic +
838 " not in leaders" )
839 else:
840 main.log.error( "leaders() returned None" )
841 except ( ValueError, TypeError ):
842 main.log.exception( "Error parsing leaders" )
843 main.log.error( repr( leaders ) )
844 partitions = main.ONOScli1.partitions()
845 try:
846 if partitions :
847 parsedPartitions = json.loads( partitions )
848 main.log.warn( json.dumps( parsedPartitions,
849 sort_keys=True,
850 indent=4,
851 separators=( ',', ': ' ) ) )
852 # TODO check for a leader in all paritions
853 # TODO check for consistency among nodes
854 else:
855 main.log.error( "partitions() returned None" )
856 except ( ValueError, TypeError ):
857 main.log.exception( "Error parsing partitions" )
858 main.log.error( repr( partitions ) )
859 pendingMap = main.ONOScli1.pendingMap()
860 try:
861 if pendingMap :
862 parsedPending = json.loads( pendingMap )
863 main.log.warn( json.dumps( parsedPending,
864 sort_keys=True,
865 indent=4,
866 separators=( ',', ': ' ) ) )
867 # TODO check something here?
868 else:
869 main.log.error( "pendingMap() returned None" )
870 except ( ValueError, TypeError ):
871 main.log.exception( "Error parsing pending map" )
872 main.log.error( repr( pendingMap ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800873
Jon Hall6aec96b2015-01-19 14:49:31 -0800874 def CASE5( self, main ):
875 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800876 Reading state of ONOS
Jon Hall6aec96b2015-01-19 14:49:31 -0800877 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800878 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700879 import time
880 assert numControllers, "numControllers not defined"
881 assert main, "main not defined"
882 assert utilities.assert_equals, "utilities.assert_equals not defined"
883 assert CLIs, "CLIs not defined"
884 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -0800885 # assumes that sts is already in you PYTHONPATH
886 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -0800887
Jon Hall6aec96b2015-01-19 14:49:31 -0800888 main.log.report( "Setting up and gathering data for current state" )
889 main.case( "Setting up and gathering data for current state" )
890 # The general idea for this test case is to pull the state of
891 # ( intents,flows, topology,... ) from each ONOS node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700892 # We can then compare them with each other and also with past states
Jon Hall73cf9cc2014-11-20 22:28:38 -0800893
Jon Hall5cfd23c2015-03-19 11:40:57 -0700894 main.step( "Check that each switch has a master" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800895 global mastershipState
Jon Hall5cfd23c2015-03-19 11:40:57 -0700896 mastershipState = '[]'
Jon Hall94fd0472014-12-08 11:52:42 -0800897
Jon Hall6aec96b2015-01-19 14:49:31 -0800898 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -0700899 rolesNotNull = main.TRUE
900 threads = []
901 for i in range( numControllers ):
902 t = main.Thread( target=CLIs[i].rolesNotNull,
903 name="rolesNotNull-" + str( i ),
904 args=[] )
905 threads.append( t )
906 t.start()
907
908 for t in threads:
909 t.join()
910 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -0800911 utilities.assert_equals(
912 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800913 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -0800914 onpass="Each device has a master",
915 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -0800916
Jon Hall5cfd23c2015-03-19 11:40:57 -0700917 main.step( "Get the Mastership of each switch from each controller" )
918 ONOSMastership = []
919 mastershipCheck = main.FALSE
920 consistentMastership = True
921 rolesResults = True
922 threads = []
923 for i in range( numControllers ):
924 t = main.Thread( target=CLIs[i].roles,
925 name="roles-" + str( i ),
926 args=[] )
927 threads.append( t )
928 t.start()
929
930 for t in threads:
931 t.join()
932 ONOSMastership.append( t.result )
933
934 for i in range( numControllers ):
935 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
936 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
937 " roles" )
938 main.log.warn(
939 "ONOS" + str( i + 1 ) + " mastership response: " +
940 repr( ONOSMastership[i] ) )
941 rolesResults = False
942 utilities.assert_equals(
943 expect=True,
944 actual=rolesResults,
945 onpass="No error in reading roles output",
946 onfail="Error in reading roles from ONOS" )
947
948 main.step( "Check for consistency in roles from each controller" )
949 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall6aec96b2015-01-19 14:49:31 -0800950 main.log.report(
951 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800952 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700953 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -0800954 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -0700955 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -0800956 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -0800957 onpass="Switch roles are consistent across all ONOS nodes",
958 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800959
Jon Hall5cfd23c2015-03-19 11:40:57 -0700960 if rolesResults and not consistentMastership:
961 for i in range( numControllers ):
962 try:
963 main.log.warn(
964 "ONOS" + str( i + 1 ) + " roles: ",
965 json.dumps(
966 json.loads( ONOSMastership[ i ] ),
967 sort_keys=True,
968 indent=4,
969 separators=( ',', ': ' ) ) )
970 except ( ValueError, TypeError ):
971 main.log.warn( repr( ONOSMastership[ i ] ) )
972 elif rolesResults and consistentMastership:
973 mastershipCheck = main.TRUE
974 mastershipState = ONOSMastership[ 0 ]
975
Jon Hall6aec96b2015-01-19 14:49:31 -0800976 main.step( "Get the intents from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800977 global intentState
978 intentState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -0700979 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -0800980 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700981 consistentIntents = True
982 intentsResults = True
983 threads = []
984 for i in range( numControllers ):
985 t = main.Thread( target=CLIs[i].intents,
986 name="intents-" + str( i ),
987 args=[],
988 kwargs={ 'jsonFormat': True } )
989 threads.append( t )
990 t.start()
991
992 for t in threads:
993 t.join()
994 ONOSIntents.append( t.result )
995
996 for i in range( numControllers ):
997 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
998 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
999 " intents" )
1000 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1001 repr( ONOSIntents[ i ] ) )
1002 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001003 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001004 expect=True,
1005 actual=intentsResults,
1006 onpass="No error in reading intents output",
1007 onfail="Error in reading intents from ONOS" )
1008
1009 main.step( "Check for consistency in Intents from each controller" )
1010 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1011 main.log.report( "Intents are consistent across all ONOS " +
1012 "nodes" )
1013 else:
1014 consistentIntents = False
1015 main.log.report( "Intents not consistent" )
1016 utilities.assert_equals(
1017 expect=True,
1018 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001019 onpass="Intents are consistent across all ONOS nodes",
1020 onfail="ONOS nodes have different views of intents" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001021
Jon Hall5cfd23c2015-03-19 11:40:57 -07001022 if intentsResults and not consistentIntents:
1023 n = len(ONOSIntents)
1024 main.log.warn( "ONOS" + str( n ) + " intents: " )
1025 main.log.warn( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1026 sort_keys=True,
1027 indent=4,
1028 separators=( ',', ': ' ) ) )
1029 for i in range( numControllers ):
1030 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
1031 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1032 main.log.warn( json.dumps( json.loads( ONOSIntents[i] ),
1033 sort_keys=True,
1034 indent=4,
1035 separators=( ',', ': ' ) ) )
1036 else:
1037 main.log.warn( nodes[ i ].name + " intents match ONOS" +
1038 str( n ) + " intents" )
1039 elif intentsResults and consistentIntents:
1040 intentCheck = main.TRUE
1041 intentState = ONOSIntents[ 0 ]
1042
Jon Hall6aec96b2015-01-19 14:49:31 -08001043 main.step( "Get the flows from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001044 global flowState
1045 flowState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001046 ONOSFlows = []
1047 ONOSFlowsJson = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001048 flowCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001049 consistentFlows = True
1050 flowsResults = True
1051 threads = []
1052 for i in range( numControllers ):
1053 t = main.Thread( target=CLIs[i].flows,
1054 name="flows-" + str( i ),
1055 args=[],
1056 kwargs={ 'jsonFormat': True } )
1057 threads.append( t )
1058 t.start()
1059
Jon Halla9d26da2015-03-30 16:45:32 -07001060 # NOTE: Flows command can take some time to run
Jon Hall5cfd23c2015-03-19 11:40:57 -07001061 time.sleep(30)
1062 for t in threads:
1063 t.join()
1064 result = t.result
1065 ONOSFlows.append( result )
1066
1067 for i in range( numControllers ):
1068 num = str( i + 1 )
1069 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1070 main.log.report( "Error in getting ONOS" + num + " flows" )
1071 main.log.warn( "ONOS" + num + " flows response: " +
1072 repr( ONOSFlows[ i ] ) )
1073 flowsResults = False
1074 ONOSFlowsJson.append( None )
Jon Hall58c76b72015-02-23 11:09:24 -08001075 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001076 try:
1077 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1078 except ( ValueError, TypeError ):
1079 # FIXME: change this to log.error?
1080 main.log.exception( "Error in parsing ONOS" + num +
1081 " response as json." )
1082 main.log.error( repr( ONOSFlows[ i ] ) )
1083 ONOSFlowsJson.append( None )
1084 flowsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001085 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001086 expect=True,
1087 actual=flowsResults,
1088 onpass="No error in reading flows output",
1089 onfail="Error in reading flows from ONOS" )
1090
1091 main.step( "Check for consistency in Flows from each controller" )
1092 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1093 if all( tmp ):
1094 main.log.report( "Flow count is consistent across all ONOS nodes" )
1095 else:
1096 consistentFlows = False
1097 utilities.assert_equals(
1098 expect=True,
1099 actual=consistentFlows,
Jon Hall6aec96b2015-01-19 14:49:31 -08001100 onpass="The flow count is consistent across all ONOS nodes",
1101 onfail="ONOS nodes have different flow counts" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001102
Jon Hall5cfd23c2015-03-19 11:40:57 -07001103 if flowsResults and not consistentFlows:
1104 for i in range( numControllers ):
1105 try:
1106 main.log.warn(
1107 "ONOS" + str( i + 1 ) + " flows: " +
1108 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1109 indent=4, separators=( ',', ': ' ) ) )
1110 except ( ValueError, TypeError ):
1111 main.log.warn(
1112 "ONOS" + str( i + 1 ) + " flows: " +
1113 repr( ONOSFlows[ i ] ) )
1114 elif flowsResults and consistentFlows:
1115 flowCheck = main.TRUE
1116 flowState = ONOSFlows[ 0 ]
1117
Jon Hall6aec96b2015-01-19 14:49:31 -08001118 main.step( "Get the OF Table entries" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001119 global flows
Jon Hall6aec96b2015-01-19 14:49:31 -08001120 flows = []
1121 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001122 flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001123 if flowCheck == main.FALSE:
1124 for table in flows:
1125 main.log.warn( table )
Jon Hall6aec96b2015-01-19 14:49:31 -08001126 # TODO: Compare switch flow tables with ONOS flow tables
Jon Hall73cf9cc2014-11-20 22:28:38 -08001127
Jon Hall6aec96b2015-01-19 14:49:31 -08001128 main.step( "Start continuous pings" )
1129 main.Mininet2.pingLong(
1130 src=main.params[ 'PING' ][ 'source1' ],
1131 target=main.params[ 'PING' ][ 'target1' ],
1132 pingTime=500 )
1133 main.Mininet2.pingLong(
1134 src=main.params[ 'PING' ][ 'source2' ],
1135 target=main.params[ 'PING' ][ 'target2' ],
1136 pingTime=500 )
1137 main.Mininet2.pingLong(
1138 src=main.params[ 'PING' ][ 'source3' ],
1139 target=main.params[ 'PING' ][ 'target3' ],
1140 pingTime=500 )
1141 main.Mininet2.pingLong(
1142 src=main.params[ 'PING' ][ 'source4' ],
1143 target=main.params[ 'PING' ][ 'target4' ],
1144 pingTime=500 )
1145 main.Mininet2.pingLong(
1146 src=main.params[ 'PING' ][ 'source5' ],
1147 target=main.params[ 'PING' ][ 'target5' ],
1148 pingTime=500 )
1149 main.Mininet2.pingLong(
1150 src=main.params[ 'PING' ][ 'source6' ],
1151 target=main.params[ 'PING' ][ 'target6' ],
1152 pingTime=500 )
1153 main.Mininet2.pingLong(
1154 src=main.params[ 'PING' ][ 'source7' ],
1155 target=main.params[ 'PING' ][ 'target7' ],
1156 pingTime=500 )
1157 main.Mininet2.pingLong(
1158 src=main.params[ 'PING' ][ 'source8' ],
1159 target=main.params[ 'PING' ][ 'target8' ],
1160 pingTime=500 )
1161 main.Mininet2.pingLong(
1162 src=main.params[ 'PING' ][ 'source9' ],
1163 target=main.params[ 'PING' ][ 'target9' ],
1164 pingTime=500 )
1165 main.Mininet2.pingLong(
1166 src=main.params[ 'PING' ][ 'source10' ],
1167 target=main.params[ 'PING' ][ 'target10' ],
1168 pingTime=500 )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001169
Jon Hall6aec96b2015-01-19 14:49:31 -08001170 main.step( "Create TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001171 ctrls = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001172 for node in nodes:
1173 temp = ( node, node.name, node.ip_address, 6633 )
1174 ctrls.append( temp )
1175 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001176
Jon Hall6aec96b2015-01-19 14:49:31 -08001177 main.step( "Collecting topology information from ONOS" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001178 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001179 threads = []
1180 for i in range( numControllers ):
1181 t = main.Thread( target=CLIs[i].devices,
1182 name="devices-" + str( i ),
1183 args=[ ] )
1184 threads.append( t )
1185 t.start()
1186
1187 for t in threads:
1188 t.join()
1189 devices.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001190 hosts = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001191 threads = []
1192 for i in range( numControllers ):
1193 t = main.Thread( target=CLIs[i].hosts,
1194 name="hosts-" + str( i ),
1195 args=[ ] )
1196 threads.append( t )
1197 t.start()
1198
1199 for t in threads:
1200 t.join()
1201 try:
1202 hosts.append( json.loads( t.result ) )
1203 except ( ValueError, TypeError ):
1204 # FIXME: better handling of this, print which node
1205 # Maybe use thread name?
1206 main.log.exception( "Error parsing json output of hosts" )
1207 # FIXME: should this be an empty json object instead?
1208 hosts.append( None )
1209
Jon Hall73cf9cc2014-11-20 22:28:38 -08001210 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001211 threads = []
1212 for i in range( numControllers ):
1213 t = main.Thread( target=CLIs[i].ports,
1214 name="ports-" + str( i ),
1215 args=[ ] )
1216 threads.append( t )
1217 t.start()
1218
1219 for t in threads:
1220 t.join()
1221 ports.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001222 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001223 threads = []
1224 for i in range( numControllers ):
1225 t = main.Thread( target=CLIs[i].links,
1226 name="links-" + str( i ),
1227 args=[ ] )
1228 threads.append( t )
1229 t.start()
1230
1231 for t in threads:
1232 t.join()
1233 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001234 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001235 threads = []
1236 for i in range( numControllers ):
1237 t = main.Thread( target=CLIs[i].clusters,
1238 name="clusters-" + str( i ),
1239 args=[ ] )
1240 threads.append( t )
1241 t.start()
1242
1243 for t in threads:
1244 t.join()
1245 clusters.append( t.result )
Jon Hall529a37f2015-01-28 10:02:00 -08001246 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001247
Jon Hall6aec96b2015-01-19 14:49:31 -08001248 # hosts
Jon Hall8f89dda2015-01-22 16:03:33 -08001249 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001250 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001251 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001252 if "Error" not in hosts[ controller ]:
1253 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001254 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001255 else: # hosts not consistent
1256 main.log.report( "hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001257 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001258 " is inconsistent with ONOS1" )
1259 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001260 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001261
1262 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001263 main.log.report( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001264 controllerStr )
1265 consistentHostsResult = main.FALSE
1266 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001267 " hosts response: " +
1268 repr( hosts[ controller ] ) )
1269 utilities.assert_equals(
1270 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001271 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001272 onpass="Hosts view is consistent across all ONOS nodes",
1273 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001274
Jon Hall58c76b72015-02-23 11:09:24 -08001275 ipResult = main.TRUE
1276 for controller in range( 0, len( hosts ) ):
1277 controllerStr = str( controller + 1 )
1278 for host in hosts[ controller ]:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001279 if not host.get( 'ips', [ ] ):
1280 main.log.error( "DEBUG:Error with host ips on controller" +
1281 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001282 ipResult = main.FALSE
1283 utilities.assert_equals(
1284 expect=main.TRUE,
1285 actual=ipResult,
1286 onpass="The ips of the hosts aren't empty",
1287 onfail="The ip of at least one host is missing" )
1288
Jon Hall6aec96b2015-01-19 14:49:31 -08001289 # Strongly connected clusters of devices
Jon Hall8f89dda2015-01-22 16:03:33 -08001290 consistentClustersResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001291 for controller in range( len( clusters ) ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001292 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001293 if "Error" not in clusters[ controller ]:
1294 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001295 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001296 else: # clusters not consistent
Jon Hall5cfd23c2015-03-19 11:40:57 -07001297 main.log.report( "clusters from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001298 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001299 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001300
1301 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001302 main.log.report( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001303 "from ONOS" + controllerStr )
1304 consistentClustersResult = main.FALSE
1305 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001306 " clusters response: " +
1307 repr( clusters[ controller ] ) )
1308 utilities.assert_equals(
1309 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001310 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001311 onpass="Clusters view is consistent across all ONOS nodes",
1312 onfail="ONOS nodes have different views of clusters" )
1313 # there should always only be one cluster
Jon Hall5cfd23c2015-03-19 11:40:57 -07001314 try:
1315 numClusters = len( json.loads( clusters[ 0 ] ) )
1316 except ( ValueError, TypeError ):
1317 main.log.exception( "Error parsing clusters[0]: " +
1318 repr( clusters[ 0 ] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001319 clusterResults = main.FALSE
1320 if numClusters == 1:
1321 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001322 utilities.assert_equals(
1323 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08001324 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08001325 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08001326 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08001327
Jon Hall6aec96b2015-01-19 14:49:31 -08001328 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001329 devicesResults = main.TRUE
1330 portsResults = main.TRUE
1331 linksResults = main.TRUE
1332 for controller in range( numControllers ):
1333 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001334 if devices[ controller ] or "Error" not in devices[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001335 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08001336 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001337 json.loads( devices[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001338 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001339 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001340 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001341 actual=currentDevicesResult,
1342 onpass="ONOS" + controllerStr +
1343 " Switches view is correct",
1344 onfail="ONOS" + controllerStr +
1345 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001346
Jon Hall6aec96b2015-01-19 14:49:31 -08001347 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001348 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08001349 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001350 json.loads( ports[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001351 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001352 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001353 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001354 actual=currentPortsResult,
1355 onpass="ONOS" + controllerStr +
1356 " ports view is correct",
1357 onfail="ONOS" + controllerStr +
1358 " ports view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001359
Jon Hall6aec96b2015-01-19 14:49:31 -08001360 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001361 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08001362 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001363 json.loads( links[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001364 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001365 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001366 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001367 actual=currentLinksResult,
1368 onpass="ONOS" + controllerStr +
1369 " links view is correct",
1370 onfail="ONOS" + controllerStr +
1371 " links view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001372
Jon Hall8f89dda2015-01-22 16:03:33 -08001373 devicesResults = devicesResults and currentDevicesResult
1374 portsResults = portsResults and currentPortsResult
1375 linksResults = linksResults and currentLinksResult
Jon Hall73cf9cc2014-11-20 22:28:38 -08001376
Jon Hall5cfd23c2015-03-19 11:40:57 -07001377 topoResult = ( devicesResults and portsResults and linksResults
1378 and consistentHostsResult and consistentClustersResult
1379 and clusterResults and ipResult )
Jon Hall8f89dda2015-01-22 16:03:33 -08001380 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08001381 onpass="Topology Check Test successful",
1382 onfail="Topology Check Test NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001383
Jon Hall8f89dda2015-01-22 16:03:33 -08001384 finalAssert = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001385 finalAssert = ( finalAssert and topoResult and flowCheck
1386 and intentCheck and consistentMastership
Jon Halla9d26da2015-03-30 16:45:32 -07001387 and mastershipCheck and rolesNotNull )
Jon Hall8f89dda2015-01-22 16:03:33 -08001388 utilities.assert_equals( expect=main.TRUE, actual=finalAssert,
Jon Hall58c76b72015-02-23 11:09:24 -08001389 onpass="State check successful",
1390 onfail="State check NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001391
Jon Hall6aec96b2015-01-19 14:49:31 -08001392 def CASE6( self, main ):
1393 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001394 The Failure case.
Jon Hall6aec96b2015-01-19 14:49:31 -08001395 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07001396 assert numControllers, "numControllers not defined"
1397 assert main, "main not defined"
1398 assert utilities.assert_equals, "utilities.assert_equals not defined"
1399 assert CLIs, "CLIs not defined"
1400 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001401 main.log.report( "Restart entire ONOS cluster" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001402 main.case( "Restart entire ONOS cluster" )
1403 main.step( "Killing ONOS nodes" )
1404 killResults = main.TRUE
1405 for node in nodes:
1406 killed = main.ONOSbench.onosKill( node.ip_address )
1407 killResults = killResults and killed
Jon Hall73cf9cc2014-11-20 22:28:38 -08001408
Jon Hall6aec96b2015-01-19 14:49:31 -08001409 main.step( "Checking if ONOS is up yet" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001410 for i in range( 2 ):
1411 onosIsupResult = main.TRUE
1412 for node in nodes:
1413 started = main.ONOSbench.isup( node.ip_address )
1414 if not started:
1415 main.log.report( node.name + " didn't start!" )
1416 onosIsupResult = onosIsupResult and started
1417 if onosIsupResult == main.TRUE:
1418 break
Jon Hall73cf9cc2014-11-20 22:28:38 -08001419
Jon Hall5cfd23c2015-03-19 11:40:57 -07001420 main.log.step( "Starting ONOS CLI sessions" )
1421 cliResults = main.TRUE
1422 threads = []
1423 for i in range( numControllers ):
1424 t = main.Thread( target=CLIs[i].startOnosCli,
1425 name="startOnosCli-" + str( i ),
1426 args=[nodes[i].ip_address] )
1427 threads.append( t )
1428 t.start()
1429
1430 for t in threads:
1431 t.join()
1432 cliResults = cliResults and t.result
Jon Hall73cf9cc2014-11-20 22:28:38 -08001433
Jon Hall8f89dda2015-01-22 16:03:33 -08001434 caseResults = main.TRUE and onosIsupResult and cliResults
1435 utilities.assert_equals( expect=main.TRUE, actual=caseResults,
Jon Hall58c76b72015-02-23 11:09:24 -08001436 onpass="ONOS restart successful",
1437 onfail="ONOS restart NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001438
Jon Hall6aec96b2015-01-19 14:49:31 -08001439 def CASE7( self, main ):
1440 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001441 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -08001442 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001443 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001444 assert numControllers, "numControllers not defined"
1445 assert main, "main not defined"
1446 assert utilities.assert_equals, "utilities.assert_equals not defined"
1447 assert CLIs, "CLIs not defined"
1448 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001449 main.case( "Running ONOS Constant State Tests" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001450
Jon Hall5cfd23c2015-03-19 11:40:57 -07001451 main.step( "Check that each switch has a master" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001452 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -07001453 rolesNotNull = main.TRUE
1454 threads = []
1455 for i in range( numControllers ):
1456 t = main.Thread( target=CLIs[i].rolesNotNull,
1457 name="rolesNotNull-" + str( i ),
1458 args=[ ] )
1459 threads.append( t )
1460 t.start()
1461
1462 for t in threads:
1463 t.join()
1464 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001465 utilities.assert_equals(
1466 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001467 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001468 onpass="Each device has a master",
1469 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001470
Jon Hall5cfd23c2015-03-19 11:40:57 -07001471 ONOSMastership = []
1472 mastershipCheck = main.FALSE
1473 consistentMastership = True
1474 rolesResults = True
1475 threads = []
1476 for i in range( numControllers ):
1477 t = main.Thread( target=CLIs[i].roles,
1478 name="roles-" + str( i ),
1479 args=[] )
1480 threads.append( t )
1481 t.start()
1482
1483 for t in threads:
1484 t.join()
1485 ONOSMastership.append( t.result )
1486
1487 for i in range( numControllers ):
1488 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1489 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1490 " roles" )
1491 main.log.warn(
1492 "ONOS" + str( i + 1 ) + " mastership response: " +
1493 repr( ONOSMastership[i] ) )
1494 rolesResults = False
1495 utilities.assert_equals(
1496 expect=True,
1497 actual=rolesResults,
1498 onpass="No error in reading roles output",
1499 onfail="Error in reading roles from ONOS" )
1500
1501 main.step( "Check for consistency in roles from each controller" )
1502 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall6aec96b2015-01-19 14:49:31 -08001503 main.log.report(
1504 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001505 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001506 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001507 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001508 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001509 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001510 onpass="Switch roles are consistent across all ONOS nodes",
1511 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001512
Jon Hall5cfd23c2015-03-19 11:40:57 -07001513 if rolesResults and not consistentMastership:
1514 for i in range( numControllers ):
1515 main.log.warn(
1516 "ONOS" + str( i + 1 ) + " roles: ",
1517 json.dumps(
1518 json.loads( ONOSMastership[ i ] ),
1519 sort_keys=True,
1520 indent=4,
1521 separators=( ',', ': ' ) ) )
1522 elif rolesResults and not consistentMastership:
1523 mastershipCheck = main.TRUE
1524
Jon Hall73cf9cc2014-11-20 22:28:38 -08001525 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -08001526 main.step( description2 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001527 try:
1528 currentJson = json.loads( ONOSMastership[0] )
1529 oldJson = json.loads( mastershipState )
1530 except ( ValueError, TypeError ):
1531 main.log.exception( "Something is wrong with parsing " +
1532 "ONOSMastership[0] or mastershipState" )
1533 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1534 main.log.error( "mastershipState" + repr( mastershipState ) )
1535 main.cleanup()
1536 main.exit()
Jon Hall8f89dda2015-01-22 16:03:33 -08001537 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001538 for i in range( 1, 29 ):
1539 switchDPID = str(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001540 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001541 current = [ switch[ 'master' ] for switch in currentJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001542 if switchDPID in switch[ 'id' ] ]
Jon Hall8f89dda2015-01-22 16:03:33 -08001543 old = [ switch[ 'master' ] for switch in oldJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001544 if switchDPID in switch[ 'id' ] ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08001545 if current == old:
Jon Hall8f89dda2015-01-22 16:03:33 -08001546 mastershipCheck = mastershipCheck and main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001547 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001548 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall8f89dda2015-01-22 16:03:33 -08001549 mastershipCheck = main.FALSE
1550 if mastershipCheck == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001551 main.log.report( "Mastership of Switches was not changed" )
1552 utilities.assert_equals(
1553 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001554 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -08001555 onpass="Mastership of Switches was not changed",
1556 onfail="Mastership of some switches changed" )
1557 # NOTE: we expect mastership to change on controller failure
Jon Hall8f89dda2015-01-22 16:03:33 -08001558 mastershipCheck = mastershipCheck and consistentMastership
Jon Hall73cf9cc2014-11-20 22:28:38 -08001559
Jon Hall6aec96b2015-01-19 14:49:31 -08001560 main.step( "Get the intents and compare across all nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001561 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001562 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001563 consistentIntents = True
1564 intentsResults = True
1565 threads = []
1566 for i in range( numControllers ):
1567 t = main.Thread( target=CLIs[i].intents,
1568 name="intents-" + str( i ),
1569 args=[],
1570 kwargs={ 'jsonFormat': True } )
1571 threads.append( t )
1572 t.start()
1573
1574 for t in threads:
1575 t.join()
1576 ONOSIntents.append( t.result )
1577
1578 for i in range( numControllers ):
1579 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1580 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1581 " intents" )
1582 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1583 repr( ONOSIntents[ i ] ) )
1584 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001585 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001586 expect=True,
1587 actual=intentsResults,
1588 onpass="No error in reading intents output",
1589 onfail="Error in reading intents from ONOS" )
1590
1591 main.step( "Check for consistency in Intents from each controller" )
1592 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1593 main.log.report( "Intents are consistent across all ONOS " +
1594 "nodes" )
1595 else:
1596 consistentIntents = False
1597 utilities.assert_equals(
1598 expect=True,
1599 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001600 onpass="Intents are consistent across all ONOS nodes",
1601 onfail="ONOS nodes have different views of intents" )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001602 intentStates = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001603 for node in ONOSIntents: # Iter through ONOS nodes
Jon Hall1b8f54a2015-02-04 13:24:20 -08001604 nodeStates = []
Jon Hall58c76b72015-02-23 11:09:24 -08001605 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001606 try:
1607 for intent in json.loads( node ):
1608 nodeStates.append( intent[ 'state' ] )
1609 except ( ValueError, TypeError ):
1610 main.log.exception( "Error in parsing intents" )
1611 main.log.error( repr( node ) )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001612 intentStates.append( nodeStates )
1613 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1614 main.log.info( dict( out ) )
1615
Jon Hall5cfd23c2015-03-19 11:40:57 -07001616 if intentsResults and not consistentIntents:
1617 for i in range( numControllers ):
1618 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1619 main.log.warn( json.dumps(
1620 json.loads( ONOSIntents[ i ] ),
1621 sort_keys=True,
1622 indent=4,
1623 separators=( ',', ': ' ) ) )
1624 elif intentsResults and consistentIntents:
1625 intentCheck = main.TRUE
1626
Jon Hall58c76b72015-02-23 11:09:24 -08001627 # NOTE: Store has no durability, so intents are lost across system
1628 # restarts
Jon Hall6aec96b2015-01-19 14:49:31 -08001629 """
1630 main.step( "Compare current intents with intents before the failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001631 # NOTE: this requires case 5 to pass for intentState to be set.
Jon Hall94fd0472014-12-08 11:52:42 -08001632 # maybe we should stop the test if that fails?
Jon Hall1b8f54a2015-02-04 13:24:20 -08001633 sameIntents = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001634 if intentState and intentState == ONOSIntents[ 0 ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001635 sameIntents = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001636 main.log.report( "Intents are consistent with before failure" )
1637 # TODO: possibly the states have changed? we may need to figure out
Jon Hall5cfd23c2015-03-19 11:40:57 -07001638 # what the acceptable states are
Jon Hall73cf9cc2014-11-20 22:28:38 -08001639 else:
Jon Hall669173b2014-12-17 11:36:30 -08001640 try:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001641 main.log.warn( "ONOS intents: " )
1642 main.log.warn( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1643 sort_keys=True, indent=4,
1644 separators=( ',', ': ' ) ) )
1645 except ( ValueError, TypeError ):
1646 main.log.exception( "Exception printing intents" )
1647 main.log.warn( repr( ONOSIntents[0] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001648 sameIntents = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001649 utilities.assert_equals(
1650 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001651 actual=sameIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001652 onpass="Intents are consistent with before failure",
1653 onfail="The Intents changed during failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001654 intentCheck = intentCheck and sameIntents
Jon Hall6aec96b2015-01-19 14:49:31 -08001655 """
1656 main.step( "Get the OF Table entries and compare to before " +
1657 "component failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001658 FlowTables = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001659 flows2 = []
1660 for i in range( 28 ):
1661 main.log.info( "Checking flow table on s" + str( i + 1 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001662 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
1663 flows2.append( tmpFlows )
1664 tempResult = main.Mininet2.flowComp(
Jon Hall6aec96b2015-01-19 14:49:31 -08001665 flow1=flows[ i ],
Jon Hall8f89dda2015-01-22 16:03:33 -08001666 flow2=tmpFlows )
1667 FlowTables = FlowTables and tempResult
1668 if FlowTables == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001669 main.log.info( "Differences in flow table for switch: s" +
1670 str( i + 1 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001671 if FlowTables == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001672 main.log.report( "No changes were found in the flow tables" )
1673 utilities.assert_equals(
1674 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001675 actual=FlowTables,
Jon Hall6aec96b2015-01-19 14:49:31 -08001676 onpass="No changes were found in the flow tables",
1677 onfail="Changes were found in the flow tables" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001678
Jon Hall6aec96b2015-01-19 14:49:31 -08001679 main.step( "Check the continuous pings to ensure that no packets " +
1680 "were dropped during component failure" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001681 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
1682 main.params[ 'TESTONIP' ] )
Jon Hall8f89dda2015-01-22 16:03:33 -08001683 LossInPings = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001684 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
1685 for i in range( 8, 18 ):
1686 main.log.info(
1687 "Checking for a loss in pings along flow from s" +
1688 str( i ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001689 LossInPings = main.Mininet2.checkForLoss(
Jon Hall6aec96b2015-01-19 14:49:31 -08001690 "/tmp/ping.h" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001691 str( i ) ) or LossInPings
1692 if LossInPings == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001693 main.log.info( "Loss in ping detected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001694 elif LossInPings == main.ERROR:
Jon Hall6aec96b2015-01-19 14:49:31 -08001695 main.log.info( "There are multiple mininet process running" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001696 elif LossInPings == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001697 main.log.info( "No Loss in the pings" )
1698 main.log.report( "No loss of dataplane connectivity" )
1699 utilities.assert_equals(
1700 expect=main.FALSE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001701 actual=LossInPings,
Jon Hall6aec96b2015-01-19 14:49:31 -08001702 onpass="No Loss of connectivity",
1703 onfail="Loss of dataplane connectivity detected" )
Jon Hall58c76b72015-02-23 11:09:24 -08001704 # NOTE: Since intents are not persisted with IntnentStore,
1705 # we expect loss in dataplane connectivity
Jon Hall8f89dda2015-01-22 16:03:33 -08001706 LossInPings = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001707
Jon Hall6aec96b2015-01-19 14:49:31 -08001708 # Test of LeadershipElection
Jon Hall8f89dda2015-01-22 16:03:33 -08001709 leaderList = []
1710 leaderResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001711 for cli in CLIs:
1712 leaderN = cli.electionTestLeader()
Jon Hall8f89dda2015-01-22 16:03:33 -08001713 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08001714 if leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001715 # error in response
1716 main.log.report( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001717 "electionTestLeader function, check the" +
Jon Hall6aec96b2015-01-19 14:49:31 -08001718 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001719 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001720 elif leaderN is None:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001721 main.log.report( cli.name +
Jon Hall6aec96b2015-01-19 14:49:31 -08001722 " shows no leader for the election-app was" +
1723 " elected after the old one died" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001724 leaderResult = main.FALSE
1725 if len( set( leaderList ) ) != 1:
1726 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001727 main.log.error(
1728 "Inconsistent view of leader for the election test app" )
1729 # TODO: print the list
Jon Hall8f89dda2015-01-22 16:03:33 -08001730 if leaderResult:
1731 main.log.report( "Leadership election tests passed( consistent " +
Jon Hall6aec96b2015-01-19 14:49:31 -08001732 "view of leader across listeners and a new " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001733 "leader was re-elected if applicable )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001734 utilities.assert_equals(
1735 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001736 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001737 onpass="Leadership election passed",
1738 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08001739
Jon Hall8f89dda2015-01-22 16:03:33 -08001740 result = ( mastershipCheck and intentCheck and FlowTables and
1741 ( not LossInPings ) and rolesNotNull and leaderResult )
Jon Hall6aec96b2015-01-19 14:49:31 -08001742 result = int( result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001743 if result == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001744 main.log.report( "Constant State Tests Passed" )
1745 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall58c76b72015-02-23 11:09:24 -08001746 onpass="Constant State Tests Passed",
1747 onfail="Constant state tests failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001748
Jon Hall6aec96b2015-01-19 14:49:31 -08001749 def CASE8( self, main ):
1750 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001751 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -08001752 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001753 import sys
Jon Hall6aec96b2015-01-19 14:49:31 -08001754 # FIXME add this path to params
1755 sys.path.append( "/home/admin/sts" )
1756 # assumes that sts is already in you PYTHONPATH
1757 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -08001758 import json
1759 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001760 assert numControllers, "numControllers not defined"
1761 assert main, "main not defined"
1762 assert utilities.assert_equals, "utilities.assert_equals not defined"
1763 assert CLIs, "CLIs not defined"
1764 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08001765
Jon Hall6aec96b2015-01-19 14:49:31 -08001766 description = "Compare ONOS Topology view to Mininet topology"
1767 main.case( description )
1768 main.log.report( description )
1769 main.step( "Create TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001770 ctrls = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001771 for node in nodes:
1772 temp = ( node, node.name, node.ip_address, 6633 )
1773 ctrls.append( temp )
1774 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001775
Jon Hall6aec96b2015-01-19 14:49:31 -08001776 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001777 devicesResults = main.TRUE
1778 portsResults = main.TRUE
1779 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08001780 hostsResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08001781 topoResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001782 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -08001783 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -08001784 main.step( "Collecting topology information from ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001785 startTime = time.time()
Jon Hall21270ac2015-02-16 17:59:55 -08001786 # Give time for Gossip to work
Jon Hall8f89dda2015-01-22 16:03:33 -08001787 while topoResult == main.FALSE and elapsed < 60:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001788 count += 1
Jon Hall94fd0472014-12-08 11:52:42 -08001789 if count > 1:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001790 # TODO: Deprecate STS usage
Jon Hall58c76b72015-02-23 11:09:24 -08001791 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall8f89dda2015-01-22 16:03:33 -08001792 cliStart = time.time()
Jon Hall94fd0472014-12-08 11:52:42 -08001793 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001794 threads = []
1795 for i in range( numControllers ):
1796 t = main.Thread( target=CLIs[i].devices,
1797 name="devices-" + str( i ),
1798 args=[ ] )
1799 threads.append( t )
1800 t.start()
1801
1802 for t in threads:
1803 t.join()
1804 devices.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001805 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -08001806 ipResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001807 threads = []
1808 for i in range( numControllers ):
1809 t = main.Thread( target=CLIs[i].hosts,
1810 name="hosts-" + str( i ),
1811 args=[ ] )
1812 threads.append( t )
1813 t.start()
1814
1815 for t in threads:
1816 t.join()
1817 try:
1818 hosts.append( json.loads( t.result ) )
1819 except ( ValueError, TypeError ):
1820 main.log.exception( "Error parsing hosts results" )
1821 main.log.error( repr( t.result ) )
Jon Hall529a37f2015-01-28 10:02:00 -08001822 for controller in range( 0, len( hosts ) ):
1823 controllerStr = str( controller + 1 )
1824 for host in hosts[ controller ]:
Jon Hall58c76b72015-02-23 11:09:24 -08001825 if host is None or host.get( 'ips', [] ) == []:
Jon Hall529a37f2015-01-28 10:02:00 -08001826 main.log.error(
1827 "DEBUG:Error with host ips on controller" +
1828 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001829 ipResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001830 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001831 threads = []
1832 for i in range( numControllers ):
1833 t = main.Thread( target=CLIs[i].ports,
1834 name="ports-" + str( i ),
1835 args=[ ] )
1836 threads.append( t )
1837 t.start()
1838
1839 for t in threads:
1840 t.join()
1841 ports.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001842 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001843 threads = []
1844 for i in range( numControllers ):
1845 t = main.Thread( target=CLIs[i].links,
1846 name="links-" + str( i ),
1847 args=[ ] )
1848 threads.append( t )
1849 t.start()
1850
1851 for t in threads:
1852 t.join()
1853 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001854 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001855 threads = []
1856 for i in range( numControllers ):
1857 t = main.Thread( target=CLIs[i].clusters,
1858 name="clusters-" + str( i ),
1859 args=[ ] )
1860 threads.append( t )
1861 t.start()
1862
1863 for t in threads:
1864 t.join()
1865 clusters.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001866
Jon Hall8f89dda2015-01-22 16:03:33 -08001867 elapsed = time.time() - startTime
1868 cliTime = time.time() - cliStart
1869 print "CLI time: " + str( cliTime )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001870
Jon Hall8f89dda2015-01-22 16:03:33 -08001871 for controller in range( numControllers ):
1872 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001873 if devices[ controller ] or "Error" not in devices[
1874 controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001875 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08001876 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08001877 json.loads( devices[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001878 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001879 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001880 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001881 actual=currentDevicesResult,
1882 onpass="ONOS" + controllerStr +
1883 " Switches view is correct",
1884 onfail="ONOS" + controllerStr +
1885 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001886
Jon Hall6aec96b2015-01-19 14:49:31 -08001887 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001888 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08001889 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08001890 json.loads( ports[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001891 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001892 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001893 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001894 actual=currentPortsResult,
1895 onpass="ONOS" + controllerStr +
1896 " ports view is correct",
1897 onfail="ONOS" + controllerStr +
1898 " ports view is incorrect" )
Jon Hall94fd0472014-12-08 11:52:42 -08001899
Jon Hall6aec96b2015-01-19 14:49:31 -08001900 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001901 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08001902 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08001903 json.loads( links[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001904 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001905 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001906 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001907 actual=currentLinksResult,
1908 onpass="ONOS" + controllerStr +
1909 " links view is correct",
1910 onfail="ONOS" + controllerStr +
1911 " links view is incorrect" )
1912
1913 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1914 currentHostsResult = main.Mininet1.compareHosts(
1915 MNTopo, hosts[ controller ] )
1916 else:
1917 currentHostsResult = main.FALSE
1918 utilities.assert_equals( expect=main.TRUE,
1919 actual=currentHostsResult,
1920 onpass="ONOS" + controllerStr +
1921 " hosts exist in Mininet",
1922 onfail="ONOS" + controllerStr +
1923 " hosts don't match Mininet" )
1924
1925 devicesResults = devicesResults and currentDevicesResult
1926 portsResults = portsResults and currentPortsResult
1927 linksResults = linksResults and currentLinksResult
1928 hostsResults = hostsResults and currentHostsResult
Jon Hall94fd0472014-12-08 11:52:42 -08001929
Jon Hall529a37f2015-01-28 10:02:00 -08001930 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001931
Jon Hall6aec96b2015-01-19 14:49:31 -08001932 # hosts
Jon Hall8f89dda2015-01-22 16:03:33 -08001933 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001934 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001935 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001936 if "Error" not in hosts[ controller ]:
1937 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001938 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001939 else: # hosts not consistent
Jon Hall8f89dda2015-01-22 16:03:33 -08001940 main.log.report( "hosts from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001941 " is inconsistent with ONOS1" )
1942 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001943 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001944
1945 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001946 main.log.report( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001947 controllerStr )
1948 consistentHostsResult = main.FALSE
1949 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001950 " hosts response: " +
1951 repr( hosts[ controller ] ) )
1952 utilities.assert_equals(
1953 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001954 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001955 onpass="Hosts view is consistent across all ONOS nodes",
1956 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001957
Jon Hall6aec96b2015-01-19 14:49:31 -08001958 # Strongly connected clusters of devices
Jon Hall8f89dda2015-01-22 16:03:33 -08001959 consistentClustersResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001960 for controller in range( len( clusters ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001961 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001962 if "Error" not in clusters[ controller ]:
1963 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001964 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001965 else: # clusters not consistent
1966 main.log.report( "clusters from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001967 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001968 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001969 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001970
1971 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001972 main.log.report( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001973 "from ONOS" + controllerStr )
1974 consistentClustersResult = main.FALSE
1975 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001976 " clusters response: " +
1977 repr( clusters[ controller ] ) )
1978 utilities.assert_equals(
1979 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001980 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001981 onpass="Clusters view is consistent across all ONOS nodes",
1982 onfail="ONOS nodes have different views of clusters" )
1983 # there should always only be one cluster
Jon Hall5cfd23c2015-03-19 11:40:57 -07001984 try:
1985 numClusters = len( json.loads( clusters[ 0 ] ) )
1986 except ( ValueError, TypeError ):
1987 main.log.exception( "Error parsing clusters[0]: " +
1988 repr( clusters[0] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001989 clusterResults = main.FALSE
1990 if numClusters == 1:
1991 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001992 utilities.assert_equals(
1993 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08001994 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08001995 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08001996 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08001997
Jon Hall8f89dda2015-01-22 16:03:33 -08001998 topoResult = ( devicesResults and portsResults and linksResults
Jon Hall58c76b72015-02-23 11:09:24 -08001999 and hostsResults and consistentHostsResult
2000 and consistentClustersResult and clusterResults
2001 and ipResult )
Jon Hall94fd0472014-12-08 11:52:42 -08002002
Jon Hall8f89dda2015-01-22 16:03:33 -08002003 topoResult = topoResult and int( count <= 2 )
2004 note = "note it takes about " + str( int( cliTime ) ) + \
2005 " seconds for the test to make all the cli calls to fetch " +\
2006 "the topology from each ONOS instance"
Jon Hall1b8f54a2015-02-04 13:24:20 -08002007 main.log.info(
Jon Hall8f89dda2015-01-22 16:03:33 -08002008 "Very crass estimate for topology discovery/convergence( " +
2009 str( note ) + " ): " + str( elapsed ) + " seconds, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002010 str( count ) + " tries" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002011 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08002012 onpass="Topology Check Test successful",
2013 onfail="Topology Check Test NOT successful" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002014 if topoResult == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002015 main.log.report( "ONOS topology view matches Mininet topology" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002016
Jon Halla9d26da2015-03-30 16:45:32 -07002017 # FIXME: move this to an ONOS state case
2018 main.step( "Checking ONOS nodes" )
2019 nodesOutput = []
2020 threads = []
2021 for i in range( numControllers ):
2022 t = main.Thread( target=CLIs[i].nodes,
2023 name="nodes-" + str( i ),
2024 args=[ ] )
2025 threads.append( t )
2026 t.start()
2027
2028 for t in threads:
2029 t.join()
2030 nodesOutput.append( t.result )
2031 ips = [ node.ip_address for node in nodes ]
2032 for i in nodesOutput:
2033 try:
2034 current = json.loads( i )
2035 for node in current:
2036 if node['ip'] in ips: # node in nodes() output is in cell
2037 if node['state'] == 'ACTIVE':
2038 pass # as it should be
2039 else:
2040 main.log.error( "Error in ONOS node availability" )
2041 main.log.error(
2042 json.dumps( current,
2043 sort_keys=True,
2044 indent=4,
2045 separators=( ',', ': ' ) ) )
2046 break
2047 except ( ValueError, TypeError ):
2048 main.log.error( "Error parsing nodes output" )
2049 main.log.warn( repr( i ) )
2050
Jon Hall6aec96b2015-01-19 14:49:31 -08002051 def CASE9( self, main ):
2052 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002053 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -08002054 """
2055 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002056 assert numControllers, "numControllers not defined"
2057 assert main, "main not defined"
2058 assert utilities.assert_equals, "utilities.assert_equals not defined"
2059 assert CLIs, "CLIs not defined"
2060 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002061 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002062
Jon Hall8f89dda2015-01-22 16:03:33 -08002063 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002064
Jon Hall6aec96b2015-01-19 14:49:31 -08002065 description = "Turn off a link to ensure that Link Discovery " +\
Jon Hall58c76b72015-02-23 11:09:24 -08002066 "is working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002067 main.log.report( description )
2068 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002069
Jon Hall6aec96b2015-01-19 14:49:31 -08002070 main.step( "Kill Link between s3 and s28" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002071 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
Jon Hall58c76b72015-02-23 11:09:24 -08002072 main.log.info( "Waiting " + str( linkSleep ) +
2073 " seconds for link down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002074 time.sleep( linkSleep )
2075 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002076 onpass="Link down successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002077 onfail="Failed to bring link down" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002078 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002079
Jon Hall6aec96b2015-01-19 14:49:31 -08002080 def CASE10( self, main ):
2081 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002082 Link s3-s28 up
Jon Hall6aec96b2015-01-19 14:49:31 -08002083 """
2084 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002085 assert numControllers, "numControllers not defined"
2086 assert main, "main not defined"
2087 assert utilities.assert_equals, "utilities.assert_equals not defined"
2088 assert CLIs, "CLIs not defined"
2089 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002090 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002091
Jon Hall8f89dda2015-01-22 16:03:33 -08002092 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002093
Jon Hall6aec96b2015-01-19 14:49:31 -08002094 description = "Restore a link to ensure that Link Discovery is " + \
Jon Hall63604932015-02-26 17:09:50 -08002095 "working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002096 main.log.report( description )
2097 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002098
Jon Hall6aec96b2015-01-19 14:49:31 -08002099 main.step( "Bring link between s3 and s28 back up" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002100 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
Jon Hall58c76b72015-02-23 11:09:24 -08002101 main.log.info( "Waiting " + str( linkSleep ) +
2102 " seconds for link up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002103 time.sleep( linkSleep )
2104 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002105 onpass="Link up successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002106 onfail="Failed to bring link up" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002107 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002108
Jon Hall6aec96b2015-01-19 14:49:31 -08002109 def CASE11( self, main ):
2110 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002111 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -08002112 """
2113 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002114 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002115 assert numControllers, "numControllers not defined"
2116 assert main, "main not defined"
2117 assert utilities.assert_equals, "utilities.assert_equals not defined"
2118 assert CLIs, "CLIs not defined"
2119 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08002120
Jon Hall8f89dda2015-01-22 16:03:33 -08002121 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002122
2123 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002124 main.log.report( description )
2125 main.case( description )
2126 switch = main.params[ 'kill' ][ 'switch' ]
2127 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08002128
Jon Hall6aec96b2015-01-19 14:49:31 -08002129 # TODO: Make this switch parameterizable
2130 main.step( "Kill " + switch )
2131 main.log.report( "Deleting " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002132 main.Mininet1.delSwitch( switch )
2133 main.log.info( "Waiting " + str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002134 " seconds for switch down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002135 time.sleep( switchSleep )
2136 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002137 # Peek at the deleted switch
2138 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002139 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002140 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -08002141 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002142 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002143 onpass="Kill switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002144 onfail="Failed to kill switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002145
Jon Hall6aec96b2015-01-19 14:49:31 -08002146 def CASE12( self, main ):
2147 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002148 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -08002149 """
2150 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002151 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002152 assert numControllers, "numControllers not defined"
2153 assert main, "main not defined"
2154 assert utilities.assert_equals, "utilities.assert_equals not defined"
2155 assert CLIs, "CLIs not defined"
2156 assert nodes, "nodes not defined"
2157 assert ONOS1Port, "ONOS1Port not defined"
2158 assert ONOS2Port, "ONOS2Port not defined"
2159 assert ONOS3Port, "ONOS3Port not defined"
2160 assert ONOS4Port, "ONOS4Port not defined"
2161 assert ONOS5Port, "ONOS5Port not defined"
2162 assert ONOS6Port, "ONOS6Port not defined"
2163 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall669173b2014-12-17 11:36:30 -08002164
Jon Hall8f89dda2015-01-22 16:03:33 -08002165 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall6aec96b2015-01-19 14:49:31 -08002166 switch = main.params[ 'kill' ][ 'switch' ]
2167 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2168 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002169 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002170 main.log.report( description )
2171 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002172
Jon Hall6aec96b2015-01-19 14:49:31 -08002173 main.step( "Add back " + switch )
2174 main.log.report( "Adding back " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002175 main.Mininet1.addSwitch( switch, dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002176 for peer in links:
Jon Hall8f89dda2015-01-22 16:03:33 -08002177 main.Mininet1.addLink( switch, peer )
Jon Hall58c76b72015-02-23 11:09:24 -08002178 main.Mininet1.assignSwController( sw=switch.split( 's' )[ 1 ],
2179 count=numControllers,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002180 ip1=nodes[ 0 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002181 port1=ONOS1Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002182 ip2=nodes[ 1 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002183 port2=ONOS2Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002184 ip3=nodes[ 2 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002185 port3=ONOS3Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002186 ip4=nodes[ 3 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002187 port4=ONOS4Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002188 ip5=nodes[ 4 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002189 port5=ONOS5Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002190 ip6=nodes[ 5 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002191 port6=ONOS6Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002192 ip7=nodes[ 6 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002193 port7=ONOS7Port )
2194 main.log.info( "Waiting " + str( switchSleep ) +
2195 " seconds for switch up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002196 time.sleep( switchSleep )
2197 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002198 # Peek at the deleted switch
2199 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002200 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002201 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002202 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002203 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002204 onpass="add switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002205 onfail="Failed to add switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002206
Jon Hall6aec96b2015-01-19 14:49:31 -08002207 def CASE13( self, main ):
2208 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002209 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -08002210 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002211 import os
2212 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002213 assert numControllers, "numControllers not defined"
2214 assert main, "main not defined"
2215 assert utilities.assert_equals, "utilities.assert_equals not defined"
2216 assert CLIs, "CLIs not defined"
2217 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002218
2219 # printing colors to terminal
Jon Hall5cfd23c2015-03-19 11:40:57 -07002220 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2221 'blue': '\033[94m', 'green': '\033[92m',
2222 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
Jon Hall73cf9cc2014-11-20 22:28:38 -08002223 description = "Test Cleanup"
Jon Hall6aec96b2015-01-19 14:49:31 -08002224 main.log.report( description )
2225 main.case( description )
2226 main.step( "Killing tcpdumps" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002227 main.Mininet2.stopTcpdump()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002228
Jon Hall6aec96b2015-01-19 14:49:31 -08002229 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002230 testname = main.TEST
Jon Hall8f89dda2015-01-22 16:03:33 -08002231 teststationUser = main.params[ 'TESTONUSER' ]
2232 teststationIP = main.params[ 'TESTONIP' ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002233 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -08002234 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -08002235 # FIXME: scp
2236 # mn files
2237 # TODO: Load these from params
2238 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002239 logFolder = "/opt/onos/log/"
2240 logFiles = [ "karaf.log", "karaf.log.1" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002241 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002242 dstDir = "~/packet_captures/"
2243 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002244 for node in nodes:
2245 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2246 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002247 teststationUser + "@" +
2248 teststationIP + ":" +
2249 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002250 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002251 main.ONOSbench.handle.expect( "\$" )
2252
Jon Hall6aec96b2015-01-19 14:49:31 -08002253 # std*.log's
2254 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002255 logFolder = "/opt/onos/var/"
2256 logFiles = [ "stderr.log", "stdout.log" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002257 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002258 dstDir = "~/packet_captures/"
2259 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002260 for node in nodes:
2261 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2262 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002263 teststationUser + "@" +
2264 teststationIP + ":" +
2265 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002266 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002267 main.ONOSbench.handle.expect( "\$" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002268 # sleep so scp can finish
2269 time.sleep( 10 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002270
2271 main.step( "Stopping Mininet" )
Jon Hall58c76b72015-02-23 11:09:24 -08002272 main.Mininet1.stopNet()
Jon Hall5cfd23c2015-03-19 11:40:57 -07002273
2274 main.step( "Checking ONOS Logs for errors" )
2275 for node in nodes:
2276 print colors[ 'purple' ] + "Checking logs for errors on " + \
2277 node.name + ":" + colors[ 'end' ]
2278 print main.ONOSbench.checkLogs( node.ip_address )
2279
Jon Hall6aec96b2015-01-19 14:49:31 -08002280 main.step( "Packing and rotating pcap archives" )
2281 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002282
Jon Hall6aec96b2015-01-19 14:49:31 -08002283 # TODO: actually check something here
2284 utilities.assert_equals( expect=main.TRUE, actual=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002285 onpass="Test cleanup successful",
2286 onfail="Test cleanup NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002287
Jon Hall6aec96b2015-01-19 14:49:31 -08002288 def CASE14( self, main ):
2289 """
Jon Hall669173b2014-12-17 11:36:30 -08002290 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -08002291 """
Jon Halla9d26da2015-03-30 16:45:32 -07002292 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002293 assert numControllers, "numControllers not defined"
2294 assert main, "main not defined"
2295 assert utilities.assert_equals, "utilities.assert_equals not defined"
2296 assert CLIs, "CLIs not defined"
2297 assert nodes, "nodes not defined"
2298
Jon Hall8f89dda2015-01-22 16:03:33 -08002299 leaderResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002300 main.log.info( "Install leadership election app" )
Jon Halla9d26da2015-03-30 16:45:32 -07002301 main.ONOScli1.activateApp( "org.onosproject.election" )
2302 leaders = []
2303 for cli in CLIs:
2304 leader = cli.electionTestLeader()
2305 if leader is None or leader == main.FALSE:
2306 main.log.report( cli.name + ": Leader for the election app " +
2307 "should be an ONOS node, instead got '" +
2308 str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002309 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002310 leaders.append( leader )
2311 if len( set( leaders ) ) != 1:
2312 leaderResult = main.FALSE
2313 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2314 str( leaders ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08002315 if leaderResult:
Jon Hall6aec96b2015-01-19 14:49:31 -08002316 main.log.report( "Leadership election tests passed( consistent " +
2317 "view of leader across listeners and a leader " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002318 "was elected )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002319 utilities.assert_equals(
2320 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002321 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002322 onpass="Leadership election passed",
2323 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002324
Jon Hall6aec96b2015-01-19 14:49:31 -08002325 def CASE15( self, main ):
2326 """
Jon Hall669173b2014-12-17 11:36:30 -08002327 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08002328 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07002329 assert numControllers, "numControllers not defined"
2330 assert main, "main not defined"
2331 assert utilities.assert_equals, "utilities.assert_equals not defined"
2332 assert CLIs, "CLIs not defined"
2333 assert nodes, "nodes not defined"
2334
Jon Hall8f89dda2015-01-22 16:03:33 -08002335 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002336 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08002337 main.log.report( description )
2338 main.case( description )
2339 main.step( "Find current leader and withdraw" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002340 leader = main.ONOScli1.electionTestLeader()
Jon Halla9d26da2015-03-30 16:45:32 -07002341 # do some sanity checking on leader before using it
Jon Hall8f89dda2015-01-22 16:03:33 -08002342 withdrawResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002343 if leader is None or leader == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002344 main.log.report(
2345 "Leader for the election app should be an ONOS node," +
Jon Hall58c76b72015-02-23 11:09:24 -08002346 "instead got '" + str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002347 leaderResult = main.FALSE
Jon Hall63604932015-02-26 17:09:50 -08002348 oldLeader = None
Jon Hall5cfd23c2015-03-19 11:40:57 -07002349 for i in range( len( CLIs ) ):
2350 if leader == nodes[ i ].ip_address:
2351 oldLeader = CLIs[ i ]
2352 break
Jon Halla9d26da2015-03-30 16:45:32 -07002353 else: # FOR/ELSE statement
Jon Hall5cfd23c2015-03-19 11:40:57 -07002354 main.log.error( "Leader election, could not find current leader" )
Jon Hall63604932015-02-26 17:09:50 -08002355 if oldLeader:
2356 withdrawResult = oldLeader.electionTestWithdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08002357 utilities.assert_equals(
2358 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002359 actual=withdrawResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002360 onpass="App was withdrawn from election",
2361 onfail="App was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08002362
Jon Hall6aec96b2015-01-19 14:49:31 -08002363 main.step( "Make sure new leader is elected" )
Jon Halla9d26da2015-03-30 16:45:32 -07002364 # FIXME: use threads
Jon Hall8f89dda2015-01-22 16:03:33 -08002365 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002366 for cli in CLIs:
2367 leaderN = cli.electionTestLeader()
2368 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002369 if leaderN == leader:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002370 main.log.report( cli.name + " still sees " + str( leader ) +
2371 " as leader after they withdrew" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002372 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002373 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002374 # error in response
2375 # TODO: add check for "Command not found:" in the driver, this
Jon Hall5cfd23c2015-03-19 11:40:57 -07002376 # means the app isn't loaded
Jon Hall6aec96b2015-01-19 14:49:31 -08002377 main.log.report( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002378 "electionTestLeader function, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002379 "check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002380 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002381 elif leaderN is None:
2382 # node may not have recieved the event yet
2383 leaderN = cli.electionTestLeader()
2384 leaderList.pop()
2385 leaderList.append( leaderN )
Jon Hall8f89dda2015-01-22 16:03:33 -08002386 consistentLeader = main.FALSE
2387 if len( set( leaderList ) ) == 1:
Jon Hall6aec96b2015-01-19 14:49:31 -08002388 main.log.info( "Each Election-app sees '" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002389 str( leaderList[ 0 ] ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002390 "' as the leader" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002391 consistentLeader = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002392 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08002393 main.log.report(
2394 "Inconsistent responses for leader of Election-app:" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002395 for n in range( len( leaderList ) ):
Jon Hall6aec96b2015-01-19 14:49:31 -08002396 main.log.report( "ONOS" + str( n + 1 ) + " response: " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002397 str( leaderList[ n ] ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002398 leaderResult = leaderResult and consistentLeader
Jon Hall8f89dda2015-01-22 16:03:33 -08002399 if leaderResult:
2400 main.log.report( "Leadership election tests passed( consistent " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002401 "view of leader across listeners and a new " +
2402 "leader was elected when the old leader " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002403 "resigned )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002404 utilities.assert_equals(
2405 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002406 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002407 onpass="Leadership election passed",
2408 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002409
Jon Hall58c76b72015-02-23 11:09:24 -08002410 main.step( "Run for election on old leader( just so everyone " +
2411 "is in the hat )" )
Jon Hall63604932015-02-26 17:09:50 -08002412 if oldLeader:
2413 runResult = oldLeader.electionTestRun()
2414 else:
2415 runResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002416 utilities.assert_equals(
2417 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002418 actual=runResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002419 onpass="App re-ran for election",
2420 onfail="App failed to run for election" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002421 if consistentLeader == main.TRUE:
2422 afterRun = main.ONOScli1.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08002423 # verify leader didn't just change
Jon Hall8f89dda2015-01-22 16:03:33 -08002424 if afterRun == leaderList[ 0 ]:
2425 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002426 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002427 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002428 # TODO: assert on run and withdraw results?
Jon Hall669173b2014-12-17 11:36:30 -08002429
Jon Hall6aec96b2015-01-19 14:49:31 -08002430 utilities.assert_equals(
2431 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002432 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002433 onpass="Leadership election passed",
2434 onfail="Something went wrong with Leadership election after " +
2435 "the old leader re-ran for election" )