blob: 43dd995a2774d0945aa244fdd7bde730d23b5eaa [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 a minority 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 HATestMinorityRestart:
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(
48 "ONOS HA test: Restart minority of ONOS nodes - 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 Hall529a37f2015-01-28 10:02:00 -0800115 cleanInstallResult = main.ONOSbench.cleanInstall()
116 else:
117 main.log.warn( "Did not pull new code so skipping mvn " +
118 "clean install" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800119 main.ONOSbench.getVersion( report=True )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800120
Jon Hall6aec96b2015-01-19 14:49:31 -0800121 main.step( "Creating ONOS package" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800122 packageResult = main.ONOSbench.onosPackage()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800123
Jon Hall6aec96b2015-01-19 14:49:31 -0800124 main.step( "Installing ONOS package" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700125 onosInstallResult = main.TRUE
126 for node in nodes:
127 tmpResult = main.ONOSbench.onosInstall( options="-f",
128 node=node.ip_address )
129 onosInstallResult = onosInstallResult and tmpResult
Jon Hall73cf9cc2014-11-20 22:28:38 -0800130
Jon Hall6aec96b2015-01-19 14:49:31 -0800131 main.step( "Checking if ONOS is up yet" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800132 for i in range( 2 ):
Jon Hall5cfd23c2015-03-19 11:40:57 -0700133 onosIsupResult = main.TRUE
134 for node in nodes:
135 started = main.ONOSbench.isup( node.ip_address )
136 if not started:
137 main.log.report( node.name + " didn't start!" )
138 main.ONOSbench.onosStop( node.ip_address )
139 main.ONOSbench.onosStart( node.ip_address )
140 onosIsupResult = onosIsupResult and started
Jon Hall8f89dda2015-01-22 16:03:33 -0800141 if onosIsupResult == main.TRUE:
Jon Hall94fd0472014-12-08 11:52:42 -0800142 break
Jon Hall73cf9cc2014-11-20 22:28:38 -0800143
Jon Hall5cfd23c2015-03-19 11:40:57 -0700144 main.log.step( "Starting ONOS CLI sessions" )
145 cliResults = main.TRUE
146 threads = []
147 for i in range( numControllers ):
148 t = main.Thread( target=CLIs[i].startOnosCli,
149 name="startOnosCli-" + str( i ),
150 args=[nodes[i].ip_address] )
151 threads.append( t )
152 t.start()
153
154 for t in threads:
155 t.join()
156 cliResults = cliResults and t.result
Jon Hall73cf9cc2014-11-20 22:28:38 -0800157
Jon Hall6aec96b2015-01-19 14:49:31 -0800158 main.step( "Start Packet Capture MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800159 main.Mininet2.startTcpdump(
Jon Hall6aec96b2015-01-19 14:49:31 -0800160 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
161 + "-MN.pcap",
162 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
163 port=main.params[ 'MNtcpdump' ][ 'port' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800164
Jon Halla9d26da2015-03-30 16:45:32 -0700165 appCheck = main.TRUE
166 threads = []
167 for i in range( numControllers ):
168 t = main.Thread( target=CLIs[i].appToIDCheck,
169 name="appToIDCheck-" + str( i ),
170 args=[] )
171 threads.append( t )
172 t.start()
173
174 for t in threads:
175 t.join()
176 appCheck = appCheck and t.result
177 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
178 onpass="App Ids seem to be correct",
179 onfail="Something is wrong with app Ids" )
180 if appCheck != main.TRUE:
181 main.log.warn( CLIs[0].apps() )
182 main.log.warn( CLIs[0].appIDs() )
183
Jon Hall8f89dda2015-01-22 16:03:33 -0800184 case1Result = ( cleanInstallResult and packageResult and
185 cellResult and verifyResult and onosInstallResult
Jon Halla9d26da2015-03-30 16:45:32 -0700186 and onosIsupResult and cliResults and appCheck)
Jon Hall73cf9cc2014-11-20 22:28:38 -0800187
Jon Hall8f89dda2015-01-22 16:03:33 -0800188 utilities.assert_equals( expect=main.TRUE, actual=case1Result,
Jon Hall58c76b72015-02-23 11:09:24 -0800189 onpass="Test startup successful",
190 onfail="Test startup NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800191
Jon Hall8f89dda2015-01-22 16:03:33 -0800192 if case1Result == main.FALSE:
Jon Hall94fd0472014-12-08 11:52:42 -0800193 main.cleanup()
194 main.exit()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800195
Jon Hall6aec96b2015-01-19 14:49:31 -0800196 def CASE2( self, main ):
197 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800198 Assign mastership to controllers
Jon Hall6aec96b2015-01-19 14:49:31 -0800199 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800200 import re
Jon Hall5cfd23c2015-03-19 11:40:57 -0700201 assert numControllers, "numControllers not defined"
202 assert main, "main not defined"
203 assert utilities.assert_equals, "utilities.assert_equals not defined"
204 assert CLIs, "CLIs not defined"
205 assert nodes, "nodes not defined"
206 assert ONOS1Port, "ONOS1Port not defined"
207 assert ONOS2Port, "ONOS2Port not defined"
208 assert ONOS3Port, "ONOS3Port not defined"
209 assert ONOS4Port, "ONOS4Port not defined"
210 assert ONOS5Port, "ONOS5Port not defined"
211 assert ONOS6Port, "ONOS6Port not defined"
212 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -0800213
Jon Hall6aec96b2015-01-19 14:49:31 -0800214 main.log.report( "Assigning switches to controllers" )
215 main.case( "Assigning Controllers" )
216 main.step( "Assign switches to controllers" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800217
Jon Hall5cfd23c2015-03-19 11:40:57 -0700218 # TODO: rewrite this function to take lists of ips and ports?
219 # or list of tuples?
Jon Hall6aec96b2015-01-19 14:49:31 -0800220 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800221 main.Mininet1.assignSwController(
Jon Hall6aec96b2015-01-19 14:49:31 -0800222 sw=str( i ),
Jon Hall8f89dda2015-01-22 16:03:33 -0800223 count=numControllers,
Jon Hall5cfd23c2015-03-19 11:40:57 -0700224 ip1=nodes[ 0 ].ip_address, port1=ONOS1Port,
225 ip2=nodes[ 1 ].ip_address, port2=ONOS2Port,
226 ip3=nodes[ 2 ].ip_address, port3=ONOS3Port,
227 ip4=nodes[ 3 ].ip_address, port4=ONOS4Port,
228 ip5=nodes[ 4 ].ip_address, port5=ONOS5Port,
229 ip6=nodes[ 5 ].ip_address, port6=ONOS6Port,
230 ip7=nodes[ 6 ].ip_address, port7=ONOS7Port )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800231
Jon Hall8f89dda2015-01-22 16:03:33 -0800232 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800233 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800234 response = main.Mininet1.getSwController( "s" + str( i ) )
Jon Hallffb386d2014-11-21 13:43:38 -0800235 try:
Jon Hall6aec96b2015-01-19 14:49:31 -0800236 main.log.info( str( response ) )
Jon Hallfebb1c72015-03-05 13:30:09 -0800237 except Exception:
Jon Hall6aec96b2015-01-19 14:49:31 -0800238 main.log.info( repr( response ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700239 for node in nodes:
240 if re.search( "tcp:" + node.ip_address, response ):
241 mastershipCheck = mastershipCheck and main.TRUE
242 else:
Jon Halla9d26da2015-03-30 16:45:32 -0700243 main.log.error( "Error, node " + node.ip_address + " is " +
244 "not in the list of controllers s" +
245 str( i ) + " is connecting to." )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700246 mastershipCheck = main.FALSE
Jon Hall8f89dda2015-01-22 16:03:33 -0800247 if mastershipCheck == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800248 main.log.report( "Switch mastership assigned correctly" )
249 utilities.assert_equals(
250 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800251 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800252 onpass="Switch mastership assigned correctly",
253 onfail="Switches not assigned correctly to controllers" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800254 # Manually assign mastership to the controller we want
Jon Hall8f89dda2015-01-22 16:03:33 -0800255 roleCall = main.TRUE
256 roleCheck = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -0800257 try:
Jon Halla9d26da2015-03-30 16:45:32 -0700258 for i in range( 1, 29 ): # switches 1 through 28
259 # set up correct variables:
260 if i == 1:
261 ip = nodes[ 0 ].ip_address # ONOS1
262 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
263 elif i == 2:
264 ip = nodes[ 1 ].ip_address # ONOS2
265 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
266 elif i == 3:
267 ip = nodes[ 1 ].ip_address # ONOS2
268 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
269 elif i == 4:
270 ip = nodes[ 3 ].ip_address # ONOS4
271 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
272 elif i == 5:
273 ip = nodes[ 2 ].ip_address # ONOS3
274 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
275 elif i == 6:
276 ip = nodes[ 2 ].ip_address # ONOS3
277 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
278 elif i == 7:
279 ip = nodes[ 5 ].ip_address # ONOS6
280 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
281 elif i >= 8 and i <= 17:
282 ip = nodes[ 4 ].ip_address # ONOS5
283 dpid = '3' + str( i ).zfill( 3 )
284 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
285 elif i >= 18 and i <= 27:
286 ip = nodes[ 6 ].ip_address # ONOS7
287 dpid = '6' + str( i ).zfill( 3 )
288 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
289 elif i == 28:
290 ip = nodes[ 0 ].ip_address # ONOS1
291 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
292 else:
293 main.log.error( "You didn't write an else statement for " +
294 "switch s" + str( i ) )
295 # Assign switch
296 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
297 # TODO: make this controller dynamic
298 roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
299 ip )
Jon Hall58c76b72015-02-23 11:09:24 -0800300 # Check assignment
Jon Hall678f4512015-03-31 09:48:31 -0700301 master = main.ONOScli1.getRole( deviceId ).get( 'master' )
302 if ip in master:
Jon Hall58c76b72015-02-23 11:09:24 -0800303 roleCheck = roleCheck and main.TRUE
304 else:
305 roleCheck = roleCheck and main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -0700306 main.log.error( "Error, controller " + ip + " is not" +
307 " master " + "of device " +
Jon Hall678f4512015-03-31 09:48:31 -0700308 str( deviceId ) + ". Master is " +
309 repr( master ) + "." )
Jon Hall58c76b72015-02-23 11:09:24 -0800310 except ( AttributeError, AssertionError ):
311 main.log.exception( "Something is wrong with ONOS device view" )
312 main.log.info( main.ONOScli1.devices() )
Jon Hall6aec96b2015-01-19 14:49:31 -0800313 utilities.assert_equals(
314 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800315 actual=roleCall,
Jon Hall6aec96b2015-01-19 14:49:31 -0800316 onpass="Re-assigned switch mastership to designated controller",
Jon Hall8f89dda2015-01-22 16:03:33 -0800317 onfail="Something wrong with deviceRole calls" )
Jon Hall94fd0472014-12-08 11:52:42 -0800318
Jon Hall6aec96b2015-01-19 14:49:31 -0800319 utilities.assert_equals(
320 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800321 actual=roleCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800322 onpass="Switches were successfully reassigned to designated " +
323 "controller",
324 onfail="Switches were not successfully reassigned" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800325 mastershipCheck = mastershipCheck and roleCall and roleCheck
326 utilities.assert_equals( expect=main.TRUE, actual=mastershipCheck,
Jon Hall21270ac2015-02-16 17:59:55 -0800327 onpass="Switch mastership correctly assigned",
328 onfail="Error in (re)assigning switch" +
329 " mastership" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800330
Jon Hall6aec96b2015-01-19 14:49:31 -0800331 def CASE3( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800332 """
333 Assign intents
Jon Hall73cf9cc2014-11-20 22:28:38 -0800334 """
335 import time
Jon Hallfebb1c72015-03-05 13:30:09 -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 Hall5cfd23c2015-03-19 11:40:57 -0700470 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 Hall678f4512015-03-31 09:48:31 -0700575 if gossipTime <= 30:
576 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800577
Jon Hall63604932015-02-26 17:09:50 -0800578 if not intentAddResult or "key" in pendingMap:
Jon Hall58c76b72015-02-23 11:09:24 -0800579 import time
Jon Hall63604932015-02-26 17:09:50 -0800580 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800581 main.log.info( "Sleeping 60 seconds to see if intents are found" )
582 time.sleep( 60 )
583 onosIds = main.ONOScli1.getAllIntentsId()
584 main.log.info( "Submitted intents: " + str( intentIds ) )
585 main.log.info( "Intents in ONOS: " + str( onosIds ) )
586 # Print the intent states
587 intents = main.ONOScli1.intents()
588 intentStates = []
589 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
590 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700591 try:
592 for intent in json.loads( intents ):
593 # Iter through intents of a node
594 state = intent.get( 'state', None )
595 if "INSTALLED" not in state:
596 installedCheck = False
597 intentId = intent.get( 'id', None )
598 intentStates.append( ( intentId, state ) )
599 except ( ValueError, TypeError ):
600 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800601 # add submitted intents not in the store
602 tmplist = [ i for i, s in intentStates ]
603 for i in intentIds:
604 if i not in tmplist:
605 intentStates.append( ( i, " - " ) )
606 intentStates.sort()
607 for i, s in intentStates:
608 count += 1
609 main.log.info( "%-6s%-15s%-15s" %
610 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700611 leaders = main.ONOScli1.leaders()
612 try:
613 if leaders:
614 parsedLeaders = json.loads( leaders )
615 main.log.warn( json.dumps( parsedLeaders,
616 sort_keys=True,
617 indent=4,
618 separators=( ',', ': ' ) ) )
619 # check for all intent partitions
620 # check for election
621 topics = []
622 for i in range( 14 ):
623 topics.append( "intent-partition-" + str( i ) )
624 # FIXME: this should only be after we start the app
625 topics.append( "org.onosproject.election" )
626 main.log.debug( topics )
627 ONOStopics = [ j['topic'] for j in parsedLeaders ]
628 for topic in topics:
629 if topic not in ONOStopics:
630 main.log.error( "Error: " + topic +
631 " not in leaders" )
632 else:
633 main.log.error( "leaders() returned None" )
634 except ( ValueError, TypeError ):
635 main.log.exception( "Error parsing leaders" )
636 main.log.error( repr( leaders ) )
637 partitions = main.ONOScli1.partitions()
638 try:
639 if partitions :
640 parsedPartitions = json.loads( partitions )
641 main.log.warn( json.dumps( parsedPartitions,
642 sort_keys=True,
643 indent=4,
644 separators=( ',', ': ' ) ) )
645 # TODO check for a leader in all paritions
646 # TODO check for consistency among nodes
647 else:
648 main.log.error( "partitions() returned None" )
649 except ( ValueError, TypeError ):
650 main.log.exception( "Error parsing partitions" )
651 main.log.error( repr( partitions ) )
652 pendingMap = main.ONOScli1.pendingMap()
653 try:
654 if pendingMap :
655 parsedPending = json.loads( pendingMap )
656 main.log.warn( json.dumps( parsedPending,
657 sort_keys=True,
658 indent=4,
659 separators=( ',', ': ' ) ) )
660 # TODO check something here?
661 else:
662 main.log.error( "pendingMap() returned None" )
663 except ( ValueError, TypeError ):
664 main.log.exception( "Error parsing pending map" )
665 main.log.error( repr( pendingMap ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800666
Jon Hall6aec96b2015-01-19 14:49:31 -0800667 def CASE4( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800668 """
669 Ping across added host intents
670 """
Jon Hallfebb1c72015-03-05 13:30:09 -0800671 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700672 import time
673 assert numControllers, "numControllers not defined"
674 assert main, "main not defined"
675 assert utilities.assert_equals, "utilities.assert_equals not defined"
676 assert CLIs, "CLIs not defined"
677 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -0800678 description = " Ping across added host intents"
Jon Hall6aec96b2015-01-19 14:49:31 -0800679 main.log.report( description )
680 main.case( description )
Jon Hall8f89dda2015-01-22 16:03:33 -0800681 PingResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800682 for i in range( 8, 18 ):
Jon Hall21270ac2015-02-16 17:59:55 -0800683 ping = main.Mininet1.pingHost( src="h" + str( i ),
684 target="h" + str( i + 10 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800685 PingResult = PingResult and ping
Jon Hall6aec96b2015-01-19 14:49:31 -0800686 if ping == main.FALSE:
687 main.log.warn( "Ping failed between h" + str( i ) +
688 " and h" + str( i + 10 ) )
689 elif ping == main.TRUE:
690 main.log.info( "Ping test passed!" )
Jon Hall21270ac2015-02-16 17:59:55 -0800691 # Don't set PingResult or you'd override failures
Jon Hall8f89dda2015-01-22 16:03:33 -0800692 if PingResult == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800693 main.log.report(
694 "Intents have not been installed correctly, pings failed." )
Jon Hall58c76b72015-02-23 11:09:24 -0800695 # TODO: pretty print
Jon Hall5cfd23c2015-03-19 11:40:57 -0700696 main.log.warn( "ONOS1 intents: " )
697 try:
698 tmpIntents = main.ONOScli1.intents()
699 main.log.warn( json.dumps( json.loads( tmpIntents ),
700 sort_keys=True,
701 indent=4,
702 separators=( ',', ': ' ) ) )
703 except ( ValueError, TypeError ):
704 main.log.warn( repr( tmpIntents ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800705 if PingResult == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800706 main.log.report(
707 "Intents have been installed correctly and verified by pings" )
708 utilities.assert_equals(
709 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800710 actual=PingResult,
Jon Hall6aec96b2015-01-19 14:49:31 -0800711 onpass="Intents have been installed correctly and pings work",
712 onfail="Intents have not been installed correctly, pings failed." )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800713
Jon Hall63604932015-02-26 17:09:50 -0800714 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800715 if PingResult is not main.TRUE:
716 # Print the intent states
717 intents = main.ONOScli1.intents()
718 intentStates = []
719 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
720 count = 0
721 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700722 try:
723 for intent in json.loads( intents ):
724 state = intent.get( 'state', None )
725 if "INSTALLED" not in state:
726 installedCheck = False
727 intentId = intent.get( 'id', None )
728 intentStates.append( ( intentId, state ) )
729 except ( ValueError, TypeError ):
730 main.log.exception( "Error parsing intents." )
Jon Hall58c76b72015-02-23 11:09:24 -0800731 intentStates.sort()
732 for i, s in intentStates:
733 count += 1
734 main.log.info( "%-6s%-15s%-15s" %
735 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700736 leaders = main.ONOScli1.leaders()
737 try:
738 if leaders:
739 parsedLeaders = json.loads( leaders )
740 main.log.warn( json.dumps( parsedLeaders,
741 sort_keys=True,
742 indent=4,
743 separators=( ',', ': ' ) ) )
744 # check for all intent partitions
745 # check for election
746 topics = []
747 for i in range( 14 ):
748 topics.append( "intent-partition-" + str( i ) )
749 # FIXME: this should only be after we start the app
750 topics.append( "org.onosproject.election" )
751 main.log.debug( topics )
752 ONOStopics = [ j['topic'] for j in parsedLeaders ]
753 for topic in topics:
754 if topic not in ONOStopics:
755 main.log.error( "Error: " + topic +
756 " not in leaders" )
757 else:
758 main.log.error( "leaders() returned None" )
759 except ( ValueError, TypeError ):
760 main.log.exception( "Error parsing leaders" )
761 main.log.error( repr( leaders ) )
762 partitions = main.ONOScli1.partitions()
763 try:
764 if partitions :
765 parsedPartitions = json.loads( partitions )
766 main.log.warn( json.dumps( parsedPartitions,
767 sort_keys=True,
768 indent=4,
769 separators=( ',', ': ' ) ) )
770 # TODO check for a leader in all paritions
771 # TODO check for consistency among nodes
772 else:
773 main.log.error( "partitions() returned None" )
774 except ( ValueError, TypeError ):
775 main.log.exception( "Error parsing partitions" )
776 main.log.error( repr( partitions ) )
777 pendingMap = main.ONOScli1.pendingMap()
778 try:
779 if pendingMap :
780 parsedPending = json.loads( pendingMap )
781 main.log.warn( json.dumps( parsedPending,
782 sort_keys=True,
783 indent=4,
784 separators=( ',', ': ' ) ) )
785 # TODO check something here?
786 else:
787 main.log.error( "pendingMap() returned None" )
788 except ( ValueError, TypeError ):
789 main.log.exception( "Error parsing pending map" )
790 main.log.error( repr( pendingMap ) )
791
Jon Hall63604932015-02-26 17:09:50 -0800792 if not installedCheck:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700793 main.log.info( "Waiting 60 seconds to see if the state of " +
794 "intents change" )
Jon Hall63604932015-02-26 17:09:50 -0800795 time.sleep( 60 )
796 # Print the intent states
797 intents = main.ONOScli1.intents()
798 intentStates = []
799 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
800 count = 0
801 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700802 try:
803 for intent in json.loads( intents ):
804 state = intent.get( 'state', None )
805 if "INSTALLED" not in state:
806 installedCheck = False
807 intentId = intent.get( 'id', None )
808 intentStates.append( ( intentId, state ) )
809 except ( ValueError, TypeError ):
810 main.log.exception( "Error parsing intents." )
Jon Hall63604932015-02-26 17:09:50 -0800811 intentStates.sort()
812 for i, s in intentStates:
813 count += 1
814 main.log.info( "%-6s%-15s%-15s" %
815 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700816 leaders = main.ONOScli1.leaders()
817 try:
818 if leaders:
819 parsedLeaders = json.loads( leaders )
820 main.log.warn( json.dumps( parsedLeaders,
821 sort_keys=True,
822 indent=4,
823 separators=( ',', ': ' ) ) )
824 # check for all intent partitions
825 # check for election
826 topics = []
827 for i in range( 14 ):
828 topics.append( "intent-partition-" + str( i ) )
829 # FIXME: this should only be after we start the app
830 topics.append( "org.onosproject.election" )
831 main.log.debug( topics )
832 ONOStopics = [ j['topic'] for j in parsedLeaders ]
833 for topic in topics:
834 if topic not in ONOStopics:
835 main.log.error( "Error: " + topic +
836 " not in leaders" )
837 else:
838 main.log.error( "leaders() returned None" )
839 except ( ValueError, TypeError ):
840 main.log.exception( "Error parsing leaders" )
841 main.log.error( repr( leaders ) )
842 partitions = main.ONOScli1.partitions()
843 try:
844 if partitions :
845 parsedPartitions = json.loads( partitions )
846 main.log.warn( json.dumps( parsedPartitions,
847 sort_keys=True,
848 indent=4,
849 separators=( ',', ': ' ) ) )
850 # TODO check for a leader in all paritions
851 # TODO check for consistency among nodes
852 else:
853 main.log.error( "partitions() returned None" )
854 except ( ValueError, TypeError ):
855 main.log.exception( "Error parsing partitions" )
856 main.log.error( repr( partitions ) )
857 pendingMap = main.ONOScli1.pendingMap()
858 try:
859 if pendingMap :
860 parsedPending = json.loads( pendingMap )
861 main.log.warn( json.dumps( parsedPending,
862 sort_keys=True,
863 indent=4,
864 separators=( ',', ': ' ) ) )
865 # TODO check something here?
866 else:
867 main.log.error( "pendingMap() returned None" )
868 except ( ValueError, TypeError ):
869 main.log.exception( "Error parsing pending map" )
870 main.log.error( repr( pendingMap ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800871
Jon Hall6aec96b2015-01-19 14:49:31 -0800872 def CASE5( self, main ):
873 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800874 Reading state of ONOS
Jon Hall6aec96b2015-01-19 14:49:31 -0800875 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800876 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700877 import time
878 assert numControllers, "numControllers not defined"
879 assert main, "main not defined"
880 assert utilities.assert_equals, "utilities.assert_equals not defined"
881 assert CLIs, "CLIs not defined"
882 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -0800883 # assumes that sts is already in you PYTHONPATH
884 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -0800885
Jon Hall6aec96b2015-01-19 14:49:31 -0800886 main.log.report( "Setting up and gathering data for current state" )
887 main.case( "Setting up and gathering data for current state" )
888 # The general idea for this test case is to pull the state of
889 # ( intents,flows, topology,... ) from each ONOS node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700890 # We can then compare them with each other and also with past states
Jon Hall73cf9cc2014-11-20 22:28:38 -0800891
Jon Hall5cfd23c2015-03-19 11:40:57 -0700892 main.step( "Check that each switch has a master" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800893 global mastershipState
Jon Hall5cfd23c2015-03-19 11:40:57 -0700894 mastershipState = '[]'
Jon Hall94fd0472014-12-08 11:52:42 -0800895
Jon Hall6aec96b2015-01-19 14:49:31 -0800896 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -0700897 rolesNotNull = main.TRUE
898 threads = []
899 for i in range( numControllers ):
900 t = main.Thread( target=CLIs[i].rolesNotNull,
901 name="rolesNotNull-" + str( i ),
902 args=[] )
903 threads.append( t )
904 t.start()
905
906 for t in threads:
907 t.join()
908 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -0800909 utilities.assert_equals(
910 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800911 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -0800912 onpass="Each device has a master",
913 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -0800914
Jon Hall5cfd23c2015-03-19 11:40:57 -0700915 main.step( "Get the Mastership of each switch from each controller" )
916 ONOSMastership = []
917 mastershipCheck = main.FALSE
918 consistentMastership = True
919 rolesResults = True
920 threads = []
921 for i in range( numControllers ):
922 t = main.Thread( target=CLIs[i].roles,
923 name="roles-" + str( i ),
924 args=[] )
925 threads.append( t )
926 t.start()
927
928 for t in threads:
929 t.join()
930 ONOSMastership.append( t.result )
931
932 for i in range( numControllers ):
933 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
934 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
935 " roles" )
936 main.log.warn(
937 "ONOS" + str( i + 1 ) + " mastership response: " +
938 repr( ONOSMastership[i] ) )
939 rolesResults = False
940 utilities.assert_equals(
941 expect=True,
942 actual=rolesResults,
943 onpass="No error in reading roles output",
944 onfail="Error in reading roles from ONOS" )
945
946 main.step( "Check for consistency in roles from each controller" )
947 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall6aec96b2015-01-19 14:49:31 -0800948 main.log.report(
949 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800950 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700951 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -0800952 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -0700953 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -0800954 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -0800955 onpass="Switch roles are consistent across all ONOS nodes",
956 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800957
Jon Hall5cfd23c2015-03-19 11:40:57 -0700958 if rolesResults and not consistentMastership:
959 for i in range( numControllers ):
960 try:
961 main.log.warn(
962 "ONOS" + str( i + 1 ) + " roles: ",
963 json.dumps(
964 json.loads( ONOSMastership[ i ] ),
965 sort_keys=True,
966 indent=4,
967 separators=( ',', ': ' ) ) )
968 except ( ValueError, TypeError ):
969 main.log.warn( repr( ONOSMastership[ i ] ) )
970 elif rolesResults and consistentMastership:
971 mastershipCheck = main.TRUE
972 mastershipState = ONOSMastership[ 0 ]
973
Jon Hall6aec96b2015-01-19 14:49:31 -0800974 main.step( "Get the intents from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800975 global intentState
976 intentState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -0700977 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -0800978 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700979 consistentIntents = True
980 intentsResults = True
981 threads = []
982 for i in range( numControllers ):
983 t = main.Thread( target=CLIs[i].intents,
984 name="intents-" + str( i ),
985 args=[],
986 kwargs={ 'jsonFormat': True } )
987 threads.append( t )
988 t.start()
989
990 for t in threads:
991 t.join()
992 ONOSIntents.append( t.result )
993
994 for i in range( numControllers ):
995 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
996 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
997 " intents" )
998 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
999 repr( ONOSIntents[ i ] ) )
1000 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001001 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001002 expect=True,
1003 actual=intentsResults,
1004 onpass="No error in reading intents output",
1005 onfail="Error in reading intents from ONOS" )
1006
1007 main.step( "Check for consistency in Intents from each controller" )
1008 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1009 main.log.report( "Intents are consistent across all ONOS " +
1010 "nodes" )
1011 else:
1012 consistentIntents = False
1013 main.log.report( "Intents not consistent" )
1014 utilities.assert_equals(
1015 expect=True,
1016 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001017 onpass="Intents are consistent across all ONOS nodes",
1018 onfail="ONOS nodes have different views of intents" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001019
Jon Hall5cfd23c2015-03-19 11:40:57 -07001020 if intentsResults and not consistentIntents:
1021 n = len(ONOSIntents)
1022 main.log.warn( "ONOS" + str( n ) + " intents: " )
1023 main.log.warn( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1024 sort_keys=True,
1025 indent=4,
1026 separators=( ',', ': ' ) ) )
1027 for i in range( numControllers ):
1028 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
1029 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1030 main.log.warn( json.dumps( json.loads( ONOSIntents[i] ),
1031 sort_keys=True,
1032 indent=4,
1033 separators=( ',', ': ' ) ) )
1034 else:
1035 main.log.warn( nodes[ i ].name + " intents match ONOS" +
1036 str( n ) + " intents" )
1037 elif intentsResults and consistentIntents:
1038 intentCheck = main.TRUE
1039 intentState = ONOSIntents[ 0 ]
1040
Jon Hall6aec96b2015-01-19 14:49:31 -08001041 main.step( "Get the flows from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001042 global flowState
1043 flowState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001044 ONOSFlows = []
1045 ONOSFlowsJson = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001046 flowCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001047 consistentFlows = True
1048 flowsResults = True
1049 threads = []
1050 for i in range( numControllers ):
1051 t = main.Thread( target=CLIs[i].flows,
1052 name="flows-" + str( i ),
1053 args=[],
1054 kwargs={ 'jsonFormat': True } )
1055 threads.append( t )
1056 t.start()
1057
Jon Halla9d26da2015-03-30 16:45:32 -07001058 # NOTE: Flows command can take some time to run
Jon Hall5cfd23c2015-03-19 11:40:57 -07001059 time.sleep(30)
1060 for t in threads:
1061 t.join()
1062 result = t.result
1063 ONOSFlows.append( result )
1064
1065 for i in range( numControllers ):
1066 num = str( i + 1 )
1067 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1068 main.log.report( "Error in getting ONOS" + num + " flows" )
1069 main.log.warn( "ONOS" + num + " flows response: " +
1070 repr( ONOSFlows[ i ] ) )
1071 flowsResults = False
1072 ONOSFlowsJson.append( None )
Jon Hall58c76b72015-02-23 11:09:24 -08001073 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001074 try:
1075 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1076 except ( ValueError, TypeError ):
1077 # FIXME: change this to log.error?
1078 main.log.exception( "Error in parsing ONOS" + num +
1079 " response as json." )
1080 main.log.error( repr( ONOSFlows[ i ] ) )
1081 ONOSFlowsJson.append( None )
1082 flowsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001083 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001084 expect=True,
1085 actual=flowsResults,
1086 onpass="No error in reading flows output",
1087 onfail="Error in reading flows from ONOS" )
1088
1089 main.step( "Check for consistency in Flows from each controller" )
1090 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1091 if all( tmp ):
1092 main.log.report( "Flow count is consistent across all ONOS nodes" )
1093 else:
1094 consistentFlows = False
1095 utilities.assert_equals(
1096 expect=True,
1097 actual=consistentFlows,
Jon Hall6aec96b2015-01-19 14:49:31 -08001098 onpass="The flow count is consistent across all ONOS nodes",
1099 onfail="ONOS nodes have different flow counts" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001100
Jon Hall5cfd23c2015-03-19 11:40:57 -07001101 if flowsResults and not consistentFlows:
1102 for i in range( numControllers ):
1103 try:
1104 main.log.warn(
1105 "ONOS" + str( i + 1 ) + " flows: " +
1106 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1107 indent=4, separators=( ',', ': ' ) ) )
1108 except ( ValueError, TypeError ):
1109 main.log.warn(
1110 "ONOS" + str( i + 1 ) + " flows: " +
1111 repr( ONOSFlows[ i ] ) )
1112 elif flowsResults and consistentFlows:
1113 flowCheck = main.TRUE
1114 flowState = ONOSFlows[ 0 ]
1115
Jon Hall6aec96b2015-01-19 14:49:31 -08001116 main.step( "Get the OF Table entries" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001117 global flows
Jon Hall6aec96b2015-01-19 14:49:31 -08001118 flows = []
1119 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001120 flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001121 if flowCheck == main.FALSE:
1122 for table in flows:
1123 main.log.warn( table )
Jon Hall6aec96b2015-01-19 14:49:31 -08001124 # TODO: Compare switch flow tables with ONOS flow tables
Jon Hall73cf9cc2014-11-20 22:28:38 -08001125
Jon Hall6aec96b2015-01-19 14:49:31 -08001126 main.step( "Start continuous pings" )
1127 main.Mininet2.pingLong(
1128 src=main.params[ 'PING' ][ 'source1' ],
1129 target=main.params[ 'PING' ][ 'target1' ],
1130 pingTime=500 )
1131 main.Mininet2.pingLong(
1132 src=main.params[ 'PING' ][ 'source2' ],
1133 target=main.params[ 'PING' ][ 'target2' ],
1134 pingTime=500 )
1135 main.Mininet2.pingLong(
1136 src=main.params[ 'PING' ][ 'source3' ],
1137 target=main.params[ 'PING' ][ 'target3' ],
1138 pingTime=500 )
1139 main.Mininet2.pingLong(
1140 src=main.params[ 'PING' ][ 'source4' ],
1141 target=main.params[ 'PING' ][ 'target4' ],
1142 pingTime=500 )
1143 main.Mininet2.pingLong(
1144 src=main.params[ 'PING' ][ 'source5' ],
1145 target=main.params[ 'PING' ][ 'target5' ],
1146 pingTime=500 )
1147 main.Mininet2.pingLong(
1148 src=main.params[ 'PING' ][ 'source6' ],
1149 target=main.params[ 'PING' ][ 'target6' ],
1150 pingTime=500 )
1151 main.Mininet2.pingLong(
1152 src=main.params[ 'PING' ][ 'source7' ],
1153 target=main.params[ 'PING' ][ 'target7' ],
1154 pingTime=500 )
1155 main.Mininet2.pingLong(
1156 src=main.params[ 'PING' ][ 'source8' ],
1157 target=main.params[ 'PING' ][ 'target8' ],
1158 pingTime=500 )
1159 main.Mininet2.pingLong(
1160 src=main.params[ 'PING' ][ 'source9' ],
1161 target=main.params[ 'PING' ][ 'target9' ],
1162 pingTime=500 )
1163 main.Mininet2.pingLong(
1164 src=main.params[ 'PING' ][ 'source10' ],
1165 target=main.params[ 'PING' ][ 'target10' ],
1166 pingTime=500 )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001167
Jon Hall6aec96b2015-01-19 14:49:31 -08001168 main.step( "Create TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001169 ctrls = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001170 for node in nodes:
1171 temp = ( node, node.name, node.ip_address, 6633 )
1172 ctrls.append( temp )
1173 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001174
Jon Hall6aec96b2015-01-19 14:49:31 -08001175 main.step( "Collecting topology information from ONOS" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001176 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001177 threads = []
1178 for i in range( numControllers ):
1179 t = main.Thread( target=CLIs[i].devices,
1180 name="devices-" + str( i ),
1181 args=[ ] )
1182 threads.append( t )
1183 t.start()
1184
1185 for t in threads:
1186 t.join()
1187 devices.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001188 hosts = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001189 threads = []
1190 for i in range( numControllers ):
1191 t = main.Thread( target=CLIs[i].hosts,
1192 name="hosts-" + str( i ),
1193 args=[ ] )
1194 threads.append( t )
1195 t.start()
1196
1197 for t in threads:
1198 t.join()
1199 try:
1200 hosts.append( json.loads( t.result ) )
1201 except ( ValueError, TypeError ):
1202 # FIXME: better handling of this, print which node
1203 # Maybe use thread name?
1204 main.log.exception( "Error parsing json output of hosts" )
1205 # FIXME: should this be an empty json object instead?
1206 hosts.append( None )
1207
Jon Hall73cf9cc2014-11-20 22:28:38 -08001208 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001209 threads = []
1210 for i in range( numControllers ):
1211 t = main.Thread( target=CLIs[i].ports,
1212 name="ports-" + str( i ),
1213 args=[ ] )
1214 threads.append( t )
1215 t.start()
1216
1217 for t in threads:
1218 t.join()
1219 ports.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001220 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001221 threads = []
1222 for i in range( numControllers ):
1223 t = main.Thread( target=CLIs[i].links,
1224 name="links-" + str( i ),
1225 args=[ ] )
1226 threads.append( t )
1227 t.start()
1228
1229 for t in threads:
1230 t.join()
1231 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001232 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001233 threads = []
1234 for i in range( numControllers ):
1235 t = main.Thread( target=CLIs[i].clusters,
1236 name="clusters-" + str( i ),
1237 args=[ ] )
1238 threads.append( t )
1239 t.start()
1240
1241 for t in threads:
1242 t.join()
1243 clusters.append( t.result )
Jon Hall529a37f2015-01-28 10:02:00 -08001244 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001245
Jon Hall6aec96b2015-01-19 14:49:31 -08001246 # hosts
Jon Hall8f89dda2015-01-22 16:03:33 -08001247 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001248 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001249 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001250 if "Error" not in hosts[ controller ]:
1251 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001252 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001253 else: # hosts not consistent
1254 main.log.report( "hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001255 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001256 " is inconsistent with ONOS1" )
1257 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001258 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001259
1260 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001261 main.log.report( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001262 controllerStr )
1263 consistentHostsResult = main.FALSE
1264 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001265 " hosts response: " +
1266 repr( hosts[ controller ] ) )
1267 utilities.assert_equals(
1268 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001269 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001270 onpass="Hosts view is consistent across all ONOS nodes",
1271 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001272
Jon Hall58c76b72015-02-23 11:09:24 -08001273 ipResult = main.TRUE
1274 for controller in range( 0, len( hosts ) ):
1275 controllerStr = str( controller + 1 )
1276 for host in hosts[ controller ]:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001277 if not host.get( 'ips', [ ] ):
1278 main.log.error( "DEBUG:Error with host ips on controller" +
1279 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001280 ipResult = main.FALSE
1281 utilities.assert_equals(
1282 expect=main.TRUE,
1283 actual=ipResult,
1284 onpass="The ips of the hosts aren't empty",
1285 onfail="The ip of at least one host is missing" )
1286
Jon Hall6aec96b2015-01-19 14:49:31 -08001287 # Strongly connected clusters of devices
Jon Hall8f89dda2015-01-22 16:03:33 -08001288 consistentClustersResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001289 for controller in range( len( clusters ) ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001290 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001291 if "Error" not in clusters[ controller ]:
1292 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001293 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001294 else: # clusters not consistent
Jon Hall5cfd23c2015-03-19 11:40:57 -07001295 main.log.report( "clusters from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001296 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001297 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001298
1299 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001300 main.log.report( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001301 "from ONOS" + controllerStr )
1302 consistentClustersResult = main.FALSE
1303 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001304 " clusters response: " +
1305 repr( clusters[ controller ] ) )
1306 utilities.assert_equals(
1307 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001308 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001309 onpass="Clusters view is consistent across all ONOS nodes",
1310 onfail="ONOS nodes have different views of clusters" )
1311 # there should always only be one cluster
Jon Hall5cfd23c2015-03-19 11:40:57 -07001312 try:
1313 numClusters = len( json.loads( clusters[ 0 ] ) )
1314 except ( ValueError, TypeError ):
1315 main.log.exception( "Error parsing clusters[0]: " +
1316 repr( clusters[ 0 ] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001317 clusterResults = main.FALSE
1318 if numClusters == 1:
1319 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001320 utilities.assert_equals(
1321 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08001322 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08001323 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08001324 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08001325
Jon Hall6aec96b2015-01-19 14:49:31 -08001326 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001327 devicesResults = main.TRUE
1328 portsResults = main.TRUE
1329 linksResults = main.TRUE
1330 for controller in range( numControllers ):
1331 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001332 if devices[ controller ] or "Error" not in devices[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001333 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08001334 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001335 json.loads( devices[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001336 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001337 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001338 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001339 actual=currentDevicesResult,
1340 onpass="ONOS" + controllerStr +
1341 " Switches view is correct",
1342 onfail="ONOS" + controllerStr +
1343 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001344
Jon Hall6aec96b2015-01-19 14:49:31 -08001345 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001346 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08001347 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001348 json.loads( ports[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001349 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001350 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001351 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001352 actual=currentPortsResult,
1353 onpass="ONOS" + controllerStr +
1354 " ports view is correct",
1355 onfail="ONOS" + controllerStr +
1356 " ports view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001357
Jon Hall6aec96b2015-01-19 14:49:31 -08001358 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001359 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08001360 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001361 json.loads( links[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001362 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001363 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001364 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001365 actual=currentLinksResult,
1366 onpass="ONOS" + controllerStr +
1367 " links view is correct",
1368 onfail="ONOS" + controllerStr +
1369 " links view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001370
Jon Hall8f89dda2015-01-22 16:03:33 -08001371 devicesResults = devicesResults and currentDevicesResult
1372 portsResults = portsResults and currentPortsResult
1373 linksResults = linksResults and currentLinksResult
Jon Hall73cf9cc2014-11-20 22:28:38 -08001374
Jon Hall5cfd23c2015-03-19 11:40:57 -07001375 topoResult = ( devicesResults and portsResults and linksResults
1376 and consistentHostsResult and consistentClustersResult
1377 and clusterResults and ipResult )
Jon Hall8f89dda2015-01-22 16:03:33 -08001378 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08001379 onpass="Topology Check Test successful",
1380 onfail="Topology Check Test NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001381
Jon Hall8f89dda2015-01-22 16:03:33 -08001382 finalAssert = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001383 finalAssert = ( finalAssert and topoResult and flowCheck
1384 and intentCheck and consistentMastership
Jon Halla9d26da2015-03-30 16:45:32 -07001385 and mastershipCheck and rolesNotNull )
Jon Hall8f89dda2015-01-22 16:03:33 -08001386 utilities.assert_equals( expect=main.TRUE, actual=finalAssert,
Jon Hall58c76b72015-02-23 11:09:24 -08001387 onpass="State check successful",
1388 onfail="State check NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001389
Jon Hall6aec96b2015-01-19 14:49:31 -08001390 def CASE6( self, main ):
1391 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001392 The Failure case.
Jon Hall6aec96b2015-01-19 14:49:31 -08001393 """
Jon Hall94fd0472014-12-08 11:52:42 -08001394 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001395 assert numControllers, "numControllers not defined"
1396 assert main, "main not defined"
1397 assert utilities.assert_equals, "utilities.assert_equals not defined"
1398 assert CLIs, "CLIs not defined"
1399 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001400 main.log.report( "Killing 3 ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001401 main.case( "Restart minority of ONOS nodes" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001402 # TODO: Randomize these nodes
Jon Hall5cfd23c2015-03-19 11:40:57 -07001403 # TODO: use threads in this case
1404 main.ONOSbench.onosKill( nodes[0].ip_address )
Jon Hall6aec96b2015-01-19 14:49:31 -08001405 time.sleep( 10 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001406 main.ONOSbench.onosKill( nodes[1].ip_address )
Jon Hall6aec96b2015-01-19 14:49:31 -08001407 time.sleep( 10 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001408 main.ONOSbench.onosKill( nodes[2].ip_address )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001409
Jon Hall6aec96b2015-01-19 14:49:31 -08001410 main.step( "Checking if ONOS is up yet" )
Jon Hallffb386d2014-11-21 13:43:38 -08001411 count = 0
Jon Hall8f89dda2015-01-22 16:03:33 -08001412 onosIsupResult = main.FALSE
1413 while onosIsupResult == main.FALSE and count < 10:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001414 onos1Isup = main.ONOSbench.isup( nodes[0].ip_address )
1415 onos2Isup = main.ONOSbench.isup( nodes[1].ip_address )
1416 onos3Isup = main.ONOSbench.isup( nodes[2].ip_address )
Jon Hall8f89dda2015-01-22 16:03:33 -08001417 onosIsupResult = onos1Isup and onos2Isup and onos3Isup
Jon Hallffb386d2014-11-21 13:43:38 -08001418 count = count + 1
Jon Hall73cf9cc2014-11-20 22:28:38 -08001419 # TODO: if it becomes an issue, we can retry this step a few times
1420
Jon Hall5cfd23c2015-03-19 11:40:57 -07001421 cliResult1 = main.ONOScli1.startOnosCli( nodes[0].ip_address )
1422 cliResult2 = main.ONOScli2.startOnosCli( nodes[1].ip_address )
1423 cliResult3 = main.ONOScli3.startOnosCli( nodes[2].ip_address )
Jon Hall8f89dda2015-01-22 16:03:33 -08001424 cliResults = cliResult1 and cliResult2 and cliResult3
Jon Hall73cf9cc2014-11-20 22:28:38 -08001425
Jon Hall21270ac2015-02-16 17:59:55 -08001426 # Grab the time of restart so we chan check how long the gossip
1427 # protocol has had time to work
1428 main.restartTime = time.time()
Jon Hall8f89dda2015-01-22 16:03:33 -08001429 caseResults = main.TRUE and onosIsupResult and cliResults
1430 utilities.assert_equals( expect=main.TRUE, actual=caseResults,
Jon Hall58c76b72015-02-23 11:09:24 -08001431 onpass="ONOS restart successful",
1432 onfail="ONOS restart NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001433
Jon Hall6aec96b2015-01-19 14:49:31 -08001434 def CASE7( self, main ):
1435 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001436 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -08001437 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001438 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001439 assert numControllers, "numControllers not defined"
1440 assert main, "main not defined"
1441 assert utilities.assert_equals, "utilities.assert_equals not defined"
1442 assert CLIs, "CLIs not defined"
1443 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001444 main.case( "Running ONOS Constant State Tests" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001445
Jon Hall5cfd23c2015-03-19 11:40:57 -07001446 main.step( "Check that each switch has a master" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001447 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -07001448 rolesNotNull = main.TRUE
1449 threads = []
1450 for i in range( numControllers ):
1451 t = main.Thread( target=CLIs[i].rolesNotNull,
1452 name="rolesNotNull-" + str( i ),
1453 args=[ ] )
1454 threads.append( t )
1455 t.start()
1456
1457 for t in threads:
1458 t.join()
1459 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001460 utilities.assert_equals(
1461 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001462 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001463 onpass="Each device has a master",
1464 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001465
Jon Hall5cfd23c2015-03-19 11:40:57 -07001466 ONOSMastership = []
1467 mastershipCheck = main.FALSE
1468 consistentMastership = True
1469 rolesResults = True
1470 threads = []
1471 for i in range( numControllers ):
1472 t = main.Thread( target=CLIs[i].roles,
1473 name="roles-" + str( i ),
1474 args=[] )
1475 threads.append( t )
1476 t.start()
1477
1478 for t in threads:
1479 t.join()
1480 ONOSMastership.append( t.result )
1481
1482 for i in range( numControllers ):
1483 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1484 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1485 " roles" )
1486 main.log.warn(
1487 "ONOS" + str( i + 1 ) + " mastership response: " +
1488 repr( ONOSMastership[i] ) )
1489 rolesResults = False
1490 utilities.assert_equals(
1491 expect=True,
1492 actual=rolesResults,
1493 onpass="No error in reading roles output",
1494 onfail="Error in reading roles from ONOS" )
1495
1496 main.step( "Check for consistency in roles from each controller" )
1497 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall6aec96b2015-01-19 14:49:31 -08001498 main.log.report(
1499 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001500 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001501 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001502 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001503 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001504 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001505 onpass="Switch roles are consistent across all ONOS nodes",
1506 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001507
Jon Hall5cfd23c2015-03-19 11:40:57 -07001508 if rolesResults and not consistentMastership:
1509 for i in range( numControllers ):
1510 main.log.warn(
1511 "ONOS" + str( i + 1 ) + " roles: ",
1512 json.dumps(
1513 json.loads( ONOSMastership[ i ] ),
1514 sort_keys=True,
1515 indent=4,
1516 separators=( ',', ': ' ) ) )
1517 elif rolesResults and not consistentMastership:
1518 mastershipCheck = main.TRUE
1519
Jon Hall73cf9cc2014-11-20 22:28:38 -08001520 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -08001521 main.step( description2 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001522 try:
1523 currentJson = json.loads( ONOSMastership[0] )
1524 oldJson = json.loads( mastershipState )
1525 except ( ValueError, TypeError ):
1526 main.log.exception( "Something is wrong with parsing " +
1527 "ONOSMastership[0] or mastershipState" )
1528 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1529 main.log.error( "mastershipState" + repr( mastershipState ) )
1530 main.cleanup()
1531 main.exit()
Jon Hall8f89dda2015-01-22 16:03:33 -08001532 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001533 for i in range( 1, 29 ):
1534 switchDPID = str(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001535 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001536 current = [ switch[ 'master' ] for switch in currentJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001537 if switchDPID in switch[ 'id' ] ]
Jon Hall8f89dda2015-01-22 16:03:33 -08001538 old = [ switch[ 'master' ] for switch in oldJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001539 if switchDPID in switch[ 'id' ] ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08001540 if current == old:
Jon Hall8f89dda2015-01-22 16:03:33 -08001541 mastershipCheck = mastershipCheck and main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001542 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001543 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall8f89dda2015-01-22 16:03:33 -08001544 mastershipCheck = main.FALSE
1545 if mastershipCheck == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001546 main.log.report( "Mastership of Switches was not changed" )
1547 utilities.assert_equals(
1548 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001549 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -08001550 onpass="Mastership of Switches was not changed",
1551 onfail="Mastership of some switches changed" )
1552 # NOTE: we expect mastership to change on controller failure
Jon Hall8f89dda2015-01-22 16:03:33 -08001553 mastershipCheck = consistentMastership
Jon Hall73cf9cc2014-11-20 22:28:38 -08001554
Jon Hall58c76b72015-02-23 11:09:24 -08001555 main.step( "Get the intents and compare across all nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001556 ONOSIntents = []
Jon Hall58c76b72015-02-23 11:09:24 -08001557 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001558 consistentIntents = True
1559 intentsResults = True
1560 threads = []
1561 for i in range( numControllers ):
1562 t = main.Thread( target=CLIs[i].intents,
1563 name="intents-" + str( i ),
1564 args=[],
1565 kwargs={ 'jsonFormat': True } )
1566 threads.append( t )
1567 t.start()
1568
1569 for t in threads:
1570 t.join()
1571 ONOSIntents.append( t.result )
1572
1573 for i in range( numControllers ):
1574 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1575 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1576 " intents" )
1577 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1578 repr( ONOSIntents[ i ] ) )
1579 intentsResults = False
Jon Hall58c76b72015-02-23 11:09:24 -08001580 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001581 expect=True,
1582 actual=intentsResults,
1583 onpass="No error in reading intents output",
1584 onfail="Error in reading intents from ONOS" )
1585
1586 main.step( "Check for consistency in Intents from each controller" )
1587 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1588 main.log.report( "Intents are consistent across all ONOS " +
1589 "nodes" )
1590 else:
1591 consistentIntents = False
1592 utilities.assert_equals(
1593 expect=True,
1594 actual=consistentIntents,
Jon Hall58c76b72015-02-23 11:09:24 -08001595 onpass="Intents are consistent across all ONOS nodes",
1596 onfail="ONOS nodes have different views of intents" )
Jon Hall58c76b72015-02-23 11:09:24 -08001597 intentStates = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001598 for node in ONOSIntents: # Iter through ONOS nodes
Jon Hall58c76b72015-02-23 11:09:24 -08001599 nodeStates = []
1600 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001601 try:
1602 for intent in json.loads( node ):
1603 nodeStates.append( intent[ 'state' ] )
1604 except ( ValueError, TypeError ):
1605 main.log.exception( "Error in parsing intents" )
1606 main.log.error( repr( node ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001607 intentStates.append( nodeStates )
1608 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1609 main.log.info( dict( out ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001610
Jon Hall5cfd23c2015-03-19 11:40:57 -07001611 if intentsResults and not consistentIntents:
1612 for i in range( numControllers ):
1613 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1614 main.log.warn( json.dumps(
1615 json.loads( ONOSIntents[ i ] ),
1616 sort_keys=True,
1617 indent=4,
1618 separators=( ',', ': ' ) ) )
1619 elif intentsResults and consistentIntents:
1620 intentCheck = main.TRUE
1621
Jon Hall58c76b72015-02-23 11:09:24 -08001622 # NOTE: Store has no durability, so intents are lost across system
1623 # restarts
1624 main.step( "Compare current intents with intents before the failure" )
1625 # NOTE: this requires case 5 to pass for intentState to be set.
1626 # maybe we should stop the test if that fails?
1627 sameIntents = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001628 if intentState and intentState == ONOSIntents[ 0 ]:
Jon Hall21270ac2015-02-16 17:59:55 -08001629 sameIntents = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08001630 main.log.report( "Intents are consistent with before failure" )
1631 # TODO: possibly the states have changed? we may need to figure out
Jon Hall5cfd23c2015-03-19 11:40:57 -07001632 # what the acceptable states are
Jon Hall58c76b72015-02-23 11:09:24 -08001633 else:
1634 try:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001635 main.log.warn( "ONOS intents: " )
1636 main.log.warn( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1637 sort_keys=True, indent=4,
1638 separators=( ',', ': ' ) ) )
1639 except ( ValueError, TypeError ):
1640 main.log.exception( "Exception printing intents" )
1641 main.log.warn( repr( ONOSIntents[0] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001642 sameIntents = main.FALSE
1643 utilities.assert_equals(
1644 expect=main.TRUE,
1645 actual=sameIntents,
1646 onpass="Intents are consistent with before failure",
1647 onfail="The Intents changed during failure" )
1648 intentCheck = intentCheck and sameIntents
Jon Hall21270ac2015-02-16 17:59:55 -08001649
Jon Hall58c76b72015-02-23 11:09:24 -08001650 main.step( "Get the OF Table entries and compare to before " +
1651 "component failure" )
1652 FlowTables = main.TRUE
1653 flows2 = []
1654 for i in range( 28 ):
1655 main.log.info( "Checking flow table on s" + str( i + 1 ) )
1656 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
1657 flows2.append( tmpFlows )
1658 tempResult = main.Mininet2.flowComp(
1659 flow1=flows[ i ],
1660 flow2=tmpFlows )
1661 FlowTables = FlowTables and tempResult
1662 if FlowTables == main.FALSE:
1663 main.log.info( "Differences in flow table for switch: s" +
1664 str( i + 1 ) )
1665 if FlowTables == main.TRUE:
1666 main.log.report( "No changes were found in the flow tables" )
1667 utilities.assert_equals(
1668 expect=main.TRUE,
1669 actual=FlowTables,
1670 onpass="No changes were found in the flow tables",
1671 onfail="Changes were found in the flow tables" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001672
Jon Hall6aec96b2015-01-19 14:49:31 -08001673 main.step( "Check the continuous pings to ensure that no packets " +
1674 "were dropped during component failure" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001675 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
1676 main.params[ 'TESTONIP' ] )
Jon Hall8f89dda2015-01-22 16:03:33 -08001677 LossInPings = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001678 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
1679 for i in range( 8, 18 ):
1680 main.log.info(
1681 "Checking for a loss in pings along flow from s" +
1682 str( i ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001683 LossInPings = main.Mininet2.checkForLoss(
Jon Hall6aec96b2015-01-19 14:49:31 -08001684 "/tmp/ping.h" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001685 str( i ) ) or LossInPings
1686 if LossInPings == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001687 main.log.info( "Loss in ping detected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001688 elif LossInPings == main.ERROR:
Jon Hall6aec96b2015-01-19 14:49:31 -08001689 main.log.info( "There are multiple mininet process running" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001690 elif LossInPings == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001691 main.log.info( "No Loss in the pings" )
1692 main.log.report( "No loss of dataplane connectivity" )
1693 utilities.assert_equals(
1694 expect=main.FALSE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001695 actual=LossInPings,
Jon Hall6aec96b2015-01-19 14:49:31 -08001696 onpass="No Loss of connectivity",
1697 onfail="Loss of dataplane connectivity detected" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001698
Jon Hall6aec96b2015-01-19 14:49:31 -08001699 # Test of LeadershipElection
Jon Hall8f89dda2015-01-22 16:03:33 -08001700 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001701 # FIXME: make sure this matches nodes that were restarted
1702 restarted = [ nodes[0].ip_address, nodes[1].ip_address,
1703 nodes[2].ip_address ]
1704
Jon Hall8f89dda2015-01-22 16:03:33 -08001705 leaderResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001706 for cli in CLIs:
1707 leaderN = cli.electionTestLeader()
Jon Hall8f89dda2015-01-22 16:03:33 -08001708 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08001709 if leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001710 # error in response
1711 main.log.report( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001712 "electionTestLeader function, check the" +
Jon Hall6aec96b2015-01-19 14:49:31 -08001713 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001714 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001715 elif leaderN is None:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001716 main.log.report( cli.name +
Jon Hall6aec96b2015-01-19 14:49:31 -08001717 " shows no leader for the election-app was" +
1718 " elected after the old one died" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001719 leaderResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001720 elif leaderN in restarted:
1721 main.log.report( cli.name + " shows " + str( leaderN ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08001722 " as leader for the election-app, but it " +
1723 "was restarted" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001724 leaderResult = main.FALSE
1725 if len( set( leaderList ) ) != 1:
1726 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001727 main.log.error(
1728 "Inconsistent view of leader for the election test app" )
1729 # TODO: print the list
Jon Hall8f89dda2015-01-22 16:03:33 -08001730 if leaderResult:
1731 main.log.report( "Leadership election tests passed( consistent " +
Jon Hall6aec96b2015-01-19 14:49:31 -08001732 "view of leader across listeners and a new " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001733 "leader was re-elected if applicable )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001734 utilities.assert_equals(
1735 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001736 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001737 onpass="Leadership election passed",
1738 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08001739
Jon Hall58c76b72015-02-23 11:09:24 -08001740 result = ( mastershipCheck and intentCheck and FlowTables and
1741 ( not LossInPings ) and rolesNotNull and leaderResult )
Jon Hall6aec96b2015-01-19 14:49:31 -08001742 result = int( result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001743 if result == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001744 main.log.report( "Constant State Tests Passed" )
1745 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hallfebb1c72015-03-05 13:30:09 -08001746 onpass="Constant State Tests Passed",
1747 onfail="Constant state tests failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001748
Jon Hall6aec96b2015-01-19 14:49:31 -08001749 def CASE8( self, main ):
1750 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001751 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -08001752 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001753 import sys
Jon Hall6aec96b2015-01-19 14:49:31 -08001754 # FIXME add this path to params
1755 sys.path.append( "/home/admin/sts" )
1756 # assumes that sts is already in you PYTHONPATH
1757 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -08001758 import json
1759 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001760 assert numControllers, "numControllers not defined"
1761 assert main, "main not defined"
1762 assert utilities.assert_equals, "utilities.assert_equals not defined"
1763 assert CLIs, "CLIs not defined"
1764 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08001765
Jon Hall6aec96b2015-01-19 14:49:31 -08001766 description = "Compare ONOS Topology view to Mininet topology"
1767 main.case( description )
1768 main.log.report( description )
1769 main.step( "Create TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001770 ctrls = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001771 for node in nodes:
1772 temp = ( node, node.name, node.ip_address, 6633 )
1773 ctrls.append( temp )
1774 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001775
Jon Hall6aec96b2015-01-19 14:49:31 -08001776 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001777 devicesResults = main.TRUE
1778 portsResults = main.TRUE
1779 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08001780 hostsResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08001781 topoResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001782 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -08001783 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -08001784 main.step( "Collecting topology information from ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001785 startTime = time.time()
Jon Hall21270ac2015-02-16 17:59:55 -08001786 # Give time for Gossip to work
Jon Hall8f89dda2015-01-22 16:03:33 -08001787 while topoResult == main.FALSE and elapsed < 60:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001788 count += 1
Jon Hall94fd0472014-12-08 11:52:42 -08001789 if count > 1:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001790 # TODO: Deprecate STS usage
Jon Hall58c76b72015-02-23 11:09:24 -08001791 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall8f89dda2015-01-22 16:03:33 -08001792 cliStart = time.time()
Jon Hall94fd0472014-12-08 11:52:42 -08001793 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001794 threads = []
1795 for i in range( numControllers ):
1796 t = main.Thread( target=CLIs[i].devices,
1797 name="devices-" + str( i ),
1798 args=[ ] )
1799 threads.append( t )
1800 t.start()
1801
1802 for t in threads:
1803 t.join()
1804 devices.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001805 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -08001806 ipResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001807 threads = []
1808 for i in range( numControllers ):
1809 t = main.Thread( target=CLIs[i].hosts,
1810 name="hosts-" + str( i ),
1811 args=[ ] )
1812 threads.append( t )
1813 t.start()
1814
1815 for t in threads:
1816 t.join()
1817 try:
1818 hosts.append( json.loads( t.result ) )
1819 except ( ValueError, TypeError ):
1820 main.log.exception( "Error parsing hosts results" )
1821 main.log.error( repr( t.result ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001822 for controller in range( 0, len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001823 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001824 for host in hosts[ controller ]:
Jon Hall58c76b72015-02-23 11:09:24 -08001825 if host is None or host.get( 'ips', [] ) == []:
Jon Hall6aec96b2015-01-19 14:49:31 -08001826 main.log.error(
1827 "DEBUG:Error with host ips on controller" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001828 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001829 ipResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001830 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001831 threads = []
1832 for i in range( numControllers ):
1833 t = main.Thread( target=CLIs[i].ports,
1834 name="ports-" + str( i ),
1835 args=[ ] )
1836 threads.append( t )
1837 t.start()
1838
1839 for t in threads:
1840 t.join()
1841 ports.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001842 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001843 threads = []
1844 for i in range( numControllers ):
1845 t = main.Thread( target=CLIs[i].links,
1846 name="links-" + str( i ),
1847 args=[ ] )
1848 threads.append( t )
1849 t.start()
1850
1851 for t in threads:
1852 t.join()
1853 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001854 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001855 threads = []
1856 for i in range( numControllers ):
1857 t = main.Thread( target=CLIs[i].clusters,
1858 name="clusters-" + str( i ),
1859 args=[ ] )
1860 threads.append( t )
1861 t.start()
1862
1863 for t in threads:
1864 t.join()
1865 clusters.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001866
Jon Hall8f89dda2015-01-22 16:03:33 -08001867 elapsed = time.time() - startTime
1868 cliTime = time.time() - cliStart
1869 print "CLI time: " + str( cliTime )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001870
Jon Hall8f89dda2015-01-22 16:03:33 -08001871 for controller in range( numControllers ):
1872 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001873 if devices[ controller ] or "Error" not in devices[
1874 controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001875 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08001876 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08001877 json.loads( devices[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001878 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001879 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001880 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001881 actual=currentDevicesResult,
1882 onpass="ONOS" + controllerStr +
1883 " Switches view is correct",
1884 onfail="ONOS" + controllerStr +
1885 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001886
Jon Hall6aec96b2015-01-19 14:49:31 -08001887 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001888 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08001889 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08001890 json.loads( ports[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001891 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001892 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001893 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001894 actual=currentPortsResult,
1895 onpass="ONOS" + controllerStr +
1896 " ports view is correct",
1897 onfail="ONOS" + controllerStr +
1898 " ports view is incorrect" )
Jon Hall94fd0472014-12-08 11:52:42 -08001899
Jon Hall6aec96b2015-01-19 14:49:31 -08001900 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001901 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08001902 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08001903 json.loads( links[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001904 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001905 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001906 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001907 actual=currentLinksResult,
1908 onpass="ONOS" + controllerStr +
1909 " links view is correct",
1910 onfail="ONOS" + controllerStr +
1911 " links view is incorrect" )
1912
1913 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1914 currentHostsResult = main.Mininet1.compareHosts(
1915 MNTopo, hosts[ controller ] )
1916 else:
1917 currentHostsResult = main.FALSE
1918 utilities.assert_equals( expect=main.TRUE,
1919 actual=currentHostsResult,
1920 onpass="ONOS" + controllerStr +
1921 " hosts exist in Mininet",
1922 onfail="ONOS" + controllerStr +
1923 " hosts don't match Mininet" )
1924
1925 devicesResults = devicesResults and currentDevicesResult
1926 portsResults = portsResults and currentPortsResult
1927 linksResults = linksResults and currentLinksResult
1928 hostsResults = hostsResults and currentHostsResult
Jon Hall94fd0472014-12-08 11:52:42 -08001929
Jon Hall529a37f2015-01-28 10:02:00 -08001930 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001931
Jon Hall6aec96b2015-01-19 14:49:31 -08001932 # hosts
Jon Hall8f89dda2015-01-22 16:03:33 -08001933 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001934 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001935 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001936 if "Error" not in hosts[ controller ]:
1937 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001938 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001939 else: # hosts not consistent
Jon Hall8f89dda2015-01-22 16:03:33 -08001940 main.log.report( "hosts from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001941 " is inconsistent with ONOS1" )
1942 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001943 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001944
1945 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001946 main.log.report( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001947 controllerStr )
1948 consistentHostsResult = main.FALSE
1949 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001950 " hosts response: " +
1951 repr( hosts[ controller ] ) )
1952 utilities.assert_equals(
1953 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001954 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001955 onpass="Hosts view is consistent across all ONOS nodes",
1956 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001957
Jon Hall6aec96b2015-01-19 14:49:31 -08001958 # Strongly connected clusters of devices
Jon Hall8f89dda2015-01-22 16:03:33 -08001959 consistentClustersResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001960 for controller in range( len( clusters ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001961 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001962 if "Error" not in clusters[ controller ]:
1963 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001964 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001965 else: # clusters not consistent
1966 main.log.report( "clusters from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001967 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001968 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001969 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001970
1971 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001972 main.log.report( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001973 "from ONOS" + controllerStr )
1974 consistentClustersResult = main.FALSE
1975 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001976 " clusters response: " +
1977 repr( clusters[ controller ] ) )
1978 utilities.assert_equals(
1979 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001980 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001981 onpass="Clusters view is consistent across all ONOS nodes",
1982 onfail="ONOS nodes have different views of clusters" )
1983 # there should always only be one cluster
Jon Hall5cfd23c2015-03-19 11:40:57 -07001984 try:
1985 numClusters = len( json.loads( clusters[ 0 ] ) )
1986 except ( ValueError, TypeError ):
1987 main.log.exception( "Error parsing clusters[0]: " +
1988 repr( clusters[0] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001989 clusterResults = main.FALSE
1990 if numClusters == 1:
1991 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001992 utilities.assert_equals(
1993 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08001994 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08001995 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08001996 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08001997
Jon Hall8f89dda2015-01-22 16:03:33 -08001998 topoResult = ( devicesResults and portsResults and linksResults
Jon Hall58c76b72015-02-23 11:09:24 -08001999 and hostsResults and consistentHostsResult
2000 and consistentClustersResult and clusterResults
2001 and ipResult )
Jon Hall94fd0472014-12-08 11:52:42 -08002002
Jon Hall8f89dda2015-01-22 16:03:33 -08002003 topoResult = topoResult and int( count <= 2 )
2004 note = "note it takes about " + str( int( cliTime ) ) + \
2005 " seconds for the test to make all the cli calls to fetch " +\
2006 "the topology from each ONOS instance"
Jon Hall1b8f54a2015-02-04 13:24:20 -08002007 main.log.info(
Jon Hall8f89dda2015-01-22 16:03:33 -08002008 "Very crass estimate for topology discovery/convergence( " +
2009 str( note ) + " ): " + str( elapsed ) + " seconds, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002010 str( count ) + " tries" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002011 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08002012 onpass="Topology Check Test successful",
2013 onfail="Topology Check Test NOT successful" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002014 if topoResult == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002015 main.log.report( "ONOS topology view matches Mininet topology" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002016
Jon Halla9d26da2015-03-30 16:45:32 -07002017 # FIXME: move this to an ONOS state case
2018 main.step( "Checking ONOS nodes" )
2019 nodesOutput = []
2020 threads = []
2021 for i in range( numControllers ):
2022 t = main.Thread( target=CLIs[i].nodes,
2023 name="nodes-" + str( i ),
2024 args=[ ] )
2025 threads.append( t )
2026 t.start()
2027
2028 for t in threads:
2029 t.join()
2030 nodesOutput.append( t.result )
2031 ips = [ node.ip_address for node in nodes ]
2032 for i in nodesOutput:
2033 try:
2034 current = json.loads( i )
2035 for node in current:
2036 if node['ip'] in ips: # node in nodes() output is in cell
2037 if node['state'] == 'ACTIVE':
2038 pass # as it should be
2039 else:
2040 main.log.error( "Error in ONOS node availability" )
2041 main.log.error(
2042 json.dumps( current,
2043 sort_keys=True,
2044 indent=4,
2045 separators=( ',', ': ' ) ) )
2046 break
2047 except ( ValueError, TypeError ):
2048 main.log.error( "Error parsing nodes output" )
2049 main.log.warn( repr( i ) )
2050
Jon Hall6aec96b2015-01-19 14:49:31 -08002051 def CASE9( self, main ):
2052 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002053 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -08002054 """
2055 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002056 assert numControllers, "numControllers not defined"
2057 assert main, "main not defined"
2058 assert utilities.assert_equals, "utilities.assert_equals not defined"
2059 assert CLIs, "CLIs not defined"
2060 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002061 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002062
Jon Hall8f89dda2015-01-22 16:03:33 -08002063 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002064
Jon Hall6aec96b2015-01-19 14:49:31 -08002065 description = "Turn off a link to ensure that Link Discovery " +\
Jon Hall58c76b72015-02-23 11:09:24 -08002066 "is working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002067 main.log.report( description )
2068 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002069
Jon Hall6aec96b2015-01-19 14:49:31 -08002070 main.step( "Kill Link between s3 and s28" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002071 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
Jon Hall58c76b72015-02-23 11:09:24 -08002072 main.log.info( "Waiting " + str( linkSleep ) +
2073 " seconds for link down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002074 time.sleep( linkSleep )
2075 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002076 onpass="Link down successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002077 onfail="Failed to bring link down" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002078 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002079
Jon Hall6aec96b2015-01-19 14:49:31 -08002080 def CASE10( self, main ):
2081 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002082 Link s3-s28 up
Jon Hall6aec96b2015-01-19 14:49:31 -08002083 """
2084 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002085 assert numControllers, "numControllers not defined"
2086 assert main, "main not defined"
2087 assert utilities.assert_equals, "utilities.assert_equals not defined"
2088 assert CLIs, "CLIs not defined"
2089 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002090 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002091
Jon Hall8f89dda2015-01-22 16:03:33 -08002092 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002093
Jon Hall6aec96b2015-01-19 14:49:31 -08002094 description = "Restore a link to ensure that Link Discovery is " + \
Jon Hall63604932015-02-26 17:09:50 -08002095 "working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002096 main.log.report( description )
2097 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002098
Jon Hall6aec96b2015-01-19 14:49:31 -08002099 main.step( "Bring link between s3 and s28 back up" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002100 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
Jon Hall58c76b72015-02-23 11:09:24 -08002101 main.log.info( "Waiting " + str( linkSleep ) +
2102 " seconds for link up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002103 time.sleep( linkSleep )
2104 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002105 onpass="Link up successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002106 onfail="Failed to bring link up" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002107 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002108
Jon Hall6aec96b2015-01-19 14:49:31 -08002109 def CASE11( self, main ):
2110 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002111 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -08002112 """
2113 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002114 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002115 assert numControllers, "numControllers not defined"
2116 assert main, "main not defined"
2117 assert utilities.assert_equals, "utilities.assert_equals not defined"
2118 assert CLIs, "CLIs not defined"
2119 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08002120
Jon Hall8f89dda2015-01-22 16:03:33 -08002121 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002122
2123 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002124 main.log.report( description )
2125 main.case( description )
2126 switch = main.params[ 'kill' ][ 'switch' ]
2127 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08002128
Jon Hall6aec96b2015-01-19 14:49:31 -08002129 # TODO: Make this switch parameterizable
2130 main.step( "Kill " + switch )
2131 main.log.report( "Deleting " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002132 main.Mininet1.delSwitch( switch )
2133 main.log.info( "Waiting " + str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002134 " seconds for switch down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002135 time.sleep( switchSleep )
2136 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002137 # Peek at the deleted switch
2138 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002139 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002140 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -08002141 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002142 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002143 onpass="Kill switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002144 onfail="Failed to kill switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002145
Jon Hall6aec96b2015-01-19 14:49:31 -08002146 def CASE12( self, main ):
2147 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002148 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -08002149 """
2150 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002151 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002152 assert numControllers, "numControllers not defined"
2153 assert main, "main not defined"
2154 assert utilities.assert_equals, "utilities.assert_equals not defined"
2155 assert CLIs, "CLIs not defined"
2156 assert nodes, "nodes not defined"
2157 assert ONOS1Port, "ONOS1Port not defined"
2158 assert ONOS2Port, "ONOS2Port not defined"
2159 assert ONOS3Port, "ONOS3Port not defined"
2160 assert ONOS4Port, "ONOS4Port not defined"
2161 assert ONOS5Port, "ONOS5Port not defined"
2162 assert ONOS6Port, "ONOS6Port not defined"
2163 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall669173b2014-12-17 11:36:30 -08002164
Jon Hall8f89dda2015-01-22 16:03:33 -08002165 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall6aec96b2015-01-19 14:49:31 -08002166 switch = main.params[ 'kill' ][ 'switch' ]
2167 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2168 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002169 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002170 main.log.report( description )
2171 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002172
Jon Hall6aec96b2015-01-19 14:49:31 -08002173 main.step( "Add back " + switch )
2174 main.log.report( "Adding back " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002175 main.Mininet1.addSwitch( switch, dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002176 for peer in links:
Jon Hall8f89dda2015-01-22 16:03:33 -08002177 main.Mininet1.addLink( switch, peer )
Jon Hall58c76b72015-02-23 11:09:24 -08002178 main.Mininet1.assignSwController( sw=switch.split( 's' )[ 1 ],
2179 count=numControllers,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002180 ip1=nodes[ 0 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002181 port1=ONOS1Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002182 ip2=nodes[ 1 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002183 port2=ONOS2Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002184 ip3=nodes[ 2 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002185 port3=ONOS3Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002186 ip4=nodes[ 3 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002187 port4=ONOS4Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002188 ip5=nodes[ 4 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002189 port5=ONOS5Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002190 ip6=nodes[ 5 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002191 port6=ONOS6Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002192 ip7=nodes[ 6 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002193 port7=ONOS7Port )
2194 main.log.info( "Waiting " + str( switchSleep ) +
2195 " seconds for switch up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002196 time.sleep( switchSleep )
2197 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002198 # Peek at the deleted switch
2199 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002200 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002201 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002202 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002203 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002204 onpass="add switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002205 onfail="Failed to add switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002206
Jon Hall6aec96b2015-01-19 14:49:31 -08002207 def CASE13( self, main ):
2208 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002209 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -08002210 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002211 import os
2212 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002213 assert numControllers, "numControllers not defined"
2214 assert main, "main not defined"
2215 assert utilities.assert_equals, "utilities.assert_equals not defined"
2216 assert CLIs, "CLIs not defined"
2217 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002218
2219 # printing colors to terminal
Jon Hall5cfd23c2015-03-19 11:40:57 -07002220 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2221 'blue': '\033[94m', 'green': '\033[92m',
2222 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
Jon Hall73cf9cc2014-11-20 22:28:38 -08002223 description = "Test Cleanup"
Jon Hall6aec96b2015-01-19 14:49:31 -08002224 main.log.report( description )
2225 main.case( description )
2226 main.step( "Killing tcpdumps" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002227 main.Mininet2.stopTcpdump()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002228
Jon Hall6aec96b2015-01-19 14:49:31 -08002229 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002230 testname = main.TEST
Jon Hall8f89dda2015-01-22 16:03:33 -08002231 teststationUser = main.params[ 'TESTONUSER' ]
2232 teststationIP = main.params[ 'TESTONIP' ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002233 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -08002234 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -08002235 # FIXME: scp
2236 # mn files
2237 # TODO: Load these from params
2238 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002239 logFolder = "/opt/onos/log/"
2240 logFiles = [ "karaf.log", "karaf.log.1" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002241 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002242 dstDir = "~/packet_captures/"
2243 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002244 for node in nodes:
2245 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2246 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002247 teststationUser + "@" +
2248 teststationIP + ":" +
2249 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002250 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002251 main.ONOSbench.handle.expect( "\$" )
2252
Jon Hall6aec96b2015-01-19 14:49:31 -08002253 # std*.log's
2254 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002255 logFolder = "/opt/onos/var/"
2256 logFiles = [ "stderr.log", "stdout.log" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002257 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002258 dstDir = "~/packet_captures/"
2259 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002260 for node in nodes:
2261 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2262 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002263 teststationUser + "@" +
2264 teststationIP + ":" +
2265 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002266 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002267 main.ONOSbench.handle.expect( "\$" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002268 # sleep so scp can finish
2269 time.sleep( 10 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002270
2271 main.step( "Stopping Mininet" )
Jon Hall58c76b72015-02-23 11:09:24 -08002272 main.Mininet1.stopNet()
Jon Hall5cfd23c2015-03-19 11:40:57 -07002273
2274 main.step( "Checking ONOS Logs for errors" )
2275 for node in nodes:
2276 print colors[ 'purple' ] + "Checking logs for errors on " + \
2277 node.name + ":" + colors[ 'end' ]
2278 print main.ONOSbench.checkLogs( node.ip_address )
2279
Jon Hall6aec96b2015-01-19 14:49:31 -08002280 main.step( "Packing and rotating pcap archives" )
2281 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002282
Jon Hall6aec96b2015-01-19 14:49:31 -08002283 # TODO: actually check something here
2284 utilities.assert_equals( expect=main.TRUE, actual=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002285 onpass="Test cleanup successful",
2286 onfail="Test cleanup NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002287
Jon Hall6aec96b2015-01-19 14:49:31 -08002288 def CASE14( self, main ):
2289 """
Jon Hall669173b2014-12-17 11:36:30 -08002290 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -08002291 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07002292 import time
2293 assert numControllers, "numControllers not defined"
2294 assert main, "main not defined"
2295 assert utilities.assert_equals, "utilities.assert_equals not defined"
2296 assert CLIs, "CLIs not defined"
2297 assert nodes, "nodes not defined"
2298
Jon Hall8f89dda2015-01-22 16:03:33 -08002299 leaderResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002300 main.log.info( "Install leadership election app" )
Jon Halla9d26da2015-03-30 16:45:32 -07002301 main.ONOScli1.activateApp( "org.onosproject.election" )
2302 leaders = []
2303 for cli in CLIs:
2304 leader = cli.electionTestLeader()
2305 if leader is None or leader == main.FALSE:
2306 main.log.report( cli.name + ": Leader for the election app " +
2307 "should be an ONOS node, instead got '" +
2308 str( leader ) + "'" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002309 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002310 leaders.append( leader )
2311 if len( set( leaders ) ) != 1:
2312 leaderResult = main.FALSE
2313 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2314 str( leaders ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08002315 if leaderResult:
Jon Hall6aec96b2015-01-19 14:49:31 -08002316 main.log.report( "Leadership election tests passed( consistent " +
2317 "view of leader across listeners and a leader " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002318 "was elected )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002319 utilities.assert_equals(
2320 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002321 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002322 onpass="Leadership election passed",
2323 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002324
Jon Hall6aec96b2015-01-19 14:49:31 -08002325 def CASE15( self, main ):
2326 """
Jon Hall669173b2014-12-17 11:36:30 -08002327 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08002328 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07002329 assert numControllers, "numControllers not defined"
2330 assert main, "main not defined"
2331 assert utilities.assert_equals, "utilities.assert_equals not defined"
2332 assert CLIs, "CLIs not defined"
2333 assert nodes, "nodes not defined"
2334
Jon Hall8f89dda2015-01-22 16:03:33 -08002335 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002336 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08002337 main.log.report( description )
2338 main.case( description )
2339 main.step( "Find current leader and withdraw" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002340 leader = main.ONOScli1.electionTestLeader()
Jon Halla9d26da2015-03-30 16:45:32 -07002341 # do some sanity checking on leader before using it
Jon Hall8f89dda2015-01-22 16:03:33 -08002342 withdrawResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002343 if leader is None or leader == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002344 main.log.report(
2345 "Leader for the election app should be an ONOS node," +
Jon Hall58c76b72015-02-23 11:09:24 -08002346 "instead got '" + str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002347 leaderResult = main.FALSE
Jon Hall63604932015-02-26 17:09:50 -08002348 oldLeader = None
Jon Hall5cfd23c2015-03-19 11:40:57 -07002349 for i in range( len( CLIs ) ):
2350 if leader == nodes[ i ].ip_address:
2351 oldLeader = CLIs[ i ]
2352 break
Jon Halla9d26da2015-03-30 16:45:32 -07002353 else: # FOR/ELSE statement
Jon Hall5cfd23c2015-03-19 11:40:57 -07002354 main.log.error( "Leader election, could not find current leader" )
Jon Hall63604932015-02-26 17:09:50 -08002355 if oldLeader:
2356 withdrawResult = oldLeader.electionTestWithdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08002357 utilities.assert_equals(
2358 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002359 actual=withdrawResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002360 onpass="App was withdrawn from election",
2361 onfail="App was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08002362
Jon Hall6aec96b2015-01-19 14:49:31 -08002363 main.step( "Make sure new leader is elected" )
Jon Halla9d26da2015-03-30 16:45:32 -07002364 # FIXME: use threads
Jon Hall8f89dda2015-01-22 16:03:33 -08002365 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002366 for cli in CLIs:
2367 leaderN = cli.electionTestLeader()
2368 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002369 if leaderN == leader:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002370 main.log.report( cli.name + " still sees " + str( leader ) +
2371 " as leader after they withdrew" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002372 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002373 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002374 # error in response
2375 # TODO: add check for "Command not found:" in the driver, this
Jon Hall5cfd23c2015-03-19 11:40:57 -07002376 # means the app isn't loaded
Jon Hall6aec96b2015-01-19 14:49:31 -08002377 main.log.report( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002378 "electionTestLeader function, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002379 "check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002380 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002381 elif leaderN is None:
2382 # node may not have recieved the event yet
2383 leaderN = cli.electionTestLeader()
2384 leaderList.pop()
2385 leaderList.append( leaderN )
Jon Hall8f89dda2015-01-22 16:03:33 -08002386 consistentLeader = main.FALSE
2387 if len( set( leaderList ) ) == 1:
Jon Hall6aec96b2015-01-19 14:49:31 -08002388 main.log.info( "Each Election-app sees '" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002389 str( leaderList[ 0 ] ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002390 "' as the leader" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002391 consistentLeader = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002392 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08002393 main.log.report(
2394 "Inconsistent responses for leader of Election-app:" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002395 for n in range( len( leaderList ) ):
Jon Hall6aec96b2015-01-19 14:49:31 -08002396 main.log.report( "ONOS" + str( n + 1 ) + " response: " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002397 str( leaderList[ n ] ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002398 leaderResult = leaderResult and consistentLeader
Jon Hall8f89dda2015-01-22 16:03:33 -08002399 if leaderResult:
2400 main.log.report( "Leadership election tests passed( consistent " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002401 "view of leader across listeners and a new " +
2402 "leader was elected when the old leader " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002403 "resigned )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002404 utilities.assert_equals(
2405 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002406 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002407 onpass="Leadership election passed",
2408 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002409
Jon Hall58c76b72015-02-23 11:09:24 -08002410 main.step( "Run for election on old leader( just so everyone " +
2411 "is in the hat )" )
Jon Hall63604932015-02-26 17:09:50 -08002412 if oldLeader:
2413 runResult = oldLeader.electionTestRun()
2414 else:
2415 runResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002416 utilities.assert_equals(
2417 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002418 actual=runResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002419 onpass="App re-ran for election",
2420 onfail="App failed to run for election" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002421 if consistentLeader == main.TRUE:
2422 afterRun = main.ONOScli1.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08002423 # verify leader didn't just change
Jon Hall8f89dda2015-01-22 16:03:33 -08002424 if afterRun == leaderList[ 0 ]:
2425 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002426 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002427 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002428 # TODO: assert on run and withdraw results?
Jon Hall669173b2014-12-17 11:36:30 -08002429
Jon Hall6aec96b2015-01-19 14:49:31 -08002430 utilities.assert_equals(
2431 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002432 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002433 onpass="Leadership election passed",
2434 onfail="Something went wrong with Leadership election after " +
2435 "the old leader re-ran for election" )