blob: bc9e69a6803bb10467c86cce20b04ba834afe5d4 [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 Hall5cfd23c2015-03-19 11:40:57 -0700301 if ip in main.ONOScli1.getRole( deviceId ).get( 'master' ):
Jon Hall58c76b72015-02-23 11:09:24 -0800302 roleCheck = roleCheck and main.TRUE
303 else:
304 roleCheck = roleCheck and main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -0700305 main.log.error( "Error, controller " + ip + " is not" +
306 " master " + "of device " +
307 str( deviceId ) )
Jon Hall58c76b72015-02-23 11:09:24 -0800308 except ( AttributeError, AssertionError ):
309 main.log.exception( "Something is wrong with ONOS device view" )
310 main.log.info( main.ONOScli1.devices() )
Jon Hall6aec96b2015-01-19 14:49:31 -0800311 utilities.assert_equals(
312 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800313 actual=roleCall,
Jon Hall6aec96b2015-01-19 14:49:31 -0800314 onpass="Re-assigned switch mastership to designated controller",
Jon Hall8f89dda2015-01-22 16:03:33 -0800315 onfail="Something wrong with deviceRole calls" )
Jon Hall94fd0472014-12-08 11:52:42 -0800316
Jon Hall6aec96b2015-01-19 14:49:31 -0800317 utilities.assert_equals(
318 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800319 actual=roleCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800320 onpass="Switches were successfully reassigned to designated " +
321 "controller",
322 onfail="Switches were not successfully reassigned" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800323 mastershipCheck = mastershipCheck and roleCall and roleCheck
324 utilities.assert_equals( expect=main.TRUE, actual=mastershipCheck,
Jon Hall21270ac2015-02-16 17:59:55 -0800325 onpass="Switch mastership correctly assigned",
326 onfail="Error in (re)assigning switch" +
327 " mastership" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800328
Jon Hall6aec96b2015-01-19 14:49:31 -0800329 def CASE3( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800330 """
331 Assign intents
Jon Hall73cf9cc2014-11-20 22:28:38 -0800332 """
333 import time
Jon Hallfebb1c72015-03-05 13:30:09 -0800334 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700335 assert numControllers, "numControllers not defined"
336 assert main, "main not defined"
337 assert utilities.assert_equals, "utilities.assert_equals not defined"
338 assert CLIs, "CLIs not defined"
339 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -0800340 main.log.report( "Adding host intents" )
341 main.case( "Adding host Intents" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800342
Jon Hall8f89dda2015-01-22 16:03:33 -0800343 main.step( "Discovering Hosts( Via pingall for now )" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800344 # FIXME: Once we have a host discovery mechanism, use that instead
Jon Hall73cf9cc2014-11-20 22:28:38 -0800345
Jon Hall6aec96b2015-01-19 14:49:31 -0800346 # install onos-app-fwd
347 main.log.info( "Install reactive forwarding app" )
Jon Halla9d26da2015-03-30 16:45:32 -0700348 appResults = CLIs[0].activateApp( "org.onosproject.fwd" )
349
350 # FIXME: add this to asserts
351 appCheck = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700352 threads = []
353 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700354 t = main.Thread( target=CLIs[i].appToIDCheck,
355 name="appToIDCheck-" + str( i ),
356 args=[] )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700357 threads.append( t )
358 t.start()
359
360 for t in threads:
361 t.join()
Jon Halla9d26da2015-03-30 16:45:32 -0700362 appCheck = appCheck and t.result
363 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
364 onpass="App Ids seem to be correct",
365 onfail="Something is wrong with app Ids" )
366 if appCheck != main.TRUE:
367 main.log.warn( CLIs[0].apps() )
368 main.log.warn( CLIs[0].appIDs() )
Jon Hall94fd0472014-12-08 11:52:42 -0800369
Jon Hall6aec96b2015-01-19 14:49:31 -0800370 # REACTIVE FWD test
Jon Hall8f89dda2015-01-22 16:03:33 -0800371 pingResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700372 for i in range(2): # Retry if pingall fails first time
373 time1 = time.time()
374 pingResult = main.Mininet1.pingall()
375 utilities.assert_equals(
376 expect=main.TRUE,
377 actual=pingResult,
378 onpass="Reactive Pingall test passed",
379 onfail="Reactive Pingall failed, one or more ping pairs failed" )
380 time2 = time.time()
381 main.log.info( "Time for pingall: %2f seconds" % ( time2 - time1 ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800382
Jon Hall6aec96b2015-01-19 14:49:31 -0800383 # uninstall onos-app-fwd
384 main.log.info( "Uninstall reactive forwarding app" )
Jon Halla9d26da2015-03-30 16:45:32 -0700385 appResults = appResults and CLIs[0].deactivateApp( "org.onosproject.fwd" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700386 threads = []
387 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700388 t = main.Thread( target=CLIs[i].appToIDCheck,
389 name="appToIDCheck-" + str( i ),
390 args=[] )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700391 threads.append( t )
392 t.start()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800393
Jon Hall5cfd23c2015-03-19 11:40:57 -0700394 for t in threads:
395 t.join()
Jon Halla9d26da2015-03-30 16:45:32 -0700396 appCheck = appCheck and t.result
397 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
398 onpass="App Ids seem to be correct",
399 onfail="Something is wrong with app Ids" )
400 if appCheck != main.TRUE:
401 main.log.warn( CLIs[0].apps() )
402 main.log.warn( CLIs[0].appIDs() )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700403
404 # timeout for fwd flows
405 time.sleep( 11 )
406
407 main.step( "Add host intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800408 intentIds = []
Jon Hall6aec96b2015-01-19 14:49:31 -0800409 # TODO: move the host numbers to params
Jon Hall58c76b72015-02-23 11:09:24 -0800410 # Maybe look at all the paths we ping?
Jon Hall8f89dda2015-01-22 16:03:33 -0800411 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800412 hostResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800413 for i in range( 8, 18 ):
414 main.log.info( "Adding host intent between h" + str( i ) +
415 " and h" + str( i + 10 ) )
416 host1 = "00:00:00:00:00:" + \
417 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
418 host2 = "00:00:00:00:00:" + \
419 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800420 # NOTE: getHost can return None
421 host1Dict = main.ONOScli1.getHost( host1 )
422 host2Dict = main.ONOScli1.getHost( host2 )
423 host1Id = None
424 host2Id = None
425 if host1Dict and host2Dict:
426 host1Id = host1Dict.get( 'id', None )
427 host2Id = host2Dict.get( 'id', None )
Jon Hall8f89dda2015-01-22 16:03:33 -0800428 if host1Id and host2Id:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700429 nodeNum = ( i % 7 )
430 tmpId = CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
Jon Hall63604932015-02-26 17:09:50 -0800431 if tmpId:
432 main.log.info( "Added intent with id: " + tmpId )
433 intentIds.append( tmpId )
434 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700435 main.log.error( "addHostIntent returned: " +
436 repr( tmpId ) )
Jon Hall669173b2014-12-17 11:36:30 -0800437 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700438 main.log.error( "Error, getHost() failed for h" + str( i ) +
439 " and/or h" + str( i + 10 ) )
440 hosts = CLIs[ 0 ].hosts()
441 main.log.warn( "Hosts output: " )
442 try:
443 main.log.warn( json.dumps( json.loads( hosts ),
444 sort_keys=True,
445 indent=4,
446 separators=( ',', ': ' ) ) )
447 except ( ValueError, TypeError ):
448 main.log.warn( repr( hosts ) )
Jon Hall58c76b72015-02-23 11:09:24 -0800449 hostResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -0700450 # FIXME: DEBUG
451 intentStart = time.time()
Jon Hall58c76b72015-02-23 11:09:24 -0800452 onosIds = main.ONOScli1.getAllIntentsId()
453 main.log.info( "Submitted intents: " + str( intentIds ) )
454 main.log.info( "Intents in ONOS: " + str( onosIds ) )
455 for intent in intentIds:
456 if intent in onosIds:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700457 pass # intent submitted is in onos
Jon Hall58c76b72015-02-23 11:09:24 -0800458 else:
459 intentAddResult = False
Jon Halla9d26da2015-03-30 16:45:32 -0700460 # FIXME: DEBUG
461 if intentAddResult:
462 intentStop = time.time()
463 else:
464 intentStop = None
Jon Hall1b8f54a2015-02-04 13:24:20 -0800465 # Print the intent states
Jon Hall58c76b72015-02-23 11:09:24 -0800466 intents = main.ONOScli1.intents()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800467 intentStates = []
Jon Hall5cfd23c2015-03-19 11:40:57 -0700468 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800469 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
470 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700471 try:
472 for intent in json.loads( intents ):
473 state = intent.get( 'state', None )
474 if "INSTALLED" not in state:
475 installedCheck = False
476 intentId = intent.get( 'id', None )
477 intentStates.append( ( intentId, state ) )
478 except ( ValueError, TypeError ):
479 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800480 # add submitted intents not in the store
481 tmplist = [ i for i, s in intentStates ]
482 missingIntents = False
483 for i in intentIds:
484 if i not in tmplist:
485 intentStates.append( ( i, " - " ) )
486 missingIntents = True
487 intentStates.sort()
488 for i, s in intentStates:
489 count += 1
490 main.log.info( "%-6s%-15s%-15s" %
491 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700492 leaders = main.ONOScli1.leaders()
493 try:
494 if leaders:
495 parsedLeaders = json.loads( leaders )
496 main.log.warn( json.dumps( parsedLeaders,
497 sort_keys=True,
498 indent=4,
499 separators=( ',', ': ' ) ) )
500 # check for all intent partitions
Jon Hall5cfd23c2015-03-19 11:40:57 -0700501 topics = []
502 for i in range( 14 ):
503 topics.append( "intent-partition-" + str( i ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700504 main.log.debug( topics )
505 ONOStopics = [ j['topic'] for j in parsedLeaders ]
506 for topic in topics:
507 if topic not in ONOStopics:
508 main.log.error( "Error: " + topic +
509 " not in leaders" )
510 else:
511 main.log.error( "leaders() returned None" )
512 except ( ValueError, TypeError ):
513 main.log.exception( "Error parsing leaders" )
514 main.log.error( repr( leaders ) )
515 partitions = main.ONOScli1.partitions()
516 try:
517 if partitions :
518 parsedPartitions = json.loads( partitions )
519 main.log.warn( json.dumps( parsedPartitions,
520 sort_keys=True,
521 indent=4,
522 separators=( ',', ': ' ) ) )
523 # TODO check for a leader in all paritions
524 # TODO check for consistency among nodes
525 else:
526 main.log.error( "partitions() returned None" )
527 except ( ValueError, TypeError ):
528 main.log.exception( "Error parsing partitions" )
529 main.log.error( repr( partitions ) )
Jon Hall63604932015-02-26 17:09:50 -0800530 pendingMap = main.ONOScli1.pendingMap()
Jon Hall5cfd23c2015-03-19 11:40:57 -0700531 try:
532 if pendingMap :
533 parsedPending = json.loads( pendingMap )
534 main.log.warn( json.dumps( parsedPending,
535 sort_keys=True,
536 indent=4,
537 separators=( ',', ': ' ) ) )
538 # TODO check something here?
539 else:
540 main.log.error( "pendingMap() returned None" )
541 except ( ValueError, TypeError ):
542 main.log.exception( "Error parsing pending map" )
543 main.log.error( repr( pendingMap ) )
544
Jon Hall58c76b72015-02-23 11:09:24 -0800545 intentAddResult = bool( pingResult and hostResult and intentAddResult
Jon Hall63604932015-02-26 17:09:50 -0800546 and not missingIntents and installedCheck )
Jon Hall6aec96b2015-01-19 14:49:31 -0800547 utilities.assert_equals(
548 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -0800549 actual=intentAddResult,
Jon Hall529a37f2015-01-28 10:02:00 -0800550 onpass="Pushed host intents to ONOS",
551 onfail="Error in pushing host intents to ONOS" )
Jon Halla9d26da2015-03-30 16:45:32 -0700552 for i in range(100):
553 onosIds = main.ONOScli1.getAllIntentsId()
554 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
555 main.log.info( "Intents in ONOS: " + str( sorted( onosIds ) ) )
556 if sorted(onosIds) == sorted(intentIds):
557 break
558 else:
559 time.sleep(1)
560 # FIXME: DEBUG
561 if not intentStop:
562 intentStop = time.time()
563 gossipTime = intentStop - intentStart
564 main.log.info( "It took about " + str( gossipTime ) +
565 " seconds for all intents to appear on ONOS1" )
566 # FIXME: make this time configurable/calculate based off of number of
567 # nodes and gossip rounds
568 utilities.assert_greater_equals(
569 expect=30, actual=gossipTime,
570 onpass="ECM anti-entropy for intents worked within " +
571 "expected time",
572 onfail="Intent ECM anti-entropy took too long" )
Jon Hall58c76b72015-02-23 11:09:24 -0800573
Jon Hall63604932015-02-26 17:09:50 -0800574 if not intentAddResult or "key" in pendingMap:
Jon Hall58c76b72015-02-23 11:09:24 -0800575 import time
Jon Hall63604932015-02-26 17:09:50 -0800576 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800577 main.log.info( "Sleeping 60 seconds to see if intents are found" )
578 time.sleep( 60 )
579 onosIds = main.ONOScli1.getAllIntentsId()
580 main.log.info( "Submitted intents: " + str( intentIds ) )
581 main.log.info( "Intents in ONOS: " + str( onosIds ) )
582 # Print the intent states
583 intents = main.ONOScli1.intents()
584 intentStates = []
585 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
586 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700587 try:
588 for intent in json.loads( intents ):
589 # Iter through intents of a node
590 state = intent.get( 'state', None )
591 if "INSTALLED" not in state:
592 installedCheck = False
593 intentId = intent.get( 'id', None )
594 intentStates.append( ( intentId, state ) )
595 except ( ValueError, TypeError ):
596 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800597 # add submitted intents not in the store
598 tmplist = [ i for i, s in intentStates ]
599 for i in intentIds:
600 if i not in tmplist:
601 intentStates.append( ( i, " - " ) )
602 intentStates.sort()
603 for i, s in intentStates:
604 count += 1
605 main.log.info( "%-6s%-15s%-15s" %
606 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700607 leaders = main.ONOScli1.leaders()
608 try:
609 if leaders:
610 parsedLeaders = json.loads( leaders )
611 main.log.warn( json.dumps( parsedLeaders,
612 sort_keys=True,
613 indent=4,
614 separators=( ',', ': ' ) ) )
615 # check for all intent partitions
616 # check for election
617 topics = []
618 for i in range( 14 ):
619 topics.append( "intent-partition-" + str( i ) )
620 # FIXME: this should only be after we start the app
621 topics.append( "org.onosproject.election" )
622 main.log.debug( topics )
623 ONOStopics = [ j['topic'] for j in parsedLeaders ]
624 for topic in topics:
625 if topic not in ONOStopics:
626 main.log.error( "Error: " + topic +
627 " not in leaders" )
628 else:
629 main.log.error( "leaders() returned None" )
630 except ( ValueError, TypeError ):
631 main.log.exception( "Error parsing leaders" )
632 main.log.error( repr( leaders ) )
633 partitions = main.ONOScli1.partitions()
634 try:
635 if partitions :
636 parsedPartitions = json.loads( partitions )
637 main.log.warn( json.dumps( parsedPartitions,
638 sort_keys=True,
639 indent=4,
640 separators=( ',', ': ' ) ) )
641 # TODO check for a leader in all paritions
642 # TODO check for consistency among nodes
643 else:
644 main.log.error( "partitions() returned None" )
645 except ( ValueError, TypeError ):
646 main.log.exception( "Error parsing partitions" )
647 main.log.error( repr( partitions ) )
648 pendingMap = main.ONOScli1.pendingMap()
649 try:
650 if pendingMap :
651 parsedPending = json.loads( pendingMap )
652 main.log.warn( json.dumps( parsedPending,
653 sort_keys=True,
654 indent=4,
655 separators=( ',', ': ' ) ) )
656 # TODO check something here?
657 else:
658 main.log.error( "pendingMap() returned None" )
659 except ( ValueError, TypeError ):
660 main.log.exception( "Error parsing pending map" )
661 main.log.error( repr( pendingMap ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800662
Jon Hall6aec96b2015-01-19 14:49:31 -0800663 def CASE4( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800664 """
665 Ping across added host intents
666 """
Jon Hallfebb1c72015-03-05 13:30:09 -0800667 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700668 import time
669 assert numControllers, "numControllers not defined"
670 assert main, "main not defined"
671 assert utilities.assert_equals, "utilities.assert_equals not defined"
672 assert CLIs, "CLIs not defined"
673 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -0800674 description = " Ping across added host intents"
Jon Hall6aec96b2015-01-19 14:49:31 -0800675 main.log.report( description )
676 main.case( description )
Jon Hall8f89dda2015-01-22 16:03:33 -0800677 PingResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800678 for i in range( 8, 18 ):
Jon Hall21270ac2015-02-16 17:59:55 -0800679 ping = main.Mininet1.pingHost( src="h" + str( i ),
680 target="h" + str( i + 10 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800681 PingResult = PingResult and ping
Jon Hall6aec96b2015-01-19 14:49:31 -0800682 if ping == main.FALSE:
683 main.log.warn( "Ping failed between h" + str( i ) +
684 " and h" + str( i + 10 ) )
685 elif ping == main.TRUE:
686 main.log.info( "Ping test passed!" )
Jon Hall21270ac2015-02-16 17:59:55 -0800687 # Don't set PingResult or you'd override failures
Jon Hall8f89dda2015-01-22 16:03:33 -0800688 if PingResult == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800689 main.log.report(
690 "Intents have not been installed correctly, pings failed." )
Jon Hall58c76b72015-02-23 11:09:24 -0800691 # TODO: pretty print
Jon Hall5cfd23c2015-03-19 11:40:57 -0700692 main.log.warn( "ONOS1 intents: " )
693 try:
694 tmpIntents = main.ONOScli1.intents()
695 main.log.warn( json.dumps( json.loads( tmpIntents ),
696 sort_keys=True,
697 indent=4,
698 separators=( ',', ': ' ) ) )
699 except ( ValueError, TypeError ):
700 main.log.warn( repr( tmpIntents ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800701 if PingResult == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800702 main.log.report(
703 "Intents have been installed correctly and verified by pings" )
704 utilities.assert_equals(
705 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800706 actual=PingResult,
Jon Hall6aec96b2015-01-19 14:49:31 -0800707 onpass="Intents have been installed correctly and pings work",
708 onfail="Intents have not been installed correctly, pings failed." )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800709
Jon Hall63604932015-02-26 17:09:50 -0800710 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800711 if PingResult is not main.TRUE:
712 # Print the intent states
713 intents = main.ONOScli1.intents()
714 intentStates = []
715 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
716 count = 0
717 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700718 try:
719 for intent in json.loads( intents ):
720 state = intent.get( 'state', None )
721 if "INSTALLED" not in state:
722 installedCheck = False
723 intentId = intent.get( 'id', None )
724 intentStates.append( ( intentId, state ) )
725 except ( ValueError, TypeError ):
726 main.log.exception( "Error parsing intents." )
Jon Hall58c76b72015-02-23 11:09:24 -0800727 intentStates.sort()
728 for i, s in intentStates:
729 count += 1
730 main.log.info( "%-6s%-15s%-15s" %
731 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700732 leaders = main.ONOScli1.leaders()
733 try:
734 if leaders:
735 parsedLeaders = json.loads( leaders )
736 main.log.warn( json.dumps( parsedLeaders,
737 sort_keys=True,
738 indent=4,
739 separators=( ',', ': ' ) ) )
740 # check for all intent partitions
741 # check for election
742 topics = []
743 for i in range( 14 ):
744 topics.append( "intent-partition-" + str( i ) )
745 # FIXME: this should only be after we start the app
746 topics.append( "org.onosproject.election" )
747 main.log.debug( topics )
748 ONOStopics = [ j['topic'] for j in parsedLeaders ]
749 for topic in topics:
750 if topic not in ONOStopics:
751 main.log.error( "Error: " + topic +
752 " not in leaders" )
753 else:
754 main.log.error( "leaders() returned None" )
755 except ( ValueError, TypeError ):
756 main.log.exception( "Error parsing leaders" )
757 main.log.error( repr( leaders ) )
758 partitions = main.ONOScli1.partitions()
759 try:
760 if partitions :
761 parsedPartitions = json.loads( partitions )
762 main.log.warn( json.dumps( parsedPartitions,
763 sort_keys=True,
764 indent=4,
765 separators=( ',', ': ' ) ) )
766 # TODO check for a leader in all paritions
767 # TODO check for consistency among nodes
768 else:
769 main.log.error( "partitions() returned None" )
770 except ( ValueError, TypeError ):
771 main.log.exception( "Error parsing partitions" )
772 main.log.error( repr( partitions ) )
773 pendingMap = main.ONOScli1.pendingMap()
774 try:
775 if pendingMap :
776 parsedPending = json.loads( pendingMap )
777 main.log.warn( json.dumps( parsedPending,
778 sort_keys=True,
779 indent=4,
780 separators=( ',', ': ' ) ) )
781 # TODO check something here?
782 else:
783 main.log.error( "pendingMap() returned None" )
784 except ( ValueError, TypeError ):
785 main.log.exception( "Error parsing pending map" )
786 main.log.error( repr( pendingMap ) )
787
Jon Hall63604932015-02-26 17:09:50 -0800788 if not installedCheck:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700789 main.log.info( "Waiting 60 seconds to see if the state of " +
790 "intents change" )
Jon Hall63604932015-02-26 17:09:50 -0800791 time.sleep( 60 )
792 # Print the intent states
793 intents = main.ONOScli1.intents()
794 intentStates = []
795 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
796 count = 0
797 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700798 try:
799 for intent in json.loads( intents ):
800 state = intent.get( 'state', None )
801 if "INSTALLED" not in state:
802 installedCheck = False
803 intentId = intent.get( 'id', None )
804 intentStates.append( ( intentId, state ) )
805 except ( ValueError, TypeError ):
806 main.log.exception( "Error parsing intents." )
Jon Hall63604932015-02-26 17:09:50 -0800807 intentStates.sort()
808 for i, s in intentStates:
809 count += 1
810 main.log.info( "%-6s%-15s%-15s" %
811 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700812 leaders = main.ONOScli1.leaders()
813 try:
814 if leaders:
815 parsedLeaders = json.loads( leaders )
816 main.log.warn( json.dumps( parsedLeaders,
817 sort_keys=True,
818 indent=4,
819 separators=( ',', ': ' ) ) )
820 # check for all intent partitions
821 # check for election
822 topics = []
823 for i in range( 14 ):
824 topics.append( "intent-partition-" + str( i ) )
825 # FIXME: this should only be after we start the app
826 topics.append( "org.onosproject.election" )
827 main.log.debug( topics )
828 ONOStopics = [ j['topic'] for j in parsedLeaders ]
829 for topic in topics:
830 if topic not in ONOStopics:
831 main.log.error( "Error: " + topic +
832 " not in leaders" )
833 else:
834 main.log.error( "leaders() returned None" )
835 except ( ValueError, TypeError ):
836 main.log.exception( "Error parsing leaders" )
837 main.log.error( repr( leaders ) )
838 partitions = main.ONOScli1.partitions()
839 try:
840 if partitions :
841 parsedPartitions = json.loads( partitions )
842 main.log.warn( json.dumps( parsedPartitions,
843 sort_keys=True,
844 indent=4,
845 separators=( ',', ': ' ) ) )
846 # TODO check for a leader in all paritions
847 # TODO check for consistency among nodes
848 else:
849 main.log.error( "partitions() returned None" )
850 except ( ValueError, TypeError ):
851 main.log.exception( "Error parsing partitions" )
852 main.log.error( repr( partitions ) )
853 pendingMap = main.ONOScli1.pendingMap()
854 try:
855 if pendingMap :
856 parsedPending = json.loads( pendingMap )
857 main.log.warn( json.dumps( parsedPending,
858 sort_keys=True,
859 indent=4,
860 separators=( ',', ': ' ) ) )
861 # TODO check something here?
862 else:
863 main.log.error( "pendingMap() returned None" )
864 except ( ValueError, TypeError ):
865 main.log.exception( "Error parsing pending map" )
866 main.log.error( repr( pendingMap ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800867
Jon Hall6aec96b2015-01-19 14:49:31 -0800868 def CASE5( self, main ):
869 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800870 Reading state of ONOS
Jon Hall6aec96b2015-01-19 14:49:31 -0800871 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800872 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700873 import time
874 assert numControllers, "numControllers not defined"
875 assert main, "main not defined"
876 assert utilities.assert_equals, "utilities.assert_equals not defined"
877 assert CLIs, "CLIs not defined"
878 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -0800879 # assumes that sts is already in you PYTHONPATH
880 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -0800881
Jon Hall6aec96b2015-01-19 14:49:31 -0800882 main.log.report( "Setting up and gathering data for current state" )
883 main.case( "Setting up and gathering data for current state" )
884 # The general idea for this test case is to pull the state of
885 # ( intents,flows, topology,... ) from each ONOS node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700886 # We can then compare them with each other and also with past states
Jon Hall73cf9cc2014-11-20 22:28:38 -0800887
Jon Hall5cfd23c2015-03-19 11:40:57 -0700888 main.step( "Check that each switch has a master" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800889 global mastershipState
Jon Hall5cfd23c2015-03-19 11:40:57 -0700890 mastershipState = '[]'
Jon Hall94fd0472014-12-08 11:52:42 -0800891
Jon Hall6aec96b2015-01-19 14:49:31 -0800892 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -0700893 rolesNotNull = main.TRUE
894 threads = []
895 for i in range( numControllers ):
896 t = main.Thread( target=CLIs[i].rolesNotNull,
897 name="rolesNotNull-" + str( i ),
898 args=[] )
899 threads.append( t )
900 t.start()
901
902 for t in threads:
903 t.join()
904 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -0800905 utilities.assert_equals(
906 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800907 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -0800908 onpass="Each device has a master",
909 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -0800910
Jon Hall5cfd23c2015-03-19 11:40:57 -0700911 main.step( "Get the Mastership of each switch from each controller" )
912 ONOSMastership = []
913 mastershipCheck = main.FALSE
914 consistentMastership = True
915 rolesResults = True
916 threads = []
917 for i in range( numControllers ):
918 t = main.Thread( target=CLIs[i].roles,
919 name="roles-" + str( i ),
920 args=[] )
921 threads.append( t )
922 t.start()
923
924 for t in threads:
925 t.join()
926 ONOSMastership.append( t.result )
927
928 for i in range( numControllers ):
929 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
930 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
931 " roles" )
932 main.log.warn(
933 "ONOS" + str( i + 1 ) + " mastership response: " +
934 repr( ONOSMastership[i] ) )
935 rolesResults = False
936 utilities.assert_equals(
937 expect=True,
938 actual=rolesResults,
939 onpass="No error in reading roles output",
940 onfail="Error in reading roles from ONOS" )
941
942 main.step( "Check for consistency in roles from each controller" )
943 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall6aec96b2015-01-19 14:49:31 -0800944 main.log.report(
945 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800946 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700947 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -0800948 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -0700949 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -0800950 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -0800951 onpass="Switch roles are consistent across all ONOS nodes",
952 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800953
Jon Hall5cfd23c2015-03-19 11:40:57 -0700954 if rolesResults and not consistentMastership:
955 for i in range( numControllers ):
956 try:
957 main.log.warn(
958 "ONOS" + str( i + 1 ) + " roles: ",
959 json.dumps(
960 json.loads( ONOSMastership[ i ] ),
961 sort_keys=True,
962 indent=4,
963 separators=( ',', ': ' ) ) )
964 except ( ValueError, TypeError ):
965 main.log.warn( repr( ONOSMastership[ i ] ) )
966 elif rolesResults and consistentMastership:
967 mastershipCheck = main.TRUE
968 mastershipState = ONOSMastership[ 0 ]
969
Jon Hall6aec96b2015-01-19 14:49:31 -0800970 main.step( "Get the intents from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800971 global intentState
972 intentState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -0700973 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -0800974 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700975 consistentIntents = True
976 intentsResults = True
977 threads = []
978 for i in range( numControllers ):
979 t = main.Thread( target=CLIs[i].intents,
980 name="intents-" + str( i ),
981 args=[],
982 kwargs={ 'jsonFormat': True } )
983 threads.append( t )
984 t.start()
985
986 for t in threads:
987 t.join()
988 ONOSIntents.append( t.result )
989
990 for i in range( numControllers ):
991 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
992 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
993 " intents" )
994 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
995 repr( ONOSIntents[ i ] ) )
996 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -0800997 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -0700998 expect=True,
999 actual=intentsResults,
1000 onpass="No error in reading intents output",
1001 onfail="Error in reading intents from ONOS" )
1002
1003 main.step( "Check for consistency in Intents from each controller" )
1004 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1005 main.log.report( "Intents are consistent across all ONOS " +
1006 "nodes" )
1007 else:
1008 consistentIntents = False
1009 main.log.report( "Intents not consistent" )
1010 utilities.assert_equals(
1011 expect=True,
1012 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001013 onpass="Intents are consistent across all ONOS nodes",
1014 onfail="ONOS nodes have different views of intents" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001015
Jon Hall5cfd23c2015-03-19 11:40:57 -07001016 if intentsResults and not consistentIntents:
1017 n = len(ONOSIntents)
1018 main.log.warn( "ONOS" + str( n ) + " intents: " )
1019 main.log.warn( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1020 sort_keys=True,
1021 indent=4,
1022 separators=( ',', ': ' ) ) )
1023 for i in range( numControllers ):
1024 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
1025 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1026 main.log.warn( json.dumps( json.loads( ONOSIntents[i] ),
1027 sort_keys=True,
1028 indent=4,
1029 separators=( ',', ': ' ) ) )
1030 else:
1031 main.log.warn( nodes[ i ].name + " intents match ONOS" +
1032 str( n ) + " intents" )
1033 elif intentsResults and consistentIntents:
1034 intentCheck = main.TRUE
1035 intentState = ONOSIntents[ 0 ]
1036
Jon Hall6aec96b2015-01-19 14:49:31 -08001037 main.step( "Get the flows from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001038 global flowState
1039 flowState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001040 ONOSFlows = []
1041 ONOSFlowsJson = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001042 flowCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001043 consistentFlows = True
1044 flowsResults = True
1045 threads = []
1046 for i in range( numControllers ):
1047 t = main.Thread( target=CLIs[i].flows,
1048 name="flows-" + str( i ),
1049 args=[],
1050 kwargs={ 'jsonFormat': True } )
1051 threads.append( t )
1052 t.start()
1053
Jon Halla9d26da2015-03-30 16:45:32 -07001054 # NOTE: Flows command can take some time to run
Jon Hall5cfd23c2015-03-19 11:40:57 -07001055 time.sleep(30)
1056 for t in threads:
1057 t.join()
1058 result = t.result
1059 ONOSFlows.append( result )
1060
1061 for i in range( numControllers ):
1062 num = str( i + 1 )
1063 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1064 main.log.report( "Error in getting ONOS" + num + " flows" )
1065 main.log.warn( "ONOS" + num + " flows response: " +
1066 repr( ONOSFlows[ i ] ) )
1067 flowsResults = False
1068 ONOSFlowsJson.append( None )
Jon Hall58c76b72015-02-23 11:09:24 -08001069 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001070 try:
1071 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1072 except ( ValueError, TypeError ):
1073 # FIXME: change this to log.error?
1074 main.log.exception( "Error in parsing ONOS" + num +
1075 " response as json." )
1076 main.log.error( repr( ONOSFlows[ i ] ) )
1077 ONOSFlowsJson.append( None )
1078 flowsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001079 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001080 expect=True,
1081 actual=flowsResults,
1082 onpass="No error in reading flows output",
1083 onfail="Error in reading flows from ONOS" )
1084
1085 main.step( "Check for consistency in Flows from each controller" )
1086 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1087 if all( tmp ):
1088 main.log.report( "Flow count is consistent across all ONOS nodes" )
1089 else:
1090 consistentFlows = False
1091 utilities.assert_equals(
1092 expect=True,
1093 actual=consistentFlows,
Jon Hall6aec96b2015-01-19 14:49:31 -08001094 onpass="The flow count is consistent across all ONOS nodes",
1095 onfail="ONOS nodes have different flow counts" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001096
Jon Hall5cfd23c2015-03-19 11:40:57 -07001097 if flowsResults and not consistentFlows:
1098 for i in range( numControllers ):
1099 try:
1100 main.log.warn(
1101 "ONOS" + str( i + 1 ) + " flows: " +
1102 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1103 indent=4, separators=( ',', ': ' ) ) )
1104 except ( ValueError, TypeError ):
1105 main.log.warn(
1106 "ONOS" + str( i + 1 ) + " flows: " +
1107 repr( ONOSFlows[ i ] ) )
1108 elif flowsResults and consistentFlows:
1109 flowCheck = main.TRUE
1110 flowState = ONOSFlows[ 0 ]
1111
Jon Hall6aec96b2015-01-19 14:49:31 -08001112 main.step( "Get the OF Table entries" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001113 global flows
Jon Hall6aec96b2015-01-19 14:49:31 -08001114 flows = []
1115 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001116 flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001117 if flowCheck == main.FALSE:
1118 for table in flows:
1119 main.log.warn( table )
Jon Hall6aec96b2015-01-19 14:49:31 -08001120 # TODO: Compare switch flow tables with ONOS flow tables
Jon Hall73cf9cc2014-11-20 22:28:38 -08001121
Jon Hall6aec96b2015-01-19 14:49:31 -08001122 main.step( "Start continuous pings" )
1123 main.Mininet2.pingLong(
1124 src=main.params[ 'PING' ][ 'source1' ],
1125 target=main.params[ 'PING' ][ 'target1' ],
1126 pingTime=500 )
1127 main.Mininet2.pingLong(
1128 src=main.params[ 'PING' ][ 'source2' ],
1129 target=main.params[ 'PING' ][ 'target2' ],
1130 pingTime=500 )
1131 main.Mininet2.pingLong(
1132 src=main.params[ 'PING' ][ 'source3' ],
1133 target=main.params[ 'PING' ][ 'target3' ],
1134 pingTime=500 )
1135 main.Mininet2.pingLong(
1136 src=main.params[ 'PING' ][ 'source4' ],
1137 target=main.params[ 'PING' ][ 'target4' ],
1138 pingTime=500 )
1139 main.Mininet2.pingLong(
1140 src=main.params[ 'PING' ][ 'source5' ],
1141 target=main.params[ 'PING' ][ 'target5' ],
1142 pingTime=500 )
1143 main.Mininet2.pingLong(
1144 src=main.params[ 'PING' ][ 'source6' ],
1145 target=main.params[ 'PING' ][ 'target6' ],
1146 pingTime=500 )
1147 main.Mininet2.pingLong(
1148 src=main.params[ 'PING' ][ 'source7' ],
1149 target=main.params[ 'PING' ][ 'target7' ],
1150 pingTime=500 )
1151 main.Mininet2.pingLong(
1152 src=main.params[ 'PING' ][ 'source8' ],
1153 target=main.params[ 'PING' ][ 'target8' ],
1154 pingTime=500 )
1155 main.Mininet2.pingLong(
1156 src=main.params[ 'PING' ][ 'source9' ],
1157 target=main.params[ 'PING' ][ 'target9' ],
1158 pingTime=500 )
1159 main.Mininet2.pingLong(
1160 src=main.params[ 'PING' ][ 'source10' ],
1161 target=main.params[ 'PING' ][ 'target10' ],
1162 pingTime=500 )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001163
Jon Hall6aec96b2015-01-19 14:49:31 -08001164 main.step( "Create TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001165 ctrls = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001166 for node in nodes:
1167 temp = ( node, node.name, node.ip_address, 6633 )
1168 ctrls.append( temp )
1169 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001170
Jon Hall6aec96b2015-01-19 14:49:31 -08001171 main.step( "Collecting topology information from ONOS" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001172 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001173 threads = []
1174 for i in range( numControllers ):
1175 t = main.Thread( target=CLIs[i].devices,
1176 name="devices-" + str( i ),
1177 args=[ ] )
1178 threads.append( t )
1179 t.start()
1180
1181 for t in threads:
1182 t.join()
1183 devices.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001184 hosts = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001185 threads = []
1186 for i in range( numControllers ):
1187 t = main.Thread( target=CLIs[i].hosts,
1188 name="hosts-" + str( i ),
1189 args=[ ] )
1190 threads.append( t )
1191 t.start()
1192
1193 for t in threads:
1194 t.join()
1195 try:
1196 hosts.append( json.loads( t.result ) )
1197 except ( ValueError, TypeError ):
1198 # FIXME: better handling of this, print which node
1199 # Maybe use thread name?
1200 main.log.exception( "Error parsing json output of hosts" )
1201 # FIXME: should this be an empty json object instead?
1202 hosts.append( None )
1203
Jon Hall73cf9cc2014-11-20 22:28:38 -08001204 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001205 threads = []
1206 for i in range( numControllers ):
1207 t = main.Thread( target=CLIs[i].ports,
1208 name="ports-" + str( i ),
1209 args=[ ] )
1210 threads.append( t )
1211 t.start()
1212
1213 for t in threads:
1214 t.join()
1215 ports.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001216 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001217 threads = []
1218 for i in range( numControllers ):
1219 t = main.Thread( target=CLIs[i].links,
1220 name="links-" + str( i ),
1221 args=[ ] )
1222 threads.append( t )
1223 t.start()
1224
1225 for t in threads:
1226 t.join()
1227 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001228 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001229 threads = []
1230 for i in range( numControllers ):
1231 t = main.Thread( target=CLIs[i].clusters,
1232 name="clusters-" + str( i ),
1233 args=[ ] )
1234 threads.append( t )
1235 t.start()
1236
1237 for t in threads:
1238 t.join()
1239 clusters.append( t.result )
Jon Hall529a37f2015-01-28 10:02:00 -08001240 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001241
Jon Hall6aec96b2015-01-19 14:49:31 -08001242 # hosts
Jon Hall8f89dda2015-01-22 16:03:33 -08001243 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001244 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001245 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001246 if "Error" not in hosts[ controller ]:
1247 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001248 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001249 else: # hosts not consistent
1250 main.log.report( "hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001251 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001252 " is inconsistent with ONOS1" )
1253 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001254 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001255
1256 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001257 main.log.report( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001258 controllerStr )
1259 consistentHostsResult = main.FALSE
1260 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001261 " hosts response: " +
1262 repr( hosts[ controller ] ) )
1263 utilities.assert_equals(
1264 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001265 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001266 onpass="Hosts view is consistent across all ONOS nodes",
1267 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001268
Jon Hall58c76b72015-02-23 11:09:24 -08001269 ipResult = main.TRUE
1270 for controller in range( 0, len( hosts ) ):
1271 controllerStr = str( controller + 1 )
1272 for host in hosts[ controller ]:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001273 if not host.get( 'ips', [ ] ):
1274 main.log.error( "DEBUG:Error with host ips on controller" +
1275 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001276 ipResult = main.FALSE
1277 utilities.assert_equals(
1278 expect=main.TRUE,
1279 actual=ipResult,
1280 onpass="The ips of the hosts aren't empty",
1281 onfail="The ip of at least one host is missing" )
1282
Jon Hall6aec96b2015-01-19 14:49:31 -08001283 # Strongly connected clusters of devices
Jon Hall8f89dda2015-01-22 16:03:33 -08001284 consistentClustersResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001285 for controller in range( len( clusters ) ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001286 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001287 if "Error" not in clusters[ controller ]:
1288 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001289 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001290 else: # clusters not consistent
Jon Hall5cfd23c2015-03-19 11:40:57 -07001291 main.log.report( "clusters from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001292 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001293 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001294
1295 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001296 main.log.report( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001297 "from ONOS" + controllerStr )
1298 consistentClustersResult = main.FALSE
1299 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001300 " clusters response: " +
1301 repr( clusters[ controller ] ) )
1302 utilities.assert_equals(
1303 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001304 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001305 onpass="Clusters view is consistent across all ONOS nodes",
1306 onfail="ONOS nodes have different views of clusters" )
1307 # there should always only be one cluster
Jon Hall5cfd23c2015-03-19 11:40:57 -07001308 try:
1309 numClusters = len( json.loads( clusters[ 0 ] ) )
1310 except ( ValueError, TypeError ):
1311 main.log.exception( "Error parsing clusters[0]: " +
1312 repr( clusters[ 0 ] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001313 clusterResults = main.FALSE
1314 if numClusters == 1:
1315 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001316 utilities.assert_equals(
1317 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08001318 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08001319 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08001320 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08001321
Jon Hall6aec96b2015-01-19 14:49:31 -08001322 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001323 devicesResults = main.TRUE
1324 portsResults = main.TRUE
1325 linksResults = main.TRUE
1326 for controller in range( numControllers ):
1327 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001328 if devices[ controller ] or "Error" not in devices[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001329 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08001330 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001331 json.loads( devices[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001332 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001333 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001334 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001335 actual=currentDevicesResult,
1336 onpass="ONOS" + controllerStr +
1337 " Switches view is correct",
1338 onfail="ONOS" + controllerStr +
1339 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001340
Jon Hall6aec96b2015-01-19 14:49:31 -08001341 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001342 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08001343 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001344 json.loads( ports[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001345 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001346 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001347 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001348 actual=currentPortsResult,
1349 onpass="ONOS" + controllerStr +
1350 " ports view is correct",
1351 onfail="ONOS" + controllerStr +
1352 " ports view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001353
Jon Hall6aec96b2015-01-19 14:49:31 -08001354 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001355 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08001356 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001357 json.loads( links[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001358 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001359 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001360 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001361 actual=currentLinksResult,
1362 onpass="ONOS" + controllerStr +
1363 " links view is correct",
1364 onfail="ONOS" + controllerStr +
1365 " links view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001366
Jon Hall8f89dda2015-01-22 16:03:33 -08001367 devicesResults = devicesResults and currentDevicesResult
1368 portsResults = portsResults and currentPortsResult
1369 linksResults = linksResults and currentLinksResult
Jon Hall73cf9cc2014-11-20 22:28:38 -08001370
Jon Hall5cfd23c2015-03-19 11:40:57 -07001371 topoResult = ( devicesResults and portsResults and linksResults
1372 and consistentHostsResult and consistentClustersResult
1373 and clusterResults and ipResult )
Jon Hall8f89dda2015-01-22 16:03:33 -08001374 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08001375 onpass="Topology Check Test successful",
1376 onfail="Topology Check Test NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001377
Jon Hall8f89dda2015-01-22 16:03:33 -08001378 finalAssert = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001379 finalAssert = ( finalAssert and topoResult and flowCheck
1380 and intentCheck and consistentMastership
Jon Halla9d26da2015-03-30 16:45:32 -07001381 and mastershipCheck and rolesNotNull )
Jon Hall8f89dda2015-01-22 16:03:33 -08001382 utilities.assert_equals( expect=main.TRUE, actual=finalAssert,
Jon Hall58c76b72015-02-23 11:09:24 -08001383 onpass="State check successful",
1384 onfail="State check NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001385
Jon Hall6aec96b2015-01-19 14:49:31 -08001386 def CASE6( self, main ):
1387 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001388 The Failure case.
Jon Hall6aec96b2015-01-19 14:49:31 -08001389 """
Jon Hall94fd0472014-12-08 11:52:42 -08001390 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001391 assert numControllers, "numControllers not defined"
1392 assert main, "main not defined"
1393 assert utilities.assert_equals, "utilities.assert_equals not defined"
1394 assert CLIs, "CLIs not defined"
1395 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001396 main.log.report( "Killing 3 ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001397 main.case( "Restart minority of ONOS nodes" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001398 # TODO: Randomize these nodes
Jon Hall5cfd23c2015-03-19 11:40:57 -07001399 # TODO: use threads in this case
1400 main.ONOSbench.onosKill( nodes[0].ip_address )
Jon Hall6aec96b2015-01-19 14:49:31 -08001401 time.sleep( 10 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001402 main.ONOSbench.onosKill( nodes[1].ip_address )
Jon Hall6aec96b2015-01-19 14:49:31 -08001403 time.sleep( 10 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001404 main.ONOSbench.onosKill( nodes[2].ip_address )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001405
Jon Hall6aec96b2015-01-19 14:49:31 -08001406 main.step( "Checking if ONOS is up yet" )
Jon Hallffb386d2014-11-21 13:43:38 -08001407 count = 0
Jon Hall8f89dda2015-01-22 16:03:33 -08001408 onosIsupResult = main.FALSE
1409 while onosIsupResult == main.FALSE and count < 10:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001410 onos1Isup = main.ONOSbench.isup( nodes[0].ip_address )
1411 onos2Isup = main.ONOSbench.isup( nodes[1].ip_address )
1412 onos3Isup = main.ONOSbench.isup( nodes[2].ip_address )
Jon Hall8f89dda2015-01-22 16:03:33 -08001413 onosIsupResult = onos1Isup and onos2Isup and onos3Isup
Jon Hallffb386d2014-11-21 13:43:38 -08001414 count = count + 1
Jon Hall73cf9cc2014-11-20 22:28:38 -08001415 # TODO: if it becomes an issue, we can retry this step a few times
1416
Jon Hall5cfd23c2015-03-19 11:40:57 -07001417 cliResult1 = main.ONOScli1.startOnosCli( nodes[0].ip_address )
1418 cliResult2 = main.ONOScli2.startOnosCli( nodes[1].ip_address )
1419 cliResult3 = main.ONOScli3.startOnosCli( nodes[2].ip_address )
Jon Hall8f89dda2015-01-22 16:03:33 -08001420 cliResults = cliResult1 and cliResult2 and cliResult3
Jon Hall73cf9cc2014-11-20 22:28:38 -08001421
Jon Hall21270ac2015-02-16 17:59:55 -08001422 # Grab the time of restart so we chan check how long the gossip
1423 # protocol has had time to work
1424 main.restartTime = time.time()
Jon Hall8f89dda2015-01-22 16:03:33 -08001425 caseResults = main.TRUE and onosIsupResult and cliResults
1426 utilities.assert_equals( expect=main.TRUE, actual=caseResults,
Jon Hall58c76b72015-02-23 11:09:24 -08001427 onpass="ONOS restart successful",
1428 onfail="ONOS restart NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001429
Jon Hall6aec96b2015-01-19 14:49:31 -08001430 def CASE7( self, main ):
1431 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001432 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -08001433 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001434 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001435 assert numControllers, "numControllers not defined"
1436 assert main, "main not defined"
1437 assert utilities.assert_equals, "utilities.assert_equals not defined"
1438 assert CLIs, "CLIs not defined"
1439 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001440 main.case( "Running ONOS Constant State Tests" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001441
Jon Hall5cfd23c2015-03-19 11:40:57 -07001442 main.step( "Check that each switch has a master" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001443 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -07001444 rolesNotNull = main.TRUE
1445 threads = []
1446 for i in range( numControllers ):
1447 t = main.Thread( target=CLIs[i].rolesNotNull,
1448 name="rolesNotNull-" + str( i ),
1449 args=[ ] )
1450 threads.append( t )
1451 t.start()
1452
1453 for t in threads:
1454 t.join()
1455 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001456 utilities.assert_equals(
1457 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001458 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001459 onpass="Each device has a master",
1460 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001461
Jon Hall5cfd23c2015-03-19 11:40:57 -07001462 ONOSMastership = []
1463 mastershipCheck = main.FALSE
1464 consistentMastership = True
1465 rolesResults = True
1466 threads = []
1467 for i in range( numControllers ):
1468 t = main.Thread( target=CLIs[i].roles,
1469 name="roles-" + str( i ),
1470 args=[] )
1471 threads.append( t )
1472 t.start()
1473
1474 for t in threads:
1475 t.join()
1476 ONOSMastership.append( t.result )
1477
1478 for i in range( numControllers ):
1479 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1480 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1481 " roles" )
1482 main.log.warn(
1483 "ONOS" + str( i + 1 ) + " mastership response: " +
1484 repr( ONOSMastership[i] ) )
1485 rolesResults = False
1486 utilities.assert_equals(
1487 expect=True,
1488 actual=rolesResults,
1489 onpass="No error in reading roles output",
1490 onfail="Error in reading roles from ONOS" )
1491
1492 main.step( "Check for consistency in roles from each controller" )
1493 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall6aec96b2015-01-19 14:49:31 -08001494 main.log.report(
1495 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001496 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001497 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001498 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001499 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001500 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001501 onpass="Switch roles are consistent across all ONOS nodes",
1502 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001503
Jon Hall5cfd23c2015-03-19 11:40:57 -07001504 if rolesResults and not consistentMastership:
1505 for i in range( numControllers ):
1506 main.log.warn(
1507 "ONOS" + str( i + 1 ) + " roles: ",
1508 json.dumps(
1509 json.loads( ONOSMastership[ i ] ),
1510 sort_keys=True,
1511 indent=4,
1512 separators=( ',', ': ' ) ) )
1513 elif rolesResults and not consistentMastership:
1514 mastershipCheck = main.TRUE
1515
Jon Hall73cf9cc2014-11-20 22:28:38 -08001516 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -08001517 main.step( description2 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001518 try:
1519 currentJson = json.loads( ONOSMastership[0] )
1520 oldJson = json.loads( mastershipState )
1521 except ( ValueError, TypeError ):
1522 main.log.exception( "Something is wrong with parsing " +
1523 "ONOSMastership[0] or mastershipState" )
1524 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1525 main.log.error( "mastershipState" + repr( mastershipState ) )
1526 main.cleanup()
1527 main.exit()
Jon Hall8f89dda2015-01-22 16:03:33 -08001528 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001529 for i in range( 1, 29 ):
1530 switchDPID = str(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001531 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001532 current = [ switch[ 'master' ] for switch in currentJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001533 if switchDPID in switch[ 'id' ] ]
Jon Hall8f89dda2015-01-22 16:03:33 -08001534 old = [ switch[ 'master' ] for switch in oldJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001535 if switchDPID in switch[ 'id' ] ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08001536 if current == old:
Jon Hall8f89dda2015-01-22 16:03:33 -08001537 mastershipCheck = mastershipCheck and main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001538 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001539 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall8f89dda2015-01-22 16:03:33 -08001540 mastershipCheck = main.FALSE
1541 if mastershipCheck == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001542 main.log.report( "Mastership of Switches was not changed" )
1543 utilities.assert_equals(
1544 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001545 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -08001546 onpass="Mastership of Switches was not changed",
1547 onfail="Mastership of some switches changed" )
1548 # NOTE: we expect mastership to change on controller failure
Jon Hall8f89dda2015-01-22 16:03:33 -08001549 mastershipCheck = consistentMastership
Jon Hall73cf9cc2014-11-20 22:28:38 -08001550
Jon Hall58c76b72015-02-23 11:09:24 -08001551 main.step( "Get the intents and compare across all nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001552 ONOSIntents = []
Jon Hall58c76b72015-02-23 11:09:24 -08001553 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001554 consistentIntents = True
1555 intentsResults = True
1556 threads = []
1557 for i in range( numControllers ):
1558 t = main.Thread( target=CLIs[i].intents,
1559 name="intents-" + str( i ),
1560 args=[],
1561 kwargs={ 'jsonFormat': True } )
1562 threads.append( t )
1563 t.start()
1564
1565 for t in threads:
1566 t.join()
1567 ONOSIntents.append( t.result )
1568
1569 for i in range( numControllers ):
1570 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1571 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1572 " intents" )
1573 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1574 repr( ONOSIntents[ i ] ) )
1575 intentsResults = False
Jon Hall58c76b72015-02-23 11:09:24 -08001576 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001577 expect=True,
1578 actual=intentsResults,
1579 onpass="No error in reading intents output",
1580 onfail="Error in reading intents from ONOS" )
1581
1582 main.step( "Check for consistency in Intents from each controller" )
1583 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1584 main.log.report( "Intents are consistent across all ONOS " +
1585 "nodes" )
1586 else:
1587 consistentIntents = False
1588 utilities.assert_equals(
1589 expect=True,
1590 actual=consistentIntents,
Jon Hall58c76b72015-02-23 11:09:24 -08001591 onpass="Intents are consistent across all ONOS nodes",
1592 onfail="ONOS nodes have different views of intents" )
Jon Hall58c76b72015-02-23 11:09:24 -08001593 intentStates = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001594 for node in ONOSIntents: # Iter through ONOS nodes
Jon Hall58c76b72015-02-23 11:09:24 -08001595 nodeStates = []
1596 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001597 try:
1598 for intent in json.loads( node ):
1599 nodeStates.append( intent[ 'state' ] )
1600 except ( ValueError, TypeError ):
1601 main.log.exception( "Error in parsing intents" )
1602 main.log.error( repr( node ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001603 intentStates.append( nodeStates )
1604 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1605 main.log.info( dict( out ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001606
Jon Hall5cfd23c2015-03-19 11:40:57 -07001607 if intentsResults and not consistentIntents:
1608 for i in range( numControllers ):
1609 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1610 main.log.warn( json.dumps(
1611 json.loads( ONOSIntents[ i ] ),
1612 sort_keys=True,
1613 indent=4,
1614 separators=( ',', ': ' ) ) )
1615 elif intentsResults and consistentIntents:
1616 intentCheck = main.TRUE
1617
Jon Hall58c76b72015-02-23 11:09:24 -08001618 # NOTE: Store has no durability, so intents are lost across system
1619 # restarts
1620 main.step( "Compare current intents with intents before the failure" )
1621 # NOTE: this requires case 5 to pass for intentState to be set.
1622 # maybe we should stop the test if that fails?
1623 sameIntents = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001624 if intentState and intentState == ONOSIntents[ 0 ]:
Jon Hall21270ac2015-02-16 17:59:55 -08001625 sameIntents = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08001626 main.log.report( "Intents are consistent with before failure" )
1627 # TODO: possibly the states have changed? we may need to figure out
Jon Hall5cfd23c2015-03-19 11:40:57 -07001628 # what the acceptable states are
Jon Hall58c76b72015-02-23 11:09:24 -08001629 else:
1630 try:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001631 main.log.warn( "ONOS intents: " )
1632 main.log.warn( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1633 sort_keys=True, indent=4,
1634 separators=( ',', ': ' ) ) )
1635 except ( ValueError, TypeError ):
1636 main.log.exception( "Exception printing intents" )
1637 main.log.warn( repr( ONOSIntents[0] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001638 sameIntents = main.FALSE
1639 utilities.assert_equals(
1640 expect=main.TRUE,
1641 actual=sameIntents,
1642 onpass="Intents are consistent with before failure",
1643 onfail="The Intents changed during failure" )
1644 intentCheck = intentCheck and sameIntents
Jon Hall21270ac2015-02-16 17:59:55 -08001645
Jon Hall58c76b72015-02-23 11:09:24 -08001646 main.step( "Get the OF Table entries and compare to before " +
1647 "component failure" )
1648 FlowTables = main.TRUE
1649 flows2 = []
1650 for i in range( 28 ):
1651 main.log.info( "Checking flow table on s" + str( i + 1 ) )
1652 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
1653 flows2.append( tmpFlows )
1654 tempResult = main.Mininet2.flowComp(
1655 flow1=flows[ i ],
1656 flow2=tmpFlows )
1657 FlowTables = FlowTables and tempResult
1658 if FlowTables == main.FALSE:
1659 main.log.info( "Differences in flow table for switch: s" +
1660 str( i + 1 ) )
1661 if FlowTables == main.TRUE:
1662 main.log.report( "No changes were found in the flow tables" )
1663 utilities.assert_equals(
1664 expect=main.TRUE,
1665 actual=FlowTables,
1666 onpass="No changes were found in the flow tables",
1667 onfail="Changes were found in the flow tables" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001668
Jon Hall6aec96b2015-01-19 14:49:31 -08001669 main.step( "Check the continuous pings to ensure that no packets " +
1670 "were dropped during component failure" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001671 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
1672 main.params[ 'TESTONIP' ] )
Jon Hall8f89dda2015-01-22 16:03:33 -08001673 LossInPings = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001674 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
1675 for i in range( 8, 18 ):
1676 main.log.info(
1677 "Checking for a loss in pings along flow from s" +
1678 str( i ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001679 LossInPings = main.Mininet2.checkForLoss(
Jon Hall6aec96b2015-01-19 14:49:31 -08001680 "/tmp/ping.h" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001681 str( i ) ) or LossInPings
1682 if LossInPings == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001683 main.log.info( "Loss in ping detected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001684 elif LossInPings == main.ERROR:
Jon Hall6aec96b2015-01-19 14:49:31 -08001685 main.log.info( "There are multiple mininet process running" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001686 elif LossInPings == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001687 main.log.info( "No Loss in the pings" )
1688 main.log.report( "No loss of dataplane connectivity" )
1689 utilities.assert_equals(
1690 expect=main.FALSE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001691 actual=LossInPings,
Jon Hall6aec96b2015-01-19 14:49:31 -08001692 onpass="No Loss of connectivity",
1693 onfail="Loss of dataplane connectivity detected" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001694
Jon Hall6aec96b2015-01-19 14:49:31 -08001695 # Test of LeadershipElection
Jon Hall8f89dda2015-01-22 16:03:33 -08001696 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001697 # FIXME: make sure this matches nodes that were restarted
1698 restarted = [ nodes[0].ip_address, nodes[1].ip_address,
1699 nodes[2].ip_address ]
1700
Jon Hall8f89dda2015-01-22 16:03:33 -08001701 leaderResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001702 for cli in CLIs:
1703 leaderN = cli.electionTestLeader()
Jon Hall8f89dda2015-01-22 16:03:33 -08001704 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08001705 if leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001706 # error in response
1707 main.log.report( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001708 "electionTestLeader function, check the" +
Jon Hall6aec96b2015-01-19 14:49:31 -08001709 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001710 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001711 elif leaderN is None:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001712 main.log.report( cli.name +
Jon Hall6aec96b2015-01-19 14:49:31 -08001713 " shows no leader for the election-app was" +
1714 " elected after the old one died" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001715 leaderResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001716 elif leaderN in restarted:
1717 main.log.report( cli.name + " shows " + str( leaderN ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08001718 " as leader for the election-app, but it " +
1719 "was restarted" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001720 leaderResult = main.FALSE
1721 if len( set( leaderList ) ) != 1:
1722 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001723 main.log.error(
1724 "Inconsistent view of leader for the election test app" )
1725 # TODO: print the list
Jon Hall8f89dda2015-01-22 16:03:33 -08001726 if leaderResult:
1727 main.log.report( "Leadership election tests passed( consistent " +
Jon Hall6aec96b2015-01-19 14:49:31 -08001728 "view of leader across listeners and a new " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001729 "leader was re-elected if applicable )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001730 utilities.assert_equals(
1731 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001732 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001733 onpass="Leadership election passed",
1734 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08001735
Jon Hall58c76b72015-02-23 11:09:24 -08001736 result = ( mastershipCheck and intentCheck and FlowTables and
1737 ( not LossInPings ) and rolesNotNull and leaderResult )
Jon Hall6aec96b2015-01-19 14:49:31 -08001738 result = int( result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001739 if result == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001740 main.log.report( "Constant State Tests Passed" )
1741 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hallfebb1c72015-03-05 13:30:09 -08001742 onpass="Constant State Tests Passed",
1743 onfail="Constant state tests failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001744
Jon Hall6aec96b2015-01-19 14:49:31 -08001745 def CASE8( self, main ):
1746 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001747 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -08001748 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001749 import sys
Jon Hall6aec96b2015-01-19 14:49:31 -08001750 # FIXME add this path to params
1751 sys.path.append( "/home/admin/sts" )
1752 # assumes that sts is already in you PYTHONPATH
1753 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -08001754 import json
1755 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001756 assert numControllers, "numControllers not defined"
1757 assert main, "main not defined"
1758 assert utilities.assert_equals, "utilities.assert_equals not defined"
1759 assert CLIs, "CLIs not defined"
1760 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08001761
Jon Hall6aec96b2015-01-19 14:49:31 -08001762 description = "Compare ONOS Topology view to Mininet topology"
1763 main.case( description )
1764 main.log.report( description )
1765 main.step( "Create TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001766 ctrls = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001767 for node in nodes:
1768 temp = ( node, node.name, node.ip_address, 6633 )
1769 ctrls.append( temp )
1770 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001771
Jon Hall6aec96b2015-01-19 14:49:31 -08001772 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001773 devicesResults = main.TRUE
1774 portsResults = main.TRUE
1775 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08001776 hostsResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08001777 topoResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001778 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -08001779 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -08001780 main.step( "Collecting topology information from ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001781 startTime = time.time()
Jon Hall21270ac2015-02-16 17:59:55 -08001782 # Give time for Gossip to work
Jon Hall8f89dda2015-01-22 16:03:33 -08001783 while topoResult == main.FALSE and elapsed < 60:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001784 count += 1
Jon Hall94fd0472014-12-08 11:52:42 -08001785 if count > 1:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001786 # TODO: Deprecate STS usage
Jon Hall58c76b72015-02-23 11:09:24 -08001787 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall8f89dda2015-01-22 16:03:33 -08001788 cliStart = time.time()
Jon Hall94fd0472014-12-08 11:52:42 -08001789 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001790 threads = []
1791 for i in range( numControllers ):
1792 t = main.Thread( target=CLIs[i].devices,
1793 name="devices-" + str( i ),
1794 args=[ ] )
1795 threads.append( t )
1796 t.start()
1797
1798 for t in threads:
1799 t.join()
1800 devices.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001801 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -08001802 ipResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001803 threads = []
1804 for i in range( numControllers ):
1805 t = main.Thread( target=CLIs[i].hosts,
1806 name="hosts-" + str( i ),
1807 args=[ ] )
1808 threads.append( t )
1809 t.start()
1810
1811 for t in threads:
1812 t.join()
1813 try:
1814 hosts.append( json.loads( t.result ) )
1815 except ( ValueError, TypeError ):
1816 main.log.exception( "Error parsing hosts results" )
1817 main.log.error( repr( t.result ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001818 for controller in range( 0, len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001819 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001820 for host in hosts[ controller ]:
Jon Hall58c76b72015-02-23 11:09:24 -08001821 if host is None or host.get( 'ips', [] ) == []:
Jon Hall6aec96b2015-01-19 14:49:31 -08001822 main.log.error(
1823 "DEBUG:Error with host ips on controller" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001824 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001825 ipResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001826 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001827 threads = []
1828 for i in range( numControllers ):
1829 t = main.Thread( target=CLIs[i].ports,
1830 name="ports-" + str( i ),
1831 args=[ ] )
1832 threads.append( t )
1833 t.start()
1834
1835 for t in threads:
1836 t.join()
1837 ports.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001838 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001839 threads = []
1840 for i in range( numControllers ):
1841 t = main.Thread( target=CLIs[i].links,
1842 name="links-" + str( i ),
1843 args=[ ] )
1844 threads.append( t )
1845 t.start()
1846
1847 for t in threads:
1848 t.join()
1849 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001850 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001851 threads = []
1852 for i in range( numControllers ):
1853 t = main.Thread( target=CLIs[i].clusters,
1854 name="clusters-" + str( i ),
1855 args=[ ] )
1856 threads.append( t )
1857 t.start()
1858
1859 for t in threads:
1860 t.join()
1861 clusters.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001862
Jon Hall8f89dda2015-01-22 16:03:33 -08001863 elapsed = time.time() - startTime
1864 cliTime = time.time() - cliStart
1865 print "CLI time: " + str( cliTime )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001866
Jon Hall8f89dda2015-01-22 16:03:33 -08001867 for controller in range( numControllers ):
1868 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001869 if devices[ controller ] or "Error" not in devices[
1870 controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001871 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08001872 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08001873 json.loads( devices[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001874 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001875 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001876 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001877 actual=currentDevicesResult,
1878 onpass="ONOS" + controllerStr +
1879 " Switches view is correct",
1880 onfail="ONOS" + controllerStr +
1881 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001882
Jon Hall6aec96b2015-01-19 14:49:31 -08001883 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001884 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08001885 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08001886 json.loads( ports[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001887 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001888 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001889 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001890 actual=currentPortsResult,
1891 onpass="ONOS" + controllerStr +
1892 " ports view is correct",
1893 onfail="ONOS" + controllerStr +
1894 " ports view is incorrect" )
Jon Hall94fd0472014-12-08 11:52:42 -08001895
Jon Hall6aec96b2015-01-19 14:49:31 -08001896 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001897 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08001898 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08001899 json.loads( links[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001900 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001901 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001902 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001903 actual=currentLinksResult,
1904 onpass="ONOS" + controllerStr +
1905 " links view is correct",
1906 onfail="ONOS" + controllerStr +
1907 " links view is incorrect" )
1908
1909 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1910 currentHostsResult = main.Mininet1.compareHosts(
1911 MNTopo, hosts[ controller ] )
1912 else:
1913 currentHostsResult = main.FALSE
1914 utilities.assert_equals( expect=main.TRUE,
1915 actual=currentHostsResult,
1916 onpass="ONOS" + controllerStr +
1917 " hosts exist in Mininet",
1918 onfail="ONOS" + controllerStr +
1919 " hosts don't match Mininet" )
1920
1921 devicesResults = devicesResults and currentDevicesResult
1922 portsResults = portsResults and currentPortsResult
1923 linksResults = linksResults and currentLinksResult
1924 hostsResults = hostsResults and currentHostsResult
Jon Hall94fd0472014-12-08 11:52:42 -08001925
Jon Hall529a37f2015-01-28 10:02:00 -08001926 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001927
Jon Hall6aec96b2015-01-19 14:49:31 -08001928 # hosts
Jon Hall8f89dda2015-01-22 16:03:33 -08001929 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001930 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001931 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001932 if "Error" not in hosts[ controller ]:
1933 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001934 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001935 else: # hosts not consistent
Jon Hall8f89dda2015-01-22 16:03:33 -08001936 main.log.report( "hosts from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001937 " is inconsistent with ONOS1" )
1938 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001939 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001940
1941 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001942 main.log.report( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001943 controllerStr )
1944 consistentHostsResult = main.FALSE
1945 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001946 " hosts response: " +
1947 repr( hosts[ controller ] ) )
1948 utilities.assert_equals(
1949 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001950 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001951 onpass="Hosts view is consistent across all ONOS nodes",
1952 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001953
Jon Hall6aec96b2015-01-19 14:49:31 -08001954 # Strongly connected clusters of devices
Jon Hall8f89dda2015-01-22 16:03:33 -08001955 consistentClustersResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001956 for controller in range( len( clusters ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001957 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001958 if "Error" not in clusters[ controller ]:
1959 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001960 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001961 else: # clusters not consistent
1962 main.log.report( "clusters from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001963 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001964 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001965 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001966
1967 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001968 main.log.report( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001969 "from ONOS" + controllerStr )
1970 consistentClustersResult = main.FALSE
1971 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001972 " clusters response: " +
1973 repr( clusters[ controller ] ) )
1974 utilities.assert_equals(
1975 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001976 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001977 onpass="Clusters view is consistent across all ONOS nodes",
1978 onfail="ONOS nodes have different views of clusters" )
1979 # there should always only be one cluster
Jon Hall5cfd23c2015-03-19 11:40:57 -07001980 try:
1981 numClusters = len( json.loads( clusters[ 0 ] ) )
1982 except ( ValueError, TypeError ):
1983 main.log.exception( "Error parsing clusters[0]: " +
1984 repr( clusters[0] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001985 clusterResults = main.FALSE
1986 if numClusters == 1:
1987 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001988 utilities.assert_equals(
1989 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08001990 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08001991 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08001992 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08001993
Jon Hall8f89dda2015-01-22 16:03:33 -08001994 topoResult = ( devicesResults and portsResults and linksResults
Jon Hall58c76b72015-02-23 11:09:24 -08001995 and hostsResults and consistentHostsResult
1996 and consistentClustersResult and clusterResults
1997 and ipResult )
Jon Hall94fd0472014-12-08 11:52:42 -08001998
Jon Hall8f89dda2015-01-22 16:03:33 -08001999 topoResult = topoResult and int( count <= 2 )
2000 note = "note it takes about " + str( int( cliTime ) ) + \
2001 " seconds for the test to make all the cli calls to fetch " +\
2002 "the topology from each ONOS instance"
Jon Hall1b8f54a2015-02-04 13:24:20 -08002003 main.log.info(
Jon Hall8f89dda2015-01-22 16:03:33 -08002004 "Very crass estimate for topology discovery/convergence( " +
2005 str( note ) + " ): " + str( elapsed ) + " seconds, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002006 str( count ) + " tries" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002007 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08002008 onpass="Topology Check Test successful",
2009 onfail="Topology Check Test NOT successful" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002010 if topoResult == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002011 main.log.report( "ONOS topology view matches Mininet topology" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002012
Jon Halla9d26da2015-03-30 16:45:32 -07002013 # FIXME: move this to an ONOS state case
2014 main.step( "Checking ONOS nodes" )
2015 nodesOutput = []
2016 threads = []
2017 for i in range( numControllers ):
2018 t = main.Thread( target=CLIs[i].nodes,
2019 name="nodes-" + str( i ),
2020 args=[ ] )
2021 threads.append( t )
2022 t.start()
2023
2024 for t in threads:
2025 t.join()
2026 nodesOutput.append( t.result )
2027 ips = [ node.ip_address for node in nodes ]
2028 for i in nodesOutput:
2029 try:
2030 current = json.loads( i )
2031 for node in current:
2032 if node['ip'] in ips: # node in nodes() output is in cell
2033 if node['state'] == 'ACTIVE':
2034 pass # as it should be
2035 else:
2036 main.log.error( "Error in ONOS node availability" )
2037 main.log.error(
2038 json.dumps( current,
2039 sort_keys=True,
2040 indent=4,
2041 separators=( ',', ': ' ) ) )
2042 break
2043 except ( ValueError, TypeError ):
2044 main.log.error( "Error parsing nodes output" )
2045 main.log.warn( repr( i ) )
2046
Jon Hall6aec96b2015-01-19 14:49:31 -08002047 def CASE9( self, main ):
2048 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002049 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -08002050 """
2051 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002052 assert numControllers, "numControllers not defined"
2053 assert main, "main not defined"
2054 assert utilities.assert_equals, "utilities.assert_equals not defined"
2055 assert CLIs, "CLIs not defined"
2056 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002057 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002058
Jon Hall8f89dda2015-01-22 16:03:33 -08002059 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002060
Jon Hall6aec96b2015-01-19 14:49:31 -08002061 description = "Turn off a link to ensure that Link Discovery " +\
Jon Hall58c76b72015-02-23 11:09:24 -08002062 "is working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002063 main.log.report( description )
2064 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002065
Jon Hall6aec96b2015-01-19 14:49:31 -08002066 main.step( "Kill Link between s3 and s28" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002067 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
Jon Hall58c76b72015-02-23 11:09:24 -08002068 main.log.info( "Waiting " + str( linkSleep ) +
2069 " seconds for link down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002070 time.sleep( linkSleep )
2071 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002072 onpass="Link down successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002073 onfail="Failed to bring link down" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002074 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002075
Jon Hall6aec96b2015-01-19 14:49:31 -08002076 def CASE10( self, main ):
2077 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002078 Link s3-s28 up
Jon Hall6aec96b2015-01-19 14:49:31 -08002079 """
2080 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002081 assert numControllers, "numControllers not defined"
2082 assert main, "main not defined"
2083 assert utilities.assert_equals, "utilities.assert_equals not defined"
2084 assert CLIs, "CLIs not defined"
2085 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002086 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002087
Jon Hall8f89dda2015-01-22 16:03:33 -08002088 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002089
Jon Hall6aec96b2015-01-19 14:49:31 -08002090 description = "Restore a link to ensure that Link Discovery is " + \
Jon Hall63604932015-02-26 17:09:50 -08002091 "working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002092 main.log.report( description )
2093 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002094
Jon Hall6aec96b2015-01-19 14:49:31 -08002095 main.step( "Bring link between s3 and s28 back up" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002096 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
Jon Hall58c76b72015-02-23 11:09:24 -08002097 main.log.info( "Waiting " + str( linkSleep ) +
2098 " seconds for link up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002099 time.sleep( linkSleep )
2100 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002101 onpass="Link up successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002102 onfail="Failed to bring link up" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002103 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002104
Jon Hall6aec96b2015-01-19 14:49:31 -08002105 def CASE11( self, main ):
2106 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002107 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -08002108 """
2109 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002110 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002111 assert numControllers, "numControllers not defined"
2112 assert main, "main not defined"
2113 assert utilities.assert_equals, "utilities.assert_equals not defined"
2114 assert CLIs, "CLIs not defined"
2115 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08002116
Jon Hall8f89dda2015-01-22 16:03:33 -08002117 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002118
2119 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002120 main.log.report( description )
2121 main.case( description )
2122 switch = main.params[ 'kill' ][ 'switch' ]
2123 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08002124
Jon Hall6aec96b2015-01-19 14:49:31 -08002125 # TODO: Make this switch parameterizable
2126 main.step( "Kill " + switch )
2127 main.log.report( "Deleting " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002128 main.Mininet1.delSwitch( switch )
2129 main.log.info( "Waiting " + str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002130 " seconds for switch down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002131 time.sleep( switchSleep )
2132 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002133 # Peek at the deleted switch
2134 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002135 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002136 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -08002137 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002138 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002139 onpass="Kill switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002140 onfail="Failed to kill switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002141
Jon Hall6aec96b2015-01-19 14:49:31 -08002142 def CASE12( self, main ):
2143 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002144 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -08002145 """
2146 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002147 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002148 assert numControllers, "numControllers not defined"
2149 assert main, "main not defined"
2150 assert utilities.assert_equals, "utilities.assert_equals not defined"
2151 assert CLIs, "CLIs not defined"
2152 assert nodes, "nodes not defined"
2153 assert ONOS1Port, "ONOS1Port not defined"
2154 assert ONOS2Port, "ONOS2Port not defined"
2155 assert ONOS3Port, "ONOS3Port not defined"
2156 assert ONOS4Port, "ONOS4Port not defined"
2157 assert ONOS5Port, "ONOS5Port not defined"
2158 assert ONOS6Port, "ONOS6Port not defined"
2159 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall669173b2014-12-17 11:36:30 -08002160
Jon Hall8f89dda2015-01-22 16:03:33 -08002161 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall6aec96b2015-01-19 14:49:31 -08002162 switch = main.params[ 'kill' ][ 'switch' ]
2163 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2164 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002165 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002166 main.log.report( description )
2167 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002168
Jon Hall6aec96b2015-01-19 14:49:31 -08002169 main.step( "Add back " + switch )
2170 main.log.report( "Adding back " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002171 main.Mininet1.addSwitch( switch, dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002172 for peer in links:
Jon Hall8f89dda2015-01-22 16:03:33 -08002173 main.Mininet1.addLink( switch, peer )
Jon Hall58c76b72015-02-23 11:09:24 -08002174 main.Mininet1.assignSwController( sw=switch.split( 's' )[ 1 ],
2175 count=numControllers,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002176 ip1=nodes[ 0 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002177 port1=ONOS1Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002178 ip2=nodes[ 1 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002179 port2=ONOS2Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002180 ip3=nodes[ 2 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002181 port3=ONOS3Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002182 ip4=nodes[ 3 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002183 port4=ONOS4Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002184 ip5=nodes[ 4 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002185 port5=ONOS5Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002186 ip6=nodes[ 5 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002187 port6=ONOS6Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002188 ip7=nodes[ 6 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002189 port7=ONOS7Port )
2190 main.log.info( "Waiting " + str( switchSleep ) +
2191 " seconds for switch up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002192 time.sleep( switchSleep )
2193 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002194 # Peek at the deleted switch
2195 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002196 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002197 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002198 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002199 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002200 onpass="add switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002201 onfail="Failed to add switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002202
Jon Hall6aec96b2015-01-19 14:49:31 -08002203 def CASE13( self, main ):
2204 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002205 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -08002206 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002207 import os
2208 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002209 assert numControllers, "numControllers not defined"
2210 assert main, "main not defined"
2211 assert utilities.assert_equals, "utilities.assert_equals not defined"
2212 assert CLIs, "CLIs not defined"
2213 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002214
2215 # printing colors to terminal
Jon Hall5cfd23c2015-03-19 11:40:57 -07002216 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2217 'blue': '\033[94m', 'green': '\033[92m',
2218 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
Jon Hall73cf9cc2014-11-20 22:28:38 -08002219 description = "Test Cleanup"
Jon Hall6aec96b2015-01-19 14:49:31 -08002220 main.log.report( description )
2221 main.case( description )
2222 main.step( "Killing tcpdumps" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002223 main.Mininet2.stopTcpdump()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002224
Jon Hall6aec96b2015-01-19 14:49:31 -08002225 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002226 testname = main.TEST
Jon Hall8f89dda2015-01-22 16:03:33 -08002227 teststationUser = main.params[ 'TESTONUSER' ]
2228 teststationIP = main.params[ 'TESTONIP' ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002229 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -08002230 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -08002231 # FIXME: scp
2232 # mn files
2233 # TODO: Load these from params
2234 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002235 logFolder = "/opt/onos/log/"
2236 logFiles = [ "karaf.log", "karaf.log.1" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002237 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002238 dstDir = "~/packet_captures/"
2239 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002240 for node in nodes:
2241 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2242 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002243 teststationUser + "@" +
2244 teststationIP + ":" +
2245 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002246 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002247 main.ONOSbench.handle.expect( "\$" )
2248
Jon Hall6aec96b2015-01-19 14:49:31 -08002249 # std*.log's
2250 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002251 logFolder = "/opt/onos/var/"
2252 logFiles = [ "stderr.log", "stdout.log" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002253 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002254 dstDir = "~/packet_captures/"
2255 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002256 for node in nodes:
2257 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2258 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002259 teststationUser + "@" +
2260 teststationIP + ":" +
2261 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002262 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002263 main.ONOSbench.handle.expect( "\$" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002264 # sleep so scp can finish
2265 time.sleep( 10 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002266
2267 main.step( "Stopping Mininet" )
Jon Hall58c76b72015-02-23 11:09:24 -08002268 main.Mininet1.stopNet()
Jon Hall5cfd23c2015-03-19 11:40:57 -07002269
2270 main.step( "Checking ONOS Logs for errors" )
2271 for node in nodes:
2272 print colors[ 'purple' ] + "Checking logs for errors on " + \
2273 node.name + ":" + colors[ 'end' ]
2274 print main.ONOSbench.checkLogs( node.ip_address )
2275
Jon Hall6aec96b2015-01-19 14:49:31 -08002276 main.step( "Packing and rotating pcap archives" )
2277 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002278
Jon Hall6aec96b2015-01-19 14:49:31 -08002279 # TODO: actually check something here
2280 utilities.assert_equals( expect=main.TRUE, actual=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002281 onpass="Test cleanup successful",
2282 onfail="Test cleanup NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002283
Jon Hall6aec96b2015-01-19 14:49:31 -08002284 def CASE14( self, main ):
2285 """
Jon Hall669173b2014-12-17 11:36:30 -08002286 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -08002287 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07002288 import time
2289 assert numControllers, "numControllers not defined"
2290 assert main, "main not defined"
2291 assert utilities.assert_equals, "utilities.assert_equals not defined"
2292 assert CLIs, "CLIs not defined"
2293 assert nodes, "nodes not defined"
2294
Jon Hall8f89dda2015-01-22 16:03:33 -08002295 leaderResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002296 main.log.info( "Install leadership election app" )
Jon Halla9d26da2015-03-30 16:45:32 -07002297 main.ONOScli1.activateApp( "org.onosproject.election" )
2298 leaders = []
2299 for cli in CLIs:
2300 leader = cli.electionTestLeader()
2301 if leader is None or leader == main.FALSE:
2302 main.log.report( cli.name + ": Leader for the election app " +
2303 "should be an ONOS node, instead got '" +
2304 str( leader ) + "'" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002305 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002306 leaders.append( leader )
2307 if len( set( leaders ) ) != 1:
2308 leaderResult = main.FALSE
2309 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2310 str( leaders ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08002311 if leaderResult:
Jon Hall6aec96b2015-01-19 14:49:31 -08002312 main.log.report( "Leadership election tests passed( consistent " +
2313 "view of leader across listeners and a leader " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002314 "was elected )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002315 utilities.assert_equals(
2316 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002317 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002318 onpass="Leadership election passed",
2319 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002320
Jon Hall6aec96b2015-01-19 14:49:31 -08002321 def CASE15( self, main ):
2322 """
Jon Hall669173b2014-12-17 11:36:30 -08002323 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08002324 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07002325 assert numControllers, "numControllers not defined"
2326 assert main, "main not defined"
2327 assert utilities.assert_equals, "utilities.assert_equals not defined"
2328 assert CLIs, "CLIs not defined"
2329 assert nodes, "nodes not defined"
2330
Jon Hall8f89dda2015-01-22 16:03:33 -08002331 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002332 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08002333 main.log.report( description )
2334 main.case( description )
2335 main.step( "Find current leader and withdraw" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002336 leader = main.ONOScli1.electionTestLeader()
Jon Halla9d26da2015-03-30 16:45:32 -07002337 # do some sanity checking on leader before using it
Jon Hall8f89dda2015-01-22 16:03:33 -08002338 withdrawResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002339 if leader is None or leader == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002340 main.log.report(
2341 "Leader for the election app should be an ONOS node," +
Jon Hall58c76b72015-02-23 11:09:24 -08002342 "instead got '" + str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002343 leaderResult = main.FALSE
Jon Hall63604932015-02-26 17:09:50 -08002344 oldLeader = None
Jon Hall5cfd23c2015-03-19 11:40:57 -07002345 for i in range( len( CLIs ) ):
2346 if leader == nodes[ i ].ip_address:
2347 oldLeader = CLIs[ i ]
2348 break
Jon Halla9d26da2015-03-30 16:45:32 -07002349 else: # FOR/ELSE statement
Jon Hall5cfd23c2015-03-19 11:40:57 -07002350 main.log.error( "Leader election, could not find current leader" )
Jon Hall63604932015-02-26 17:09:50 -08002351 if oldLeader:
2352 withdrawResult = oldLeader.electionTestWithdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08002353 utilities.assert_equals(
2354 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002355 actual=withdrawResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002356 onpass="App was withdrawn from election",
2357 onfail="App was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08002358
Jon Hall6aec96b2015-01-19 14:49:31 -08002359 main.step( "Make sure new leader is elected" )
Jon Halla9d26da2015-03-30 16:45:32 -07002360 # FIXME: use threads
Jon Hall8f89dda2015-01-22 16:03:33 -08002361 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002362 for cli in CLIs:
2363 leaderN = cli.electionTestLeader()
2364 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002365 if leaderN == leader:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002366 main.log.report( cli.name + " still sees " + str( leader ) +
2367 " as leader after they withdrew" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002368 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002369 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002370 # error in response
2371 # TODO: add check for "Command not found:" in the driver, this
Jon Hall5cfd23c2015-03-19 11:40:57 -07002372 # means the app isn't loaded
Jon Hall6aec96b2015-01-19 14:49:31 -08002373 main.log.report( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002374 "electionTestLeader function, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002375 "check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002376 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002377 elif leaderN is None:
2378 # node may not have recieved the event yet
2379 leaderN = cli.electionTestLeader()
2380 leaderList.pop()
2381 leaderList.append( leaderN )
Jon Hall8f89dda2015-01-22 16:03:33 -08002382 consistentLeader = main.FALSE
2383 if len( set( leaderList ) ) == 1:
Jon Hall6aec96b2015-01-19 14:49:31 -08002384 main.log.info( "Each Election-app sees '" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002385 str( leaderList[ 0 ] ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002386 "' as the leader" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002387 consistentLeader = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002388 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08002389 main.log.report(
2390 "Inconsistent responses for leader of Election-app:" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002391 for n in range( len( leaderList ) ):
Jon Hall6aec96b2015-01-19 14:49:31 -08002392 main.log.report( "ONOS" + str( n + 1 ) + " response: " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002393 str( leaderList[ n ] ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002394 leaderResult = leaderResult and consistentLeader
Jon Hall8f89dda2015-01-22 16:03:33 -08002395 if leaderResult:
2396 main.log.report( "Leadership election tests passed( consistent " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002397 "view of leader across listeners and a new " +
2398 "leader was elected when the old leader " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002399 "resigned )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002400 utilities.assert_equals(
2401 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002402 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002403 onpass="Leadership election passed",
2404 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002405
Jon Hall58c76b72015-02-23 11:09:24 -08002406 main.step( "Run for election on old leader( just so everyone " +
2407 "is in the hat )" )
Jon Hall63604932015-02-26 17:09:50 -08002408 if oldLeader:
2409 runResult = oldLeader.electionTestRun()
2410 else:
2411 runResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002412 utilities.assert_equals(
2413 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002414 actual=runResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002415 onpass="App re-ran for election",
2416 onfail="App failed to run for election" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002417 if consistentLeader == main.TRUE:
2418 afterRun = main.ONOScli1.electionTestLeader()
Jon Hall6aec96b2015-01-19 14:49:31 -08002419 # verify leader didn't just change
Jon Hall8f89dda2015-01-22 16:03:33 -08002420 if afterRun == leaderList[ 0 ]:
2421 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002422 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002423 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002424 # TODO: assert on run and withdraw results?
Jon Hall669173b2014-12-17 11:36:30 -08002425
Jon Hall6aec96b2015-01-19 14:49:31 -08002426 utilities.assert_equals(
2427 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002428 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002429 onpass="Leadership election passed",
2430 onfail="Something went wrong with Leadership election after " +
2431 "the old leader re-ran for election" )