blob: 7a21c012d520df569c473824214ccaac63bcd379 [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
Jon Hallc9eabec2015-06-10 14:33:14 -07007CASE2: Assign devices to controllers
8CASE21: Assign mastership to controllers
Jon Hall73cf9cc2014-11-20 22:28:38 -08009CASE3: Assign intents
10CASE4: Ping across added host intents
11CASE5: Reading state of ONOS
12CASE6: The Failure case.
13CASE7: Check state after control plane failure
14CASE8: Compare topo
15CASE9: Link s3-s28 down
16CASE10: Link s3-s28 up
17CASE11: Switch down
18CASE12: Switch up
19CASE13: Clean up
Jon Hall669173b2014-12-17 11:36:30 -080020CASE14: start election app on all onos nodes
21CASE15: Check that Leadership Election is still functional
Jon Hall390696c2015-05-05 17:13:41 -070022CASE16: Install Distributed Primitives app
23CASE17: Check for basic functionality with distributed primitives
Jon Hall6aec96b2015-01-19 14:49:31 -080024"""
Jon Hall8f89dda2015-01-22 16:03:33 -080025
26
Jon Hall73cf9cc2014-11-20 22:28:38 -080027class HATestMinorityRestart:
28
Jon Hall6aec96b2015-01-19 14:49:31 -080029 def __init__( self ):
Jon Hall73cf9cc2014-11-20 22:28:38 -080030 self.default = ''
31
Jon Hall6aec96b2015-01-19 14:49:31 -080032 def CASE1( self, main ):
33 """
Jon Hall73cf9cc2014-11-20 22:28:38 -080034 CASE1 is to compile ONOS and push it to the test machines
35
36 Startup sequence:
Jon Hall73cf9cc2014-11-20 22:28:38 -080037 cell <name>
38 onos-verify-cell
39 NOTE: temporary - onos-remove-raft-logs
Jon Hall58c76b72015-02-23 11:09:24 -080040 onos-uninstall
41 start mininet
42 git pull
43 mvn clean install
44 onos-package
Jon Hall73cf9cc2014-11-20 22:28:38 -080045 onos-install -f
46 onos-wait-for-start
Jon Hall58c76b72015-02-23 11:09:24 -080047 start cli sessions
48 start tcpdump
Jon Hall6aec96b2015-01-19 14:49:31 -080049 """
Jon Hall40d2cbd2015-06-03 16:24:29 -070050 main.log.info( "ONOS HA test: Restart minority of ONOS nodes - " +
Jon Hall390696c2015-05-05 17:13:41 -070051 "initialization" )
Jon Hall6aec96b2015-01-19 14:49:31 -080052 main.case( "Setting up test environment" )
Jon Hallfeff3082015-05-19 10:23:26 -070053 main.caseExplaination = "Setup the test environment including " +\
54 "installing ONOS, starting Mininet and ONOS" +\
55 "cli sessions."
Jon Hall6aec96b2015-01-19 14:49:31 -080056 # TODO: save all the timers and output them for plotting
Jon Hall73cf9cc2014-11-20 22:28:38 -080057
Jon Hall5cfd23c2015-03-19 11:40:57 -070058 # load some variables from the params file
Jon Hall8f89dda2015-01-22 16:03:33 -080059 PULLCODE = False
Jon Hall6aec96b2015-01-19 14:49:31 -080060 if main.params[ 'Git' ] == 'True':
Jon Hall8f89dda2015-01-22 16:03:33 -080061 PULLCODE = True
Jon Hall529a37f2015-01-28 10:02:00 -080062 gitBranch = main.params[ 'branch' ]
Jon Hall8f89dda2015-01-22 16:03:33 -080063 cellName = main.params[ 'ENV' ][ 'cellName' ]
Jon Hall6aec96b2015-01-19 14:49:31 -080064
65 # set global variables
Jon Hall8f89dda2015-01-22 16:03:33 -080066 global ONOS1Port
Jon Hall8f89dda2015-01-22 16:03:33 -080067 global ONOS2Port
Jon Hall8f89dda2015-01-22 16:03:33 -080068 global ONOS3Port
Jon Hall8f89dda2015-01-22 16:03:33 -080069 global ONOS4Port
Jon Hall8f89dda2015-01-22 16:03:33 -080070 global ONOS5Port
Jon Hall8f89dda2015-01-22 16:03:33 -080071 global ONOS6Port
Jon Hall8f89dda2015-01-22 16:03:33 -080072 global ONOS7Port
73 global numControllers
Jon Hall8f89dda2015-01-22 16:03:33 -080074 numControllers = int( main.params[ 'num_controllers' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -080075
Jon Hall5cfd23c2015-03-19 11:40:57 -070076 # FIXME: just get controller port from params?
77 # TODO: do we really need all these?
78 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
79 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
80 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
81 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
82 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
83 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
84 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
85
86 global CLIs
87 CLIs = []
88 global nodes
89 nodes = []
90 for i in range( 1, numControllers + 1 ):
91 CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
92 nodes.append( getattr( main, 'ONOS' + str( i ) ) )
93
Jon Hall6aec96b2015-01-19 14:49:31 -080094 main.step( "Applying cell variable to environment" )
Jon Hall8f89dda2015-01-22 16:03:33 -080095 cellResult = main.ONOSbench.setCell( cellName )
96 verifyResult = main.ONOSbench.verifyCell()
Jon Hall73cf9cc2014-11-20 22:28:38 -080097
Jon Hall6aec96b2015-01-19 14:49:31 -080098 # FIXME:this is short term fix
Jon Hall40d2cbd2015-06-03 16:24:29 -070099 main.log.info( "Removing raft logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800100 main.ONOSbench.onosRemoveRaftLogs()
Jon Hall5cfd23c2015-03-19 11:40:57 -0700101
Jon Hall40d2cbd2015-06-03 16:24:29 -0700102 main.log.info( "Uninstalling ONOS" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700103 for node in nodes:
104 main.ONOSbench.onosUninstall( node.ip_address )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800105
Jon Hall390696c2015-05-05 17:13:41 -0700106 # Make sure ONOS is DEAD
Jon Hall40d2cbd2015-06-03 16:24:29 -0700107 main.log.info( "Killing any ONOS processes" )
Jon Hall390696c2015-05-05 17:13:41 -0700108 killResults = main.TRUE
109 for node in nodes:
110 killed = main.ONOSbench.onosKill( node.ip_address )
111 killResults = killResults and killed
112
Jon Hall8f89dda2015-01-22 16:03:33 -0800113 cleanInstallResult = main.TRUE
114 gitPullResult = main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800115
Jon Hall97f31752015-02-04 12:01:04 -0800116 main.step( "Starting Mininet" )
Jon Hall390696c2015-05-05 17:13:41 -0700117 mnResult = main.Mininet1.startNet( )
118 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
119 onpass="Mininet Started",
120 onfail="Error starting Mininet" )
Jon Hall97f31752015-02-04 12:01:04 -0800121
Jon Hallfeff3082015-05-19 10:23:26 -0700122 main.step( "Git checkout and pull " + gitBranch )
Jon Hall8f89dda2015-01-22 16:03:33 -0800123 if PULLCODE:
Jon Hall529a37f2015-01-28 10:02:00 -0800124 main.ONOSbench.gitCheckout( gitBranch )
Jon Hall8f89dda2015-01-22 16:03:33 -0800125 gitPullResult = main.ONOSbench.gitPull()
Jon Hall390696c2015-05-05 17:13:41 -0700126 # values of 1 or 3 are good
127 utilities.assert_lesser( expect=0, actual=gitPullResult,
128 onpass="Git pull successful",
129 onfail="Git pull failed" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800130 main.ONOSbench.getVersion( report=True )
Jon Hallfeff3082015-05-19 10:23:26 -0700131
132 main.step( "Using mvn clean install" )
133 cleanInstallResult = main.TRUE
Jon Hall40d2cbd2015-06-03 16:24:29 -0700134 if PULLCODE and gitPullResult == main.TRUE:
Jon Hallfeff3082015-05-19 10:23:26 -0700135 cleanInstallResult = main.ONOSbench.cleanInstall()
Jon Hall40d2cbd2015-06-03 16:24:29 -0700136 else:
137 main.log.warn( "Did not pull new code so skipping mvn " +
138 "clean install" )
Jon Hallfeff3082015-05-19 10:23:26 -0700139 utilities.assert_equals( expect=main.TRUE,
140 actual=cleanInstallResult,
141 onpass="MCI successful",
142 onfail="MCI failed" )
Jon Hall390696c2015-05-05 17:13:41 -0700143 # GRAPHS
144 # NOTE: important params here:
145 # job = name of Jenkins job
146 # Plot Name = Plot-HA, only can be used if multiple plots
147 # index = The number of the graph under plot name
148 job = "HAMinorityRestart"
Jon Hall40d2cbd2015-06-03 16:24:29 -0700149 plotName = "Plot-HA"
Jon Hall390696c2015-05-05 17:13:41 -0700150 graphs = '<ac:structured-macro ac:name="html">\n'
151 graphs += '<ac:plain-text-body><![CDATA[\n'
152 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
Jon Hall40d2cbd2015-06-03 16:24:29 -0700153 '/plot/' + plotName + '/getPlot?index=0' +\
154 '&width=500&height=300"' +\
Jon Hall390696c2015-05-05 17:13:41 -0700155 'noborder="0" width="500" height="300" scrolling="yes" ' +\
156 'seamless="seamless"></iframe>\n'
157 graphs += ']]></ac:plain-text-body>\n'
158 graphs += '</ac:structured-macro>\n'
159 main.log.wiki(graphs)
Jon Hall73cf9cc2014-11-20 22:28:38 -0800160
Jon Hall6aec96b2015-01-19 14:49:31 -0800161 main.step( "Creating ONOS package" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800162 packageResult = main.ONOSbench.onosPackage()
Jon Hall390696c2015-05-05 17:13:41 -0700163 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
164 onpass="ONOS package successful",
165 onfail="ONOS package failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800166
Jon Hall6aec96b2015-01-19 14:49:31 -0800167 main.step( "Installing ONOS package" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700168 onosInstallResult = main.TRUE
169 for node in nodes:
170 tmpResult = main.ONOSbench.onosInstall( options="-f",
171 node=node.ip_address )
172 onosInstallResult = onosInstallResult and tmpResult
Jon Hall390696c2015-05-05 17:13:41 -0700173 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
174 onpass="ONOS install successful",
175 onfail="ONOS install failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800176
Jon Hall6aec96b2015-01-19 14:49:31 -0800177 main.step( "Checking if ONOS is up yet" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800178 for i in range( 2 ):
Jon Hall5cfd23c2015-03-19 11:40:57 -0700179 onosIsupResult = main.TRUE
180 for node in nodes:
181 started = main.ONOSbench.isup( node.ip_address )
182 if not started:
Jon Hall40d2cbd2015-06-03 16:24:29 -0700183 main.log.error( node.name + " didn't start!" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700184 main.ONOSbench.onosStop( node.ip_address )
185 main.ONOSbench.onosStart( node.ip_address )
186 onosIsupResult = onosIsupResult and started
Jon Hall8f89dda2015-01-22 16:03:33 -0800187 if onosIsupResult == main.TRUE:
Jon Hall94fd0472014-12-08 11:52:42 -0800188 break
Jon Hall390696c2015-05-05 17:13:41 -0700189 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
190 onpass="ONOS startup successful",
191 onfail="ONOS startup failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800192
Jon Hall5cfd23c2015-03-19 11:40:57 -0700193 main.log.step( "Starting ONOS CLI sessions" )
194 cliResults = main.TRUE
195 threads = []
196 for i in range( numControllers ):
197 t = main.Thread( target=CLIs[i].startOnosCli,
198 name="startOnosCli-" + str( i ),
199 args=[nodes[i].ip_address] )
200 threads.append( t )
201 t.start()
202
203 for t in threads:
204 t.join()
205 cliResults = cliResults and t.result
Jon Hall390696c2015-05-05 17:13:41 -0700206 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
207 onpass="ONOS cli startup successful",
208 onfail="ONOS cli startup failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800209
Jon Hall40d2cbd2015-06-03 16:24:29 -0700210 if main.params[ 'tcpdump' ].lower() == "true":
211 main.step( "Start Packet Capture MN" )
212 main.Mininet2.startTcpdump(
213 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
214 + "-MN.pcap",
215 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
216 port=main.params[ 'MNtcpdump' ][ 'port' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800217
Jon Hall390696c2015-05-05 17:13:41 -0700218 main.step( "App Ids check" )
Jon Halla9d26da2015-03-30 16:45:32 -0700219 appCheck = main.TRUE
220 threads = []
221 for i in range( numControllers ):
222 t = main.Thread( target=CLIs[i].appToIDCheck,
223 name="appToIDCheck-" + str( i ),
224 args=[] )
225 threads.append( t )
226 t.start()
227
228 for t in threads:
229 t.join()
230 appCheck = appCheck and t.result
Jon Halla9d26da2015-03-30 16:45:32 -0700231 if appCheck != main.TRUE:
232 main.log.warn( CLIs[0].apps() )
233 main.log.warn( CLIs[0].appIDs() )
Jon Hall390696c2015-05-05 17:13:41 -0700234 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
235 onpass="App Ids seem to be correct",
236 onfail="Something is wrong with app Ids" )
Jon Halla9d26da2015-03-30 16:45:32 -0700237
Jon Hallfeff3082015-05-19 10:23:26 -0700238 if cliResults == main.FALSE:
239 main.log.error( "Failed to start ONOS, stopping test" )
Jon Hall94fd0472014-12-08 11:52:42 -0800240 main.cleanup()
241 main.exit()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800242
Jon Hall6aec96b2015-01-19 14:49:31 -0800243 def CASE2( self, main ):
244 """
Jon Hallc9eabec2015-06-10 14:33:14 -0700245 Assign devices to controllers
Jon Hall6aec96b2015-01-19 14:49:31 -0800246 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800247 import re
Jon Hall390696c2015-05-05 17:13:41 -0700248 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -0700249 assert numControllers, "numControllers not defined"
250 assert main, "main not defined"
251 assert utilities.assert_equals, "utilities.assert_equals not defined"
252 assert CLIs, "CLIs not defined"
253 assert nodes, "nodes not defined"
254 assert ONOS1Port, "ONOS1Port not defined"
255 assert ONOS2Port, "ONOS2Port not defined"
256 assert ONOS3Port, "ONOS3Port not defined"
257 assert ONOS4Port, "ONOS4Port not defined"
258 assert ONOS5Port, "ONOS5Port not defined"
259 assert ONOS6Port, "ONOS6Port not defined"
260 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -0800261
Jon Hallc9eabec2015-06-10 14:33:14 -0700262 main.case( "Assigning devices to controllers" )
Jon Hallfeff3082015-05-19 10:23:26 -0700263 main.caseExplaination = "Assign switches to ONOS using 'ovs-vsctl' " +\
264 "and check that an ONOS node becomes the " +\
Jon Hallc9eabec2015-06-10 14:33:14 -0700265 "master of the device."
Jon Hall6aec96b2015-01-19 14:49:31 -0800266 main.step( "Assign switches to controllers" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800267
Jon Hall0f523f22015-07-06 09:31:09 -0700268 ipList = []
269 for i in range( numControllers ):
270 ipList.append( nodes[ i ].ip_address )
271 swList = []
Jon Hall6aec96b2015-01-19 14:49:31 -0800272 for i in range( 1, 29 ):
Jon Hall0f523f22015-07-06 09:31:09 -0700273 swList.append( "s" + str( i ) )
274 main.Mininet1.assignSwController( sw=swList, ip=ipList )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800275
Jon Hall8f89dda2015-01-22 16:03:33 -0800276 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800277 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800278 response = main.Mininet1.getSwController( "s" + str( i ) )
Jon Hallffb386d2014-11-21 13:43:38 -0800279 try:
Jon Hall6aec96b2015-01-19 14:49:31 -0800280 main.log.info( str( response ) )
Jon Hallfebb1c72015-03-05 13:30:09 -0800281 except Exception:
Jon Hall6aec96b2015-01-19 14:49:31 -0800282 main.log.info( repr( response ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700283 for node in nodes:
284 if re.search( "tcp:" + node.ip_address, response ):
285 mastershipCheck = mastershipCheck and main.TRUE
286 else:
Jon Halla9d26da2015-03-30 16:45:32 -0700287 main.log.error( "Error, node " + node.ip_address + " is " +
288 "not in the list of controllers s" +
289 str( i ) + " is connecting to." )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700290 mastershipCheck = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800291 utilities.assert_equals(
292 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800293 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800294 onpass="Switch mastership assigned correctly",
295 onfail="Switches not assigned correctly to controllers" )
Jon Hall390696c2015-05-05 17:13:41 -0700296
Jon Hallc9eabec2015-06-10 14:33:14 -0700297 def CASE21( self, main ):
298 """
299 Assign mastership to controllers
300 """
301 import re
302 import time
303 assert numControllers, "numControllers not defined"
304 assert main, "main not defined"
305 assert utilities.assert_equals, "utilities.assert_equals not defined"
306 assert CLIs, "CLIs not defined"
307 assert nodes, "nodes not defined"
308 assert ONOS1Port, "ONOS1Port not defined"
309 assert ONOS2Port, "ONOS2Port not defined"
310 assert ONOS3Port, "ONOS3Port not defined"
311 assert ONOS4Port, "ONOS4Port not defined"
312 assert ONOS5Port, "ONOS5Port not defined"
313 assert ONOS6Port, "ONOS6Port not defined"
314 assert ONOS7Port, "ONOS7Port not defined"
315
316 main.case( "Assigning Controller roles for switches" )
317 main.caseExplaination = "Check that ONOS is connected to each " +\
318 "device. Then manually assign" +\
319 " mastership to specific ONOS nodes using" +\
320 " 'device-role'"
Jon Hall390696c2015-05-05 17:13:41 -0700321 main.step( "Assign mastership of switches to specific controllers" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800322 # Manually assign mastership to the controller we want
Jon Hall8f89dda2015-01-22 16:03:33 -0800323 roleCall = main.TRUE
Jon Hall390696c2015-05-05 17:13:41 -0700324
325 ipList = [ ]
326 deviceList = []
Jon Hall58c76b72015-02-23 11:09:24 -0800327 try:
Jon Halla9d26da2015-03-30 16:45:32 -0700328 for i in range( 1, 29 ): # switches 1 through 28
329 # set up correct variables:
330 if i == 1:
331 ip = nodes[ 0 ].ip_address # ONOS1
332 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
333 elif i == 2:
334 ip = nodes[ 1 ].ip_address # ONOS2
335 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
336 elif i == 3:
337 ip = nodes[ 1 ].ip_address # ONOS2
338 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
339 elif i == 4:
340 ip = nodes[ 3 ].ip_address # ONOS4
341 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
342 elif i == 5:
343 ip = nodes[ 2 ].ip_address # ONOS3
344 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
345 elif i == 6:
346 ip = nodes[ 2 ].ip_address # ONOS3
347 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
348 elif i == 7:
349 ip = nodes[ 5 ].ip_address # ONOS6
350 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
351 elif i >= 8 and i <= 17:
352 ip = nodes[ 4 ].ip_address # ONOS5
353 dpid = '3' + str( i ).zfill( 3 )
354 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
355 elif i >= 18 and i <= 27:
356 ip = nodes[ 6 ].ip_address # ONOS7
357 dpid = '6' + str( i ).zfill( 3 )
358 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
359 elif i == 28:
360 ip = nodes[ 0 ].ip_address # ONOS1
361 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
362 else:
363 main.log.error( "You didn't write an else statement for " +
364 "switch s" + str( i ) )
Jon Hallc9eabec2015-06-10 14:33:14 -0700365 roleCall = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -0700366 # Assign switch
367 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
368 # TODO: make this controller dynamic
369 roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
370 ip )
Jon Hall390696c2015-05-05 17:13:41 -0700371 ipList.append( ip )
372 deviceList.append( deviceId )
Jon Hall58c76b72015-02-23 11:09:24 -0800373 except ( AttributeError, AssertionError ):
374 main.log.exception( "Something is wrong with ONOS device view" )
375 main.log.info( main.ONOScli1.devices() )
Jon Hall6aec96b2015-01-19 14:49:31 -0800376 utilities.assert_equals(
377 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800378 actual=roleCall,
Jon Hall6aec96b2015-01-19 14:49:31 -0800379 onpass="Re-assigned switch mastership to designated controller",
Jon Hall8f89dda2015-01-22 16:03:33 -0800380 onfail="Something wrong with deviceRole calls" )
Jon Hall94fd0472014-12-08 11:52:42 -0800381
Jon Hall390696c2015-05-05 17:13:41 -0700382 main.step( "Check mastership was correctly assigned" )
383 roleCheck = main.TRUE
384 # NOTE: This is due to the fact that device mastership change is not
385 # atomic and is actually a multi step process
386 time.sleep( 5 )
387 for i in range( len( ipList ) ):
388 ip = ipList[i]
389 deviceId = deviceList[i]
390 # Check assignment
391 master = main.ONOScli1.getRole( deviceId ).get( 'master' )
392 if ip in master:
393 roleCheck = roleCheck and main.TRUE
394 else:
395 roleCheck = roleCheck and main.FALSE
396 main.log.error( "Error, controller " + ip + " is not" +
397 " master " + "of device " +
398 str( deviceId ) + ". Master is " +
399 repr( master ) + "." )
Jon Hall6aec96b2015-01-19 14:49:31 -0800400 utilities.assert_equals(
401 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800402 actual=roleCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800403 onpass="Switches were successfully reassigned to designated " +
404 "controller",
405 onfail="Switches were not successfully reassigned" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800406
Jon Hall6aec96b2015-01-19 14:49:31 -0800407 def CASE3( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800408 """
409 Assign intents
Jon Hall73cf9cc2014-11-20 22:28:38 -0800410 """
411 import time
Jon Hallfebb1c72015-03-05 13:30:09 -0800412 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700413 assert numControllers, "numControllers not defined"
414 assert main, "main not defined"
415 assert utilities.assert_equals, "utilities.assert_equals not defined"
416 assert CLIs, "CLIs not defined"
417 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -0800418 main.case( "Adding host Intents" )
Jon Hallfeff3082015-05-19 10:23:26 -0700419 main.caseExplaination = "Discover hosts by using pingall then " +\
420 "assign predetermined host-to-host intents." +\
421 " After installation, check that the intent" +\
422 " is distributed to all nodes and the state" +\
423 " is INSTALLED"
Jon Hall73cf9cc2014-11-20 22:28:38 -0800424
Jon Hall6aec96b2015-01-19 14:49:31 -0800425 # install onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700426 main.step( "Install reactive forwarding app" )
427 installResults = CLIs[0].activateApp( "org.onosproject.fwd" )
428 utilities.assert_equals( expect=main.TRUE, actual=installResults,
429 onpass="Install fwd successful",
430 onfail="Install fwd failed" )
Jon Halla9d26da2015-03-30 16:45:32 -0700431
Jon Hallfeff3082015-05-19 10:23:26 -0700432 main.step( "Check app ids" )
Jon Halla9d26da2015-03-30 16:45:32 -0700433 appCheck = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700434 threads = []
435 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700436 t = main.Thread( target=CLIs[i].appToIDCheck,
437 name="appToIDCheck-" + str( i ),
438 args=[] )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700439 threads.append( t )
440 t.start()
441
442 for t in threads:
443 t.join()
Jon Halla9d26da2015-03-30 16:45:32 -0700444 appCheck = appCheck and t.result
Jon Halla9d26da2015-03-30 16:45:32 -0700445 if appCheck != main.TRUE:
446 main.log.warn( CLIs[0].apps() )
447 main.log.warn( CLIs[0].appIDs() )
Jon Hall390696c2015-05-05 17:13:41 -0700448 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
449 onpass="App Ids seem to be correct",
450 onfail="Something is wrong with app Ids" )
Jon Hall94fd0472014-12-08 11:52:42 -0800451
Jon Hallfeff3082015-05-19 10:23:26 -0700452 main.step( "Discovering Hosts( Via pingall for now )" )
453 # FIXME: Once we have a host discovery mechanism, use that instead
Jon Hall6aec96b2015-01-19 14:49:31 -0800454 # REACTIVE FWD test
Jon Hall8f89dda2015-01-22 16:03:33 -0800455 pingResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700456 for i in range(2): # Retry if pingall fails first time
457 time1 = time.time()
458 pingResult = main.Mininet1.pingall()
Jon Hall0f523f22015-07-06 09:31:09 -0700459 if i == 0:
460 utilities.assert_equals(
461 expect=main.TRUE,
462 actual=pingResult,
463 onpass="Reactive Pingall test passed",
464 onfail="Reactive Pingall failed, " +
465 "one or more ping pairs failed" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700466 time2 = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700467 main.log.info( "Time for pingall: %2f seconds" %
468 ( time2 - time1 ) )
469 # timeout for fwd flows
470 time.sleep( 11 )
Jon Hall6aec96b2015-01-19 14:49:31 -0800471 # uninstall onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700472 main.step( "Uninstall reactive forwarding app" )
473 uninstallResult = CLIs[0].deactivateApp( "org.onosproject.fwd" )
474 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
475 onpass="Uninstall fwd successful",
476 onfail="Uninstall fwd failed" )
Jon Hallfeff3082015-05-19 10:23:26 -0700477
478 main.step( "Check app ids" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700479 threads = []
Jon Hallfeff3082015-05-19 10:23:26 -0700480 appCheck2 = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700481 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700482 t = main.Thread( target=CLIs[i].appToIDCheck,
483 name="appToIDCheck-" + str( i ),
484 args=[] )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700485 threads.append( t )
486 t.start()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800487
Jon Hall5cfd23c2015-03-19 11:40:57 -0700488 for t in threads:
489 t.join()
Jon Hallfeff3082015-05-19 10:23:26 -0700490 appCheck2 = appCheck2 and t.result
491 if appCheck2 != main.TRUE:
Jon Halla9d26da2015-03-30 16:45:32 -0700492 main.log.warn( CLIs[0].apps() )
493 main.log.warn( CLIs[0].appIDs() )
Jon Hallfeff3082015-05-19 10:23:26 -0700494 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
Jon Hall390696c2015-05-05 17:13:41 -0700495 onpass="App Ids seem to be correct",
496 onfail="Something is wrong with app Ids" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700497
Jon Hallfeff3082015-05-19 10:23:26 -0700498 main.step( "Add host intents via cli" )
Jon Hall58c76b72015-02-23 11:09:24 -0800499 intentIds = []
Jon Hall6aec96b2015-01-19 14:49:31 -0800500 # TODO: move the host numbers to params
Jon Hall58c76b72015-02-23 11:09:24 -0800501 # Maybe look at all the paths we ping?
Jon Hall8f89dda2015-01-22 16:03:33 -0800502 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800503 hostResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800504 for i in range( 8, 18 ):
505 main.log.info( "Adding host intent between h" + str( i ) +
506 " and h" + str( i + 10 ) )
507 host1 = "00:00:00:00:00:" + \
508 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
509 host2 = "00:00:00:00:00:" + \
510 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800511 # NOTE: getHost can return None
512 host1Dict = main.ONOScli1.getHost( host1 )
513 host2Dict = main.ONOScli1.getHost( host2 )
514 host1Id = None
515 host2Id = None
516 if host1Dict and host2Dict:
517 host1Id = host1Dict.get( 'id', None )
518 host2Id = host2Dict.get( 'id', None )
Jon Hall8f89dda2015-01-22 16:03:33 -0800519 if host1Id and host2Id:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700520 nodeNum = ( i % 7 )
521 tmpId = CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
Jon Hall63604932015-02-26 17:09:50 -0800522 if tmpId:
523 main.log.info( "Added intent with id: " + tmpId )
524 intentIds.append( tmpId )
525 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700526 main.log.error( "addHostIntent returned: " +
527 repr( tmpId ) )
Jon Hall669173b2014-12-17 11:36:30 -0800528 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700529 main.log.error( "Error, getHost() failed for h" + str( i ) +
530 " and/or h" + str( i + 10 ) )
531 hosts = CLIs[ 0 ].hosts()
532 main.log.warn( "Hosts output: " )
533 try:
534 main.log.warn( json.dumps( json.loads( hosts ),
535 sort_keys=True,
536 indent=4,
537 separators=( ',', ': ' ) ) )
538 except ( ValueError, TypeError ):
539 main.log.warn( repr( hosts ) )
Jon Hall58c76b72015-02-23 11:09:24 -0800540 hostResult = main.FALSE
Jon Hallfeff3082015-05-19 10:23:26 -0700541 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
542 onpass="Found a host id for each host",
543 onfail="Error looking up host ids" )
544
Jon Halla9d26da2015-03-30 16:45:32 -0700545 intentStart = time.time()
Jon Hall58c76b72015-02-23 11:09:24 -0800546 onosIds = main.ONOScli1.getAllIntentsId()
547 main.log.info( "Submitted intents: " + str( intentIds ) )
548 main.log.info( "Intents in ONOS: " + str( onosIds ) )
549 for intent in intentIds:
550 if intent in onosIds:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700551 pass # intent submitted is in onos
Jon Hall58c76b72015-02-23 11:09:24 -0800552 else:
553 intentAddResult = False
Jon Halla9d26da2015-03-30 16:45:32 -0700554 if intentAddResult:
555 intentStop = time.time()
556 else:
557 intentStop = None
Jon Hall1b8f54a2015-02-04 13:24:20 -0800558 # Print the intent states
Jon Hall58c76b72015-02-23 11:09:24 -0800559 intents = main.ONOScli1.intents()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800560 intentStates = []
Jon Hall5cfd23c2015-03-19 11:40:57 -0700561 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800562 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
563 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700564 try:
565 for intent in json.loads( intents ):
566 state = intent.get( 'state', None )
567 if "INSTALLED" not in state:
568 installedCheck = False
569 intentId = intent.get( 'id', None )
570 intentStates.append( ( intentId, state ) )
571 except ( ValueError, TypeError ):
572 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800573 # add submitted intents not in the store
574 tmplist = [ i for i, s in intentStates ]
575 missingIntents = False
576 for i in intentIds:
577 if i not in tmplist:
578 intentStates.append( ( i, " - " ) )
579 missingIntents = True
580 intentStates.sort()
581 for i, s in intentStates:
582 count += 1
583 main.log.info( "%-6s%-15s%-15s" %
584 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700585 leaders = main.ONOScli1.leaders()
586 try:
Jon Hallc9eabec2015-06-10 14:33:14 -0700587 missing = False
Jon Hall5cfd23c2015-03-19 11:40:57 -0700588 if leaders:
589 parsedLeaders = json.loads( leaders )
590 main.log.warn( json.dumps( parsedLeaders,
591 sort_keys=True,
592 indent=4,
593 separators=( ',', ': ' ) ) )
594 # check for all intent partitions
Jon Hall5cfd23c2015-03-19 11:40:57 -0700595 topics = []
596 for i in range( 14 ):
597 topics.append( "intent-partition-" + str( i ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700598 main.log.debug( topics )
599 ONOStopics = [ j['topic'] for j in parsedLeaders ]
600 for topic in topics:
601 if topic not in ONOStopics:
602 main.log.error( "Error: " + topic +
603 " not in leaders" )
Jon Hallc9eabec2015-06-10 14:33:14 -0700604 missing = True
Jon Hall5cfd23c2015-03-19 11:40:57 -0700605 else:
606 main.log.error( "leaders() returned None" )
607 except ( ValueError, TypeError ):
608 main.log.exception( "Error parsing leaders" )
609 main.log.error( repr( leaders ) )
Jon Hallc9eabec2015-06-10 14:33:14 -0700610 # Check all nodes
611 if missing:
612 for node in CLIs:
613 response = node.leaders( jsonFormat=False)
614 main.log.warn( str( node.name ) + " leaders output: \n" +
615 str( response ) )
616
Jon Hall5cfd23c2015-03-19 11:40:57 -0700617 partitions = main.ONOScli1.partitions()
618 try:
619 if partitions :
620 parsedPartitions = json.loads( partitions )
621 main.log.warn( json.dumps( parsedPartitions,
622 sort_keys=True,
623 indent=4,
624 separators=( ',', ': ' ) ) )
625 # TODO check for a leader in all paritions
626 # TODO check for consistency among nodes
627 else:
628 main.log.error( "partitions() returned None" )
629 except ( ValueError, TypeError ):
630 main.log.exception( "Error parsing partitions" )
631 main.log.error( repr( partitions ) )
Jon Hall63604932015-02-26 17:09:50 -0800632 pendingMap = main.ONOScli1.pendingMap()
Jon Hall5cfd23c2015-03-19 11:40:57 -0700633 try:
634 if pendingMap :
635 parsedPending = json.loads( pendingMap )
636 main.log.warn( json.dumps( parsedPending,
637 sort_keys=True,
638 indent=4,
639 separators=( ',', ': ' ) ) )
640 # TODO check something here?
641 else:
642 main.log.error( "pendingMap() returned None" )
643 except ( ValueError, TypeError ):
644 main.log.exception( "Error parsing pending map" )
645 main.log.error( repr( pendingMap ) )
646
Jon Hallfeff3082015-05-19 10:23:26 -0700647 intentAddResult = bool( intentAddResult and not missingIntents and
648 installedCheck )
649 if not intentAddResult:
650 main.log.error( "Error in pushing host intents to ONOS" )
651
Jon Hall390696c2015-05-05 17:13:41 -0700652 main.step( "Intent Anti-Entropy dispersion" )
Jon Halla9d26da2015-03-30 16:45:32 -0700653 for i in range(100):
Jon Hall390696c2015-05-05 17:13:41 -0700654 correct = True
Jon Halla9d26da2015-03-30 16:45:32 -0700655 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Hall390696c2015-05-05 17:13:41 -0700656 for cli in CLIs:
657 onosIds = []
658 ids = cli.getAllIntentsId()
659 onosIds.append( ids )
660 main.log.debug( "Intents in " + cli.name + ": " +
661 str( sorted( onosIds ) ) )
662 if sorted( ids ) != sorted( intentIds ):
Jon Hallc9eabec2015-06-10 14:33:14 -0700663 main.log.debug( "Set of intent IDs doesn't match" )
Jon Hall390696c2015-05-05 17:13:41 -0700664 correct = False
Jon Hall40d2cbd2015-06-03 16:24:29 -0700665 break
666 else:
667 intents = json.loads( cli.intents() )
668 for intent in intents:
669 if intent[ 'state' ] != "INSTALLED":
Jon Hallc9eabec2015-06-10 14:33:14 -0700670 main.log.warn( "Intent " + intent[ 'id' ] +
671 " is " + intent[ 'state' ] )
Jon Hall40d2cbd2015-06-03 16:24:29 -0700672 correct = False
673 break
Jon Hall390696c2015-05-05 17:13:41 -0700674 if correct:
Jon Halla9d26da2015-03-30 16:45:32 -0700675 break
676 else:
677 time.sleep(1)
Jon Halla9d26da2015-03-30 16:45:32 -0700678 if not intentStop:
679 intentStop = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700680 global gossipTime
Jon Halla9d26da2015-03-30 16:45:32 -0700681 gossipTime = intentStop - intentStart
682 main.log.info( "It took about " + str( gossipTime ) +
Jon Hall390696c2015-05-05 17:13:41 -0700683 " seconds for all intents to appear in each node" )
Jon Halla9d26da2015-03-30 16:45:32 -0700684 # FIXME: make this time configurable/calculate based off of number of
685 # nodes and gossip rounds
686 utilities.assert_greater_equals(
Jon Hall390696c2015-05-05 17:13:41 -0700687 expect=40, actual=gossipTime,
Jon Halla9d26da2015-03-30 16:45:32 -0700688 onpass="ECM anti-entropy for intents worked within " +
689 "expected time",
690 onfail="Intent ECM anti-entropy took too long" )
Jon Hall390696c2015-05-05 17:13:41 -0700691 if gossipTime <= 40:
Jon Hall678f4512015-03-31 09:48:31 -0700692 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800693
Jon Hall63604932015-02-26 17:09:50 -0800694 if not intentAddResult or "key" in pendingMap:
Jon Hall58c76b72015-02-23 11:09:24 -0800695 import time
Jon Hall63604932015-02-26 17:09:50 -0800696 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800697 main.log.info( "Sleeping 60 seconds to see if intents are found" )
698 time.sleep( 60 )
699 onosIds = main.ONOScli1.getAllIntentsId()
700 main.log.info( "Submitted intents: " + str( intentIds ) )
701 main.log.info( "Intents in ONOS: " + str( onosIds ) )
702 # Print the intent states
703 intents = main.ONOScli1.intents()
704 intentStates = []
705 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
706 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700707 try:
708 for intent in json.loads( intents ):
709 # Iter through intents of a node
710 state = intent.get( 'state', None )
711 if "INSTALLED" not in state:
712 installedCheck = False
713 intentId = intent.get( 'id', None )
714 intentStates.append( ( intentId, state ) )
715 except ( ValueError, TypeError ):
716 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800717 # add submitted intents not in the store
718 tmplist = [ i for i, s in intentStates ]
719 for i in intentIds:
720 if i not in tmplist:
721 intentStates.append( ( i, " - " ) )
722 intentStates.sort()
723 for i, s in intentStates:
724 count += 1
725 main.log.info( "%-6s%-15s%-15s" %
726 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700727 leaders = main.ONOScli1.leaders()
728 try:
Jon Hallc9eabec2015-06-10 14:33:14 -0700729 missing = False
Jon Hall5cfd23c2015-03-19 11:40:57 -0700730 if leaders:
731 parsedLeaders = json.loads( leaders )
732 main.log.warn( json.dumps( parsedLeaders,
733 sort_keys=True,
734 indent=4,
735 separators=( ',', ': ' ) ) )
736 # check for all intent partitions
737 # check for election
738 topics = []
739 for i in range( 14 ):
740 topics.append( "intent-partition-" + str( i ) )
741 # FIXME: this should only be after we start the app
742 topics.append( "org.onosproject.election" )
743 main.log.debug( topics )
744 ONOStopics = [ j['topic'] for j in parsedLeaders ]
745 for topic in topics:
746 if topic not in ONOStopics:
747 main.log.error( "Error: " + topic +
748 " not in leaders" )
Jon Hallc9eabec2015-06-10 14:33:14 -0700749 missing = True
Jon Hall5cfd23c2015-03-19 11:40:57 -0700750 else:
751 main.log.error( "leaders() returned None" )
752 except ( ValueError, TypeError ):
753 main.log.exception( "Error parsing leaders" )
754 main.log.error( repr( leaders ) )
Jon Hallc9eabec2015-06-10 14:33:14 -0700755 # Check all nodes
756 if missing:
757 for node in CLIs:
758 response = node.leaders( jsonFormat=False)
759 main.log.warn( str( node.name ) + " leaders output: \n" +
760 str( response ) )
761
Jon Hall5cfd23c2015-03-19 11:40:57 -0700762 partitions = main.ONOScli1.partitions()
763 try:
764 if partitions :
765 parsedPartitions = json.loads( partitions )
766 main.log.warn( json.dumps( parsedPartitions,
767 sort_keys=True,
768 indent=4,
769 separators=( ',', ': ' ) ) )
770 # TODO check for a leader in all paritions
771 # TODO check for consistency among nodes
772 else:
773 main.log.error( "partitions() returned None" )
774 except ( ValueError, TypeError ):
775 main.log.exception( "Error parsing partitions" )
776 main.log.error( repr( partitions ) )
777 pendingMap = main.ONOScli1.pendingMap()
778 try:
779 if pendingMap :
780 parsedPending = json.loads( pendingMap )
781 main.log.warn( json.dumps( parsedPending,
782 sort_keys=True,
783 indent=4,
784 separators=( ',', ': ' ) ) )
785 # TODO check something here?
786 else:
787 main.log.error( "pendingMap() returned None" )
788 except ( ValueError, TypeError ):
789 main.log.exception( "Error parsing pending map" )
790 main.log.error( repr( pendingMap ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800791
Jon Hall6aec96b2015-01-19 14:49:31 -0800792 def CASE4( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800793 """
794 Ping across added host intents
795 """
Jon Hallfebb1c72015-03-05 13:30:09 -0800796 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700797 import time
798 assert numControllers, "numControllers not defined"
799 assert main, "main not defined"
800 assert utilities.assert_equals, "utilities.assert_equals not defined"
801 assert CLIs, "CLIs not defined"
802 assert nodes, "nodes not defined"
Jon Hallfeff3082015-05-19 10:23:26 -0700803 main.case( "Verify connectivity by sendind traffic across Intents" )
804 main.caseExplaination = "Ping across added host intents to check " +\
805 "functionality and check the state of " +\
806 "the intent"
807 main.step( "Ping across added host intents" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800808 PingResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800809 for i in range( 8, 18 ):
Jon Hall21270ac2015-02-16 17:59:55 -0800810 ping = main.Mininet1.pingHost( src="h" + str( i ),
811 target="h" + str( i + 10 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800812 PingResult = PingResult and ping
Jon Hall6aec96b2015-01-19 14:49:31 -0800813 if ping == main.FALSE:
814 main.log.warn( "Ping failed between h" + str( i ) +
815 " and h" + str( i + 10 ) )
816 elif ping == main.TRUE:
817 main.log.info( "Ping test passed!" )
Jon Hall21270ac2015-02-16 17:59:55 -0800818 # Don't set PingResult or you'd override failures
Jon Hall8f89dda2015-01-22 16:03:33 -0800819 if PingResult == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -0700820 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -0800821 "Intents have not been installed correctly, pings failed." )
Jon Hall58c76b72015-02-23 11:09:24 -0800822 # TODO: pretty print
Jon Hall5cfd23c2015-03-19 11:40:57 -0700823 main.log.warn( "ONOS1 intents: " )
824 try:
825 tmpIntents = main.ONOScli1.intents()
826 main.log.warn( json.dumps( json.loads( tmpIntents ),
827 sort_keys=True,
828 indent=4,
829 separators=( ',', ': ' ) ) )
830 except ( ValueError, TypeError ):
831 main.log.warn( repr( tmpIntents ) )
Jon Hall6aec96b2015-01-19 14:49:31 -0800832 utilities.assert_equals(
833 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800834 actual=PingResult,
Jon Hall6aec96b2015-01-19 14:49:31 -0800835 onpass="Intents have been installed correctly and pings work",
836 onfail="Intents have not been installed correctly, pings failed." )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800837
Jon Hallfeff3082015-05-19 10:23:26 -0700838 main.step( "Check Intent state" )
Jon Hall40d2cbd2015-06-03 16:24:29 -0700839 installedCheck = False
Jon Hallc9eabec2015-06-10 14:33:14 -0700840 loopCount = 0
841 while not installedCheck and loopCount < 40:
Jon Hall40d2cbd2015-06-03 16:24:29 -0700842 installedCheck = True
843 # Print the intent states
844 intents = main.ONOScli1.intents()
845 intentStates = []
846 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
847 count = 0
848 # Iter through intents of a node
849 try:
850 for intent in json.loads( intents ):
851 state = intent.get( 'state', None )
852 if "INSTALLED" not in state:
853 installedCheck = False
854 intentId = intent.get( 'id', None )
855 intentStates.append( ( intentId, state ) )
856 except ( ValueError, TypeError ):
857 main.log.exception( "Error parsing intents." )
858 # Print states
859 intentStates.sort()
860 for i, s in intentStates:
861 count += 1
862 main.log.info( "%-6s%-15s%-15s" %
863 ( str( count ), str( i ), str( s ) ) )
864 if not installedCheck:
865 time.sleep( 1 )
Jon Hallc9eabec2015-06-10 14:33:14 -0700866 loopCount += 1
Jon Hallfeff3082015-05-19 10:23:26 -0700867 utilities.assert_equals( expect=True, actual=installedCheck,
868 onpass="Intents are all INSTALLED",
Jon Hall40d2cbd2015-06-03 16:24:29 -0700869 onfail="Intents are not all in " +
Jon Hallfeff3082015-05-19 10:23:26 -0700870 "INSTALLED state" )
871
872 main.step( "Check leadership of topics" )
873 leaders = main.ONOScli1.leaders()
874 topicCheck = main.TRUE
875 try:
876 if leaders:
877 parsedLeaders = json.loads( leaders )
878 main.log.warn( json.dumps( parsedLeaders,
879 sort_keys=True,
880 indent=4,
881 separators=( ',', ': ' ) ) )
882 # check for all intent partitions
883 # check for election
884 # TODO: Look at Devices as topics now that it uses this system
885 topics = []
886 for i in range( 14 ):
887 topics.append( "intent-partition-" + str( i ) )
888 # FIXME: this should only be after we start the app
889 # FIXME: topics.append( "org.onosproject.election" )
890 # Print leaders output
891 main.log.debug( topics )
892 ONOStopics = [ j['topic'] for j in parsedLeaders ]
893 for topic in topics:
894 if topic not in ONOStopics:
895 main.log.error( "Error: " + topic +
896 " not in leaders" )
897 topicCheck = main.FALSE
898 else:
899 main.log.error( "leaders() returned None" )
900 topicCheck = main.FALSE
901 except ( ValueError, TypeError ):
902 topicCheck = main.FALSE
903 main.log.exception( "Error parsing leaders" )
904 main.log.error( repr( leaders ) )
905 # TODO: Check for a leader of these topics
Jon Hallc9eabec2015-06-10 14:33:14 -0700906 # Check all nodes
907 if topicCheck:
908 for node in CLIs:
909 response = node.leaders( jsonFormat=False)
910 main.log.warn( str( node.name ) + " leaders output: \n" +
911 str( response ) )
912
Jon Hallfeff3082015-05-19 10:23:26 -0700913 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
914 onpass="intent Partitions is in leaders",
915 onfail="Some topics were lost " )
916 # Print partitions
917 partitions = main.ONOScli1.partitions()
918 try:
919 if partitions :
920 parsedPartitions = json.loads( partitions )
921 main.log.warn( json.dumps( parsedPartitions,
922 sort_keys=True,
923 indent=4,
924 separators=( ',', ': ' ) ) )
925 # TODO check for a leader in all paritions
926 # TODO check for consistency among nodes
927 else:
928 main.log.error( "partitions() returned None" )
929 except ( ValueError, TypeError ):
930 main.log.exception( "Error parsing partitions" )
931 main.log.error( repr( partitions ) )
932 # Print Pending Map
933 pendingMap = main.ONOScli1.pendingMap()
934 try:
935 if pendingMap :
936 parsedPending = json.loads( pendingMap )
937 main.log.warn( json.dumps( parsedPending,
938 sort_keys=True,
939 indent=4,
940 separators=( ',', ': ' ) ) )
941 # TODO check something here?
942 else:
943 main.log.error( "pendingMap() returned None" )
944 except ( ValueError, TypeError ):
945 main.log.exception( "Error parsing pending map" )
946 main.log.error( repr( pendingMap ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700947
Jon Hall63604932015-02-26 17:09:50 -0800948 if not installedCheck:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700949 main.log.info( "Waiting 60 seconds to see if the state of " +
950 "intents change" )
Jon Hall63604932015-02-26 17:09:50 -0800951 time.sleep( 60 )
952 # Print the intent states
953 intents = main.ONOScli1.intents()
954 intentStates = []
955 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
956 count = 0
957 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700958 try:
959 for intent in json.loads( intents ):
960 state = intent.get( 'state', None )
961 if "INSTALLED" not in state:
962 installedCheck = False
963 intentId = intent.get( 'id', None )
964 intentStates.append( ( intentId, state ) )
965 except ( ValueError, TypeError ):
966 main.log.exception( "Error parsing intents." )
Jon Hall63604932015-02-26 17:09:50 -0800967 intentStates.sort()
968 for i, s in intentStates:
969 count += 1
970 main.log.info( "%-6s%-15s%-15s" %
971 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700972 leaders = main.ONOScli1.leaders()
973 try:
Jon Hallc9eabec2015-06-10 14:33:14 -0700974 missing = False
Jon Hall5cfd23c2015-03-19 11:40:57 -0700975 if leaders:
976 parsedLeaders = json.loads( leaders )
977 main.log.warn( json.dumps( parsedLeaders,
978 sort_keys=True,
979 indent=4,
980 separators=( ',', ': ' ) ) )
981 # check for all intent partitions
982 # check for election
983 topics = []
984 for i in range( 14 ):
985 topics.append( "intent-partition-" + str( i ) )
986 # FIXME: this should only be after we start the app
987 topics.append( "org.onosproject.election" )
988 main.log.debug( topics )
989 ONOStopics = [ j['topic'] for j in parsedLeaders ]
990 for topic in topics:
991 if topic not in ONOStopics:
992 main.log.error( "Error: " + topic +
993 " not in leaders" )
Jon Hallc9eabec2015-06-10 14:33:14 -0700994 missing = True
Jon Hall5cfd23c2015-03-19 11:40:57 -0700995 else:
996 main.log.error( "leaders() returned None" )
997 except ( ValueError, TypeError ):
998 main.log.exception( "Error parsing leaders" )
999 main.log.error( repr( leaders ) )
Jon Hallc9eabec2015-06-10 14:33:14 -07001000 if missing:
1001 for node in CLIs:
1002 response = node.leaders( jsonFormat=False)
1003 main.log.warn( str( node.name ) + " leaders output: \n" +
1004 str( response ) )
1005
Jon Hall5cfd23c2015-03-19 11:40:57 -07001006 partitions = main.ONOScli1.partitions()
1007 try:
1008 if partitions :
1009 parsedPartitions = json.loads( partitions )
1010 main.log.warn( json.dumps( parsedPartitions,
1011 sort_keys=True,
1012 indent=4,
1013 separators=( ',', ': ' ) ) )
1014 # TODO check for a leader in all paritions
1015 # TODO check for consistency among nodes
1016 else:
1017 main.log.error( "partitions() returned None" )
1018 except ( ValueError, TypeError ):
1019 main.log.exception( "Error parsing partitions" )
1020 main.log.error( repr( partitions ) )
1021 pendingMap = main.ONOScli1.pendingMap()
1022 try:
1023 if pendingMap :
1024 parsedPending = json.loads( pendingMap )
1025 main.log.warn( json.dumps( parsedPending,
1026 sort_keys=True,
1027 indent=4,
1028 separators=( ',', ': ' ) ) )
1029 # TODO check something here?
1030 else:
1031 main.log.error( "pendingMap() returned None" )
1032 except ( ValueError, TypeError ):
1033 main.log.exception( "Error parsing pending map" )
1034 main.log.error( repr( pendingMap ) )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001035 # Print flowrules
1036 main.log.debug( CLIs[0].flows( jsonFormat=False ) )
Jon Hallfeff3082015-05-19 10:23:26 -07001037 main.step( "Wait a minute then ping again" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001038 # the wait is above
Jon Hallfeff3082015-05-19 10:23:26 -07001039 PingResult = main.TRUE
1040 for i in range( 8, 18 ):
1041 ping = main.Mininet1.pingHost( src="h" + str( i ),
1042 target="h" + str( i + 10 ) )
1043 PingResult = PingResult and ping
1044 if ping == main.FALSE:
1045 main.log.warn( "Ping failed between h" + str( i ) +
1046 " and h" + str( i + 10 ) )
1047 elif ping == main.TRUE:
1048 main.log.info( "Ping test passed!" )
1049 # Don't set PingResult or you'd override failures
1050 if PingResult == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001051 main.log.error(
Jon Hallfeff3082015-05-19 10:23:26 -07001052 "Intents have not been installed correctly, pings failed." )
1053 # TODO: pretty print
1054 main.log.warn( "ONOS1 intents: " )
1055 try:
1056 tmpIntents = main.ONOScli1.intents()
1057 main.log.warn( json.dumps( json.loads( tmpIntents ),
1058 sort_keys=True,
1059 indent=4,
1060 separators=( ',', ': ' ) ) )
1061 except ( ValueError, TypeError ):
1062 main.log.warn( repr( tmpIntents ) )
1063 utilities.assert_equals(
1064 expect=main.TRUE,
1065 actual=PingResult,
1066 onpass="Intents have been installed correctly and pings work",
1067 onfail="Intents have not been installed correctly, pings failed." )
1068
Jon Hall6aec96b2015-01-19 14:49:31 -08001069 def CASE5( self, main ):
1070 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001071 Reading state of ONOS
Jon Hall6aec96b2015-01-19 14:49:31 -08001072 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001073 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001074 import time
1075 assert numControllers, "numControllers not defined"
1076 assert main, "main not defined"
1077 assert utilities.assert_equals, "utilities.assert_equals not defined"
1078 assert CLIs, "CLIs not defined"
1079 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001080 # assumes that sts is already in you PYTHONPATH
1081 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -08001082
Jon Hall6aec96b2015-01-19 14:49:31 -08001083 main.case( "Setting up and gathering data for current state" )
1084 # The general idea for this test case is to pull the state of
1085 # ( intents,flows, topology,... ) from each ONOS node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001086 # We can then compare them with each other and also with past states
Jon Hall73cf9cc2014-11-20 22:28:38 -08001087
Jon Hall5cfd23c2015-03-19 11:40:57 -07001088 main.step( "Check that each switch has a master" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001089 global mastershipState
Jon Hall5cfd23c2015-03-19 11:40:57 -07001090 mastershipState = '[]'
Jon Hall94fd0472014-12-08 11:52:42 -08001091
Jon Hall6aec96b2015-01-19 14:49:31 -08001092 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -07001093 rolesNotNull = main.TRUE
1094 threads = []
1095 for i in range( numControllers ):
1096 t = main.Thread( target=CLIs[i].rolesNotNull,
1097 name="rolesNotNull-" + str( i ),
1098 args=[] )
1099 threads.append( t )
1100 t.start()
1101
1102 for t in threads:
1103 t.join()
1104 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001105 utilities.assert_equals(
1106 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001107 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001108 onpass="Each device has a master",
1109 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001110
Jon Hall5cfd23c2015-03-19 11:40:57 -07001111 main.step( "Get the Mastership of each switch from each controller" )
1112 ONOSMastership = []
1113 mastershipCheck = main.FALSE
1114 consistentMastership = True
1115 rolesResults = True
1116 threads = []
1117 for i in range( numControllers ):
1118 t = main.Thread( target=CLIs[i].roles,
1119 name="roles-" + str( i ),
1120 args=[] )
1121 threads.append( t )
1122 t.start()
1123
1124 for t in threads:
1125 t.join()
1126 ONOSMastership.append( t.result )
1127
1128 for i in range( numControllers ):
1129 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001130 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001131 " roles" )
1132 main.log.warn(
1133 "ONOS" + str( i + 1 ) + " mastership response: " +
1134 repr( ONOSMastership[i] ) )
1135 rolesResults = False
1136 utilities.assert_equals(
1137 expect=True,
1138 actual=rolesResults,
1139 onpass="No error in reading roles output",
1140 onfail="Error in reading roles from ONOS" )
1141
1142 main.step( "Check for consistency in roles from each controller" )
1143 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001144 main.log.info(
Jon Hall6aec96b2015-01-19 14:49:31 -08001145 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001146 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001147 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001148 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001149 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001150 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001151 onpass="Switch roles are consistent across all ONOS nodes",
1152 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001153
Jon Hall5cfd23c2015-03-19 11:40:57 -07001154 if rolesResults and not consistentMastership:
1155 for i in range( numControllers ):
1156 try:
1157 main.log.warn(
1158 "ONOS" + str( i + 1 ) + " roles: ",
1159 json.dumps(
1160 json.loads( ONOSMastership[ i ] ),
1161 sort_keys=True,
1162 indent=4,
1163 separators=( ',', ': ' ) ) )
1164 except ( ValueError, TypeError ):
1165 main.log.warn( repr( ONOSMastership[ i ] ) )
1166 elif rolesResults and consistentMastership:
1167 mastershipCheck = main.TRUE
1168 mastershipState = ONOSMastership[ 0 ]
1169
Jon Hall6aec96b2015-01-19 14:49:31 -08001170 main.step( "Get the intents from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001171 global intentState
1172 intentState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001173 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001174 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001175 consistentIntents = True
1176 intentsResults = True
1177 threads = []
1178 for i in range( numControllers ):
1179 t = main.Thread( target=CLIs[i].intents,
1180 name="intents-" + str( i ),
1181 args=[],
1182 kwargs={ 'jsonFormat': True } )
1183 threads.append( t )
1184 t.start()
1185
1186 for t in threads:
1187 t.join()
1188 ONOSIntents.append( t.result )
1189
1190 for i in range( numControllers ):
1191 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001192 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001193 " intents" )
1194 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1195 repr( ONOSIntents[ i ] ) )
1196 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001197 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001198 expect=True,
1199 actual=intentsResults,
1200 onpass="No error in reading intents output",
1201 onfail="Error in reading intents from ONOS" )
1202
1203 main.step( "Check for consistency in Intents from each controller" )
1204 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001205 main.log.info( "Intents are consistent across all ONOS " +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001206 "nodes" )
1207 else:
1208 consistentIntents = False
Jon Hall40d2cbd2015-06-03 16:24:29 -07001209 main.log.error( "Intents not consistent" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001210 utilities.assert_equals(
1211 expect=True,
1212 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001213 onpass="Intents are consistent across all ONOS nodes",
1214 onfail="ONOS nodes have different views of intents" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001215
Jon Hall390696c2015-05-05 17:13:41 -07001216 if intentsResults:
1217 # Try to make it easy to figure out what is happening
1218 #
1219 # Intent ONOS1 ONOS2 ...
1220 # 0x01 INSTALLED INSTALLING
1221 # ... ... ...
1222 # ... ... ...
1223 title = " Id"
1224 for n in range( numControllers ):
1225 title += " " * 10 + "ONOS" + str( n + 1 )
1226 main.log.warn( title )
1227 # get all intent keys in the cluster
1228 keys = []
1229 for nodeStr in ONOSIntents:
1230 node = json.loads( nodeStr )
1231 for intent in node:
1232 keys.append( intent.get( 'id' ) )
1233 keys = set( keys )
1234 for key in keys:
1235 row = "%-13s" % key
1236 for nodeStr in ONOSIntents:
1237 node = json.loads( nodeStr )
1238 for intent in node:
1239 if intent.get( 'id', "Error" ) == key:
1240 row += "%-15s" % intent.get( 'state' )
1241 main.log.warn( row )
1242 # End table view
1243
Jon Hall5cfd23c2015-03-19 11:40:57 -07001244 if intentsResults and not consistentIntents:
Jon Hall390696c2015-05-05 17:13:41 -07001245 # print the json objects
Jon Hall5cfd23c2015-03-19 11:40:57 -07001246 n = len(ONOSIntents)
Jon Hall390696c2015-05-05 17:13:41 -07001247 main.log.debug( "ONOS" + str( n ) + " intents: " )
1248 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1249 sort_keys=True,
1250 indent=4,
1251 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001252 for i in range( numControllers ):
1253 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
Jon Hall390696c2015-05-05 17:13:41 -07001254 main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
1255 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1256 sort_keys=True,
1257 indent=4,
1258 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001259 else:
Jon Hall390696c2015-05-05 17:13:41 -07001260 main.log.debug( nodes[ i ].name + " intents match ONOS" +
1261 str( n ) + " intents" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001262 elif intentsResults and consistentIntents:
1263 intentCheck = main.TRUE
1264 intentState = ONOSIntents[ 0 ]
1265
Jon Hall6aec96b2015-01-19 14:49:31 -08001266 main.step( "Get the flows from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001267 global flowState
1268 flowState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001269 ONOSFlows = []
1270 ONOSFlowsJson = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001271 flowCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001272 consistentFlows = True
1273 flowsResults = True
1274 threads = []
1275 for i in range( numControllers ):
1276 t = main.Thread( target=CLIs[i].flows,
1277 name="flows-" + str( i ),
1278 args=[],
1279 kwargs={ 'jsonFormat': True } )
1280 threads.append( t )
1281 t.start()
1282
Jon Halla9d26da2015-03-30 16:45:32 -07001283 # NOTE: Flows command can take some time to run
Jon Hall5cfd23c2015-03-19 11:40:57 -07001284 time.sleep(30)
1285 for t in threads:
1286 t.join()
1287 result = t.result
1288 ONOSFlows.append( result )
1289
1290 for i in range( numControllers ):
1291 num = str( i + 1 )
1292 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001293 main.log.error( "Error in getting ONOS" + num + " flows" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001294 main.log.warn( "ONOS" + num + " flows response: " +
1295 repr( ONOSFlows[ i ] ) )
1296 flowsResults = False
1297 ONOSFlowsJson.append( None )
Jon Hall58c76b72015-02-23 11:09:24 -08001298 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001299 try:
1300 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1301 except ( ValueError, TypeError ):
1302 # FIXME: change this to log.error?
1303 main.log.exception( "Error in parsing ONOS" + num +
1304 " response as json." )
1305 main.log.error( repr( ONOSFlows[ i ] ) )
1306 ONOSFlowsJson.append( None )
1307 flowsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001308 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001309 expect=True,
1310 actual=flowsResults,
1311 onpass="No error in reading flows output",
1312 onfail="Error in reading flows from ONOS" )
1313
1314 main.step( "Check for consistency in Flows from each controller" )
1315 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1316 if all( tmp ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001317 main.log.info( "Flow count is consistent across all ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001318 else:
1319 consistentFlows = False
1320 utilities.assert_equals(
1321 expect=True,
1322 actual=consistentFlows,
Jon Hall6aec96b2015-01-19 14:49:31 -08001323 onpass="The flow count is consistent across all ONOS nodes",
1324 onfail="ONOS nodes have different flow counts" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001325
Jon Hall5cfd23c2015-03-19 11:40:57 -07001326 if flowsResults and not consistentFlows:
1327 for i in range( numControllers ):
1328 try:
1329 main.log.warn(
1330 "ONOS" + str( i + 1 ) + " flows: " +
1331 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1332 indent=4, separators=( ',', ': ' ) ) )
1333 except ( ValueError, TypeError ):
1334 main.log.warn(
1335 "ONOS" + str( i + 1 ) + " flows: " +
1336 repr( ONOSFlows[ i ] ) )
1337 elif flowsResults and consistentFlows:
1338 flowCheck = main.TRUE
1339 flowState = ONOSFlows[ 0 ]
1340
Jon Hall6aec96b2015-01-19 14:49:31 -08001341 main.step( "Get the OF Table entries" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001342 global flows
Jon Hall6aec96b2015-01-19 14:49:31 -08001343 flows = []
1344 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001345 flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001346 if flowCheck == main.FALSE:
1347 for table in flows:
1348 main.log.warn( table )
Jon Hall6aec96b2015-01-19 14:49:31 -08001349 # TODO: Compare switch flow tables with ONOS flow tables
Jon Hall73cf9cc2014-11-20 22:28:38 -08001350
Jon Hall6aec96b2015-01-19 14:49:31 -08001351 main.step( "Start continuous pings" )
1352 main.Mininet2.pingLong(
1353 src=main.params[ 'PING' ][ 'source1' ],
1354 target=main.params[ 'PING' ][ 'target1' ],
1355 pingTime=500 )
1356 main.Mininet2.pingLong(
1357 src=main.params[ 'PING' ][ 'source2' ],
1358 target=main.params[ 'PING' ][ 'target2' ],
1359 pingTime=500 )
1360 main.Mininet2.pingLong(
1361 src=main.params[ 'PING' ][ 'source3' ],
1362 target=main.params[ 'PING' ][ 'target3' ],
1363 pingTime=500 )
1364 main.Mininet2.pingLong(
1365 src=main.params[ 'PING' ][ 'source4' ],
1366 target=main.params[ 'PING' ][ 'target4' ],
1367 pingTime=500 )
1368 main.Mininet2.pingLong(
1369 src=main.params[ 'PING' ][ 'source5' ],
1370 target=main.params[ 'PING' ][ 'target5' ],
1371 pingTime=500 )
1372 main.Mininet2.pingLong(
1373 src=main.params[ 'PING' ][ 'source6' ],
1374 target=main.params[ 'PING' ][ 'target6' ],
1375 pingTime=500 )
1376 main.Mininet2.pingLong(
1377 src=main.params[ 'PING' ][ 'source7' ],
1378 target=main.params[ 'PING' ][ 'target7' ],
1379 pingTime=500 )
1380 main.Mininet2.pingLong(
1381 src=main.params[ 'PING' ][ 'source8' ],
1382 target=main.params[ 'PING' ][ 'target8' ],
1383 pingTime=500 )
1384 main.Mininet2.pingLong(
1385 src=main.params[ 'PING' ][ 'source9' ],
1386 target=main.params[ 'PING' ][ 'target9' ],
1387 pingTime=500 )
1388 main.Mininet2.pingLong(
1389 src=main.params[ 'PING' ][ 'source10' ],
1390 target=main.params[ 'PING' ][ 'target10' ],
1391 pingTime=500 )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001392
Jon Hall6aec96b2015-01-19 14:49:31 -08001393 main.step( "Create TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001394 ctrls = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001395 for node in nodes:
1396 temp = ( node, node.name, node.ip_address, 6633 )
1397 ctrls.append( temp )
1398 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001399
Jon Hall6aec96b2015-01-19 14:49:31 -08001400 main.step( "Collecting topology information from ONOS" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001401 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001402 threads = []
1403 for i in range( numControllers ):
1404 t = main.Thread( target=CLIs[i].devices,
1405 name="devices-" + str( i ),
1406 args=[ ] )
1407 threads.append( t )
1408 t.start()
1409
1410 for t in threads:
1411 t.join()
1412 devices.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001413 hosts = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001414 threads = []
1415 for i in range( numControllers ):
1416 t = main.Thread( target=CLIs[i].hosts,
1417 name="hosts-" + str( i ),
1418 args=[ ] )
1419 threads.append( t )
1420 t.start()
1421
1422 for t in threads:
1423 t.join()
1424 try:
1425 hosts.append( json.loads( t.result ) )
1426 except ( ValueError, TypeError ):
1427 # FIXME: better handling of this, print which node
1428 # Maybe use thread name?
1429 main.log.exception( "Error parsing json output of hosts" )
1430 # FIXME: should this be an empty json object instead?
1431 hosts.append( None )
1432
Jon Hall73cf9cc2014-11-20 22:28:38 -08001433 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001434 threads = []
1435 for i in range( numControllers ):
1436 t = main.Thread( target=CLIs[i].ports,
1437 name="ports-" + str( i ),
1438 args=[ ] )
1439 threads.append( t )
1440 t.start()
1441
1442 for t in threads:
1443 t.join()
1444 ports.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001445 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001446 threads = []
1447 for i in range( numControllers ):
1448 t = main.Thread( target=CLIs[i].links,
1449 name="links-" + str( i ),
1450 args=[ ] )
1451 threads.append( t )
1452 t.start()
1453
1454 for t in threads:
1455 t.join()
1456 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001457 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001458 threads = []
1459 for i in range( numControllers ):
1460 t = main.Thread( target=CLIs[i].clusters,
1461 name="clusters-" + str( i ),
1462 args=[ ] )
1463 threads.append( t )
1464 t.start()
1465
1466 for t in threads:
1467 t.join()
1468 clusters.append( t.result )
Jon Hall529a37f2015-01-28 10:02:00 -08001469 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001470
Jon Hall6aec96b2015-01-19 14:49:31 -08001471 # hosts
Jon Hall390696c2015-05-05 17:13:41 -07001472 main.step( "Host view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001473 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001474 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001475 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001476 if "Error" not in hosts[ controller ]:
1477 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001478 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001479 else: # hosts not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07001480 main.log.error( "hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001481 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001482 " is inconsistent with ONOS1" )
1483 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001484 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001485
1486 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001487 main.log.error( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001488 controllerStr )
1489 consistentHostsResult = main.FALSE
1490 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001491 " hosts response: " +
1492 repr( hosts[ controller ] ) )
1493 utilities.assert_equals(
1494 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001495 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001496 onpass="Hosts view is consistent across all ONOS nodes",
1497 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001498
Jon Hall390696c2015-05-05 17:13:41 -07001499 main.step( "Each host has an IP address" )
Jon Hall58c76b72015-02-23 11:09:24 -08001500 ipResult = main.TRUE
1501 for controller in range( 0, len( hosts ) ):
1502 controllerStr = str( controller + 1 )
1503 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07001504 if not host.get( 'ipAddresses', [ ] ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001505 main.log.error( "DEBUG:Error with host ips on controller" +
1506 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001507 ipResult = main.FALSE
1508 utilities.assert_equals(
1509 expect=main.TRUE,
1510 actual=ipResult,
1511 onpass="The ips of the hosts aren't empty",
1512 onfail="The ip of at least one host is missing" )
1513
Jon Hall6aec96b2015-01-19 14:49:31 -08001514 # Strongly connected clusters of devices
Jon Hall390696c2015-05-05 17:13:41 -07001515 main.step( "Cluster view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001516 consistentClustersResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001517 for controller in range( len( clusters ) ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001518 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001519 if "Error" not in clusters[ controller ]:
1520 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001521 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001522 else: # clusters not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07001523 main.log.error( "clusters from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001524 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001525 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001526
1527 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001528 main.log.error( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001529 "from ONOS" + controllerStr )
1530 consistentClustersResult = main.FALSE
1531 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001532 " clusters response: " +
1533 repr( clusters[ controller ] ) )
1534 utilities.assert_equals(
1535 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001536 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001537 onpass="Clusters view is consistent across all ONOS nodes",
1538 onfail="ONOS nodes have different views of clusters" )
1539 # there should always only be one cluster
Jon Hall390696c2015-05-05 17:13:41 -07001540 main.step( "Cluster view correct across ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001541 try:
1542 numClusters = len( json.loads( clusters[ 0 ] ) )
1543 except ( ValueError, TypeError ):
1544 main.log.exception( "Error parsing clusters[0]: " +
1545 repr( clusters[ 0 ] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001546 clusterResults = main.FALSE
1547 if numClusters == 1:
1548 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001549 utilities.assert_equals(
1550 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08001551 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08001552 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08001553 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08001554
Jon Hall6aec96b2015-01-19 14:49:31 -08001555 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001556 devicesResults = main.TRUE
1557 portsResults = main.TRUE
1558 linksResults = main.TRUE
1559 for controller in range( numControllers ):
1560 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001561 if devices[ controller ] or "Error" not in devices[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001562 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08001563 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001564 json.loads( devices[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001565 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001566 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001567 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001568 actual=currentDevicesResult,
1569 onpass="ONOS" + controllerStr +
1570 " Switches view is correct",
1571 onfail="ONOS" + controllerStr +
1572 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001573
Jon Hall6aec96b2015-01-19 14:49:31 -08001574 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001575 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08001576 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001577 json.loads( ports[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001578 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001579 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001580 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001581 actual=currentPortsResult,
1582 onpass="ONOS" + controllerStr +
1583 " ports view is correct",
1584 onfail="ONOS" + controllerStr +
1585 " ports view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001586
Jon Hall6aec96b2015-01-19 14:49:31 -08001587 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001588 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08001589 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001590 json.loads( links[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001591 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001592 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001593 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001594 actual=currentLinksResult,
1595 onpass="ONOS" + controllerStr +
1596 " links view is correct",
1597 onfail="ONOS" + controllerStr +
1598 " links view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001599
Jon Hall8f89dda2015-01-22 16:03:33 -08001600 devicesResults = devicesResults and currentDevicesResult
1601 portsResults = portsResults and currentPortsResult
1602 linksResults = linksResults and currentLinksResult
Jon Hall73cf9cc2014-11-20 22:28:38 -08001603
Jon Hall5cfd23c2015-03-19 11:40:57 -07001604 topoResult = ( devicesResults and portsResults and linksResults
1605 and consistentHostsResult and consistentClustersResult
1606 and clusterResults and ipResult )
Jon Hall8f89dda2015-01-22 16:03:33 -08001607 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08001608 onpass="Topology Check Test successful",
1609 onfail="Topology Check Test NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001610
Jon Hall6aec96b2015-01-19 14:49:31 -08001611 def CASE6( self, main ):
1612 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001613 The Failure case.
Jon Hall6aec96b2015-01-19 14:49:31 -08001614 """
Jon Hall94fd0472014-12-08 11:52:42 -08001615 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001616 assert numControllers, "numControllers not defined"
1617 assert main, "main not defined"
1618 assert utilities.assert_equals, "utilities.assert_equals not defined"
1619 assert CLIs, "CLIs not defined"
1620 assert nodes, "nodes not defined"
Jon Hall5cfd23c2015-03-19 11:40:57 -07001621 main.case( "Restart minority of ONOS nodes" )
Jon Hall390696c2015-05-05 17:13:41 -07001622 main.step( "Killing 3 ONOS nodes" )
Jon Hallfeff3082015-05-19 10:23:26 -07001623 killTime = time.time()
Jon Hall390696c2015-05-05 17:13:41 -07001624 # TODO: Randomize these nodes or base this on partitions
Jon Hall5cfd23c2015-03-19 11:40:57 -07001625 # TODO: use threads in this case
Jon Hall390696c2015-05-05 17:13:41 -07001626 killResults = main.ONOSbench.onosKill( nodes[0].ip_address )
Jon Hall6aec96b2015-01-19 14:49:31 -08001627 time.sleep( 10 )
Jon Hall390696c2015-05-05 17:13:41 -07001628 killResults = killResults and\
1629 main.ONOSbench.onosKill( nodes[1].ip_address )
Jon Hall6aec96b2015-01-19 14:49:31 -08001630 time.sleep( 10 )
Jon Hall390696c2015-05-05 17:13:41 -07001631 killResults = killResults and\
1632 main.ONOSbench.onosKill( nodes[2].ip_address )
1633 utilities.assert_equals( expect=main.TRUE, actual=killResults,
1634 onpass="ONOS Killed successfully",
1635 onfail="ONOS kill NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001636
Jon Hall6aec96b2015-01-19 14:49:31 -08001637 main.step( "Checking if ONOS is up yet" )
Jon Hallffb386d2014-11-21 13:43:38 -08001638 count = 0
Jon Hall8f89dda2015-01-22 16:03:33 -08001639 onosIsupResult = main.FALSE
1640 while onosIsupResult == main.FALSE and count < 10:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001641 onos1Isup = main.ONOSbench.isup( nodes[0].ip_address )
1642 onos2Isup = main.ONOSbench.isup( nodes[1].ip_address )
1643 onos3Isup = main.ONOSbench.isup( nodes[2].ip_address )
Jon Hall8f89dda2015-01-22 16:03:33 -08001644 onosIsupResult = onos1Isup and onos2Isup and onos3Isup
Jon Hallffb386d2014-11-21 13:43:38 -08001645 count = count + 1
Jon Hall73cf9cc2014-11-20 22:28:38 -08001646 # TODO: if it becomes an issue, we can retry this step a few times
Jon Hall390696c2015-05-05 17:13:41 -07001647 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1648 onpass="ONOS restarted successfully",
1649 onfail="ONOS restart NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001650
Jon Hall390696c2015-05-05 17:13:41 -07001651 main.step( "Restarting ONOS CLIs" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001652 cliResult1 = main.ONOScli1.startOnosCli( nodes[0].ip_address )
1653 cliResult2 = main.ONOScli2.startOnosCli( nodes[1].ip_address )
1654 cliResult3 = main.ONOScli3.startOnosCli( nodes[2].ip_address )
Jon Hall8f89dda2015-01-22 16:03:33 -08001655 cliResults = cliResult1 and cliResult2 and cliResult3
Jon Hall390696c2015-05-05 17:13:41 -07001656 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1657 onpass="ONOS cli restarted",
1658 onfail="ONOS cli did not restart" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001659
Jon Hall21270ac2015-02-16 17:59:55 -08001660 # Grab the time of restart so we chan check how long the gossip
1661 # protocol has had time to work
Jon Hallfeff3082015-05-19 10:23:26 -07001662 main.restartTime = time.time() - killTime
1663 main.log.debug( "Restart time: " + str( main.restartTime ) )
1664 '''
1665 # FIXME: revisit test plan for election with madan
1666 # Rerun for election on restarted nodes
1667 run1 = CLIs[0].electionTestRun()
1668 run2 = CLIs[1].electionTestRun()
1669 run3 = CLIs[2].electionTestRun()
1670 runResults = run1 and run2 and run3
1671 utilities.assert_equals( expect=main.TRUE, actual=runResults,
1672 onpass="Reran for election",
1673 onfail="Failed to rerun for election" )
1674 '''
1675 # TODO: MAke this configurable. Also, we are breaking the above timer
1676 time.sleep( 60 )
1677 main.log.debug( CLIs[0].nodes( jsonFormat=False ) )
1678 main.log.debug( CLIs[0].leaders( jsonFormat=False ) )
1679 main.log.debug( CLIs[0].partitions( jsonFormat=False ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001680
Jon Hall6aec96b2015-01-19 14:49:31 -08001681 def CASE7( self, main ):
1682 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001683 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -08001684 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001685 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001686 assert numControllers, "numControllers not defined"
1687 assert main, "main not defined"
1688 assert utilities.assert_equals, "utilities.assert_equals not defined"
1689 assert CLIs, "CLIs not defined"
1690 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001691 main.case( "Running ONOS Constant State Tests" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001692
Jon Hall5cfd23c2015-03-19 11:40:57 -07001693 main.step( "Check that each switch has a master" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001694 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -07001695 rolesNotNull = main.TRUE
1696 threads = []
1697 for i in range( numControllers ):
1698 t = main.Thread( target=CLIs[i].rolesNotNull,
1699 name="rolesNotNull-" + str( i ),
1700 args=[ ] )
1701 threads.append( t )
1702 t.start()
1703
1704 for t in threads:
1705 t.join()
1706 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001707 utilities.assert_equals(
1708 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001709 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001710 onpass="Each device has a master",
1711 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001712
Jon Hall390696c2015-05-05 17:13:41 -07001713 main.step( "Read device roles from ONOS" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001714 ONOSMastership = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001715 consistentMastership = True
1716 rolesResults = True
1717 threads = []
1718 for i in range( numControllers ):
1719 t = main.Thread( target=CLIs[i].roles,
1720 name="roles-" + str( i ),
1721 args=[] )
1722 threads.append( t )
1723 t.start()
1724
1725 for t in threads:
1726 t.join()
1727 ONOSMastership.append( t.result )
1728
1729 for i in range( numControllers ):
1730 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001731 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001732 " roles" )
1733 main.log.warn(
1734 "ONOS" + str( i + 1 ) + " mastership response: " +
1735 repr( ONOSMastership[i] ) )
1736 rolesResults = False
1737 utilities.assert_equals(
1738 expect=True,
1739 actual=rolesResults,
1740 onpass="No error in reading roles output",
1741 onfail="Error in reading roles from ONOS" )
1742
1743 main.step( "Check for consistency in roles from each controller" )
1744 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001745 main.log.info(
Jon Hall6aec96b2015-01-19 14:49:31 -08001746 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001747 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001748 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001749 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001750 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001751 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001752 onpass="Switch roles are consistent across all ONOS nodes",
1753 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001754
Jon Hall5cfd23c2015-03-19 11:40:57 -07001755 if rolesResults and not consistentMastership:
1756 for i in range( numControllers ):
1757 main.log.warn(
1758 "ONOS" + str( i + 1 ) + " roles: ",
1759 json.dumps(
1760 json.loads( ONOSMastership[ i ] ),
1761 sort_keys=True,
1762 indent=4,
1763 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001764
Jon Hallfeff3082015-05-19 10:23:26 -07001765 # NOTE: we expect mastership to change on controller failure
1766 '''
Jon Hall73cf9cc2014-11-20 22:28:38 -08001767 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -08001768 main.step( description2 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001769 try:
1770 currentJson = json.loads( ONOSMastership[0] )
1771 oldJson = json.loads( mastershipState )
1772 except ( ValueError, TypeError ):
1773 main.log.exception( "Something is wrong with parsing " +
1774 "ONOSMastership[0] or mastershipState" )
1775 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1776 main.log.error( "mastershipState" + repr( mastershipState ) )
1777 main.cleanup()
1778 main.exit()
Jon Hall8f89dda2015-01-22 16:03:33 -08001779 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001780 for i in range( 1, 29 ):
1781 switchDPID = str(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001782 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001783 current = [ switch[ 'master' ] for switch in currentJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001784 if switchDPID in switch[ 'id' ] ]
Jon Hall8f89dda2015-01-22 16:03:33 -08001785 old = [ switch[ 'master' ] for switch in oldJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001786 if switchDPID in switch[ 'id' ] ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08001787 if current == old:
Jon Hall8f89dda2015-01-22 16:03:33 -08001788 mastershipCheck = mastershipCheck and main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001789 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001790 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall8f89dda2015-01-22 16:03:33 -08001791 mastershipCheck = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001792 utilities.assert_equals(
1793 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001794 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -08001795 onpass="Mastership of Switches was not changed",
1796 onfail="Mastership of some switches changed" )
Jon Hallfeff3082015-05-19 10:23:26 -07001797 '''
Jon Hall73cf9cc2014-11-20 22:28:38 -08001798
Jon Hall58c76b72015-02-23 11:09:24 -08001799 main.step( "Get the intents and compare across all nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001800 ONOSIntents = []
Jon Hall58c76b72015-02-23 11:09:24 -08001801 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001802 consistentIntents = True
1803 intentsResults = True
1804 threads = []
1805 for i in range( numControllers ):
1806 t = main.Thread( target=CLIs[i].intents,
1807 name="intents-" + str( i ),
1808 args=[],
1809 kwargs={ 'jsonFormat': True } )
1810 threads.append( t )
1811 t.start()
1812
1813 for t in threads:
1814 t.join()
1815 ONOSIntents.append( t.result )
1816
1817 for i in range( numControllers ):
1818 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001819 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001820 " intents" )
1821 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1822 repr( ONOSIntents[ i ] ) )
1823 intentsResults = False
Jon Hall58c76b72015-02-23 11:09:24 -08001824 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001825 expect=True,
1826 actual=intentsResults,
1827 onpass="No error in reading intents output",
1828 onfail="Error in reading intents from ONOS" )
1829
1830 main.step( "Check for consistency in Intents from each controller" )
1831 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001832 main.log.info( "Intents are consistent across all ONOS " +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001833 "nodes" )
1834 else:
1835 consistentIntents = False
Jon Hall390696c2015-05-05 17:13:41 -07001836
1837 # Try to make it easy to figure out what is happening
1838 #
1839 # Intent ONOS1 ONOS2 ...
1840 # 0x01 INSTALLED INSTALLING
1841 # ... ... ...
1842 # ... ... ...
1843 title = " ID"
1844 for n in range( numControllers ):
1845 title += " " * 10 + "ONOS" + str( n + 1 )
1846 main.log.warn( title )
1847 # get all intent keys in the cluster
1848 keys = []
1849 for nodeStr in ONOSIntents:
1850 node = json.loads( nodeStr )
1851 for intent in node:
1852 keys.append( intent.get( 'id' ) )
1853 keys = set( keys )
1854 for key in keys:
1855 row = "%-13s" % key
1856 for nodeStr in ONOSIntents:
1857 node = json.loads( nodeStr )
1858 for intent in node:
1859 if intent.get( 'id' ) == key:
1860 row += "%-15s" % intent.get( 'state' )
1861 main.log.warn( row )
1862 # End table view
1863
Jon Hall5cfd23c2015-03-19 11:40:57 -07001864 utilities.assert_equals(
1865 expect=True,
1866 actual=consistentIntents,
Jon Hall58c76b72015-02-23 11:09:24 -08001867 onpass="Intents are consistent across all ONOS nodes",
1868 onfail="ONOS nodes have different views of intents" )
Jon Hall58c76b72015-02-23 11:09:24 -08001869 intentStates = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001870 for node in ONOSIntents: # Iter through ONOS nodes
Jon Hall58c76b72015-02-23 11:09:24 -08001871 nodeStates = []
1872 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001873 try:
1874 for intent in json.loads( node ):
1875 nodeStates.append( intent[ 'state' ] )
1876 except ( ValueError, TypeError ):
1877 main.log.exception( "Error in parsing intents" )
1878 main.log.error( repr( node ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001879 intentStates.append( nodeStates )
1880 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1881 main.log.info( dict( out ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001882
Jon Hall5cfd23c2015-03-19 11:40:57 -07001883 if intentsResults and not consistentIntents:
1884 for i in range( numControllers ):
1885 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1886 main.log.warn( json.dumps(
1887 json.loads( ONOSIntents[ i ] ),
1888 sort_keys=True,
1889 indent=4,
1890 separators=( ',', ': ' ) ) )
1891 elif intentsResults and consistentIntents:
1892 intentCheck = main.TRUE
1893
Jon Hall58c76b72015-02-23 11:09:24 -08001894 # NOTE: Store has no durability, so intents are lost across system
1895 # restarts
1896 main.step( "Compare current intents with intents before the failure" )
1897 # NOTE: this requires case 5 to pass for intentState to be set.
1898 # maybe we should stop the test if that fails?
Jon Hall40d2cbd2015-06-03 16:24:29 -07001899 sameIntents = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001900 if intentState and intentState == ONOSIntents[ 0 ]:
Jon Hall21270ac2015-02-16 17:59:55 -08001901 sameIntents = main.TRUE
Jon Hallfeff3082015-05-19 10:23:26 -07001902 main.log.info( "Intents are consistent with before failure" )
Jon Hall58c76b72015-02-23 11:09:24 -08001903 # TODO: possibly the states have changed? we may need to figure out
Jon Hall5cfd23c2015-03-19 11:40:57 -07001904 # what the acceptable states are
Jon Hall40d2cbd2015-06-03 16:24:29 -07001905 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
1906 sameIntents = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08001907 try:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001908 before = json.loads( intentState )
1909 after = json.loads( ONOSIntents[ 0 ] )
1910 for intent in before:
1911 if intent not in after:
1912 sameIntents = main.FALSE
Jon Hallc9eabec2015-06-10 14:33:14 -07001913 main.log.debug( "Intent is not currently in ONOS " +
Jon Hall40d2cbd2015-06-03 16:24:29 -07001914 "(at least in the same form):" )
1915 main.log.debug( json.dumps( intent ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001916 except ( ValueError, TypeError ):
1917 main.log.exception( "Exception printing intents" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001918 main.log.debug( repr( ONOSIntents[0] ) )
1919 main.log.debug( repr( intentState ) )
1920 if sameIntents == main.FALSE:
1921 try:
1922 main.log.debug( "ONOS intents before: " )
1923 main.log.debug( json.dumps( json.loads( intentState ),
1924 sort_keys=True, indent=4,
1925 separators=( ',', ': ' ) ) )
1926 main.log.debug( "Current ONOS intents: " )
1927 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1928 sort_keys=True, indent=4,
1929 separators=( ',', ': ' ) ) )
1930 except ( ValueError, TypeError ):
1931 main.log.exception( "Exception printing intents" )
1932 main.log.debug( repr( ONOSIntents[0] ) )
1933 main.log.debug( repr( intentState ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001934 utilities.assert_equals(
1935 expect=main.TRUE,
1936 actual=sameIntents,
1937 onpass="Intents are consistent with before failure",
1938 onfail="The Intents changed during failure" )
1939 intentCheck = intentCheck and sameIntents
Jon Hall21270ac2015-02-16 17:59:55 -08001940
Jon Hall58c76b72015-02-23 11:09:24 -08001941 main.step( "Get the OF Table entries and compare to before " +
1942 "component failure" )
1943 FlowTables = main.TRUE
1944 flows2 = []
1945 for i in range( 28 ):
1946 main.log.info( "Checking flow table on s" + str( i + 1 ) )
1947 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
1948 flows2.append( tmpFlows )
1949 tempResult = main.Mininet2.flowComp(
1950 flow1=flows[ i ],
1951 flow2=tmpFlows )
1952 FlowTables = FlowTables and tempResult
1953 if FlowTables == main.FALSE:
1954 main.log.info( "Differences in flow table for switch: s" +
1955 str( i + 1 ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001956 utilities.assert_equals(
1957 expect=main.TRUE,
1958 actual=FlowTables,
1959 onpass="No changes were found in the flow tables",
1960 onfail="Changes were found in the flow tables" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001961
Jon Hall6aec96b2015-01-19 14:49:31 -08001962 main.step( "Check the continuous pings to ensure that no packets " +
1963 "were dropped during component failure" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001964 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
1965 main.params[ 'TESTONIP' ] )
Jon Hall8f89dda2015-01-22 16:03:33 -08001966 LossInPings = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001967 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
1968 for i in range( 8, 18 ):
1969 main.log.info(
1970 "Checking for a loss in pings along flow from s" +
1971 str( i ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001972 LossInPings = main.Mininet2.checkForLoss(
Jon Hall6aec96b2015-01-19 14:49:31 -08001973 "/tmp/ping.h" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001974 str( i ) ) or LossInPings
1975 if LossInPings == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001976 main.log.info( "Loss in ping detected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001977 elif LossInPings == main.ERROR:
Jon Hall6aec96b2015-01-19 14:49:31 -08001978 main.log.info( "There are multiple mininet process running" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001979 elif LossInPings == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001980 main.log.info( "No Loss in the pings" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001981 main.log.info( "No loss of dataplane connectivity" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001982 utilities.assert_equals(
1983 expect=main.FALSE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001984 actual=LossInPings,
Jon Hall6aec96b2015-01-19 14:49:31 -08001985 onpass="No Loss of connectivity",
1986 onfail="Loss of dataplane connectivity detected" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001987
Jon Hall390696c2015-05-05 17:13:41 -07001988 main.step( "Leadership Election is still functional" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001989 # Test of LeadershipElection
Jon Hall8f89dda2015-01-22 16:03:33 -08001990 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001991 # FIXME: make sure this matches nodes that were restarted
1992 restarted = [ nodes[0].ip_address, nodes[1].ip_address,
1993 nodes[2].ip_address ]
Jon Hall390696c2015-05-05 17:13:41 -07001994
Jon Hall8f89dda2015-01-22 16:03:33 -08001995 leaderResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001996 for cli in CLIs:
1997 leaderN = cli.electionTestLeader()
Jon Hall8f89dda2015-01-22 16:03:33 -08001998 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08001999 if leaderN == main.FALSE:
Jon Hallfeff3082015-05-19 10:23:26 -07002000 # error in response
Jon Hall40d2cbd2015-06-03 16:24:29 -07002001 main.log.error( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002002 "electionTestLeader function, check the" +
Jon Hall6aec96b2015-01-19 14:49:31 -08002003 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002004 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002005 elif leaderN is None:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002006 main.log.error( cli.name +
Jon Hall6aec96b2015-01-19 14:49:31 -08002007 " shows no leader for the election-app was" +
2008 " elected after the old one died" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002009 leaderResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002010 elif leaderN in restarted:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002011 main.log.error( cli.name + " shows " + str( leaderN ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002012 " as leader for the election-app, but it " +
2013 "was restarted" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002014 leaderResult = main.FALSE
2015 if len( set( leaderList ) ) != 1:
2016 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002017 main.log.error(
2018 "Inconsistent view of leader for the election test app" )
2019 # TODO: print the list
Jon Hall6aec96b2015-01-19 14:49:31 -08002020 utilities.assert_equals(
2021 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002022 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002023 onpass="Leadership election passed",
2024 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002025
Jon Hall6aec96b2015-01-19 14:49:31 -08002026 def CASE8( self, main ):
2027 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002028 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -08002029 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002030 import sys
Jon Hall6aec96b2015-01-19 14:49:31 -08002031 # FIXME add this path to params
2032 sys.path.append( "/home/admin/sts" )
2033 # assumes that sts is already in you PYTHONPATH
2034 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -08002035 import json
2036 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002037 assert numControllers, "numControllers not defined"
2038 assert main, "main not defined"
2039 assert utilities.assert_equals, "utilities.assert_equals not defined"
2040 assert CLIs, "CLIs not defined"
2041 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08002042
Jon Hallfeff3082015-05-19 10:23:26 -07002043 main.case( "Compare ONOS Topology view to Mininet topology" )
2044 main.caseExplaination = "Compare topology objects between Mininet" +\
2045 " and ONOS"
Jon Hall6aec96b2015-01-19 14:49:31 -08002046 main.step( "Create TestONTopology object" )
Jon Hallfeff3082015-05-19 10:23:26 -07002047 try:
2048 ctrls = []
2049 for node in nodes:
2050 temp = ( node, node.name, node.ip_address, 6633 )
2051 ctrls.append( temp )
2052 MNTopo = TestONTopology( main.Mininet1, ctrls )
2053 except Exception:
2054 objResult = main.FALSE
2055 else:
2056 objResult = main.TRUE
2057 utilities.assert_equals( expect=main.TRUE, actual=objResult,
2058 onpass="Created TestONTopology object",
2059 onfail="Exception while creating " +
2060 "TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002061
Jon Hallfeff3082015-05-19 10:23:26 -07002062 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002063 devicesResults = main.TRUE
2064 portsResults = main.TRUE
2065 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08002066 hostsResults = main.TRUE
Jon Hallc9eabec2015-06-10 14:33:14 -07002067 hostAttachmentResults = True
Jon Hall8f89dda2015-01-22 16:03:33 -08002068 topoResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08002069 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -08002070 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -08002071 main.step( "Collecting topology information from ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002072 startTime = time.time()
Jon Hall21270ac2015-02-16 17:59:55 -08002073 # Give time for Gossip to work
Jon Hall8f89dda2015-01-22 16:03:33 -08002074 while topoResult == main.FALSE and elapsed < 60:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002075 count += 1
Jon Hall94fd0472014-12-08 11:52:42 -08002076 if count > 1:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002077 # TODO: Deprecate STS usage
Jon Hall58c76b72015-02-23 11:09:24 -08002078 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall8f89dda2015-01-22 16:03:33 -08002079 cliStart = time.time()
Jon Hall94fd0472014-12-08 11:52:42 -08002080 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002081 threads = []
2082 for i in range( numControllers ):
2083 t = main.Thread( target=CLIs[i].devices,
2084 name="devices-" + str( i ),
2085 args=[ ] )
2086 threads.append( t )
2087 t.start()
2088
2089 for t in threads:
2090 t.join()
2091 devices.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002092 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -08002093 ipResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002094 threads = []
2095 for i in range( numControllers ):
2096 t = main.Thread( target=CLIs[i].hosts,
2097 name="hosts-" + str( i ),
2098 args=[ ] )
2099 threads.append( t )
2100 t.start()
2101
2102 for t in threads:
2103 t.join()
2104 try:
2105 hosts.append( json.loads( t.result ) )
2106 except ( ValueError, TypeError ):
2107 main.log.exception( "Error parsing hosts results" )
2108 main.log.error( repr( t.result ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08002109 for controller in range( 0, len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08002110 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08002111 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07002112 if host is None or host.get( 'ipAddresses', [] ) == []:
Jon Hall6aec96b2015-01-19 14:49:31 -08002113 main.log.error(
Jon Hall40d2cbd2015-06-03 16:24:29 -07002114 "DEBUG:Error with host ipAddresses on controller" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002115 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08002116 ipResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002117 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002118 threads = []
2119 for i in range( numControllers ):
2120 t = main.Thread( target=CLIs[i].ports,
2121 name="ports-" + str( i ),
2122 args=[ ] )
2123 threads.append( t )
2124 t.start()
2125
2126 for t in threads:
2127 t.join()
2128 ports.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002129 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002130 threads = []
2131 for i in range( numControllers ):
2132 t = main.Thread( target=CLIs[i].links,
2133 name="links-" + str( i ),
2134 args=[ ] )
2135 threads.append( t )
2136 t.start()
2137
2138 for t in threads:
2139 t.join()
2140 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002141 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002142 threads = []
2143 for i in range( numControllers ):
2144 t = main.Thread( target=CLIs[i].clusters,
2145 name="clusters-" + str( i ),
2146 args=[ ] )
2147 threads.append( t )
2148 t.start()
2149
2150 for t in threads:
2151 t.join()
2152 clusters.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002153
Jon Hall8f89dda2015-01-22 16:03:33 -08002154 elapsed = time.time() - startTime
2155 cliTime = time.time() - cliStart
Jon Hallc9eabec2015-06-10 14:33:14 -07002156 print "Elapsed time: " + str( elapsed )
Jon Hall8f89dda2015-01-22 16:03:33 -08002157 print "CLI time: " + str( cliTime )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002158
Jon Hall8f89dda2015-01-22 16:03:33 -08002159 for controller in range( numControllers ):
2160 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08002161 if devices[ controller ] or "Error" not in devices[
2162 controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08002163 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08002164 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002165 json.loads( devices[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002166 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002167 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002168 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002169 actual=currentDevicesResult,
2170 onpass="ONOS" + controllerStr +
2171 " Switches view is correct",
2172 onfail="ONOS" + controllerStr +
2173 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002174
Jon Hall6aec96b2015-01-19 14:49:31 -08002175 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08002176 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08002177 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002178 json.loads( ports[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002179 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002180 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002181 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002182 actual=currentPortsResult,
2183 onpass="ONOS" + controllerStr +
2184 " ports view is correct",
2185 onfail="ONOS" + controllerStr +
2186 " ports view is incorrect" )
Jon Hall94fd0472014-12-08 11:52:42 -08002187
Jon Hall6aec96b2015-01-19 14:49:31 -08002188 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08002189 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08002190 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002191 json.loads( links[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002192 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002193 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002194 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002195 actual=currentLinksResult,
2196 onpass="ONOS" + controllerStr +
2197 " links view is correct",
2198 onfail="ONOS" + controllerStr +
2199 " links view is incorrect" )
2200
2201 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2202 currentHostsResult = main.Mininet1.compareHosts(
2203 MNTopo, hosts[ controller ] )
2204 else:
2205 currentHostsResult = main.FALSE
2206 utilities.assert_equals( expect=main.TRUE,
2207 actual=currentHostsResult,
2208 onpass="ONOS" + controllerStr +
2209 " hosts exist in Mininet",
2210 onfail="ONOS" + controllerStr +
2211 " hosts don't match Mininet" )
Jon Hallc9eabec2015-06-10 14:33:14 -07002212 # CHECKING HOST ATTACHMENT POINTS
2213 hostAttachment = True
2214 noHosts = False
2215 # FIXME: topo-HA/obelisk specific mappings:
2216 # key is mac and value is dpid
2217 mappings = {}
2218 for i in range( 1, 29 ): # hosts 1 through 28
2219 # set up correct variables:
2220 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2221 if i == 1:
2222 deviceId = "1000".zfill(16)
2223 elif i == 2:
2224 deviceId = "2000".zfill(16)
2225 elif i == 3:
2226 deviceId = "3000".zfill(16)
2227 elif i == 4:
2228 deviceId = "3004".zfill(16)
2229 elif i == 5:
2230 deviceId = "5000".zfill(16)
2231 elif i == 6:
2232 deviceId = "6000".zfill(16)
2233 elif i == 7:
2234 deviceId = "6007".zfill(16)
2235 elif i >= 8 and i <= 17:
2236 dpid = '3' + str( i ).zfill( 3 )
2237 deviceId = dpid.zfill(16)
2238 elif i >= 18 and i <= 27:
2239 dpid = '6' + str( i ).zfill( 3 )
2240 deviceId = dpid.zfill(16)
2241 elif i == 28:
2242 deviceId = "2800".zfill(16)
2243 mappings[ macId ] = deviceId
2244 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2245 if hosts[ controller ] == []:
2246 main.log.warn( "There are no hosts discovered" )
2247 noHosts = True
2248 else:
2249 for host in hosts[ controller ]:
2250 mac = None
2251 location = None
2252 device = None
2253 port = None
2254 try:
2255 mac = host.get( 'mac' )
2256 assert mac, "mac field could not be found for this host object"
Jon Hall58c76b72015-02-23 11:09:24 -08002257
Jon Hallc9eabec2015-06-10 14:33:14 -07002258 location = host.get( 'location' )
2259 assert location, "location field could not be found for this host object"
2260
2261 # Trim the protocol identifier off deviceId
2262 device = str( location.get( 'elementId' ) ).split(':')[1]
2263 assert device, "elementId field could not be found for this host location object"
2264
2265 port = location.get( 'port' )
2266 assert port, "port field could not be found for this host location object"
2267
2268 # Now check if this matches where they should be
2269 if mac and device and port:
2270 if str( port ) != "1":
2271 main.log.error( "The attachment port is incorrect for " +
2272 "host " + str( mac ) +
2273 ". Expected: 1 Actual: " + str( port) )
2274 hostAttachment = False
2275 if device != mappings[ str( mac ) ]:
2276 main.log.error( "The attachment device is incorrect for " +
2277 "host " + str( mac ) +
2278 ". Expected: " + mappings[ str( mac ) ] +
2279 " Actual: " + device )
2280 hostAttachment = False
2281 else:
2282 hostAttachment = False
2283 except AssertionError:
2284 main.log.exception( "Json object not as expected" )
2285 main.log.error( repr( host ) )
2286 hostAttachment = False
2287 else:
2288 main.log.error( "No hosts json output or \"Error\"" +
2289 " in output. hosts = " +
2290 repr( hosts[ controller ] ) )
2291 if noHosts is False:
2292 hostAttachment = True
2293
2294 # END CHECKING HOST ATTACHMENT POINTS
Jon Hall58c76b72015-02-23 11:09:24 -08002295 devicesResults = devicesResults and currentDevicesResult
2296 portsResults = portsResults and currentPortsResult
2297 linksResults = linksResults and currentLinksResult
2298 hostsResults = hostsResults and currentHostsResult
Jon Hallc9eabec2015-06-10 14:33:14 -07002299 hostAttachmentResults = hostAttachmentResults and hostAttachment
Jon Hall94fd0472014-12-08 11:52:42 -08002300
Jon Hallc9eabec2015-06-10 14:33:14 -07002301 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08002302
Jon Hallc9eabec2015-06-10 14:33:14 -07002303 # hosts
2304 main.step( "Hosts view is consistent across all ONOS nodes" )
2305 consistentHostsResult = main.TRUE
2306 for controller in range( len( hosts ) ):
2307 controllerStr = str( controller + 1 )
2308 if "Error" not in hosts[ controller ]:
2309 if hosts[ controller ] == hosts[ 0 ]:
2310 continue
2311 else: # hosts not consistent
2312 main.log.error( "hosts from ONOS" + controllerStr +
2313 " is inconsistent with ONOS1" )
2314 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08002315 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002316
Jon Hallc9eabec2015-06-10 14:33:14 -07002317 else:
2318 main.log.error( "Error in getting ONOS hosts from ONOS" +
2319 controllerStr )
2320 consistentHostsResult = main.FALSE
2321 main.log.warn( "ONOS" + controllerStr +
2322 " hosts response: " +
2323 repr( hosts[ controller ] ) )
2324 utilities.assert_equals(
2325 expect=main.TRUE,
2326 actual=consistentHostsResult,
2327 onpass="Hosts view is consistent across all ONOS nodes",
2328 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08002329
Jon Hallc9eabec2015-06-10 14:33:14 -07002330 main.step( "Hosts information is correct" )
2331 hostsResults = hostsResults and ipResult
2332 utilities.assert_equals(
2333 expect=main.TRUE,
2334 actual=hostsResults,
2335 onpass="Host information is correct",
2336 onfail="Host information is incorrect" )
2337
2338 main.step( "Host attachment points to the network" )
2339 utilities.assert_equals(
2340 expect=True,
2341 actual=hostAttachmentResults,
2342 onpass="Hosts are correctly attached to the network",
2343 onfail="ONOS did not correctly attach hosts to the network" )
2344
2345 # Strongly connected clusters of devices
2346 main.step( "Clusters view is consistent across all ONOS nodes" )
2347 consistentClustersResult = main.TRUE
2348 for controller in range( len( clusters ) ):
2349 controllerStr = str( controller + 1 )
2350 if "Error" not in clusters[ controller ]:
2351 if clusters[ controller ] == clusters[ 0 ]:
2352 continue
2353 else: # clusters not consistent
2354 main.log.error( "clusters from ONOS" +
2355 controllerStr +
2356 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002357 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002358
Jon Hallc9eabec2015-06-10 14:33:14 -07002359 else:
2360 main.log.error( "Error in getting dataplane clusters " +
2361 "from ONOS" + controllerStr )
2362 consistentClustersResult = main.FALSE
2363 main.log.warn( "ONOS" + controllerStr +
2364 " clusters response: " +
2365 repr( clusters[ controller ] ) )
2366 utilities.assert_equals(
2367 expect=main.TRUE,
2368 actual=consistentClustersResult,
2369 onpass="Clusters view is consistent across all ONOS nodes",
2370 onfail="ONOS nodes have different views of clusters" )
2371
2372 main.step( "There is only one SCC" )
2373 # there should always only be one cluster
2374 try:
2375 numClusters = len( json.loads( clusters[ 0 ] ) )
2376 except ( ValueError, TypeError ):
2377 main.log.exception( "Error parsing clusters[0]: " +
2378 repr( clusters[0] ) )
2379 clusterResults = main.FALSE
2380 if numClusters == 1:
2381 clusterResults = main.TRUE
2382 utilities.assert_equals(
2383 expect=1,
2384 actual=numClusters,
2385 onpass="ONOS shows 1 SCC",
2386 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2387
2388 topoResult = ( devicesResults and portsResults and linksResults
2389 and hostsResults and consistentHostsResult
2390 and consistentClustersResult and clusterResults
2391 and ipResult and hostAttachmentResults )
Jon Hall94fd0472014-12-08 11:52:42 -08002392
Jon Hall8f89dda2015-01-22 16:03:33 -08002393 topoResult = topoResult and int( count <= 2 )
2394 note = "note it takes about " + str( int( cliTime ) ) + \
2395 " seconds for the test to make all the cli calls to fetch " +\
2396 "the topology from each ONOS instance"
Jon Hall1b8f54a2015-02-04 13:24:20 -08002397 main.log.info(
Jon Hall8f89dda2015-01-22 16:03:33 -08002398 "Very crass estimate for topology discovery/convergence( " +
2399 str( note ) + " ): " + str( elapsed ) + " seconds, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002400 str( count ) + " tries" )
Jon Hallc9eabec2015-06-10 14:33:14 -07002401
2402 main.step( "Device information is correct" )
2403 utilities.assert_equals(
2404 expect=main.TRUE,
2405 actual=devicesResults,
2406 onpass="Device information is correct",
2407 onfail="Device information is incorrect" )
2408
2409 main.step( "Port information is correct" )
2410 utilities.assert_equals(
2411 expect=main.TRUE,
2412 actual=portsResults,
2413 onpass="Port information is correct",
2414 onfail="Port information is incorrect" )
2415
2416 main.step( "Links are correct" )
2417 utilities.assert_equals(
2418 expect=main.TRUE,
2419 actual=linksResults,
2420 onpass="Link are correct",
2421 onfail="Links are incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002422
Jon Halla9d26da2015-03-30 16:45:32 -07002423 # FIXME: move this to an ONOS state case
2424 main.step( "Checking ONOS nodes" )
2425 nodesOutput = []
Jon Hall390696c2015-05-05 17:13:41 -07002426 nodeResults = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002427 threads = []
2428 for i in range( numControllers ):
2429 t = main.Thread( target=CLIs[i].nodes,
2430 name="nodes-" + str( i ),
2431 args=[ ] )
2432 threads.append( t )
2433 t.start()
2434
2435 for t in threads:
2436 t.join()
2437 nodesOutput.append( t.result )
2438 ips = [ node.ip_address for node in nodes ]
2439 for i in nodesOutput:
2440 try:
2441 current = json.loads( i )
2442 for node in current:
Jon Hall390696c2015-05-05 17:13:41 -07002443 currentResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002444 if node['ip'] in ips: # node in nodes() output is in cell
2445 if node['state'] == 'ACTIVE':
Jon Hall390696c2015-05-05 17:13:41 -07002446 currentResult = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002447 else:
2448 main.log.error( "Error in ONOS node availability" )
2449 main.log.error(
2450 json.dumps( current,
2451 sort_keys=True,
2452 indent=4,
2453 separators=( ',', ': ' ) ) )
2454 break
Jon Hall390696c2015-05-05 17:13:41 -07002455 nodeResults = nodeResults and currentResult
Jon Halla9d26da2015-03-30 16:45:32 -07002456 except ( ValueError, TypeError ):
2457 main.log.error( "Error parsing nodes output" )
2458 main.log.warn( repr( i ) )
Jon Hall390696c2015-05-05 17:13:41 -07002459 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2460 onpass="Nodes check successful",
2461 onfail="Nodes check NOT successful" )
Jon Halla9d26da2015-03-30 16:45:32 -07002462
Jon Hall6aec96b2015-01-19 14:49:31 -08002463 def CASE9( self, main ):
2464 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002465 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -08002466 """
2467 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002468 assert numControllers, "numControllers not defined"
2469 assert main, "main not defined"
2470 assert utilities.assert_equals, "utilities.assert_equals not defined"
2471 assert CLIs, "CLIs not defined"
2472 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002473 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002474
Jon Hall8f89dda2015-01-22 16:03:33 -08002475 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002476
Jon Hall6aec96b2015-01-19 14:49:31 -08002477 description = "Turn off a link to ensure that Link Discovery " +\
Jon Hall58c76b72015-02-23 11:09:24 -08002478 "is working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002479 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002480
Jon Hall6aec96b2015-01-19 14:49:31 -08002481 main.step( "Kill Link between s3 and s28" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002482 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
Jon Hall58c76b72015-02-23 11:09:24 -08002483 main.log.info( "Waiting " + str( linkSleep ) +
2484 " seconds for link down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002485 time.sleep( linkSleep )
2486 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002487 onpass="Link down successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002488 onfail="Failed to bring link down" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002489 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002490
Jon Hall6aec96b2015-01-19 14:49:31 -08002491 def CASE10( self, main ):
2492 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002493 Link s3-s28 up
Jon Hall6aec96b2015-01-19 14:49:31 -08002494 """
2495 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002496 assert numControllers, "numControllers not defined"
2497 assert main, "main not defined"
2498 assert utilities.assert_equals, "utilities.assert_equals not defined"
2499 assert CLIs, "CLIs not defined"
2500 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002501 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002502
Jon Hall8f89dda2015-01-22 16:03:33 -08002503 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002504
Jon Hall6aec96b2015-01-19 14:49:31 -08002505 description = "Restore a link to ensure that Link Discovery is " + \
Jon Hall63604932015-02-26 17:09:50 -08002506 "working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002507 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002508
Jon Hall6aec96b2015-01-19 14:49:31 -08002509 main.step( "Bring link between s3 and s28 back up" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002510 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
Jon Hall58c76b72015-02-23 11:09:24 -08002511 main.log.info( "Waiting " + str( linkSleep ) +
2512 " seconds for link up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002513 time.sleep( linkSleep )
2514 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002515 onpass="Link up successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002516 onfail="Failed to bring link up" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002517 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002518
Jon Hall6aec96b2015-01-19 14:49:31 -08002519 def CASE11( self, main ):
2520 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002521 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -08002522 """
2523 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002524 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002525 assert numControllers, "numControllers not defined"
2526 assert main, "main not defined"
2527 assert utilities.assert_equals, "utilities.assert_equals not defined"
2528 assert CLIs, "CLIs not defined"
2529 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08002530
Jon Hall8f89dda2015-01-22 16:03:33 -08002531 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002532
2533 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002534 main.case( description )
2535 switch = main.params[ 'kill' ][ 'switch' ]
2536 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08002537
Jon Hall6aec96b2015-01-19 14:49:31 -08002538 # TODO: Make this switch parameterizable
2539 main.step( "Kill " + switch )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002540 main.log.info( "Deleting " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002541 main.Mininet1.delSwitch( switch )
2542 main.log.info( "Waiting " + str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002543 " seconds for switch down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002544 time.sleep( switchSleep )
2545 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002546 # Peek at the deleted switch
2547 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002548 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002549 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -08002550 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002551 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002552 onpass="Kill switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002553 onfail="Failed to kill switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002554
Jon Hall6aec96b2015-01-19 14:49:31 -08002555 def CASE12( self, main ):
2556 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002557 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -08002558 """
2559 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002560 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002561 assert numControllers, "numControllers not defined"
2562 assert main, "main not defined"
2563 assert utilities.assert_equals, "utilities.assert_equals not defined"
2564 assert CLIs, "CLIs not defined"
2565 assert nodes, "nodes not defined"
2566 assert ONOS1Port, "ONOS1Port not defined"
2567 assert ONOS2Port, "ONOS2Port not defined"
2568 assert ONOS3Port, "ONOS3Port not defined"
2569 assert ONOS4Port, "ONOS4Port not defined"
2570 assert ONOS5Port, "ONOS5Port not defined"
2571 assert ONOS6Port, "ONOS6Port not defined"
2572 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall669173b2014-12-17 11:36:30 -08002573
Jon Hall8f89dda2015-01-22 16:03:33 -08002574 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall6aec96b2015-01-19 14:49:31 -08002575 switch = main.params[ 'kill' ][ 'switch' ]
2576 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2577 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002578 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002579 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002580
Jon Hall6aec96b2015-01-19 14:49:31 -08002581 main.step( "Add back " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002582 main.Mininet1.addSwitch( switch, dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002583 for peer in links:
Jon Hall8f89dda2015-01-22 16:03:33 -08002584 main.Mininet1.addLink( switch, peer )
Jon Hall0f523f22015-07-06 09:31:09 -07002585 ipList = []
2586 for i in range( numControllers ):
2587 ipList.append( nodes[ i ].ip_address )
2588 main.Mininet1.assignSwController( sw=switch, ip=ipList )
Jon Hall58c76b72015-02-23 11:09:24 -08002589 main.log.info( "Waiting " + str( switchSleep ) +
2590 " seconds for switch up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002591 time.sleep( switchSleep )
2592 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002593 # Peek at the deleted switch
2594 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002595 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002596 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002597 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002598 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002599 onpass="add switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002600 onfail="Failed to add switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002601
Jon Hall6aec96b2015-01-19 14:49:31 -08002602 def CASE13( self, main ):
2603 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002604 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -08002605 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002606 import os
2607 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002608 assert numControllers, "numControllers not defined"
2609 assert main, "main not defined"
2610 assert utilities.assert_equals, "utilities.assert_equals not defined"
2611 assert CLIs, "CLIs not defined"
2612 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002613
2614 # printing colors to terminal
Jon Hall5cfd23c2015-03-19 11:40:57 -07002615 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2616 'blue': '\033[94m', 'green': '\033[92m',
2617 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
Jon Hall40d2cbd2015-06-03 16:24:29 -07002618 main.case( "Test Cleanup" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002619 main.step( "Killing tcpdumps" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002620 main.Mininet2.stopTcpdump()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002621
Jon Hall6aec96b2015-01-19 14:49:31 -08002622 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002623 testname = main.TEST
Jon Hall8f89dda2015-01-22 16:03:33 -08002624 teststationUser = main.params[ 'TESTONUSER' ]
2625 teststationIP = main.params[ 'TESTONIP' ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002626 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -08002627 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -08002628 # FIXME: scp
2629 # mn files
2630 # TODO: Load these from params
2631 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002632 logFolder = "/opt/onos/log/"
2633 logFiles = [ "karaf.log", "karaf.log.1" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002634 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002635 dstDir = "~/packet_captures/"
2636 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002637 for node in nodes:
2638 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2639 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002640 teststationUser + "@" +
2641 teststationIP + ":" +
2642 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002643 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002644 main.ONOSbench.handle.expect( "\$" )
2645
Jon Hall6aec96b2015-01-19 14:49:31 -08002646 # std*.log's
2647 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002648 logFolder = "/opt/onos/var/"
2649 logFiles = [ "stderr.log", "stdout.log" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002650 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002651 dstDir = "~/packet_captures/"
2652 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002653 for node in nodes:
2654 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2655 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002656 teststationUser + "@" +
2657 teststationIP + ":" +
2658 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002659 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002660 main.ONOSbench.handle.expect( "\$" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002661 # sleep so scp can finish
2662 time.sleep( 10 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002663
2664 main.step( "Stopping Mininet" )
Jon Hall390696c2015-05-05 17:13:41 -07002665 mnResult = main.Mininet1.stopNet()
2666 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2667 onpass="Mininet stopped",
2668 onfail="MN cleanup NOT successful" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002669
2670 main.step( "Checking ONOS Logs for errors" )
2671 for node in nodes:
2672 print colors[ 'purple' ] + "Checking logs for errors on " + \
2673 node.name + ":" + colors[ 'end' ]
Jon Hall40d2cbd2015-06-03 16:24:29 -07002674 print main.ONOSbench.checkLogs( node.ip_address, restart=True )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002675
Jon Hall6aec96b2015-01-19 14:49:31 -08002676 main.step( "Packing and rotating pcap archives" )
2677 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002678
Jon Hallfeff3082015-05-19 10:23:26 -07002679 try:
2680 timerLog = open( main.logdir + "/Timers.csv", 'w')
2681 # Overwrite with empty line and close
Jon Hall40d2cbd2015-06-03 16:24:29 -07002682 labels = "Gossip Intents, Restart"
2683 data = str( gossipTime ) + ", " + str( main.restartTime )
2684 timerLog.write( labels + "\n" + data )
Jon Hallfeff3082015-05-19 10:23:26 -07002685 timerLog.close()
2686 except NameError, e:
2687 main.log.exception(e)
2688
Jon Hall6aec96b2015-01-19 14:49:31 -08002689 def CASE14( self, main ):
2690 """
Jon Hall669173b2014-12-17 11:36:30 -08002691 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -08002692 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07002693 assert numControllers, "numControllers not defined"
2694 assert main, "main not defined"
2695 assert utilities.assert_equals, "utilities.assert_equals not defined"
2696 assert CLIs, "CLIs not defined"
2697 assert nodes, "nodes not defined"
2698
Jon Hall390696c2015-05-05 17:13:41 -07002699 main.case("Start Leadership Election app")
2700 main.step( "Install leadership election app" )
Jon Hallfeff3082015-05-19 10:23:26 -07002701 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
2702 utilities.assert_equals(
2703 expect=main.TRUE,
2704 actual=appResult,
2705 onpass="Election app installed",
2706 onfail="Something went wrong with installing Leadership election" )
2707
2708 main.step( "Run for election on each node" )
2709 leaderResult = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002710 leaders = []
2711 for cli in CLIs:
Jon Hall390696c2015-05-05 17:13:41 -07002712 cli.electionTestRun()
2713 for cli in CLIs:
Jon Halla9d26da2015-03-30 16:45:32 -07002714 leader = cli.electionTestLeader()
2715 if leader is None or leader == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002716 main.log.error( cli.name + ": Leader for the election app " +
Jon Halla9d26da2015-03-30 16:45:32 -07002717 "should be an ONOS node, instead got '" +
2718 str( leader ) + "'" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002719 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002720 leaders.append( leader )
Jon Hall6aec96b2015-01-19 14:49:31 -08002721 utilities.assert_equals(
2722 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002723 actual=leaderResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002724 onpass="Successfully ran for leadership",
2725 onfail="Failed to run for leadership" )
2726
2727 main.step( "Check that each node shows the same leader" )
2728 sameLeader = main.TRUE
2729 if len( set( leaders ) ) != 1:
2730 sameLeader = main.FALSE
2731 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2732 str( leaders ) )
2733 utilities.assert_equals(
2734 expect=main.TRUE,
2735 actual=sameLeader,
2736 onpass="Leadership is consistent for the election topic",
2737 onfail="Nodes have different leaders" )
Jon Hall669173b2014-12-17 11:36:30 -08002738
Jon Hall6aec96b2015-01-19 14:49:31 -08002739 def CASE15( self, main ):
2740 """
Jon Hall669173b2014-12-17 11:36:30 -08002741 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08002742 """
Jon Hall390696c2015-05-05 17:13:41 -07002743 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002744 assert numControllers, "numControllers not defined"
2745 assert main, "main not defined"
2746 assert utilities.assert_equals, "utilities.assert_equals not defined"
2747 assert CLIs, "CLIs not defined"
2748 assert nodes, "nodes not defined"
2749
Jon Hall8f89dda2015-01-22 16:03:33 -08002750 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002751 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08002752 main.case( description )
Jon Hallfeff3082015-05-19 10:23:26 -07002753
2754 main.step( "Check that each node shows the same leader" )
2755 sameLeader = main.TRUE
2756 leaders = []
2757 for cli in CLIs:
2758 leader = cli.electionTestLeader()
2759 leaders.append( leader )
2760 if len( set( leaders ) ) != 1:
2761 sameLeader = main.FALSE
2762 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2763 str( leaders ) )
2764 utilities.assert_equals(
2765 expect=main.TRUE,
2766 actual=sameLeader,
2767 onpass="Leadership is consistent for the election topic",
2768 onfail="Nodes have different leaders" )
2769
Jon Hall6aec96b2015-01-19 14:49:31 -08002770 main.step( "Find current leader and withdraw" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002771 leader = main.ONOScli1.electionTestLeader()
Jon Halla9d26da2015-03-30 16:45:32 -07002772 # do some sanity checking on leader before using it
Jon Hall8f89dda2015-01-22 16:03:33 -08002773 withdrawResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002774 if leader is None or leader == main.FALSE:
Jon Hallfeff3082015-05-19 10:23:26 -07002775 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002776 "Leader for the election app should be an ONOS node," +
Jon Hall58c76b72015-02-23 11:09:24 -08002777 "instead got '" + str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002778 leaderResult = main.FALSE
Jon Hall63604932015-02-26 17:09:50 -08002779 oldLeader = None
Jon Hall5cfd23c2015-03-19 11:40:57 -07002780 for i in range( len( CLIs ) ):
2781 if leader == nodes[ i ].ip_address:
2782 oldLeader = CLIs[ i ]
2783 break
Jon Halla9d26da2015-03-30 16:45:32 -07002784 else: # FOR/ELSE statement
Jon Hall5cfd23c2015-03-19 11:40:57 -07002785 main.log.error( "Leader election, could not find current leader" )
Jon Hall63604932015-02-26 17:09:50 -08002786 if oldLeader:
2787 withdrawResult = oldLeader.electionTestWithdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08002788 utilities.assert_equals(
2789 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002790 actual=withdrawResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002791 onpass="Node was withdrawn from election",
2792 onfail="Node was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08002793
Jon Hall6aec96b2015-01-19 14:49:31 -08002794 main.step( "Make sure new leader is elected" )
Jon Halla9d26da2015-03-30 16:45:32 -07002795 # FIXME: use threads
Jon Hall8f89dda2015-01-22 16:03:33 -08002796 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002797 for cli in CLIs:
2798 leaderN = cli.electionTestLeader()
2799 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002800 if leaderN == leader:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002801 main.log.error( cli.name + " still sees " + str( leader ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002802 " as leader after they withdrew" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002803 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002804 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002805 # error in response
2806 # TODO: add check for "Command not found:" in the driver, this
Jon Hall5cfd23c2015-03-19 11:40:57 -07002807 # means the app isn't loaded
Jon Hall40d2cbd2015-06-03 16:24:29 -07002808 main.log.error( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002809 "electionTestLeader function, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002810 "check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002811 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002812 elif leaderN is None:
2813 # node may not have recieved the event yet
Jon Hall390696c2015-05-05 17:13:41 -07002814 time.sleep(7)
Jon Halla9d26da2015-03-30 16:45:32 -07002815 leaderN = cli.electionTestLeader()
2816 leaderList.pop()
2817 leaderList.append( leaderN )
Jon Hall8f89dda2015-01-22 16:03:33 -08002818 consistentLeader = main.FALSE
2819 if len( set( leaderList ) ) == 1:
Jon Hall6aec96b2015-01-19 14:49:31 -08002820 main.log.info( "Each Election-app sees '" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002821 str( leaderList[ 0 ] ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002822 "' as the leader" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002823 consistentLeader = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002824 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002825 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002826 "Inconsistent responses for leader of Election-app:" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002827 for n in range( len( leaderList ) ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07002828 main.log.error( "ONOS" + str( n + 1 ) + " response: " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002829 str( leaderList[ n ] ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002830 leaderResult = leaderResult and consistentLeader
Jon Hall6aec96b2015-01-19 14:49:31 -08002831 utilities.assert_equals(
2832 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002833 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002834 onpass="Leadership election passed",
2835 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002836
Jon Hall58c76b72015-02-23 11:09:24 -08002837 main.step( "Run for election on old leader( just so everyone " +
2838 "is in the hat )" )
Jon Hall63604932015-02-26 17:09:50 -08002839 if oldLeader:
2840 runResult = oldLeader.electionTestRun()
2841 else:
2842 runResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002843 utilities.assert_equals(
2844 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002845 actual=runResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002846 onpass="App re-ran for election",
2847 onfail="App failed to run for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002848
Jon Hallfeff3082015-05-19 10:23:26 -07002849 main.step( "Leader did not change when old leader re-ran" )
Jon Hall390696c2015-05-05 17:13:41 -07002850 afterRun = main.ONOScli1.electionTestLeader()
2851 # verify leader didn't just change
2852 if afterRun == leaderList[ 0 ]:
2853 afterResult = main.TRUE
2854 else:
2855 afterResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002856
Jon Hall6aec96b2015-01-19 14:49:31 -08002857 utilities.assert_equals(
2858 expect=main.TRUE,
Jon Hall390696c2015-05-05 17:13:41 -07002859 actual=afterResult,
2860 onpass="Old leader successfully re-ran for election",
Jon Hall6aec96b2015-01-19 14:49:31 -08002861 onfail="Something went wrong with Leadership election after " +
2862 "the old leader re-ran for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002863
Jon Hall390696c2015-05-05 17:13:41 -07002864 def CASE16( self, main ):
2865 """
2866 Install Distributed Primitives app
2867 """
Jon Hall40d2cbd2015-06-03 16:24:29 -07002868 import time
Jon Hall390696c2015-05-05 17:13:41 -07002869 assert numControllers, "numControllers not defined"
2870 assert main, "main not defined"
2871 assert utilities.assert_equals, "utilities.assert_equals not defined"
2872 assert CLIs, "CLIs not defined"
2873 assert nodes, "nodes not defined"
2874
2875 # Variables for the distributed primitives tests
2876 global pCounterName
2877 global iCounterName
2878 global pCounterValue
2879 global iCounterValue
2880 global onosSet
2881 global onosSetName
2882 pCounterName = "TestON-Partitions"
2883 iCounterName = "TestON-inMemory"
2884 pCounterValue = 0
2885 iCounterValue = 0
2886 onosSet = set([])
2887 onosSetName = "TestON-set"
2888
2889 description = "Install Primitives app"
2890 main.case( description )
2891 main.step( "Install Primitives app" )
2892 appName = "org.onosproject.distributedprimitives"
2893 appResults = CLIs[0].activateApp( appName )
2894 utilities.assert_equals( expect=main.TRUE,
2895 actual=appResults,
2896 onpass="Primitives app activated",
2897 onfail="Primitives app not activated" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002898 time.sleep( 5 ) # To allow all nodes to activate
Jon Hall390696c2015-05-05 17:13:41 -07002899
2900 def CASE17( self, main ):
2901 """
2902 Check for basic functionality with distributed primitives
2903 """
Jon Hallc9eabec2015-06-10 14:33:14 -07002904 import json
Jon Hall390696c2015-05-05 17:13:41 -07002905 # Make sure variables are defined/set
2906 assert numControllers, "numControllers not defined"
2907 assert main, "main not defined"
2908 assert utilities.assert_equals, "utilities.assert_equals not defined"
2909 assert CLIs, "CLIs not defined"
2910 assert nodes, "nodes not defined"
2911 assert pCounterName, "pCounterName not defined"
2912 assert iCounterName, "iCounterName not defined"
2913 assert onosSetName, "onosSetName not defined"
2914 # NOTE: assert fails if value is 0/None/Empty/False
2915 try:
2916 pCounterValue
2917 except NameError:
2918 main.log.error( "pCounterValue not defined, setting to 0" )
2919 pCounterValue = 0
2920 try:
2921 iCounterValue
2922 except NameError:
2923 main.log.error( "iCounterValue not defined, setting to 0" )
2924 iCounterValue = 0
2925 try:
2926 onosSet
2927 except NameError:
2928 main.log.error( "onosSet not defined, setting to empty Set" )
2929 onosSet = set([])
2930 # Variables for the distributed primitives tests. These are local only
2931 addValue = "a"
2932 addAllValue = "a b c d e f"
2933 retainValue = "c d e f"
2934
2935 description = "Check for basic functionality with distributed " +\
2936 "primitives"
2937 main.case( description )
2938 main.caseExplaination = "Test the methods of the distributed primitives (counters and sets) throught the cli"
2939 # DISTRIBUTED ATOMIC COUNTERS
2940 main.step( "Increment and get a default counter on each node" )
2941 pCounters = []
2942 threads = []
Jon Hallfeff3082015-05-19 10:23:26 -07002943 addedPValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002944 for i in range( numControllers ):
2945 t = main.Thread( target=CLIs[i].counterTestIncrement,
2946 name="counterIncrement-" + str( i ),
2947 args=[ pCounterName ] )
2948 pCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002949 addedPValues.append( pCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002950 threads.append( t )
2951 t.start()
2952
2953 for t in threads:
2954 t.join()
2955 pCounters.append( t.result )
2956 # Check that counter incremented numController times
2957 pCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002958 for i in addedPValues:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002959 tmpResult = i in pCounters
Jon Hallfeff3082015-05-19 10:23:26 -07002960 pCounterResults = pCounterResults and tmpResult
2961 if not tmpResult:
2962 main.log.error( str( i ) + " is not in partitioned "
2963 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002964 utilities.assert_equals( expect=True,
2965 actual=pCounterResults,
2966 onpass="Default counter incremented",
2967 onfail="Error incrementing default" +
2968 " counter" )
2969
2970 main.step( "Increment and get an in memory counter on each node" )
2971 iCounters = []
Jon Hallfeff3082015-05-19 10:23:26 -07002972 addedIValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002973 threads = []
2974 for i in range( numControllers ):
2975 t = main.Thread( target=CLIs[i].counterTestIncrement,
2976 name="icounterIncrement-" + str( i ),
2977 args=[ iCounterName ],
2978 kwargs={ "inMemory": True } )
2979 iCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002980 addedIValues.append( iCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002981 threads.append( t )
2982 t.start()
2983
2984 for t in threads:
2985 t.join()
2986 iCounters.append( t.result )
2987 # Check that counter incremented numController times
2988 iCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002989 for i in addedIValues:
2990 tmpResult = i in iCounters
2991 iCounterResults = iCounterResults and tmpResult
2992 if not tmpResult:
2993 main.log.error( str( i ) + " is not in the in-memory "
2994 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002995 utilities.assert_equals( expect=True,
2996 actual=iCounterResults,
2997 onpass="In memory counter incremented",
2998 onfail="Error incrementing in memory" +
2999 " counter" )
3000
3001 main.step( "Check counters are consistant across nodes" )
3002 onosCounters = []
3003 threads = []
3004 for i in range( numControllers ):
3005 t = main.Thread( target=CLIs[i].counters,
3006 name="counters-" + str( i ) )
3007 threads.append( t )
3008 t.start()
3009 for t in threads:
3010 t.join()
3011 onosCounters.append( t.result )
3012 tmp = [ i == onosCounters[ 0 ] for i in onosCounters ]
3013 if all( tmp ):
3014 main.log.info( "Counters are consistent across all nodes" )
3015 consistentCounterResults = main.TRUE
3016 else:
3017 main.log.error( "Counters are not consistent across all nodes" )
3018 consistentCounterResults = main.FALSE
3019 utilities.assert_equals( expect=main.TRUE,
3020 actual=consistentCounterResults,
3021 onpass="ONOS counters are consistent " +
3022 "across nodes",
3023 onfail="ONOS Counters are inconsistent " +
3024 "across nodes" )
3025
3026 main.step( "Counters we added have the correct values" )
3027 correctResults = main.TRUE
3028 for i in range( numControllers ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07003029 current = json.loads( onosCounters[i] )
3030 pValue = None
3031 iValue = None
Jon Hall390696c2015-05-05 17:13:41 -07003032 try:
Jon Hall40d2cbd2015-06-03 16:24:29 -07003033 for database in current:
3034 partitioned = database.get( 'partitionedDatabaseCounters' )
3035 if partitioned:
3036 for value in partitioned:
3037 if value.get( 'name' ) == pCounterName:
3038 pValue = value.get( 'value' )
3039 break
3040 inMemory = database.get( 'inMemoryDatabaseCounters' )
3041 if inMemory:
3042 for value in inMemory:
3043 if value.get( 'name' ) == iCounterName:
3044 iValue = value.get( 'value' )
3045 break
Jon Hall390696c2015-05-05 17:13:41 -07003046 except AttributeError, e:
3047 main.log.error( "ONOS" + str( i + 1 ) + " counters result " +
3048 "is not as expected" )
3049 correctResults = main.FALSE
Jon Hall40d2cbd2015-06-03 16:24:29 -07003050 if pValue == pCounterValue:
3051 main.log.info( "Partitioned counter value is correct" )
3052 else:
3053 main.log.error( "Partitioned counter value is incorrect," +
3054 " expected value: " + str( pCounterValue )
3055 + " current value: " + str( pValue ) )
3056 correctResults = main.FALSE
3057 if iValue == iCounterValue:
3058 main.log.info( "In memory counter value is correct" )
3059 else:
3060 main.log.error( "In memory counter value is incorrect, " +
3061 "expected value: " + str( iCounterValue ) +
3062 " current value: " + str( iValue ) )
3063 correctResults = main.FALSE
Jon Hall390696c2015-05-05 17:13:41 -07003064 utilities.assert_equals( expect=main.TRUE,
3065 actual=correctResults,
3066 onpass="Added counters are correct",
3067 onfail="Added counters are incorrect" )
3068 # DISTRIBUTED SETS
3069 main.step( "Distributed Set get" )
3070 size = len( onosSet )
3071 getResponses = []
3072 threads = []
3073 for i in range( numControllers ):
3074 t = main.Thread( target=CLIs[i].setTestGet,
3075 name="setTestGet-" + str( i ),
3076 args=[ onosSetName ] )
3077 threads.append( t )
3078 t.start()
3079 for t in threads:
3080 t.join()
3081 getResponses.append( t.result )
3082
3083 getResults = main.TRUE
3084 for i in range( numControllers ):
3085 if isinstance( getResponses[ i ], list):
3086 current = set( getResponses[ i ] )
3087 if len( current ) == len( getResponses[ i ] ):
3088 # no repeats
3089 if onosSet != current:
3090 main.log.error( "ONOS" + str( i + 1 ) +
3091 " has incorrect view" +
3092 " of set " + onosSetName + ":\n" +
3093 str( getResponses[ i ] ) )
3094 main.log.debug( "Expected: " + str( onosSet ) )
3095 main.log.debug( "Actual: " + str( current ) )
3096 getResults = main.FALSE
3097 else:
3098 # error, set is not a set
3099 main.log.error( "ONOS" + str( i + 1 ) +
3100 " has repeat elements in" +
3101 " set " + onosSetName + ":\n" +
3102 str( getResponses[ i ] ) )
3103 getResults = main.FALSE
3104 elif getResponses[ i ] == main.ERROR:
3105 getResults = main.FALSE
3106 utilities.assert_equals( expect=main.TRUE,
3107 actual=getResults,
3108 onpass="Set elements are correct",
3109 onfail="Set elements are incorrect" )
3110
3111 main.step( "Distributed Set size" )
3112 sizeResponses = []
3113 threads = []
3114 for i in range( numControllers ):
3115 t = main.Thread( target=CLIs[i].setTestSize,
3116 name="setTestSize-" + str( i ),
3117 args=[ onosSetName ] )
3118 threads.append( t )
3119 t.start()
3120 for t in threads:
3121 t.join()
3122 sizeResponses.append( t.result )
3123
3124 sizeResults = main.TRUE
3125 for i in range( numControllers ):
3126 if size != sizeResponses[ i ]:
3127 sizeResults = main.FALSE
3128 main.log.error( "ONOS" + str( i + 1 ) +
3129 " expected a size of " + str( size ) +
3130 " for set " + onosSetName +
3131 " but got " + str( sizeResponses[ i ] ) )
3132 utilities.assert_equals( expect=main.TRUE,
3133 actual=sizeResults,
3134 onpass="Set sizes are correct",
3135 onfail="Set sizes are incorrect" )
3136
3137 main.step( "Distributed Set add()" )
3138 onosSet.add( addValue )
3139 addResponses = []
3140 threads = []
3141 for i in range( numControllers ):
3142 t = main.Thread( target=CLIs[i].setTestAdd,
3143 name="setTestAdd-" + str( i ),
3144 args=[ onosSetName, addValue ] )
3145 threads.append( t )
3146 t.start()
3147 for t in threads:
3148 t.join()
3149 addResponses.append( t.result )
3150
3151 # main.TRUE = successfully changed the set
3152 # main.FALSE = action resulted in no change in set
3153 # main.ERROR - Some error in executing the function
3154 addResults = main.TRUE
3155 for i in range( numControllers ):
3156 if addResponses[ i ] == main.TRUE:
3157 # All is well
3158 pass
3159 elif addResponses[ i ] == main.FALSE:
3160 # Already in set, probably fine
3161 pass
3162 elif addResponses[ i ] == main.ERROR:
3163 # Error in execution
3164 addResults = main.FALSE
3165 else:
3166 # unexpected result
3167 addResults = main.FALSE
3168 if addResults != main.TRUE:
3169 main.log.error( "Error executing set add" )
3170
3171 # Check if set is still correct
3172 size = len( onosSet )
3173 getResponses = []
3174 threads = []
3175 for i in range( numControllers ):
3176 t = main.Thread( target=CLIs[i].setTestGet,
3177 name="setTestGet-" + str( i ),
3178 args=[ onosSetName ] )
3179 threads.append( t )
3180 t.start()
3181 for t in threads:
3182 t.join()
3183 getResponses.append( t.result )
3184 getResults = main.TRUE
3185 for i in range( numControllers ):
3186 if isinstance( getResponses[ i ], list):
3187 current = set( getResponses[ i ] )
3188 if len( current ) == len( getResponses[ i ] ):
3189 # no repeats
3190 if onosSet != current:
3191 main.log.error( "ONOS" + str( i + 1 ) +
3192 " has incorrect view" +
3193 " of set " + onosSetName + ":\n" +
3194 str( getResponses[ i ] ) )
3195 main.log.debug( "Expected: " + str( onosSet ) )
3196 main.log.debug( "Actual: " + str( current ) )
3197 getResults = main.FALSE
3198 else:
3199 # error, set is not a set
3200 main.log.error( "ONOS" + str( i + 1 ) +
3201 " has repeat elements in" +
3202 " set " + onosSetName + ":\n" +
3203 str( getResponses[ i ] ) )
3204 getResults = main.FALSE
3205 elif getResponses[ i ] == main.ERROR:
3206 getResults = main.FALSE
3207 sizeResponses = []
3208 threads = []
3209 for i in range( numControllers ):
3210 t = main.Thread( target=CLIs[i].setTestSize,
3211 name="setTestSize-" + str( i ),
3212 args=[ onosSetName ] )
3213 threads.append( t )
3214 t.start()
3215 for t in threads:
3216 t.join()
3217 sizeResponses.append( t.result )
3218 sizeResults = main.TRUE
3219 for i in range( numControllers ):
3220 if size != sizeResponses[ i ]:
3221 sizeResults = main.FALSE
3222 main.log.error( "ONOS" + str( i + 1 ) +
3223 " expected a size of " + str( size ) +
3224 " for set " + onosSetName +
3225 " but got " + str( sizeResponses[ i ] ) )
3226 addResults = addResults and getResults and sizeResults
3227 utilities.assert_equals( expect=main.TRUE,
3228 actual=addResults,
3229 onpass="Set add correct",
3230 onfail="Set add was incorrect" )
3231
3232 main.step( "Distributed Set addAll()" )
3233 onosSet.update( addAllValue.split() )
3234 addResponses = []
3235 threads = []
3236 for i in range( numControllers ):
3237 t = main.Thread( target=CLIs[i].setTestAdd,
3238 name="setTestAddAll-" + str( i ),
3239 args=[ onosSetName, addAllValue ] )
3240 threads.append( t )
3241 t.start()
3242 for t in threads:
3243 t.join()
3244 addResponses.append( t.result )
3245
3246 # main.TRUE = successfully changed the set
3247 # main.FALSE = action resulted in no change in set
3248 # main.ERROR - Some error in executing the function
3249 addAllResults = main.TRUE
3250 for i in range( numControllers ):
3251 if addResponses[ i ] == main.TRUE:
3252 # All is well
3253 pass
3254 elif addResponses[ i ] == main.FALSE:
3255 # Already in set, probably fine
3256 pass
3257 elif addResponses[ i ] == main.ERROR:
3258 # Error in execution
3259 addAllResults = main.FALSE
3260 else:
3261 # unexpected result
3262 addAllResults = main.FALSE
3263 if addAllResults != main.TRUE:
3264 main.log.error( "Error executing set addAll" )
3265
3266 # Check if set is still correct
3267 size = len( onosSet )
3268 getResponses = []
3269 threads = []
3270 for i in range( numControllers ):
3271 t = main.Thread( target=CLIs[i].setTestGet,
3272 name="setTestGet-" + str( i ),
3273 args=[ onosSetName ] )
3274 threads.append( t )
3275 t.start()
3276 for t in threads:
3277 t.join()
3278 getResponses.append( t.result )
3279 getResults = main.TRUE
3280 for i in range( numControllers ):
3281 if isinstance( getResponses[ i ], list):
3282 current = set( getResponses[ i ] )
3283 if len( current ) == len( getResponses[ i ] ):
3284 # no repeats
3285 if onosSet != current:
3286 main.log.error( "ONOS" + str( i + 1 ) +
3287 " has incorrect view" +
3288 " of set " + onosSetName + ":\n" +
3289 str( getResponses[ i ] ) )
3290 main.log.debug( "Expected: " + str( onosSet ) )
3291 main.log.debug( "Actual: " + str( current ) )
3292 getResults = main.FALSE
3293 else:
3294 # error, set is not a set
3295 main.log.error( "ONOS" + str( i + 1 ) +
3296 " has repeat elements in" +
3297 " set " + onosSetName + ":\n" +
3298 str( getResponses[ i ] ) )
3299 getResults = main.FALSE
3300 elif getResponses[ i ] == main.ERROR:
3301 getResults = main.FALSE
3302 sizeResponses = []
3303 threads = []
3304 for i in range( numControllers ):
3305 t = main.Thread( target=CLIs[i].setTestSize,
3306 name="setTestSize-" + str( i ),
3307 args=[ onosSetName ] )
3308 threads.append( t )
3309 t.start()
3310 for t in threads:
3311 t.join()
3312 sizeResponses.append( t.result )
3313 sizeResults = main.TRUE
3314 for i in range( numControllers ):
3315 if size != sizeResponses[ i ]:
3316 sizeResults = main.FALSE
3317 main.log.error( "ONOS" + str( i + 1 ) +
3318 " expected a size of " + str( size ) +
3319 " for set " + onosSetName +
3320 " but got " + str( sizeResponses[ i ] ) )
3321 addAllResults = addAllResults and getResults and sizeResults
3322 utilities.assert_equals( expect=main.TRUE,
3323 actual=addAllResults,
3324 onpass="Set addAll correct",
3325 onfail="Set addAll was incorrect" )
3326
3327 main.step( "Distributed Set contains()" )
3328 containsResponses = []
3329 threads = []
3330 for i in range( numControllers ):
3331 t = main.Thread( target=CLIs[i].setTestGet,
3332 name="setContains-" + str( i ),
3333 args=[ onosSetName ],
3334 kwargs={ "values": addValue } )
3335 threads.append( t )
3336 t.start()
3337 for t in threads:
3338 t.join()
3339 # NOTE: This is the tuple
3340 containsResponses.append( t.result )
3341
3342 containsResults = main.TRUE
3343 for i in range( numControllers ):
3344 if containsResponses[ i ] == main.ERROR:
3345 containsResults = main.FALSE
3346 else:
3347 containsResults = containsResults and\
3348 containsResponses[ i ][ 1 ]
3349 utilities.assert_equals( expect=main.TRUE,
3350 actual=containsResults,
3351 onpass="Set contains is functional",
3352 onfail="Set contains failed" )
3353
3354 main.step( "Distributed Set containsAll()" )
3355 containsAllResponses = []
3356 threads = []
3357 for i in range( numControllers ):
3358 t = main.Thread( target=CLIs[i].setTestGet,
3359 name="setContainsAll-" + str( i ),
3360 args=[ onosSetName ],
3361 kwargs={ "values": addAllValue } )
3362 threads.append( t )
3363 t.start()
3364 for t in threads:
3365 t.join()
3366 # NOTE: This is the tuple
3367 containsAllResponses.append( t.result )
3368
3369 containsAllResults = main.TRUE
3370 for i in range( numControllers ):
3371 if containsResponses[ i ] == main.ERROR:
3372 containsResults = main.FALSE
3373 else:
3374 containsResults = containsResults and\
3375 containsResponses[ i ][ 1 ]
3376 utilities.assert_equals( expect=main.TRUE,
3377 actual=containsAllResults,
3378 onpass="Set containsAll is functional",
3379 onfail="Set containsAll failed" )
3380
3381 main.step( "Distributed Set remove()" )
3382 onosSet.remove( addValue )
3383 removeResponses = []
3384 threads = []
3385 for i in range( numControllers ):
3386 t = main.Thread( target=CLIs[i].setTestRemove,
3387 name="setTestRemove-" + str( i ),
3388 args=[ onosSetName, addValue ] )
3389 threads.append( t )
3390 t.start()
3391 for t in threads:
3392 t.join()
3393 removeResponses.append( t.result )
3394
3395 # main.TRUE = successfully changed the set
3396 # main.FALSE = action resulted in no change in set
3397 # main.ERROR - Some error in executing the function
3398 removeResults = main.TRUE
3399 for i in range( numControllers ):
3400 if removeResponses[ i ] == main.TRUE:
3401 # All is well
3402 pass
3403 elif removeResponses[ i ] == main.FALSE:
3404 # not in set, probably fine
3405 pass
3406 elif removeResponses[ i ] == main.ERROR:
3407 # Error in execution
3408 removeResults = main.FALSE
3409 else:
3410 # unexpected result
3411 removeResults = main.FALSE
3412 if removeResults != main.TRUE:
3413 main.log.error( "Error executing set remove" )
3414
3415 # Check if set is still correct
3416 size = len( onosSet )
3417 getResponses = []
3418 threads = []
3419 for i in range( numControllers ):
3420 t = main.Thread( target=CLIs[i].setTestGet,
3421 name="setTestGet-" + str( i ),
3422 args=[ onosSetName ] )
3423 threads.append( t )
3424 t.start()
3425 for t in threads:
3426 t.join()
3427 getResponses.append( t.result )
3428 getResults = main.TRUE
3429 for i in range( numControllers ):
3430 if isinstance( getResponses[ i ], list):
3431 current = set( getResponses[ i ] )
3432 if len( current ) == len( getResponses[ i ] ):
3433 # no repeats
3434 if onosSet != current:
3435 main.log.error( "ONOS" + str( i + 1 ) +
3436 " has incorrect view" +
3437 " of set " + onosSetName + ":\n" +
3438 str( getResponses[ i ] ) )
3439 main.log.debug( "Expected: " + str( onosSet ) )
3440 main.log.debug( "Actual: " + str( current ) )
3441 getResults = main.FALSE
3442 else:
3443 # error, set is not a set
3444 main.log.error( "ONOS" + str( i + 1 ) +
3445 " has repeat elements in" +
3446 " set " + onosSetName + ":\n" +
3447 str( getResponses[ i ] ) )
3448 getResults = main.FALSE
3449 elif getResponses[ i ] == main.ERROR:
3450 getResults = main.FALSE
3451 sizeResponses = []
3452 threads = []
3453 for i in range( numControllers ):
3454 t = main.Thread( target=CLIs[i].setTestSize,
3455 name="setTestSize-" + str( i ),
3456 args=[ onosSetName ] )
3457 threads.append( t )
3458 t.start()
3459 for t in threads:
3460 t.join()
3461 sizeResponses.append( t.result )
3462 sizeResults = main.TRUE
3463 for i in range( numControllers ):
3464 if size != sizeResponses[ i ]:
3465 sizeResults = main.FALSE
3466 main.log.error( "ONOS" + str( i + 1 ) +
3467 " expected a size of " + str( size ) +
3468 " for set " + onosSetName +
3469 " but got " + str( sizeResponses[ i ] ) )
3470 removeResults = removeResults and getResults and sizeResults
3471 utilities.assert_equals( expect=main.TRUE,
3472 actual=removeResults,
3473 onpass="Set remove correct",
3474 onfail="Set remove was incorrect" )
3475
3476 main.step( "Distributed Set removeAll()" )
3477 onosSet.difference_update( addAllValue.split() )
3478 removeAllResponses = []
3479 threads = []
3480 try:
3481 for i in range( numControllers ):
3482 t = main.Thread( target=CLIs[i].setTestRemove,
3483 name="setTestRemoveAll-" + str( i ),
3484 args=[ onosSetName, addAllValue ] )
3485 threads.append( t )
3486 t.start()
3487 for t in threads:
3488 t.join()
3489 removeAllResponses.append( t.result )
3490 except Exception, e:
3491 main.log.exception(e)
3492
3493 # main.TRUE = successfully changed the set
3494 # main.FALSE = action resulted in no change in set
3495 # main.ERROR - Some error in executing the function
3496 removeAllResults = main.TRUE
3497 for i in range( numControllers ):
3498 if removeAllResponses[ i ] == main.TRUE:
3499 # All is well
3500 pass
3501 elif removeAllResponses[ i ] == main.FALSE:
3502 # not in set, probably fine
3503 pass
3504 elif removeAllResponses[ i ] == main.ERROR:
3505 # Error in execution
3506 removeAllResults = main.FALSE
3507 else:
3508 # unexpected result
3509 removeAllResults = main.FALSE
3510 if removeAllResults != main.TRUE:
3511 main.log.error( "Error executing set removeAll" )
3512
3513 # Check if set is still correct
3514 size = len( onosSet )
3515 getResponses = []
3516 threads = []
3517 for i in range( numControllers ):
3518 t = main.Thread( target=CLIs[i].setTestGet,
3519 name="setTestGet-" + str( i ),
3520 args=[ onosSetName ] )
3521 threads.append( t )
3522 t.start()
3523 for t in threads:
3524 t.join()
3525 getResponses.append( t.result )
3526 getResults = main.TRUE
3527 for i in range( numControllers ):
3528 if isinstance( getResponses[ i ], list):
3529 current = set( getResponses[ i ] )
3530 if len( current ) == len( getResponses[ i ] ):
3531 # no repeats
3532 if onosSet != current:
3533 main.log.error( "ONOS" + str( i + 1 ) +
3534 " has incorrect view" +
3535 " of set " + onosSetName + ":\n" +
3536 str( getResponses[ i ] ) )
3537 main.log.debug( "Expected: " + str( onosSet ) )
3538 main.log.debug( "Actual: " + str( current ) )
3539 getResults = main.FALSE
3540 else:
3541 # error, set is not a set
3542 main.log.error( "ONOS" + str( i + 1 ) +
3543 " has repeat elements in" +
3544 " set " + onosSetName + ":\n" +
3545 str( getResponses[ i ] ) )
3546 getResults = main.FALSE
3547 elif getResponses[ i ] == main.ERROR:
3548 getResults = main.FALSE
3549 sizeResponses = []
3550 threads = []
3551 for i in range( numControllers ):
3552 t = main.Thread( target=CLIs[i].setTestSize,
3553 name="setTestSize-" + str( i ),
3554 args=[ onosSetName ] )
3555 threads.append( t )
3556 t.start()
3557 for t in threads:
3558 t.join()
3559 sizeResponses.append( t.result )
3560 sizeResults = main.TRUE
3561 for i in range( numControllers ):
3562 if size != sizeResponses[ i ]:
3563 sizeResults = main.FALSE
3564 main.log.error( "ONOS" + str( i + 1 ) +
3565 " expected a size of " + str( size ) +
3566 " for set " + onosSetName +
3567 " but got " + str( sizeResponses[ i ] ) )
3568 removeAllResults = removeAllResults and getResults and sizeResults
3569 utilities.assert_equals( expect=main.TRUE,
3570 actual=removeAllResults,
3571 onpass="Set removeAll correct",
3572 onfail="Set removeAll was incorrect" )
3573
3574 main.step( "Distributed Set addAll()" )
3575 onosSet.update( addAllValue.split() )
3576 addResponses = []
3577 threads = []
3578 for i in range( numControllers ):
3579 t = main.Thread( target=CLIs[i].setTestAdd,
3580 name="setTestAddAll-" + str( i ),
3581 args=[ onosSetName, addAllValue ] )
3582 threads.append( t )
3583 t.start()
3584 for t in threads:
3585 t.join()
3586 addResponses.append( t.result )
3587
3588 # main.TRUE = successfully changed the set
3589 # main.FALSE = action resulted in no change in set
3590 # main.ERROR - Some error in executing the function
3591 addAllResults = main.TRUE
3592 for i in range( numControllers ):
3593 if addResponses[ i ] == main.TRUE:
3594 # All is well
3595 pass
3596 elif addResponses[ i ] == main.FALSE:
3597 # Already in set, probably fine
3598 pass
3599 elif addResponses[ i ] == main.ERROR:
3600 # Error in execution
3601 addAllResults = main.FALSE
3602 else:
3603 # unexpected result
3604 addAllResults = main.FALSE
3605 if addAllResults != main.TRUE:
3606 main.log.error( "Error executing set addAll" )
3607
3608 # Check if set is still correct
3609 size = len( onosSet )
3610 getResponses = []
3611 threads = []
3612 for i in range( numControllers ):
3613 t = main.Thread( target=CLIs[i].setTestGet,
3614 name="setTestGet-" + str( i ),
3615 args=[ onosSetName ] )
3616 threads.append( t )
3617 t.start()
3618 for t in threads:
3619 t.join()
3620 getResponses.append( t.result )
3621 getResults = main.TRUE
3622 for i in range( numControllers ):
3623 if isinstance( getResponses[ i ], list):
3624 current = set( getResponses[ i ] )
3625 if len( current ) == len( getResponses[ i ] ):
3626 # no repeats
3627 if onosSet != current:
3628 main.log.error( "ONOS" + str( i + 1 ) +
3629 " has incorrect view" +
3630 " of set " + onosSetName + ":\n" +
3631 str( getResponses[ i ] ) )
3632 main.log.debug( "Expected: " + str( onosSet ) )
3633 main.log.debug( "Actual: " + str( current ) )
3634 getResults = main.FALSE
3635 else:
3636 # error, set is not a set
3637 main.log.error( "ONOS" + str( i + 1 ) +
3638 " has repeat elements in" +
3639 " set " + onosSetName + ":\n" +
3640 str( getResponses[ i ] ) )
3641 getResults = main.FALSE
3642 elif getResponses[ i ] == main.ERROR:
3643 getResults = main.FALSE
3644 sizeResponses = []
3645 threads = []
3646 for i in range( numControllers ):
3647 t = main.Thread( target=CLIs[i].setTestSize,
3648 name="setTestSize-" + str( i ),
3649 args=[ onosSetName ] )
3650 threads.append( t )
3651 t.start()
3652 for t in threads:
3653 t.join()
3654 sizeResponses.append( t.result )
3655 sizeResults = main.TRUE
3656 for i in range( numControllers ):
3657 if size != sizeResponses[ i ]:
3658 sizeResults = main.FALSE
3659 main.log.error( "ONOS" + str( i + 1 ) +
3660 " expected a size of " + str( size ) +
3661 " for set " + onosSetName +
3662 " but got " + str( sizeResponses[ i ] ) )
3663 addAllResults = addAllResults and getResults and sizeResults
3664 utilities.assert_equals( expect=main.TRUE,
3665 actual=addAllResults,
3666 onpass="Set addAll correct",
3667 onfail="Set addAll was incorrect" )
3668
3669 main.step( "Distributed Set clear()" )
3670 onosSet.clear()
3671 clearResponses = []
3672 threads = []
3673 for i in range( numControllers ):
3674 t = main.Thread( target=CLIs[i].setTestRemove,
3675 name="setTestClear-" + str( i ),
3676 args=[ onosSetName, " "], # Values doesn't matter
3677 kwargs={ "clear": True } )
3678 threads.append( t )
3679 t.start()
3680 for t in threads:
3681 t.join()
3682 clearResponses.append( t.result )
3683
3684 # main.TRUE = successfully changed the set
3685 # main.FALSE = action resulted in no change in set
3686 # main.ERROR - Some error in executing the function
3687 clearResults = main.TRUE
3688 for i in range( numControllers ):
3689 if clearResponses[ i ] == main.TRUE:
3690 # All is well
3691 pass
3692 elif clearResponses[ i ] == main.FALSE:
3693 # Nothing set, probably fine
3694 pass
3695 elif clearResponses[ i ] == main.ERROR:
3696 # Error in execution
3697 clearResults = main.FALSE
3698 else:
3699 # unexpected result
3700 clearResults = main.FALSE
3701 if clearResults != main.TRUE:
3702 main.log.error( "Error executing set clear" )
3703
3704 # Check if set is still correct
3705 size = len( onosSet )
3706 getResponses = []
3707 threads = []
3708 for i in range( numControllers ):
3709 t = main.Thread( target=CLIs[i].setTestGet,
3710 name="setTestGet-" + str( i ),
3711 args=[ onosSetName ] )
3712 threads.append( t )
3713 t.start()
3714 for t in threads:
3715 t.join()
3716 getResponses.append( t.result )
3717 getResults = main.TRUE
3718 for i in range( numControllers ):
3719 if isinstance( getResponses[ i ], list):
3720 current = set( getResponses[ i ] )
3721 if len( current ) == len( getResponses[ i ] ):
3722 # no repeats
3723 if onosSet != current:
3724 main.log.error( "ONOS" + str( i + 1 ) +
3725 " has incorrect view" +
3726 " of set " + onosSetName + ":\n" +
3727 str( getResponses[ i ] ) )
3728 main.log.debug( "Expected: " + str( onosSet ) )
3729 main.log.debug( "Actual: " + str( current ) )
3730 getResults = main.FALSE
3731 else:
3732 # error, set is not a set
3733 main.log.error( "ONOS" + str( i + 1 ) +
3734 " has repeat elements in" +
3735 " set " + onosSetName + ":\n" +
3736 str( getResponses[ i ] ) )
3737 getResults = main.FALSE
3738 elif getResponses[ i ] == main.ERROR:
3739 getResults = main.FALSE
3740 sizeResponses = []
3741 threads = []
3742 for i in range( numControllers ):
3743 t = main.Thread( target=CLIs[i].setTestSize,
3744 name="setTestSize-" + str( i ),
3745 args=[ onosSetName ] )
3746 threads.append( t )
3747 t.start()
3748 for t in threads:
3749 t.join()
3750 sizeResponses.append( t.result )
3751 sizeResults = main.TRUE
3752 for i in range( numControllers ):
3753 if size != sizeResponses[ i ]:
3754 sizeResults = main.FALSE
3755 main.log.error( "ONOS" + str( i + 1 ) +
3756 " expected a size of " + str( size ) +
3757 " for set " + onosSetName +
3758 " but got " + str( sizeResponses[ i ] ) )
3759 clearResults = clearResults and getResults and sizeResults
3760 utilities.assert_equals( expect=main.TRUE,
3761 actual=clearResults,
3762 onpass="Set clear correct",
3763 onfail="Set clear was incorrect" )
3764
3765 main.step( "Distributed Set addAll()" )
3766 onosSet.update( addAllValue.split() )
3767 addResponses = []
3768 threads = []
3769 for i in range( numControllers ):
3770 t = main.Thread( target=CLIs[i].setTestAdd,
3771 name="setTestAddAll-" + str( i ),
3772 args=[ onosSetName, addAllValue ] )
3773 threads.append( t )
3774 t.start()
3775 for t in threads:
3776 t.join()
3777 addResponses.append( t.result )
3778
3779 # main.TRUE = successfully changed the set
3780 # main.FALSE = action resulted in no change in set
3781 # main.ERROR - Some error in executing the function
3782 addAllResults = main.TRUE
3783 for i in range( numControllers ):
3784 if addResponses[ i ] == main.TRUE:
3785 # All is well
3786 pass
3787 elif addResponses[ i ] == main.FALSE:
3788 # Already in set, probably fine
3789 pass
3790 elif addResponses[ i ] == main.ERROR:
3791 # Error in execution
3792 addAllResults = main.FALSE
3793 else:
3794 # unexpected result
3795 addAllResults = main.FALSE
3796 if addAllResults != main.TRUE:
3797 main.log.error( "Error executing set addAll" )
3798
3799 # Check if set is still correct
3800 size = len( onosSet )
3801 getResponses = []
3802 threads = []
3803 for i in range( numControllers ):
3804 t = main.Thread( target=CLIs[i].setTestGet,
3805 name="setTestGet-" + str( i ),
3806 args=[ onosSetName ] )
3807 threads.append( t )
3808 t.start()
3809 for t in threads:
3810 t.join()
3811 getResponses.append( t.result )
3812 getResults = main.TRUE
3813 for i in range( numControllers ):
3814 if isinstance( getResponses[ i ], list):
3815 current = set( getResponses[ i ] )
3816 if len( current ) == len( getResponses[ i ] ):
3817 # no repeats
3818 if onosSet != current:
3819 main.log.error( "ONOS" + str( i + 1 ) +
3820 " has incorrect view" +
3821 " of set " + onosSetName + ":\n" +
3822 str( getResponses[ i ] ) )
3823 main.log.debug( "Expected: " + str( onosSet ) )
3824 main.log.debug( "Actual: " + str( current ) )
3825 getResults = main.FALSE
3826 else:
3827 # error, set is not a set
3828 main.log.error( "ONOS" + str( i + 1 ) +
3829 " has repeat elements in" +
3830 " set " + onosSetName + ":\n" +
3831 str( getResponses[ i ] ) )
3832 getResults = main.FALSE
3833 elif getResponses[ i ] == main.ERROR:
3834 getResults = main.FALSE
3835 sizeResponses = []
3836 threads = []
3837 for i in range( numControllers ):
3838 t = main.Thread( target=CLIs[i].setTestSize,
3839 name="setTestSize-" + str( i ),
3840 args=[ onosSetName ] )
3841 threads.append( t )
3842 t.start()
3843 for t in threads:
3844 t.join()
3845 sizeResponses.append( t.result )
3846 sizeResults = main.TRUE
3847 for i in range( numControllers ):
3848 if size != sizeResponses[ i ]:
3849 sizeResults = main.FALSE
3850 main.log.error( "ONOS" + str( i + 1 ) +
3851 " expected a size of " + str( size ) +
3852 " for set " + onosSetName +
3853 " but got " + str( sizeResponses[ i ] ) )
3854 addAllResults = addAllResults and getResults and sizeResults
3855 utilities.assert_equals( expect=main.TRUE,
3856 actual=addAllResults,
3857 onpass="Set addAll correct",
3858 onfail="Set addAll was incorrect" )
3859
3860 main.step( "Distributed Set retain()" )
3861 onosSet.intersection_update( retainValue.split() )
3862 retainResponses = []
3863 threads = []
3864 for i in range( numControllers ):
3865 t = main.Thread( target=CLIs[i].setTestRemove,
3866 name="setTestRetain-" + str( i ),
3867 args=[ onosSetName, retainValue ],
3868 kwargs={ "retain": True } )
3869 threads.append( t )
3870 t.start()
3871 for t in threads:
3872 t.join()
3873 retainResponses.append( t.result )
3874
3875 # main.TRUE = successfully changed the set
3876 # main.FALSE = action resulted in no change in set
3877 # main.ERROR - Some error in executing the function
3878 retainResults = main.TRUE
3879 for i in range( numControllers ):
3880 if retainResponses[ i ] == main.TRUE:
3881 # All is well
3882 pass
3883 elif retainResponses[ i ] == main.FALSE:
3884 # Already in set, probably fine
3885 pass
3886 elif retainResponses[ i ] == main.ERROR:
3887 # Error in execution
3888 retainResults = main.FALSE
3889 else:
3890 # unexpected result
3891 retainResults = main.FALSE
3892 if retainResults != main.TRUE:
3893 main.log.error( "Error executing set retain" )
3894
3895 # Check if set is still correct
3896 size = len( onosSet )
3897 getResponses = []
3898 threads = []
3899 for i in range( numControllers ):
3900 t = main.Thread( target=CLIs[i].setTestGet,
3901 name="setTestGet-" + str( i ),
3902 args=[ onosSetName ] )
3903 threads.append( t )
3904 t.start()
3905 for t in threads:
3906 t.join()
3907 getResponses.append( t.result )
3908 getResults = main.TRUE
3909 for i in range( numControllers ):
3910 if isinstance( getResponses[ i ], list):
3911 current = set( getResponses[ i ] )
3912 if len( current ) == len( getResponses[ i ] ):
3913 # no repeats
3914 if onosSet != current:
3915 main.log.error( "ONOS" + str( i + 1 ) +
3916 " has incorrect view" +
3917 " of set " + onosSetName + ":\n" +
3918 str( getResponses[ i ] ) )
3919 main.log.debug( "Expected: " + str( onosSet ) )
3920 main.log.debug( "Actual: " + str( current ) )
3921 getResults = main.FALSE
3922 else:
3923 # error, set is not a set
3924 main.log.error( "ONOS" + str( i + 1 ) +
3925 " has repeat elements in" +
3926 " set " + onosSetName + ":\n" +
3927 str( getResponses[ i ] ) )
3928 getResults = main.FALSE
3929 elif getResponses[ i ] == main.ERROR:
3930 getResults = main.FALSE
3931 sizeResponses = []
3932 threads = []
3933 for i in range( numControllers ):
3934 t = main.Thread( target=CLIs[i].setTestSize,
3935 name="setTestSize-" + str( i ),
3936 args=[ onosSetName ] )
3937 threads.append( t )
3938 t.start()
3939 for t in threads:
3940 t.join()
3941 sizeResponses.append( t.result )
3942 sizeResults = main.TRUE
3943 for i in range( numControllers ):
3944 if size != sizeResponses[ i ]:
3945 sizeResults = main.FALSE
3946 main.log.error( "ONOS" + str( i + 1 ) +
3947 " expected a size of " +
3948 str( size ) + " for set " + onosSetName +
3949 " but got " + str( sizeResponses[ i ] ) )
3950 retainResults = retainResults and getResults and sizeResults
3951 utilities.assert_equals( expect=main.TRUE,
3952 actual=retainResults,
3953 onpass="Set retain correct",
3954 onfail="Set retain was incorrect" )
3955