blob: 475da9a06da121e0c059bf8ac6c1f9cbe8f39421 [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 Hall5cfd23c2015-03-19 11:40:57 -0700301 if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
Jon Hall58c76b72015-02-23 11:09:24 -0800302 roleCheck = roleCheck and main.TRUE
303 else:
304 roleCheck = roleCheck and main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -0700305 main.log.error( "Error, controller " + ip + " is not" +
306 " master " + "of device " +
307 str( deviceId ) )
Jon Hall58c76b72015-02-23 11:09:24 -0800308 except ( AttributeError, AssertionError ):
309 main.log.exception( "Something is wrong with ONOS device view" )
310 main.log.info( main.ONOScli1.devices() )
Jon Hall6aec96b2015-01-19 14:49:31 -0800311 utilities.assert_equals(
312 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800313 actual=roleCall,
Jon Hall6aec96b2015-01-19 14:49:31 -0800314 onpass="Re-assigned switch mastership to designated controller",
Jon Hall8f89dda2015-01-22 16:03:33 -0800315 onfail="Something wrong with deviceRole calls" )
Jon Hall94fd0472014-12-08 11:52:42 -0800316
Jon Hall6aec96b2015-01-19 14:49:31 -0800317 utilities.assert_equals(
318 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800319 actual=roleCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800320 onpass="Switches were successfully reassigned to designated " +
321 "controller",
322 onfail="Switches were not successfully reassigned" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800323 mastershipCheck = mastershipCheck and roleCall and roleCheck
324 utilities.assert_equals( expect=main.TRUE, actual=mastershipCheck,
Jon Hall21270ac2015-02-16 17:59:55 -0800325 onpass="Switch mastership correctly assigned",
326 onfail="Error in (re)assigning switch" +
327 " mastership" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800328
Jon Hall6aec96b2015-01-19 14:49:31 -0800329 def CASE3( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800330 """
331 Assign intents
Jon Hall73cf9cc2014-11-20 22:28:38 -0800332 """
Jon Hall6aec96b2015-01-19 14:49:31 -0800333 # FIXME: we must reinstall intents until we have a persistant
334 # datastore!
Jon Hall73cf9cc2014-11-20 22:28:38 -0800335 import time
Jon Hall58c76b72015-02-23 11:09:24 -0800336 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700337 assert numControllers, "numControllers not defined"
338 assert main, "main not defined"
339 assert utilities.assert_equals, "utilities.assert_equals not defined"
340 assert CLIs, "CLIs not defined"
341 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -0800342 main.log.report( "Adding host intents" )
343 main.case( "Adding host Intents" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800344
Jon Hall8f89dda2015-01-22 16:03:33 -0800345 main.step( "Discovering Hosts( Via pingall for now )" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800346 # FIXME: Once we have a host discovery mechanism, use that instead
Jon Hall73cf9cc2014-11-20 22:28:38 -0800347
Jon Hall6aec96b2015-01-19 14:49:31 -0800348 # install onos-app-fwd
349 main.log.info( "Install reactive forwarding app" )
Jon Halla9d26da2015-03-30 16:45:32 -0700350 appResults = CLIs[0].activateApp( "org.onosproject.fwd" )
351
352 # FIXME: add this to asserts
353 appCheck = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700354 threads = []
355 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700356 t = main.Thread( target=CLIs[i].appToIDCheck,
357 name="appToIDCheck-" + str( i ),
358 args=[] )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700359 threads.append( t )
360 t.start()
361
362 for t in threads:
363 t.join()
Jon Halla9d26da2015-03-30 16:45:32 -0700364 appCheck = appCheck and t.result
365 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
366 onpass="App Ids seem to be correct",
367 onfail="Something is wrong with app Ids" )
368 if appCheck != main.TRUE:
369 main.log.warn( CLIs[0].apps() )
370 main.log.warn( CLIs[0].appIDs() )
Jon Hall94fd0472014-12-08 11:52:42 -0800371
Jon Hall6aec96b2015-01-19 14:49:31 -0800372 # REACTIVE FWD test
Jon Hall8f89dda2015-01-22 16:03:33 -0800373 pingResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700374 for i in range(2): # Retry if pingall fails first time
375 time1 = time.time()
376 pingResult = main.Mininet1.pingall()
377 utilities.assert_equals(
378 expect=main.TRUE,
379 actual=pingResult,
380 onpass="Reactive Pingall test passed",
381 onfail="Reactive Pingall failed, one or more ping pairs failed" )
382 time2 = time.time()
383 main.log.info( "Time for pingall: %2f seconds" % ( time2 - time1 ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800384
Jon Hall6aec96b2015-01-19 14:49:31 -0800385 # uninstall onos-app-fwd
386 main.log.info( "Uninstall reactive forwarding app" )
Jon Halla9d26da2015-03-30 16:45:32 -0700387 appResults = appResults and CLIs[0].deactivateApp( "org.onosproject.fwd" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700388 threads = []
389 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700390 t = main.Thread( target=CLIs[i].appToIDCheck,
391 name="appToIDCheck-" + str( i ),
392 args=[] )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700393 threads.append( t )
394 t.start()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800395
Jon Hall5cfd23c2015-03-19 11:40:57 -0700396 for t in threads:
397 t.join()
Jon Halla9d26da2015-03-30 16:45:32 -0700398 appCheck = appCheck and t.result
399 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
400 onpass="App Ids seem to be correct",
401 onfail="Something is wrong with app Ids" )
402 if appCheck != main.TRUE:
403 main.log.warn( CLIs[0].apps() )
404 main.log.warn( CLIs[0].appIDs() )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700405
406 # timeout for fwd flows
407 time.sleep( 11 )
408
409 main.step( "Add host intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800410 intentIds = []
Jon Hall6aec96b2015-01-19 14:49:31 -0800411 # TODO: move the host numbers to params
Jon Hall58c76b72015-02-23 11:09:24 -0800412 # Maybe look at all the paths we ping?
Jon Hall8f89dda2015-01-22 16:03:33 -0800413 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800414 hostResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800415 for i in range( 8, 18 ):
416 main.log.info( "Adding host intent between h" + str( i ) +
417 " and h" + str( i + 10 ) )
418 host1 = "00:00:00:00:00:" + \
419 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
420 host2 = "00:00:00:00:00:" + \
421 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800422 # NOTE: getHost can return None
423 host1Dict = main.ONOScli1.getHost( host1 )
424 host2Dict = main.ONOScli1.getHost( host2 )
425 host1Id = None
426 host2Id = None
427 if host1Dict and host2Dict:
428 host1Id = host1Dict.get( 'id', None )
429 host2Id = host2Dict.get( 'id', None )
Jon Hall8f89dda2015-01-22 16:03:33 -0800430 if host1Id and host2Id:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700431 nodeNum = ( i % 7 )
432 tmpId = CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
Jon Hall63604932015-02-26 17:09:50 -0800433 if tmpId:
434 main.log.info( "Added intent with id: " + tmpId )
435 intentIds.append( tmpId )
436 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700437 main.log.error( "addHostIntent returned: " +
438 repr( tmpId ) )
Jon Hall669173b2014-12-17 11:36:30 -0800439 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700440 main.log.error( "Error, getHost() failed for h" + str( i ) +
441 " and/or h" + str( i + 10 ) )
442 hosts = CLIs[ 0 ].hosts()
443 main.log.warn( "Hosts output: " )
444 try:
445 main.log.warn( json.dumps( json.loads( hosts ),
446 sort_keys=True,
447 indent=4,
448 separators=( ',', ': ' ) ) )
449 except ( ValueError, TypeError ):
450 main.log.warn( repr( hosts ) )
Jon Hall58c76b72015-02-23 11:09:24 -0800451 hostResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -0700452 # FIXME: DEBUG
453 intentStart = time.time()
Jon Hall58c76b72015-02-23 11:09:24 -0800454 onosIds = main.ONOScli1.getAllIntentsId()
455 main.log.info( "Submitted intents: " + str( intentIds ) )
456 main.log.info( "Intents in ONOS: " + str( onosIds ) )
457 for intent in intentIds:
458 if intent in onosIds:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700459 pass # intent submitted is in onos
Jon Hall58c76b72015-02-23 11:09:24 -0800460 else:
461 intentAddResult = False
Jon Halla9d26da2015-03-30 16:45:32 -0700462 # FIXME: DEBUG
463 if intentAddResult:
464 intentStop = time.time()
465 else:
466 intentStop = None
Jon Hall1b8f54a2015-02-04 13:24:20 -0800467 # Print the intent states
Jon Hall58c76b72015-02-23 11:09:24 -0800468 intents = main.ONOScli1.intents()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800469 intentStates = []
Jon Hall63604932015-02-26 17:09:50 -0800470 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800471 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
472 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700473 try:
474 for intent in json.loads( intents ):
475 state = intent.get( 'state', None )
476 if "INSTALLED" not in state:
477 installedCheck = False
478 intentId = intent.get( 'id', None )
479 intentStates.append( ( intentId, state ) )
480 except ( ValueError, TypeError ):
481 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800482 # add submitted intents not in the store
483 tmplist = [ i for i, s in intentStates ]
484 missingIntents = False
485 for i in intentIds:
486 if i not in tmplist:
487 intentStates.append( ( i, " - " ) )
488 missingIntents = True
489 intentStates.sort()
490 for i, s in intentStates:
491 count += 1
492 main.log.info( "%-6s%-15s%-15s" %
493 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700494 leaders = main.ONOScli1.leaders()
495 try:
496 if leaders:
497 parsedLeaders = json.loads( leaders )
498 main.log.warn( json.dumps( parsedLeaders,
499 sort_keys=True,
500 indent=4,
501 separators=( ',', ': ' ) ) )
502 # check for all intent partitions
Jon Hall5cfd23c2015-03-19 11:40:57 -0700503 topics = []
504 for i in range( 14 ):
505 topics.append( "intent-partition-" + str( i ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700506 main.log.debug( topics )
507 ONOStopics = [ j['topic'] for j in parsedLeaders ]
508 for topic in topics:
509 if topic not in ONOStopics:
510 main.log.error( "Error: " + topic +
511 " not in leaders" )
512 else:
513 main.log.error( "leaders() returned None" )
514 except ( ValueError, TypeError ):
515 main.log.exception( "Error parsing leaders" )
516 main.log.error( repr( leaders ) )
517 partitions = main.ONOScli1.partitions()
518 try:
519 if partitions :
520 parsedPartitions = json.loads( partitions )
521 main.log.warn( json.dumps( parsedPartitions,
522 sort_keys=True,
523 indent=4,
524 separators=( ',', ': ' ) ) )
525 # TODO check for a leader in all paritions
526 # TODO check for consistency among nodes
527 else:
528 main.log.error( "partitions() returned None" )
529 except ( ValueError, TypeError ):
530 main.log.exception( "Error parsing partitions" )
531 main.log.error( repr( partitions ) )
Jon Hall63604932015-02-26 17:09:50 -0800532 pendingMap = main.ONOScli1.pendingMap()
Jon Hall5cfd23c2015-03-19 11:40:57 -0700533 try:
534 if pendingMap :
535 parsedPending = json.loads( pendingMap )
536 main.log.warn( json.dumps( parsedPending,
537 sort_keys=True,
538 indent=4,
539 separators=( ',', ': ' ) ) )
540 # TODO check something here?
541 else:
542 main.log.error( "pendingMap() returned None" )
543 except ( ValueError, TypeError ):
544 main.log.exception( "Error parsing pending map" )
545 main.log.error( repr( pendingMap ) )
546
Jon Hall58c76b72015-02-23 11:09:24 -0800547 intentAddResult = bool( pingResult and hostResult and intentAddResult
Jon Hall63604932015-02-26 17:09:50 -0800548 and not missingIntents and installedCheck )
Jon Hall6aec96b2015-01-19 14:49:31 -0800549 utilities.assert_equals(
550 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -0800551 actual=intentAddResult,
Jon Hall529a37f2015-01-28 10:02:00 -0800552 onpass="Pushed host intents to ONOS",
553 onfail="Error in pushing host intents to ONOS" )
Jon Halla9d26da2015-03-30 16:45:32 -0700554 for i in range(100):
555 onosIds = main.ONOScli1.getAllIntentsId()
556 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
557 main.log.info( "Intents in ONOS: " + str( sorted( onosIds ) ) )
558 if sorted(onosIds) == sorted(intentIds):
559 break
560 else:
561 time.sleep(1)
562 # FIXME: DEBUG
563 if not intentStop:
564 intentStop = time.time()
565 gossipTime = intentStop - intentStart
566 main.log.info( "It took about " + str( gossipTime ) +
567 " seconds for all intents to appear on ONOS1" )
568 # FIXME: make this time configurable/calculate based off of number of
569 # nodes and gossip rounds
570 utilities.assert_greater_equals(
571 expect=30, actual=gossipTime,
572 onpass="ECM anti-entropy for intents worked within " +
573 "expected time",
574 onfail="Intent ECM anti-entropy took too long" )
Jon Hall58c76b72015-02-23 11:09:24 -0800575
Jon Hall63604932015-02-26 17:09:50 -0800576 if not intentAddResult or "key" in pendingMap:
Jon Hall58c76b72015-02-23 11:09:24 -0800577 import time
Jon Hall63604932015-02-26 17:09:50 -0800578 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800579 main.log.info( "Sleeping 60 seconds to see if intents are found" )
580 time.sleep( 60 )
581 onosIds = main.ONOScli1.getAllIntentsId()
582 main.log.info( "Submitted intents: " + str( intentIds ) )
583 main.log.info( "Intents in ONOS: " + str( onosIds ) )
584 # Print the intent states
585 intents = main.ONOScli1.intents()
586 intentStates = []
587 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
588 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700589 try:
590 for intent in json.loads( intents ):
591 # Iter through intents of a node
592 state = intent.get( 'state', None )
593 if "INSTALLED" not in state:
594 installedCheck = False
595 intentId = intent.get( 'id', None )
596 intentStates.append( ( intentId, state ) )
597 except ( ValueError, TypeError ):
598 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800599 # add submitted intents not in the store
600 tmplist = [ i for i, s in intentStates ]
601 for i in intentIds:
602 if i not in tmplist:
603 intentStates.append( ( i, " - " ) )
604 intentStates.sort()
605 for i, s in intentStates:
606 count += 1
607 main.log.info( "%-6s%-15s%-15s" %
608 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700609 leaders = main.ONOScli1.leaders()
610 try:
611 if leaders:
612 parsedLeaders = json.loads( leaders )
613 main.log.warn( json.dumps( parsedLeaders,
614 sort_keys=True,
615 indent=4,
616 separators=( ',', ': ' ) ) )
617 # check for all intent partitions
618 # check for election
619 topics = []
620 for i in range( 14 ):
621 topics.append( "intent-partition-" + str( i ) )
622 # FIXME: this should only be after we start the app
623 topics.append( "org.onosproject.election" )
624 main.log.debug( topics )
625 ONOStopics = [ j['topic'] for j in parsedLeaders ]
626 for topic in topics:
627 if topic not in ONOStopics:
628 main.log.error( "Error: " + topic +
629 " not in leaders" )
630 else:
631 main.log.error( "leaders() returned None" )
632 except ( ValueError, TypeError ):
633 main.log.exception( "Error parsing leaders" )
634 main.log.error( repr( leaders ) )
635 partitions = main.ONOScli1.partitions()
636 try:
637 if partitions :
638 parsedPartitions = json.loads( partitions )
639 main.log.warn( json.dumps( parsedPartitions,
640 sort_keys=True,
641 indent=4,
642 separators=( ',', ': ' ) ) )
643 # TODO check for a leader in all paritions
644 # TODO check for consistency among nodes
645 else:
646 main.log.error( "partitions() returned None" )
647 except ( ValueError, TypeError ):
648 main.log.exception( "Error parsing partitions" )
649 main.log.error( repr( partitions ) )
650 pendingMap = main.ONOScli1.pendingMap()
651 try:
652 if pendingMap :
653 parsedPending = json.loads( pendingMap )
654 main.log.warn( json.dumps( parsedPending,
655 sort_keys=True,
656 indent=4,
657 separators=( ',', ': ' ) ) )
658 # TODO check something here?
659 else:
660 main.log.error( "pendingMap() returned None" )
661 except ( ValueError, TypeError ):
662 main.log.exception( "Error parsing pending map" )
663 main.log.error( repr( pendingMap ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800664
Jon Hall6aec96b2015-01-19 14:49:31 -0800665 def CASE4( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800666 """
667 Ping across added host intents
668 """
Jon Hall58c76b72015-02-23 11:09:24 -0800669 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700670 import time
671 assert numControllers, "numControllers not defined"
672 assert main, "main not defined"
673 assert utilities.assert_equals, "utilities.assert_equals not defined"
674 assert CLIs, "CLIs not defined"
675 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -0800676 description = " Ping across added host intents"
Jon Hall6aec96b2015-01-19 14:49:31 -0800677 main.log.report( description )
678 main.case( description )
Jon Hall8f89dda2015-01-22 16:03:33 -0800679 PingResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800680 for i in range( 8, 18 ):
Jon Hall58c76b72015-02-23 11:09:24 -0800681 ping = main.Mininet1.pingHost( src="h" + str( i ),
682 target="h" + str( i + 10 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800683 PingResult = PingResult and ping
Jon Hall6aec96b2015-01-19 14:49:31 -0800684 if ping == main.FALSE:
685 main.log.warn( "Ping failed between h" + str( i ) +
686 " and h" + str( i + 10 ) )
687 elif ping == main.TRUE:
688 main.log.info( "Ping test passed!" )
Jon Hall21270ac2015-02-16 17:59:55 -0800689 # Don't set PingResult or you'd override failures
Jon Hall8f89dda2015-01-22 16:03:33 -0800690 if PingResult == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800691 main.log.report(
692 "Intents have not been installed correctly, pings failed." )
Jon Hall58c76b72015-02-23 11:09:24 -0800693 # TODO: pretty print
Jon Hall5cfd23c2015-03-19 11:40:57 -0700694 main.log.warn( "ONOS1 intents: " )
695 try:
696 tmpIntents = main.ONOScli1.intents()
697 main.log.warn( json.dumps( json.loads( tmpIntents ),
698 sort_keys=True,
699 indent=4,
700 separators=( ',', ': ' ) ) )
701 except ( ValueError, TypeError ):
702 main.log.warn( repr( tmpIntents ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800703 if PingResult == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800704 main.log.report(
705 "Intents have been installed correctly and verified by pings" )
706 utilities.assert_equals(
707 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800708 actual=PingResult,
Jon Hall6aec96b2015-01-19 14:49:31 -0800709 onpass="Intents have been installed correctly and pings work",
710 onfail="Intents have not been installed correctly, pings failed." )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800711
Jon Hall63604932015-02-26 17:09:50 -0800712 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800713 if PingResult is not main.TRUE:
714 # Print the intent states
715 intents = main.ONOScli1.intents()
716 intentStates = []
717 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
718 count = 0
719 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700720 try:
721 for intent in json.loads( intents ):
722 state = intent.get( 'state', None )
723 if "INSTALLED" not in state:
724 installedCheck = False
725 intentId = intent.get( 'id', None )
726 intentStates.append( ( intentId, state ) )
727 except ( ValueError, TypeError ):
728 main.log.exception( "Error parsing intents." )
Jon Hall58c76b72015-02-23 11:09:24 -0800729 intentStates.sort()
730 for i, s in intentStates:
731 count += 1
732 main.log.info( "%-6s%-15s%-15s" %
733 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700734 leaders = main.ONOScli1.leaders()
735 try:
736 if leaders:
737 parsedLeaders = json.loads( leaders )
738 main.log.warn( json.dumps( parsedLeaders,
739 sort_keys=True,
740 indent=4,
741 separators=( ',', ': ' ) ) )
742 # check for all intent partitions
743 # check for election
744 topics = []
745 for i in range( 14 ):
746 topics.append( "intent-partition-" + str( i ) )
747 # FIXME: this should only be after we start the app
748 topics.append( "org.onosproject.election" )
749 main.log.debug( topics )
750 ONOStopics = [ j['topic'] for j in parsedLeaders ]
751 for topic in topics:
752 if topic not in ONOStopics:
753 main.log.error( "Error: " + topic +
754 " not in leaders" )
755 else:
756 main.log.error( "leaders() returned None" )
757 except ( ValueError, TypeError ):
758 main.log.exception( "Error parsing leaders" )
759 main.log.error( repr( leaders ) )
760 partitions = main.ONOScli1.partitions()
761 try:
762 if partitions :
763 parsedPartitions = json.loads( partitions )
764 main.log.warn( json.dumps( parsedPartitions,
765 sort_keys=True,
766 indent=4,
767 separators=( ',', ': ' ) ) )
768 # TODO check for a leader in all paritions
769 # TODO check for consistency among nodes
770 else:
771 main.log.error( "partitions() returned None" )
772 except ( ValueError, TypeError ):
773 main.log.exception( "Error parsing partitions" )
774 main.log.error( repr( partitions ) )
775 pendingMap = main.ONOScli1.pendingMap()
776 try:
777 if pendingMap :
778 parsedPending = json.loads( pendingMap )
779 main.log.warn( json.dumps( parsedPending,
780 sort_keys=True,
781 indent=4,
782 separators=( ',', ': ' ) ) )
783 # TODO check something here?
784 else:
785 main.log.error( "pendingMap() returned None" )
786 except ( ValueError, TypeError ):
787 main.log.exception( "Error parsing pending map" )
788 main.log.error( repr( pendingMap ) )
789
Jon Hall63604932015-02-26 17:09:50 -0800790 if not installedCheck:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700791 main.log.info( "Waiting 60 seconds to see if the state of " +
792 "intents change" )
Jon Hall63604932015-02-26 17:09:50 -0800793 time.sleep( 60 )
794 # Print the intent states
795 intents = main.ONOScli1.intents()
796 intentStates = []
797 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
798 count = 0
799 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700800 try:
801 for intent in json.loads( intents ):
802 state = intent.get( 'state', None )
803 if "INSTALLED" not in state:
804 installedCheck = False
805 intentId = intent.get( 'id', None )
806 intentStates.append( ( intentId, state ) )
807 except ( ValueError, TypeError ):
808 main.log.exception( "Error parsing intents." )
Jon Hall63604932015-02-26 17:09:50 -0800809 intentStates.sort()
810 for i, s in intentStates:
811 count += 1
812 main.log.info( "%-6s%-15s%-15s" %
813 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700814 leaders = main.ONOScli1.leaders()
815 try:
816 if leaders:
817 parsedLeaders = json.loads( leaders )
818 main.log.warn( json.dumps( parsedLeaders,
819 sort_keys=True,
820 indent=4,
821 separators=( ',', ': ' ) ) )
822 # check for all intent partitions
823 # check for election
824 topics = []
825 for i in range( 14 ):
826 topics.append( "intent-partition-" + str( i ) )
827 # FIXME: this should only be after we start the app
828 topics.append( "org.onosproject.election" )
829 main.log.debug( topics )
830 ONOStopics = [ j['topic'] for j in parsedLeaders ]
831 for topic in topics:
832 if topic not in ONOStopics:
833 main.log.error( "Error: " + topic +
834 " not in leaders" )
835 else:
836 main.log.error( "leaders() returned None" )
837 except ( ValueError, TypeError ):
838 main.log.exception( "Error parsing leaders" )
839 main.log.error( repr( leaders ) )
840 partitions = main.ONOScli1.partitions()
841 try:
842 if partitions :
843 parsedPartitions = json.loads( partitions )
844 main.log.warn( json.dumps( parsedPartitions,
845 sort_keys=True,
846 indent=4,
847 separators=( ',', ': ' ) ) )
848 # TODO check for a leader in all paritions
849 # TODO check for consistency among nodes
850 else:
851 main.log.error( "partitions() returned None" )
852 except ( ValueError, TypeError ):
853 main.log.exception( "Error parsing partitions" )
854 main.log.error( repr( partitions ) )
855 pendingMap = main.ONOScli1.pendingMap()
856 try:
857 if pendingMap :
858 parsedPending = json.loads( pendingMap )
859 main.log.warn( json.dumps( parsedPending,
860 sort_keys=True,
861 indent=4,
862 separators=( ',', ': ' ) ) )
863 # TODO check something here?
864 else:
865 main.log.error( "pendingMap() returned None" )
866 except ( ValueError, TypeError ):
867 main.log.exception( "Error parsing pending map" )
868 main.log.error( repr( pendingMap ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800869
Jon Hall6aec96b2015-01-19 14:49:31 -0800870 def CASE5( self, main ):
871 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800872 Reading state of ONOS
Jon Hall6aec96b2015-01-19 14:49:31 -0800873 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800874 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700875 import time
876 assert numControllers, "numControllers not defined"
877 assert main, "main not defined"
878 assert utilities.assert_equals, "utilities.assert_equals not defined"
879 assert CLIs, "CLIs not defined"
880 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -0800881 # assumes that sts is already in you PYTHONPATH
882 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -0800883
Jon Hall6aec96b2015-01-19 14:49:31 -0800884 main.log.report( "Setting up and gathering data for current state" )
885 main.case( "Setting up and gathering data for current state" )
886 # The general idea for this test case is to pull the state of
887 # ( intents,flows, topology,... ) from each ONOS node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700888 # We can then compare them with each other and also with past states
Jon Hall73cf9cc2014-11-20 22:28:38 -0800889
Jon Hall5cfd23c2015-03-19 11:40:57 -0700890 main.step( "Check that each switch has a master" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800891 global mastershipState
Jon Hall5cfd23c2015-03-19 11:40:57 -0700892 mastershipState = '[]'
Jon Hall94fd0472014-12-08 11:52:42 -0800893
Jon Hall6aec96b2015-01-19 14:49:31 -0800894 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -0700895 rolesNotNull = main.TRUE
896 threads = []
897 for i in range( numControllers ):
898 t = main.Thread( target=CLIs[i].rolesNotNull,
899 name="rolesNotNull-" + str( i ),
900 args=[] )
901 threads.append( t )
902 t.start()
903
904 for t in threads:
905 t.join()
906 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -0800907 utilities.assert_equals(
908 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800909 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -0800910 onpass="Each device has a master",
911 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -0800912
Jon Hall5cfd23c2015-03-19 11:40:57 -0700913 main.step( "Get the Mastership of each switch from each controller" )
914 ONOSMastership = []
915 mastershipCheck = main.FALSE
916 consistentMastership = True
917 rolesResults = True
918 threads = []
919 for i in range( numControllers ):
920 t = main.Thread( target=CLIs[i].roles,
921 name="roles-" + str( i ),
922 args=[] )
923 threads.append( t )
924 t.start()
925
926 for t in threads:
927 t.join()
928 ONOSMastership.append( t.result )
929
930 for i in range( numControllers ):
931 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
932 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
933 " roles" )
934 main.log.warn(
935 "ONOS" + str( i + 1 ) + " mastership response: " +
936 repr( ONOSMastership[i] ) )
937 rolesResults = False
938 utilities.assert_equals(
939 expect=True,
940 actual=rolesResults,
941 onpass="No error in reading roles output",
942 onfail="Error in reading roles from ONOS" )
943
944 main.step( "Check for consistency in roles from each controller" )
945 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall6aec96b2015-01-19 14:49:31 -0800946 main.log.report(
947 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800948 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700949 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -0800950 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -0700951 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -0800952 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -0800953 onpass="Switch roles are consistent across all ONOS nodes",
954 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800955
Jon Hall5cfd23c2015-03-19 11:40:57 -0700956 if rolesResults and not consistentMastership:
957 for i in range( numControllers ):
958 try:
959 main.log.warn(
960 "ONOS" + str( i + 1 ) + " roles: ",
961 json.dumps(
962 json.loads( ONOSMastership[ i ] ),
963 sort_keys=True,
964 indent=4,
965 separators=( ',', ': ' ) ) )
966 except ( ValueError, TypeError ):
967 main.log.warn( repr( ONOSMastership[ i ] ) )
968 elif rolesResults and consistentMastership:
969 mastershipCheck = main.TRUE
970 mastershipState = ONOSMastership[ 0 ]
971
Jon Hall6aec96b2015-01-19 14:49:31 -0800972 main.step( "Get the intents from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800973 global intentState
974 intentState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -0700975 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -0800976 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700977 consistentIntents = True
978 intentsResults = True
979 threads = []
980 for i in range( numControllers ):
981 t = main.Thread( target=CLIs[i].intents,
982 name="intents-" + str( i ),
983 args=[],
984 kwargs={ 'jsonFormat': True } )
985 threads.append( t )
986 t.start()
987
988 for t in threads:
989 t.join()
990 ONOSIntents.append( t.result )
991
992 for i in range( numControllers ):
993 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
994 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
995 " intents" )
996 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
997 repr( ONOSIntents[ i ] ) )
998 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -0800999 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001000 expect=True,
1001 actual=intentsResults,
1002 onpass="No error in reading intents output",
1003 onfail="Error in reading intents from ONOS" )
1004
1005 main.step( "Check for consistency in Intents from each controller" )
1006 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1007 main.log.report( "Intents are consistent across all ONOS " +
1008 "nodes" )
1009 else:
1010 consistentIntents = False
1011 main.log.report( "Intents not consistent" )
1012 utilities.assert_equals(
1013 expect=True,
1014 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001015 onpass="Intents are consistent across all ONOS nodes",
1016 onfail="ONOS nodes have different views of intents" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001017
Jon Hall5cfd23c2015-03-19 11:40:57 -07001018 if intentsResults and not consistentIntents:
1019 n = len(ONOSIntents)
1020 main.log.warn( "ONOS" + str( n ) + " intents: " )
1021 main.log.warn( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1022 sort_keys=True,
1023 indent=4,
1024 separators=( ',', ': ' ) ) )
1025 for i in range( numControllers ):
1026 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
1027 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1028 main.log.warn( json.dumps( json.loads( ONOSIntents[i] ),
1029 sort_keys=True,
1030 indent=4,
1031 separators=( ',', ': ' ) ) )
1032 else:
1033 main.log.warn( nodes[ i ].name + " intents match ONOS" +
1034 str( n ) + " intents" )
1035 elif intentsResults and consistentIntents:
1036 intentCheck = main.TRUE
1037 intentState = ONOSIntents[ 0 ]
1038
Jon Hall6aec96b2015-01-19 14:49:31 -08001039 main.step( "Get the flows from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001040 global flowState
1041 flowState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001042 ONOSFlows = []
1043 ONOSFlowsJson = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001044 flowCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001045 consistentFlows = True
1046 flowsResults = True
1047 threads = []
1048 for i in range( numControllers ):
1049 t = main.Thread( target=CLIs[i].flows,
1050 name="flows-" + str( i ),
1051 args=[],
1052 kwargs={ 'jsonFormat': True } )
1053 threads.append( t )
1054 t.start()
1055
Jon Halla9d26da2015-03-30 16:45:32 -07001056 # NOTE: Flows command can take some time to run
Jon Hall5cfd23c2015-03-19 11:40:57 -07001057 time.sleep(30)
1058 for t in threads:
1059 t.join()
1060 result = t.result
1061 ONOSFlows.append( result )
1062
1063 for i in range( numControllers ):
1064 num = str( i + 1 )
1065 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1066 main.log.report( "Error in getting ONOS" + num + " flows" )
1067 main.log.warn( "ONOS" + num + " flows response: " +
1068 repr( ONOSFlows[ i ] ) )
1069 flowsResults = False
1070 ONOSFlowsJson.append( None )
Jon Hall58c76b72015-02-23 11:09:24 -08001071 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001072 try:
1073 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1074 except ( ValueError, TypeError ):
1075 # FIXME: change this to log.error?
1076 main.log.exception( "Error in parsing ONOS" + num +
1077 " response as json." )
1078 main.log.error( repr( ONOSFlows[ i ] ) )
1079 ONOSFlowsJson.append( None )
1080 flowsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001081 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001082 expect=True,
1083 actual=flowsResults,
1084 onpass="No error in reading flows output",
1085 onfail="Error in reading flows from ONOS" )
1086
1087 main.step( "Check for consistency in Flows from each controller" )
1088 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1089 if all( tmp ):
1090 main.log.report( "Flow count is consistent across all ONOS nodes" )
1091 else:
1092 consistentFlows = False
1093 utilities.assert_equals(
1094 expect=True,
1095 actual=consistentFlows,
Jon Hall6aec96b2015-01-19 14:49:31 -08001096 onpass="The flow count is consistent across all ONOS nodes",
1097 onfail="ONOS nodes have different flow counts" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001098
Jon Hall5cfd23c2015-03-19 11:40:57 -07001099 if flowsResults and not consistentFlows:
1100 for i in range( numControllers ):
1101 try:
1102 main.log.warn(
1103 "ONOS" + str( i + 1 ) + " flows: " +
1104 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1105 indent=4, separators=( ',', ': ' ) ) )
1106 except ( ValueError, TypeError ):
1107 main.log.warn(
1108 "ONOS" + str( i + 1 ) + " flows: " +
1109 repr( ONOSFlows[ i ] ) )
1110 elif flowsResults and consistentFlows:
1111 flowCheck = main.TRUE
1112 flowState = ONOSFlows[ 0 ]
1113
Jon Hall6aec96b2015-01-19 14:49:31 -08001114 main.step( "Get the OF Table entries" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001115 global flows
Jon Hall6aec96b2015-01-19 14:49:31 -08001116 flows = []
1117 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001118 flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001119 if flowCheck == main.FALSE:
1120 for table in flows:
1121 main.log.warn( table )
Jon Hall6aec96b2015-01-19 14:49:31 -08001122 # TODO: Compare switch flow tables with ONOS flow tables
Jon Hall73cf9cc2014-11-20 22:28:38 -08001123
Jon Hall6aec96b2015-01-19 14:49:31 -08001124 main.step( "Start continuous pings" )
1125 main.Mininet2.pingLong(
1126 src=main.params[ 'PING' ][ 'source1' ],
1127 target=main.params[ 'PING' ][ 'target1' ],
1128 pingTime=500 )
1129 main.Mininet2.pingLong(
1130 src=main.params[ 'PING' ][ 'source2' ],
1131 target=main.params[ 'PING' ][ 'target2' ],
1132 pingTime=500 )
1133 main.Mininet2.pingLong(
1134 src=main.params[ 'PING' ][ 'source3' ],
1135 target=main.params[ 'PING' ][ 'target3' ],
1136 pingTime=500 )
1137 main.Mininet2.pingLong(
1138 src=main.params[ 'PING' ][ 'source4' ],
1139 target=main.params[ 'PING' ][ 'target4' ],
1140 pingTime=500 )
1141 main.Mininet2.pingLong(
1142 src=main.params[ 'PING' ][ 'source5' ],
1143 target=main.params[ 'PING' ][ 'target5' ],
1144 pingTime=500 )
1145 main.Mininet2.pingLong(
1146 src=main.params[ 'PING' ][ 'source6' ],
1147 target=main.params[ 'PING' ][ 'target6' ],
1148 pingTime=500 )
1149 main.Mininet2.pingLong(
1150 src=main.params[ 'PING' ][ 'source7' ],
1151 target=main.params[ 'PING' ][ 'target7' ],
1152 pingTime=500 )
1153 main.Mininet2.pingLong(
1154 src=main.params[ 'PING' ][ 'source8' ],
1155 target=main.params[ 'PING' ][ 'target8' ],
1156 pingTime=500 )
1157 main.Mininet2.pingLong(
1158 src=main.params[ 'PING' ][ 'source9' ],
1159 target=main.params[ 'PING' ][ 'target9' ],
1160 pingTime=500 )
1161 main.Mininet2.pingLong(
1162 src=main.params[ 'PING' ][ 'source10' ],
1163 target=main.params[ 'PING' ][ 'target10' ],
1164 pingTime=500 )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001165
Jon Hall6aec96b2015-01-19 14:49:31 -08001166 main.step( "Create TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001167 ctrls = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001168 for node in nodes:
1169 temp = ( node, node.name, node.ip_address, 6633 )
1170 ctrls.append( temp )
1171 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001172
Jon Hall6aec96b2015-01-19 14:49:31 -08001173 main.step( "Collecting topology information from ONOS" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001174 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001175 threads = []
1176 for i in range( numControllers ):
1177 t = main.Thread( target=CLIs[i].devices,
1178 name="devices-" + str( i ),
1179 args=[ ] )
1180 threads.append( t )
1181 t.start()
1182
1183 for t in threads:
1184 t.join()
1185 devices.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001186 hosts = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001187 threads = []
1188 for i in range( numControllers ):
1189 t = main.Thread( target=CLIs[i].hosts,
1190 name="hosts-" + str( i ),
1191 args=[ ] )
1192 threads.append( t )
1193 t.start()
1194
1195 for t in threads:
1196 t.join()
1197 try:
1198 hosts.append( json.loads( t.result ) )
1199 except ( ValueError, TypeError ):
1200 # FIXME: better handling of this, print which node
1201 # Maybe use thread name?
1202 main.log.exception( "Error parsing json output of hosts" )
1203 # FIXME: should this be an empty json object instead?
1204 hosts.append( None )
1205
Jon Hall73cf9cc2014-11-20 22:28:38 -08001206 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001207 threads = []
1208 for i in range( numControllers ):
1209 t = main.Thread( target=CLIs[i].ports,
1210 name="ports-" + str( i ),
1211 args=[ ] )
1212 threads.append( t )
1213 t.start()
1214
1215 for t in threads:
1216 t.join()
1217 ports.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001218 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001219 threads = []
1220 for i in range( numControllers ):
1221 t = main.Thread( target=CLIs[i].links,
1222 name="links-" + str( i ),
1223 args=[ ] )
1224 threads.append( t )
1225 t.start()
1226
1227 for t in threads:
1228 t.join()
1229 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001230 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001231 threads = []
1232 for i in range( numControllers ):
1233 t = main.Thread( target=CLIs[i].clusters,
1234 name="clusters-" + str( i ),
1235 args=[ ] )
1236 threads.append( t )
1237 t.start()
1238
1239 for t in threads:
1240 t.join()
1241 clusters.append( t.result )
Jon Hall529a37f2015-01-28 10:02:00 -08001242 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001243
Jon Hall6aec96b2015-01-19 14:49:31 -08001244 # hosts
Jon Hall8f89dda2015-01-22 16:03:33 -08001245 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001246 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001247 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001248 if "Error" not in hosts[ controller ]:
1249 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001250 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001251 else: # hosts not consistent
1252 main.log.report( "hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001253 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001254 " is inconsistent with ONOS1" )
1255 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001256 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001257
1258 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001259 main.log.report( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001260 controllerStr )
1261 consistentHostsResult = main.FALSE
1262 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001263 " hosts response: " +
1264 repr( hosts[ controller ] ) )
1265 utilities.assert_equals(
1266 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001267 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001268 onpass="Hosts view is consistent across all ONOS nodes",
1269 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001270
Jon Hall58c76b72015-02-23 11:09:24 -08001271 ipResult = main.TRUE
1272 for controller in range( 0, len( hosts ) ):
1273 controllerStr = str( controller + 1 )
1274 for host in hosts[ controller ]:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001275 if not host.get( 'ips', [ ] ):
1276 main.log.error( "DEBUG:Error with host ips on controller" +
1277 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001278 ipResult = main.FALSE
1279 utilities.assert_equals(
1280 expect=main.TRUE,
1281 actual=ipResult,
1282 onpass="The ips of the hosts aren't empty",
1283 onfail="The ip of at least one host is missing" )
1284
Jon Hall6aec96b2015-01-19 14:49:31 -08001285 # Strongly connected clusters of devices
Jon Hall8f89dda2015-01-22 16:03:33 -08001286 consistentClustersResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001287 for controller in range( len( clusters ) ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001288 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001289 if "Error" not in clusters[ controller ]:
1290 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001291 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001292 else: # clusters not consistent
Jon Hall5cfd23c2015-03-19 11:40:57 -07001293 main.log.report( "clusters from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001294 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001295 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001296
1297 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001298 main.log.report( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001299 "from ONOS" + controllerStr )
1300 consistentClustersResult = main.FALSE
1301 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001302 " clusters response: " +
1303 repr( clusters[ controller ] ) )
1304 utilities.assert_equals(
1305 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001306 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001307 onpass="Clusters view is consistent across all ONOS nodes",
1308 onfail="ONOS nodes have different views of clusters" )
1309 # there should always only be one cluster
Jon Hall5cfd23c2015-03-19 11:40:57 -07001310 try:
1311 numClusters = len( json.loads( clusters[ 0 ] ) )
1312 except ( ValueError, TypeError ):
1313 main.log.exception( "Error parsing clusters[0]: " +
1314 repr( clusters[ 0 ] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001315 clusterResults = main.FALSE
1316 if numClusters == 1:
1317 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001318 utilities.assert_equals(
1319 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08001320 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08001321 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08001322 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08001323
Jon Hall6aec96b2015-01-19 14:49:31 -08001324 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001325 devicesResults = main.TRUE
1326 portsResults = main.TRUE
1327 linksResults = main.TRUE
1328 for controller in range( numControllers ):
1329 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001330 if devices[ controller ] or "Error" not in devices[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001331 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08001332 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001333 json.loads( devices[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001334 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001335 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001336 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001337 actual=currentDevicesResult,
1338 onpass="ONOS" + controllerStr +
1339 " Switches view is correct",
1340 onfail="ONOS" + controllerStr +
1341 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001342
Jon Hall6aec96b2015-01-19 14:49:31 -08001343 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001344 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08001345 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001346 json.loads( ports[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001347 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001348 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001349 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001350 actual=currentPortsResult,
1351 onpass="ONOS" + controllerStr +
1352 " ports view is correct",
1353 onfail="ONOS" + controllerStr +
1354 " ports view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001355
Jon Hall6aec96b2015-01-19 14:49:31 -08001356 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001357 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08001358 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001359 json.loads( links[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001360 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001361 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001362 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001363 actual=currentLinksResult,
1364 onpass="ONOS" + controllerStr +
1365 " links view is correct",
1366 onfail="ONOS" + controllerStr +
1367 " links view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001368
Jon Hall8f89dda2015-01-22 16:03:33 -08001369 devicesResults = devicesResults and currentDevicesResult
1370 portsResults = portsResults and currentPortsResult
1371 linksResults = linksResults and currentLinksResult
Jon Hall73cf9cc2014-11-20 22:28:38 -08001372
Jon Hall5cfd23c2015-03-19 11:40:57 -07001373 topoResult = ( devicesResults and portsResults and linksResults
1374 and consistentHostsResult and consistentClustersResult
1375 and clusterResults and ipResult )
Jon Hall8f89dda2015-01-22 16:03:33 -08001376 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08001377 onpass="Topology Check Test successful",
1378 onfail="Topology Check Test NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001379
Jon Hall8f89dda2015-01-22 16:03:33 -08001380 finalAssert = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001381 finalAssert = ( finalAssert and topoResult and flowCheck
1382 and intentCheck and consistentMastership
Jon Halla9d26da2015-03-30 16:45:32 -07001383 and mastershipCheck and rolesNotNull )
Jon Hall8f89dda2015-01-22 16:03:33 -08001384 utilities.assert_equals( expect=main.TRUE, actual=finalAssert,
Jon Hall58c76b72015-02-23 11:09:24 -08001385 onpass="State check successful",
1386 onfail="State check NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001387
Jon Hall6aec96b2015-01-19 14:49:31 -08001388 def CASE6( self, main ):
1389 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001390 The Failure case.
Jon Hall6aec96b2015-01-19 14:49:31 -08001391 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07001392 assert numControllers, "numControllers not defined"
1393 assert main, "main not defined"
1394 assert utilities.assert_equals, "utilities.assert_equals not defined"
1395 assert CLIs, "CLIs not defined"
1396 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001397 main.log.report( "Restart entire ONOS cluster" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001398 main.case( "Restart entire ONOS cluster" )
1399 main.step( "Killing ONOS nodes" )
1400 killResults = main.TRUE
1401 for node in nodes:
1402 killed = main.ONOSbench.onosKill( node.ip_address )
1403 killResults = killResults and killed
Jon Hall73cf9cc2014-11-20 22:28:38 -08001404
Jon Hall6aec96b2015-01-19 14:49:31 -08001405 main.step( "Checking if ONOS is up yet" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001406 for i in range( 2 ):
1407 onosIsupResult = main.TRUE
1408 for node in nodes:
1409 started = main.ONOSbench.isup( node.ip_address )
1410 if not started:
1411 main.log.report( node.name + " didn't start!" )
1412 onosIsupResult = onosIsupResult and started
1413 if onosIsupResult == main.TRUE:
1414 break
Jon Hall73cf9cc2014-11-20 22:28:38 -08001415
Jon Hall5cfd23c2015-03-19 11:40:57 -07001416 main.log.step( "Starting ONOS CLI sessions" )
1417 cliResults = main.TRUE
1418 threads = []
1419 for i in range( numControllers ):
1420 t = main.Thread( target=CLIs[i].startOnosCli,
1421 name="startOnosCli-" + str( i ),
1422 args=[nodes[i].ip_address] )
1423 threads.append( t )
1424 t.start()
1425
1426 for t in threads:
1427 t.join()
1428 cliResults = cliResults and t.result
Jon Hall73cf9cc2014-11-20 22:28:38 -08001429
Jon Hall8f89dda2015-01-22 16:03:33 -08001430 caseResults = main.TRUE and onosIsupResult and cliResults
1431 utilities.assert_equals( expect=main.TRUE, actual=caseResults,
Jon Hall58c76b72015-02-23 11:09:24 -08001432 onpass="ONOS restart successful",
1433 onfail="ONOS restart NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001434
Jon Hall6aec96b2015-01-19 14:49:31 -08001435 def CASE7( self, main ):
1436 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001437 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -08001438 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001439 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001440 assert numControllers, "numControllers not defined"
1441 assert main, "main not defined"
1442 assert utilities.assert_equals, "utilities.assert_equals not defined"
1443 assert CLIs, "CLIs not defined"
1444 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001445 main.case( "Running ONOS Constant State Tests" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001446
Jon Hall5cfd23c2015-03-19 11:40:57 -07001447 main.step( "Check that each switch has a master" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001448 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -07001449 rolesNotNull = main.TRUE
1450 threads = []
1451 for i in range( numControllers ):
1452 t = main.Thread( target=CLIs[i].rolesNotNull,
1453 name="rolesNotNull-" + str( i ),
1454 args=[ ] )
1455 threads.append( t )
1456 t.start()
1457
1458 for t in threads:
1459 t.join()
1460 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001461 utilities.assert_equals(
1462 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001463 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001464 onpass="Each device has a master",
1465 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001466
Jon Hall5cfd23c2015-03-19 11:40:57 -07001467 ONOSMastership = []
1468 mastershipCheck = main.FALSE
1469 consistentMastership = True
1470 rolesResults = True
1471 threads = []
1472 for i in range( numControllers ):
1473 t = main.Thread( target=CLIs[i].roles,
1474 name="roles-" + str( i ),
1475 args=[] )
1476 threads.append( t )
1477 t.start()
1478
1479 for t in threads:
1480 t.join()
1481 ONOSMastership.append( t.result )
1482
1483 for i in range( numControllers ):
1484 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1485 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1486 " roles" )
1487 main.log.warn(
1488 "ONOS" + str( i + 1 ) + " mastership response: " +
1489 repr( ONOSMastership[i] ) )
1490 rolesResults = False
1491 utilities.assert_equals(
1492 expect=True,
1493 actual=rolesResults,
1494 onpass="No error in reading roles output",
1495 onfail="Error in reading roles from ONOS" )
1496
1497 main.step( "Check for consistency in roles from each controller" )
1498 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall6aec96b2015-01-19 14:49:31 -08001499 main.log.report(
1500 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001501 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001502 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001503 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001504 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001505 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001506 onpass="Switch roles are consistent across all ONOS nodes",
1507 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001508
Jon Hall5cfd23c2015-03-19 11:40:57 -07001509 if rolesResults and not consistentMastership:
1510 for i in range( numControllers ):
1511 main.log.warn(
1512 "ONOS" + str( i + 1 ) + " roles: ",
1513 json.dumps(
1514 json.loads( ONOSMastership[ i ] ),
1515 sort_keys=True,
1516 indent=4,
1517 separators=( ',', ': ' ) ) )
1518 elif rolesResults and not consistentMastership:
1519 mastershipCheck = main.TRUE
1520
Jon Hall73cf9cc2014-11-20 22:28:38 -08001521 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -08001522 main.step( description2 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001523 try:
1524 currentJson = json.loads( ONOSMastership[0] )
1525 oldJson = json.loads( mastershipState )
1526 except ( ValueError, TypeError ):
1527 main.log.exception( "Something is wrong with parsing " +
1528 "ONOSMastership[0] or mastershipState" )
1529 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1530 main.log.error( "mastershipState" + repr( mastershipState ) )
1531 main.cleanup()
1532 main.exit()
Jon Hall8f89dda2015-01-22 16:03:33 -08001533 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001534 for i in range( 1, 29 ):
1535 switchDPID = str(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001536 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001537 current = [ switch[ 'master' ] for switch in currentJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001538 if switchDPID in switch[ 'id' ] ]
Jon Hall8f89dda2015-01-22 16:03:33 -08001539 old = [ switch[ 'master' ] for switch in oldJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001540 if switchDPID in switch[ 'id' ] ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08001541 if current == old:
Jon Hall8f89dda2015-01-22 16:03:33 -08001542 mastershipCheck = mastershipCheck and main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001543 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001544 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall8f89dda2015-01-22 16:03:33 -08001545 mastershipCheck = main.FALSE
1546 if mastershipCheck == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001547 main.log.report( "Mastership of Switches was not changed" )
1548 utilities.assert_equals(
1549 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001550 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -08001551 onpass="Mastership of Switches was not changed",
1552 onfail="Mastership of some switches changed" )
1553 # NOTE: we expect mastership to change on controller failure
Jon Hall8f89dda2015-01-22 16:03:33 -08001554 mastershipCheck = mastershipCheck and consistentMastership
Jon Hall73cf9cc2014-11-20 22:28:38 -08001555
Jon Hall6aec96b2015-01-19 14:49:31 -08001556 main.step( "Get the intents and compare across all nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001557 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001558 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001559 consistentIntents = True
1560 intentsResults = True
1561 threads = []
1562 for i in range( numControllers ):
1563 t = main.Thread( target=CLIs[i].intents,
1564 name="intents-" + str( i ),
1565 args=[],
1566 kwargs={ 'jsonFormat': True } )
1567 threads.append( t )
1568 t.start()
1569
1570 for t in threads:
1571 t.join()
1572 ONOSIntents.append( t.result )
1573
1574 for i in range( numControllers ):
1575 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1576 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1577 " intents" )
1578 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1579 repr( ONOSIntents[ i ] ) )
1580 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001581 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001582 expect=True,
1583 actual=intentsResults,
1584 onpass="No error in reading intents output",
1585 onfail="Error in reading intents from ONOS" )
1586
1587 main.step( "Check for consistency in Intents from each controller" )
1588 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1589 main.log.report( "Intents are consistent across all ONOS " +
1590 "nodes" )
1591 else:
1592 consistentIntents = False
1593 utilities.assert_equals(
1594 expect=True,
1595 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001596 onpass="Intents are consistent across all ONOS nodes",
1597 onfail="ONOS nodes have different views of intents" )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001598 intentStates = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001599 for node in ONOSIntents: # Iter through ONOS nodes
Jon Hall1b8f54a2015-02-04 13:24:20 -08001600 nodeStates = []
Jon Hall58c76b72015-02-23 11:09:24 -08001601 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001602 try:
1603 for intent in json.loads( node ):
1604 nodeStates.append( intent[ 'state' ] )
1605 except ( ValueError, TypeError ):
1606 main.log.exception( "Error in parsing intents" )
1607 main.log.error( repr( node ) )
Jon Hall1b8f54a2015-02-04 13:24:20 -08001608 intentStates.append( nodeStates )
1609 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1610 main.log.info( dict( out ) )
1611
Jon Hall5cfd23c2015-03-19 11:40:57 -07001612 if intentsResults and not consistentIntents:
1613 for i in range( numControllers ):
1614 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1615 main.log.warn( json.dumps(
1616 json.loads( ONOSIntents[ i ] ),
1617 sort_keys=True,
1618 indent=4,
1619 separators=( ',', ': ' ) ) )
1620 elif intentsResults and consistentIntents:
1621 intentCheck = main.TRUE
1622
Jon Hall58c76b72015-02-23 11:09:24 -08001623 # NOTE: Store has no durability, so intents are lost across system
1624 # restarts
Jon Hall6aec96b2015-01-19 14:49:31 -08001625 """
1626 main.step( "Compare current intents with intents before the failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001627 # NOTE: this requires case 5 to pass for intentState to be set.
Jon Hall94fd0472014-12-08 11:52:42 -08001628 # maybe we should stop the test if that fails?
Jon Hall1b8f54a2015-02-04 13:24:20 -08001629 sameIntents = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001630 if intentState and intentState == ONOSIntents[ 0 ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001631 sameIntents = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001632 main.log.report( "Intents are consistent with before failure" )
1633 # TODO: possibly the states have changed? we may need to figure out
Jon Hall5cfd23c2015-03-19 11:40:57 -07001634 # what the acceptable states are
Jon Hall73cf9cc2014-11-20 22:28:38 -08001635 else:
Jon Hall669173b2014-12-17 11:36:30 -08001636 try:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001637 main.log.warn( "ONOS intents: " )
1638 main.log.warn( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1639 sort_keys=True, indent=4,
1640 separators=( ',', ': ' ) ) )
1641 except ( ValueError, TypeError ):
1642 main.log.exception( "Exception printing intents" )
1643 main.log.warn( repr( ONOSIntents[0] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001644 sameIntents = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001645 utilities.assert_equals(
1646 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001647 actual=sameIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001648 onpass="Intents are consistent with before failure",
1649 onfail="The Intents changed during failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001650 intentCheck = intentCheck and sameIntents
Jon Hall6aec96b2015-01-19 14:49:31 -08001651 """
1652 main.step( "Get the OF Table entries and compare to before " +
1653 "component failure" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001654 FlowTables = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001655 flows2 = []
1656 for i in range( 28 ):
1657 main.log.info( "Checking flow table on s" + str( i + 1 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001658 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
1659 flows2.append( tmpFlows )
1660 tempResult = main.Mininet2.flowComp(
Jon Hall6aec96b2015-01-19 14:49:31 -08001661 flow1=flows[ i ],
Jon Hall8f89dda2015-01-22 16:03:33 -08001662 flow2=tmpFlows )
1663 FlowTables = FlowTables and tempResult
1664 if FlowTables == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001665 main.log.info( "Differences in flow table for switch: s" +
1666 str( i + 1 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001667 if FlowTables == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001668 main.log.report( "No changes were found in the flow tables" )
1669 utilities.assert_equals(
1670 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001671 actual=FlowTables,
Jon Hall6aec96b2015-01-19 14:49:31 -08001672 onpass="No changes were found in the flow tables",
1673 onfail="Changes were found in the flow tables" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001674
Jon Hall6aec96b2015-01-19 14:49:31 -08001675 main.step( "Check the continuous pings to ensure that no packets " +
1676 "were dropped during component failure" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001677 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
1678 main.params[ 'TESTONIP' ] )
Jon Hall8f89dda2015-01-22 16:03:33 -08001679 LossInPings = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001680 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
1681 for i in range( 8, 18 ):
1682 main.log.info(
1683 "Checking for a loss in pings along flow from s" +
1684 str( i ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001685 LossInPings = main.Mininet2.checkForLoss(
Jon Hall6aec96b2015-01-19 14:49:31 -08001686 "/tmp/ping.h" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001687 str( i ) ) or LossInPings
1688 if LossInPings == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001689 main.log.info( "Loss in ping detected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001690 elif LossInPings == main.ERROR:
Jon Hall6aec96b2015-01-19 14:49:31 -08001691 main.log.info( "There are multiple mininet process running" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001692 elif LossInPings == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001693 main.log.info( "No Loss in the pings" )
1694 main.log.report( "No loss of dataplane connectivity" )
1695 utilities.assert_equals(
1696 expect=main.FALSE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001697 actual=LossInPings,
Jon Hall6aec96b2015-01-19 14:49:31 -08001698 onpass="No Loss of connectivity",
1699 onfail="Loss of dataplane connectivity detected" )
Jon Hall58c76b72015-02-23 11:09:24 -08001700 # NOTE: Since intents are not persisted with IntnentStore,
1701 # we expect loss in dataplane connectivity
Jon Hall8f89dda2015-01-22 16:03:33 -08001702 LossInPings = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001703
Jon Hall6aec96b2015-01-19 14:49:31 -08001704 # Test of LeadershipElection
Jon Hall8f89dda2015-01-22 16:03:33 -08001705 leaderList = []
1706 leaderResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001707 for cli in CLIs:
1708 leaderN = cli.electionTestLeader()
Jon Hall8f89dda2015-01-22 16:03:33 -08001709 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08001710 if leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001711 # error in response
1712 main.log.report( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001713 "electionTestLeader function, check the" +
Jon Hall6aec96b2015-01-19 14:49:31 -08001714 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001715 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001716 elif leaderN is None:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001717 main.log.report( cli.name +
Jon Hall6aec96b2015-01-19 14:49:31 -08001718 " shows no leader for the election-app was" +
1719 " elected after the old one died" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001720 leaderResult = main.FALSE
1721 if len( set( leaderList ) ) != 1:
1722 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001723 main.log.error(
1724 "Inconsistent view of leader for the election test app" )
1725 # TODO: print the list
Jon Hall8f89dda2015-01-22 16:03:33 -08001726 if leaderResult:
1727 main.log.report( "Leadership election tests passed( consistent " +
Jon Hall6aec96b2015-01-19 14:49:31 -08001728 "view of leader across listeners and a new " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001729 "leader was re-elected if applicable )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001730 utilities.assert_equals(
1731 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001732 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001733 onpass="Leadership election passed",
1734 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08001735
Jon Hall8f89dda2015-01-22 16:03:33 -08001736 result = ( mastershipCheck and intentCheck and FlowTables and
1737 ( not LossInPings ) and rolesNotNull and leaderResult )
Jon Hall6aec96b2015-01-19 14:49:31 -08001738 result = int( result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001739 if result == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001740 main.log.report( "Constant State Tests Passed" )
1741 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall58c76b72015-02-23 11:09:24 -08001742 onpass="Constant State Tests Passed",
1743 onfail="Constant state tests failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001744
Jon Hall6aec96b2015-01-19 14:49:31 -08001745 def CASE8( self, main ):
1746 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001747 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -08001748 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001749 import sys
Jon Hall6aec96b2015-01-19 14:49:31 -08001750 # FIXME add this path to params
1751 sys.path.append( "/home/admin/sts" )
1752 # assumes that sts is already in you PYTHONPATH
1753 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -08001754 import json
1755 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001756 assert numControllers, "numControllers not defined"
1757 assert main, "main not defined"
1758 assert utilities.assert_equals, "utilities.assert_equals not defined"
1759 assert CLIs, "CLIs not defined"
1760 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08001761
Jon Hall6aec96b2015-01-19 14:49:31 -08001762 description = "Compare ONOS Topology view to Mininet topology"
1763 main.case( description )
1764 main.log.report( description )
1765 main.step( "Create TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001766 ctrls = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001767 for node in nodes:
1768 temp = ( node, node.name, node.ip_address, 6633 )
1769 ctrls.append( temp )
1770 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001771
Jon Hall6aec96b2015-01-19 14:49:31 -08001772 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001773 devicesResults = main.TRUE
1774 portsResults = main.TRUE
1775 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08001776 hostsResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08001777 topoResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001778 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -08001779 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -08001780 main.step( "Collecting topology information from ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001781 startTime = time.time()
Jon Hall21270ac2015-02-16 17:59:55 -08001782 # Give time for Gossip to work
Jon Hall8f89dda2015-01-22 16:03:33 -08001783 while topoResult == main.FALSE and elapsed < 60:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001784 count += 1
Jon Hall94fd0472014-12-08 11:52:42 -08001785 if count > 1:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001786 # TODO: Deprecate STS usage
Jon Hall58c76b72015-02-23 11:09:24 -08001787 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall8f89dda2015-01-22 16:03:33 -08001788 cliStart = time.time()
Jon Hall94fd0472014-12-08 11:52:42 -08001789 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001790 threads = []
1791 for i in range( numControllers ):
1792 t = main.Thread( target=CLIs[i].devices,
1793 name="devices-" + str( i ),
1794 args=[ ] )
1795 threads.append( t )
1796 t.start()
1797
1798 for t in threads:
1799 t.join()
1800 devices.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001801 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -08001802 ipResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001803 threads = []
1804 for i in range( numControllers ):
1805 t = main.Thread( target=CLIs[i].hosts,
1806 name="hosts-" + str( i ),
1807 args=[ ] )
1808 threads.append( t )
1809 t.start()
1810
1811 for t in threads:
1812 t.join()
1813 try:
1814 hosts.append( json.loads( t.result ) )
1815 except ( ValueError, TypeError ):
1816 main.log.exception( "Error parsing hosts results" )
1817 main.log.error( repr( t.result ) )
Jon Hall529a37f2015-01-28 10:02:00 -08001818 for controller in range( 0, len( hosts ) ):
1819 controllerStr = str( controller + 1 )
1820 for host in hosts[ controller ]:
Jon Hall58c76b72015-02-23 11:09:24 -08001821 if host is None or host.get( 'ips', [] ) == []:
Jon Hall529a37f2015-01-28 10:02:00 -08001822 main.log.error(
1823 "DEBUG:Error with host ips on controller" +
1824 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001825 ipResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001826 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001827 threads = []
1828 for i in range( numControllers ):
1829 t = main.Thread( target=CLIs[i].ports,
1830 name="ports-" + str( i ),
1831 args=[ ] )
1832 threads.append( t )
1833 t.start()
1834
1835 for t in threads:
1836 t.join()
1837 ports.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001838 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001839 threads = []
1840 for i in range( numControllers ):
1841 t = main.Thread( target=CLIs[i].links,
1842 name="links-" + str( i ),
1843 args=[ ] )
1844 threads.append( t )
1845 t.start()
1846
1847 for t in threads:
1848 t.join()
1849 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001850 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001851 threads = []
1852 for i in range( numControllers ):
1853 t = main.Thread( target=CLIs[i].clusters,
1854 name="clusters-" + str( i ),
1855 args=[ ] )
1856 threads.append( t )
1857 t.start()
1858
1859 for t in threads:
1860 t.join()
1861 clusters.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001862
Jon Hall8f89dda2015-01-22 16:03:33 -08001863 elapsed = time.time() - startTime
1864 cliTime = time.time() - cliStart
1865 print "CLI time: " + str( cliTime )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001866
Jon Hall8f89dda2015-01-22 16:03:33 -08001867 for controller in range( numControllers ):
1868 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001869 if devices[ controller ] or "Error" not in devices[
1870 controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001871 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08001872 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08001873 json.loads( devices[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001874 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001875 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001876 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001877 actual=currentDevicesResult,
1878 onpass="ONOS" + controllerStr +
1879 " Switches view is correct",
1880 onfail="ONOS" + controllerStr +
1881 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001882
Jon Hall6aec96b2015-01-19 14:49:31 -08001883 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001884 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08001885 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08001886 json.loads( ports[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001887 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001888 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001889 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001890 actual=currentPortsResult,
1891 onpass="ONOS" + controllerStr +
1892 " ports view is correct",
1893 onfail="ONOS" + controllerStr +
1894 " ports view is incorrect" )
Jon Hall94fd0472014-12-08 11:52:42 -08001895
Jon Hall6aec96b2015-01-19 14:49:31 -08001896 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001897 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08001898 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08001899 json.loads( links[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001900 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001901 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001902 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001903 actual=currentLinksResult,
1904 onpass="ONOS" + controllerStr +
1905 " links view is correct",
1906 onfail="ONOS" + controllerStr +
1907 " links view is incorrect" )
1908
1909 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1910 currentHostsResult = main.Mininet1.compareHosts(
1911 MNTopo, hosts[ controller ] )
1912 else:
1913 currentHostsResult = main.FALSE
1914 utilities.assert_equals( expect=main.TRUE,
1915 actual=currentHostsResult,
1916 onpass="ONOS" + controllerStr +
1917 " hosts exist in Mininet",
1918 onfail="ONOS" + controllerStr +
1919 " hosts don't match Mininet" )
1920
1921 devicesResults = devicesResults and currentDevicesResult
1922 portsResults = portsResults and currentPortsResult
1923 linksResults = linksResults and currentLinksResult
1924 hostsResults = hostsResults and currentHostsResult
Jon Hall94fd0472014-12-08 11:52:42 -08001925
Jon Hall529a37f2015-01-28 10:02:00 -08001926 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001927
Jon Hall6aec96b2015-01-19 14:49:31 -08001928 # hosts
Jon Hall8f89dda2015-01-22 16:03:33 -08001929 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001930 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001931 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001932 if "Error" not in hosts[ controller ]:
1933 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001934 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001935 else: # hosts not consistent
Jon Hall8f89dda2015-01-22 16:03:33 -08001936 main.log.report( "hosts from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001937 " is inconsistent with ONOS1" )
1938 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001939 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001940
1941 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001942 main.log.report( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001943 controllerStr )
1944 consistentHostsResult = main.FALSE
1945 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001946 " hosts response: " +
1947 repr( hosts[ controller ] ) )
1948 utilities.assert_equals(
1949 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001950 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001951 onpass="Hosts view is consistent across all ONOS nodes",
1952 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001953
Jon Hall6aec96b2015-01-19 14:49:31 -08001954 # Strongly connected clusters of devices
Jon Hall8f89dda2015-01-22 16:03:33 -08001955 consistentClustersResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001956 for controller in range( len( clusters ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001957 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001958 if "Error" not in clusters[ controller ]:
1959 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001960 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001961 else: # clusters not consistent
1962 main.log.report( "clusters from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001963 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001964 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001965 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001966
1967 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001968 main.log.report( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001969 "from ONOS" + controllerStr )
1970 consistentClustersResult = main.FALSE
1971 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001972 " clusters response: " +
1973 repr( clusters[ controller ] ) )
1974 utilities.assert_equals(
1975 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001976 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001977 onpass="Clusters view is consistent across all ONOS nodes",
1978 onfail="ONOS nodes have different views of clusters" )
1979 # there should always only be one cluster
Jon Hall5cfd23c2015-03-19 11:40:57 -07001980 try:
1981 numClusters = len( json.loads( clusters[ 0 ] ) )
1982 except ( ValueError, TypeError ):
1983 main.log.exception( "Error parsing clusters[0]: " +
1984 repr( clusters[0] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001985 clusterResults = main.FALSE
1986 if numClusters == 1:
1987 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001988 utilities.assert_equals(
1989 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08001990 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08001991 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08001992 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08001993
Jon Hall8f89dda2015-01-22 16:03:33 -08001994 topoResult = ( devicesResults and portsResults and linksResults
Jon Hall58c76b72015-02-23 11:09:24 -08001995 and hostsResults and consistentHostsResult
1996 and consistentClustersResult and clusterResults
1997 and ipResult )
Jon Hall94fd0472014-12-08 11:52:42 -08001998
Jon Hall8f89dda2015-01-22 16:03:33 -08001999 topoResult = topoResult and int( count <= 2 )
2000 note = "note it takes about " + str( int( cliTime ) ) + \
2001 " seconds for the test to make all the cli calls to fetch " +\
2002 "the topology from each ONOS instance"
Jon Hall1b8f54a2015-02-04 13:24:20 -08002003 main.log.info(
Jon Hall8f89dda2015-01-22 16:03:33 -08002004 "Very crass estimate for topology discovery/convergence( " +
2005 str( note ) + " ): " + str( elapsed ) + " seconds, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002006 str( count ) + " tries" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002007 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08002008 onpass="Topology Check Test successful",
2009 onfail="Topology Check Test NOT successful" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002010 if topoResult == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002011 main.log.report( "ONOS topology view matches Mininet topology" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002012
Jon Halla9d26da2015-03-30 16:45:32 -07002013 # FIXME: move this to an ONOS state case
2014 main.step( "Checking ONOS nodes" )
2015 nodesOutput = []
2016 threads = []
2017 for i in range( numControllers ):
2018 t = main.Thread( target=CLIs[i].nodes,
2019 name="nodes-" + str( i ),
2020 args=[ ] )
2021 threads.append( t )
2022 t.start()
2023
2024 for t in threads:
2025 t.join()
2026 nodesOutput.append( t.result )
2027 ips = [ node.ip_address for node in nodes ]
2028 for i in nodesOutput:
2029 try:
2030 current = json.loads( i )
2031 for node in current:
2032 if node['ip'] in ips: # node in nodes() output is in cell
2033 if node['state'] == 'ACTIVE':
2034 pass # as it should be
2035 else:
2036 main.log.error( "Error in ONOS node availability" )
2037 main.log.error(
2038 json.dumps( current,
2039 sort_keys=True,
2040 indent=4,
2041 separators=( ',', ': ' ) ) )
2042 break
2043 except ( ValueError, TypeError ):
2044 main.log.error( "Error parsing nodes output" )
2045 main.log.warn( repr( i ) )
2046
Jon Hall6aec96b2015-01-19 14:49:31 -08002047 def CASE9( self, main ):
2048 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002049 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -08002050 """
2051 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002052 assert numControllers, "numControllers not defined"
2053 assert main, "main not defined"
2054 assert utilities.assert_equals, "utilities.assert_equals not defined"
2055 assert CLIs, "CLIs not defined"
2056 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002057 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002058
Jon Hall8f89dda2015-01-22 16:03:33 -08002059 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002060
Jon Hall6aec96b2015-01-19 14:49:31 -08002061 description = "Turn off a link to ensure that Link Discovery " +\
Jon Hall58c76b72015-02-23 11:09:24 -08002062 "is working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002063 main.log.report( description )
2064 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002065
Jon Hall6aec96b2015-01-19 14:49:31 -08002066 main.step( "Kill Link between s3 and s28" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002067 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
Jon Hall58c76b72015-02-23 11:09:24 -08002068 main.log.info( "Waiting " + str( linkSleep ) +
2069 " seconds for link down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002070 time.sleep( linkSleep )
2071 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002072 onpass="Link down successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002073 onfail="Failed to bring link down" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002074 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002075
Jon Hall6aec96b2015-01-19 14:49:31 -08002076 def CASE10( self, main ):
2077 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002078 Link s3-s28 up
Jon Hall6aec96b2015-01-19 14:49:31 -08002079 """
2080 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002081 assert numControllers, "numControllers not defined"
2082 assert main, "main not defined"
2083 assert utilities.assert_equals, "utilities.assert_equals not defined"
2084 assert CLIs, "CLIs not defined"
2085 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002086 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002087
Jon Hall8f89dda2015-01-22 16:03:33 -08002088 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002089
Jon Hall6aec96b2015-01-19 14:49:31 -08002090 description = "Restore a link to ensure that Link Discovery is " + \
Jon Hall63604932015-02-26 17:09:50 -08002091 "working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002092 main.log.report( description )
2093 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002094
Jon Hall6aec96b2015-01-19 14:49:31 -08002095 main.step( "Bring link between s3 and s28 back up" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002096 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
Jon Hall58c76b72015-02-23 11:09:24 -08002097 main.log.info( "Waiting " + str( linkSleep ) +
2098 " seconds for link up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002099 time.sleep( linkSleep )
2100 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002101 onpass="Link up successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002102 onfail="Failed to bring link up" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002103 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002104
Jon Hall6aec96b2015-01-19 14:49:31 -08002105 def CASE11( self, main ):
2106 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002107 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -08002108 """
2109 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002110 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002111 assert numControllers, "numControllers not defined"
2112 assert main, "main not defined"
2113 assert utilities.assert_equals, "utilities.assert_equals not defined"
2114 assert CLIs, "CLIs not defined"
2115 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08002116
Jon Hall8f89dda2015-01-22 16:03:33 -08002117 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002118
2119 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002120 main.log.report( description )
2121 main.case( description )
2122 switch = main.params[ 'kill' ][ 'switch' ]
2123 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08002124
Jon Hall6aec96b2015-01-19 14:49:31 -08002125 # TODO: Make this switch parameterizable
2126 main.step( "Kill " + switch )
2127 main.log.report( "Deleting " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002128 main.Mininet1.delSwitch( switch )
2129 main.log.info( "Waiting " + str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002130 " seconds for switch down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002131 time.sleep( switchSleep )
2132 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002133 # Peek at the deleted switch
2134 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002135 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002136 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -08002137 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002138 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002139 onpass="Kill switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002140 onfail="Failed to kill switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002141
Jon Hall6aec96b2015-01-19 14:49:31 -08002142 def CASE12( self, main ):
2143 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002144 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -08002145 """
2146 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002147 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002148 assert numControllers, "numControllers not defined"
2149 assert main, "main not defined"
2150 assert utilities.assert_equals, "utilities.assert_equals not defined"
2151 assert CLIs, "CLIs not defined"
2152 assert nodes, "nodes not defined"
2153 assert ONOS1Port, "ONOS1Port not defined"
2154 assert ONOS2Port, "ONOS2Port not defined"
2155 assert ONOS3Port, "ONOS3Port not defined"
2156 assert ONOS4Port, "ONOS4Port not defined"
2157 assert ONOS5Port, "ONOS5Port not defined"
2158 assert ONOS6Port, "ONOS6Port not defined"
2159 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall669173b2014-12-17 11:36:30 -08002160
Jon Hall8f89dda2015-01-22 16:03:33 -08002161 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall6aec96b2015-01-19 14:49:31 -08002162 switch = main.params[ 'kill' ][ 'switch' ]
2163 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2164 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002165 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002166 main.log.report( description )
2167 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002168
Jon Hall6aec96b2015-01-19 14:49:31 -08002169 main.step( "Add back " + switch )
2170 main.log.report( "Adding back " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002171 main.Mininet1.addSwitch( switch, dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002172 for peer in links:
Jon Hall8f89dda2015-01-22 16:03:33 -08002173 main.Mininet1.addLink( switch, peer )
Jon Hall58c76b72015-02-23 11:09:24 -08002174 main.Mininet1.assignSwController( sw=switch.split( 's' )[ 1 ],
2175 count=numControllers,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002176 ip1=nodes[ 0 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002177 port1=ONOS1Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002178 ip2=nodes[ 1 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002179 port2=ONOS2Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002180 ip3=nodes[ 2 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002181 port3=ONOS3Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002182 ip4=nodes[ 3 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002183 port4=ONOS4Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002184 ip5=nodes[ 4 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002185 port5=ONOS5Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002186 ip6=nodes[ 5 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002187 port6=ONOS6Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002188 ip7=nodes[ 6 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002189 port7=ONOS7Port )
2190 main.log.info( "Waiting " + str( switchSleep ) +
2191 " seconds for switch up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002192 time.sleep( switchSleep )
2193 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002194 # Peek at the deleted switch
2195 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002196 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002197 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002198 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002199 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002200 onpass="add switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002201 onfail="Failed to add switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002202
Jon Hall6aec96b2015-01-19 14:49:31 -08002203 def CASE13( self, main ):
2204 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002205 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -08002206 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002207 import os
2208 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002209 assert numControllers, "numControllers not defined"
2210 assert main, "main not defined"
2211 assert utilities.assert_equals, "utilities.assert_equals not defined"
2212 assert CLIs, "CLIs not defined"
2213 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002214
2215 # printing colors to terminal
Jon Hall5cfd23c2015-03-19 11:40:57 -07002216 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2217 'blue': '\033[94m', 'green': '\033[92m',
2218 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
Jon Hall73cf9cc2014-11-20 22:28:38 -08002219 description = "Test Cleanup"
Jon Hall6aec96b2015-01-19 14:49:31 -08002220 main.log.report( description )
2221 main.case( description )
2222 main.step( "Killing tcpdumps" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002223 main.Mininet2.stopTcpdump()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002224
Jon Hall6aec96b2015-01-19 14:49:31 -08002225 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002226 testname = main.TEST
Jon Hall8f89dda2015-01-22 16:03:33 -08002227 teststationUser = main.params[ 'TESTONUSER' ]
2228 teststationIP = main.params[ 'TESTONIP' ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002229 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -08002230 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -08002231 # FIXME: scp
2232 # mn files
2233 # TODO: Load these from params
2234 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002235 logFolder = "/opt/onos/log/"
2236 logFiles = [ "karaf.log", "karaf.log.1" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002237 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002238 dstDir = "~/packet_captures/"
2239 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002240 for node in nodes:
2241 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2242 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002243 teststationUser + "@" +
2244 teststationIP + ":" +
2245 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002246 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002247 main.ONOSbench.handle.expect( "\$" )
2248
Jon Hall6aec96b2015-01-19 14:49:31 -08002249 # std*.log's
2250 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002251 logFolder = "/opt/onos/var/"
2252 logFiles = [ "stderr.log", "stdout.log" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002253 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002254 dstDir = "~/packet_captures/"
2255 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002256 for node in nodes:
2257 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2258 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002259 teststationUser + "@" +
2260 teststationIP + ":" +
2261 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002262 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002263 main.ONOSbench.handle.expect( "\$" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002264 # sleep so scp can finish
2265 time.sleep( 10 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002266
2267 main.step( "Stopping Mininet" )
Jon Hall58c76b72015-02-23 11:09:24 -08002268 main.Mininet1.stopNet()
Jon Hall5cfd23c2015-03-19 11:40:57 -07002269
2270 main.step( "Checking ONOS Logs for errors" )
2271 for node in nodes:
2272 print colors[ 'purple' ] + "Checking logs for errors on " + \
2273 node.name + ":" + colors[ 'end' ]
2274 print main.ONOSbench.checkLogs( node.ip_address )
2275
Jon Hall6aec96b2015-01-19 14:49:31 -08002276 main.step( "Packing and rotating pcap archives" )
2277 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002278
Jon Hall6aec96b2015-01-19 14:49:31 -08002279 # TODO: actually check something here
2280 utilities.assert_equals( expect=main.TRUE, actual=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002281 onpass="Test cleanup successful",
2282 onfail="Test cleanup NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002283
Jon Hall6aec96b2015-01-19 14:49:31 -08002284 def CASE14( self, main ):
2285 """
Jon Hall669173b2014-12-17 11:36:30 -08002286 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -08002287 """
Jon Halla9d26da2015-03-30 16:45:32 -07002288 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002289 assert numControllers, "numControllers not defined"
2290 assert main, "main not defined"
2291 assert utilities.assert_equals, "utilities.assert_equals not defined"
2292 assert CLIs, "CLIs not defined"
2293 assert nodes, "nodes not defined"
2294
Jon Hall8f89dda2015-01-22 16:03:33 -08002295 leaderResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002296 main.log.info( "Install leadership election app" )
Jon Halla9d26da2015-03-30 16:45:32 -07002297 main.ONOScli1.activateApp( "org.onosproject.election" )
2298 leaders = []
2299 for cli in CLIs:
2300 leader = cli.electionTestLeader()
2301 if leader is None or leader == main.FALSE:
2302 main.log.report( cli.name + ": Leader for the election app " +
2303 "should be an ONOS node, instead got '" +
2304 str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002305 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002306 leaders.append( leader )
2307 if len( set( leaders ) ) != 1:
2308 leaderResult = main.FALSE
2309 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2310 str( leaders ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08002311 if leaderResult:
Jon Hall6aec96b2015-01-19 14:49:31 -08002312 main.log.report( "Leadership election tests passed( consistent " +
2313 "view of leader across listeners and a leader " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002314 "was elected )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002315 utilities.assert_equals(
2316 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002317 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002318 onpass="Leadership election passed",
2319 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002320
Jon Hall6aec96b2015-01-19 14:49:31 -08002321 def CASE15( self, main ):
2322 """
Jon Hall669173b2014-12-17 11:36:30 -08002323 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08002324 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07002325 assert numControllers, "numControllers not defined"
2326 assert main, "main not defined"
2327 assert utilities.assert_equals, "utilities.assert_equals not defined"
2328 assert CLIs, "CLIs not defined"
2329 assert nodes, "nodes not defined"
2330
Jon Hall8f89dda2015-01-22 16:03:33 -08002331 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002332 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08002333 main.log.report( description )
2334 main.case( description )
2335 main.step( "Find current leader and withdraw" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002336 leader = main.ONOScli1.electionTestLeader()
Jon Halla9d26da2015-03-30 16:45:32 -07002337 # do some sanity checking on leader before using it
Jon Hall8f89dda2015-01-22 16:03:33 -08002338 withdrawResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002339 if leader is None or leader == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002340 main.log.report(
2341 "Leader for the election app should be an ONOS node," +
Jon Hall58c76b72015-02-23 11:09:24 -08002342 "instead got '" + str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002343 leaderResult = main.FALSE
Jon Hall63604932015-02-26 17:09:50 -08002344 oldLeader = None
Jon Hall5cfd23c2015-03-19 11:40:57 -07002345 for i in range( len( CLIs ) ):
2346 if leader == nodes[ i ].ip_address:
2347 oldLeader = CLIs[ i ]
2348 break
Jon Halla9d26da2015-03-30 16:45:32 -07002349 else: # FOR/ELSE statement
Jon Hall5cfd23c2015-03-19 11:40:57 -07002350 main.log.error( "Leader election, could not find current leader" )
Jon Hall63604932015-02-26 17:09:50 -08002351 if oldLeader:
2352 withdrawResult = oldLeader.electionTestWithdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08002353 utilities.assert_equals(
2354 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002355 actual=withdrawResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002356 onpass="App was withdrawn from election",
2357 onfail="App was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08002358
Jon Hall6aec96b2015-01-19 14:49:31 -08002359 main.step( "Make sure new leader is elected" )
Jon Halla9d26da2015-03-30 16:45:32 -07002360 # FIXME: use threads
Jon Hall8f89dda2015-01-22 16:03:33 -08002361 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002362 for cli in CLIs:
2363 leaderN = cli.electionTestLeader()
2364 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002365 if leaderN == leader:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002366 main.log.report( cli.name + " still sees " + str( leader ) +
2367 " as leader after they withdrew" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002368 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002369 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002370 # error in response
2371 # TODO: add check for "Command not found:" in the driver, this
Jon Hall5cfd23c2015-03-19 11:40:57 -07002372 # means the app isn't loaded
Jon Hall6aec96b2015-01-19 14:49:31 -08002373 main.log.report( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002374 "electionTestLeader function, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002375 "check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002376 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002377 elif leaderN is None:
2378 # node may not have recieved the event yet
2379 leaderN = cli.electionTestLeader()
2380 leaderList.pop()
2381 leaderList.append( leaderN )
Jon Hall8f89dda2015-01-22 16:03:33 -08002382 consistentLeader = main.FALSE
2383 if len( set( leaderList ) ) == 1:
Jon Hall6aec96b2015-01-19 14:49:31 -08002384 main.log.info( "Each Election-app sees '" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002385 str( leaderList[ 0 ] ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002386 "' as the leader" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002387 consistentLeader = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002388 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08002389 main.log.report(
2390 "Inconsistent responses for leader of Election-app:" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002391 for n in range( len( leaderList ) ):
Jon Hall6aec96b2015-01-19 14:49:31 -08002392 main.log.report( "ONOS" + str( n + 1 ) + " response: " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002393 str( leaderList[ n ] ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002394 leaderResult = leaderResult and consistentLeader
Jon Hall8f89dda2015-01-22 16:03:33 -08002395 if leaderResult:
2396 main.log.report( "Leadership election tests passed( consistent " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002397 "view of leader across listeners and a new " +
2398 "leader was elected when the old leader " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002399 "resigned )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002400 utilities.assert_equals(
2401 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002402 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002403 onpass="Leadership election passed",
2404 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002405
Jon Hall58c76b72015-02-23 11:09:24 -08002406 main.step( "Run for election on old leader( just so everyone " +
2407 "is in the hat )" )
Jon Hall63604932015-02-26 17:09:50 -08002408 if oldLeader:
2409 runResult = oldLeader.electionTestRun()
2410 else:
2411 runResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002412 utilities.assert_equals(
2413 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002414 actual=runResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002415 onpass="App re-ran for election",
2416 onfail="App failed to run for election" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002417 if consistentLeader == main.TRUE:
2418 afterRun = main.ONOScli1.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08002419 # verify leader didn't just change
Jon Hall8f89dda2015-01-22 16:03:33 -08002420 if afterRun == leaderList[ 0 ]:
2421 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002422 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002423 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002424 # TODO: assert on run and withdraw results?
Jon Hall669173b2014-12-17 11:36:30 -08002425
Jon Hall6aec96b2015-01-19 14:49:31 -08002426 utilities.assert_equals(
2427 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002428 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002429 onpass="Leadership election passed",
2430 onfail="Something went wrong with Leadership election after " +
2431 "the old leader re-ran for election" )