blob: 5f5222eadf8d027d1c905f90c1444916ecc28b50 [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 Hall5cfd23c2015-03-19 11:40:57 -0700268 # TODO: rewrite this function to take lists of ips and ports?
269 # or list of tuples?
Jon Hall6aec96b2015-01-19 14:49:31 -0800270 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800271 main.Mininet1.assignSwController(
Jon Hall6aec96b2015-01-19 14:49:31 -0800272 sw=str( i ),
Jon Hall8f89dda2015-01-22 16:03:33 -0800273 count=numControllers,
Jon Hall5cfd23c2015-03-19 11:40:57 -0700274 ip1=nodes[ 0 ].ip_address, port1=ONOS1Port,
275 ip2=nodes[ 1 ].ip_address, port2=ONOS2Port,
276 ip3=nodes[ 2 ].ip_address, port3=ONOS3Port,
277 ip4=nodes[ 3 ].ip_address, port4=ONOS4Port,
278 ip5=nodes[ 4 ].ip_address, port5=ONOS5Port,
279 ip6=nodes[ 5 ].ip_address, port6=ONOS6Port,
280 ip7=nodes[ 6 ].ip_address, port7=ONOS7Port )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800281
Jon Hall8f89dda2015-01-22 16:03:33 -0800282 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800283 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800284 response = main.Mininet1.getSwController( "s" + str( i ) )
Jon Hallffb386d2014-11-21 13:43:38 -0800285 try:
Jon Hall6aec96b2015-01-19 14:49:31 -0800286 main.log.info( str( response ) )
Jon Hallfebb1c72015-03-05 13:30:09 -0800287 except Exception:
Jon Hall6aec96b2015-01-19 14:49:31 -0800288 main.log.info( repr( response ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700289 for node in nodes:
290 if re.search( "tcp:" + node.ip_address, response ):
291 mastershipCheck = mastershipCheck and main.TRUE
292 else:
Jon Halla9d26da2015-03-30 16:45:32 -0700293 main.log.error( "Error, node " + node.ip_address + " is " +
294 "not in the list of controllers s" +
295 str( i ) + " is connecting to." )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700296 mastershipCheck = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800297 utilities.assert_equals(
298 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800299 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800300 onpass="Switch mastership assigned correctly",
301 onfail="Switches not assigned correctly to controllers" )
Jon Hall390696c2015-05-05 17:13:41 -0700302
Jon Hallc9eabec2015-06-10 14:33:14 -0700303 def CASE21( self, main ):
304 """
305 Assign mastership to controllers
306 """
307 import re
308 import time
309 assert numControllers, "numControllers not defined"
310 assert main, "main not defined"
311 assert utilities.assert_equals, "utilities.assert_equals not defined"
312 assert CLIs, "CLIs not defined"
313 assert nodes, "nodes not defined"
314 assert ONOS1Port, "ONOS1Port not defined"
315 assert ONOS2Port, "ONOS2Port not defined"
316 assert ONOS3Port, "ONOS3Port not defined"
317 assert ONOS4Port, "ONOS4Port not defined"
318 assert ONOS5Port, "ONOS5Port not defined"
319 assert ONOS6Port, "ONOS6Port not defined"
320 assert ONOS7Port, "ONOS7Port not defined"
321
322 main.case( "Assigning Controller roles for switches" )
323 main.caseExplaination = "Check that ONOS is connected to each " +\
324 "device. Then manually assign" +\
325 " mastership to specific ONOS nodes using" +\
326 " 'device-role'"
Jon Hall390696c2015-05-05 17:13:41 -0700327 main.step( "Assign mastership of switches to specific controllers" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800328 # Manually assign mastership to the controller we want
Jon Hall8f89dda2015-01-22 16:03:33 -0800329 roleCall = main.TRUE
Jon Hall390696c2015-05-05 17:13:41 -0700330
331 ipList = [ ]
332 deviceList = []
Jon Hall58c76b72015-02-23 11:09:24 -0800333 try:
Jon Halla9d26da2015-03-30 16:45:32 -0700334 for i in range( 1, 29 ): # switches 1 through 28
335 # set up correct variables:
336 if i == 1:
337 ip = nodes[ 0 ].ip_address # ONOS1
338 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
339 elif i == 2:
340 ip = nodes[ 1 ].ip_address # ONOS2
341 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
342 elif i == 3:
343 ip = nodes[ 1 ].ip_address # ONOS2
344 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
345 elif i == 4:
346 ip = nodes[ 3 ].ip_address # ONOS4
347 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
348 elif i == 5:
349 ip = nodes[ 2 ].ip_address # ONOS3
350 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
351 elif i == 6:
352 ip = nodes[ 2 ].ip_address # ONOS3
353 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
354 elif i == 7:
355 ip = nodes[ 5 ].ip_address # ONOS6
356 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
357 elif i >= 8 and i <= 17:
358 ip = nodes[ 4 ].ip_address # ONOS5
359 dpid = '3' + str( i ).zfill( 3 )
360 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
361 elif i >= 18 and i <= 27:
362 ip = nodes[ 6 ].ip_address # ONOS7
363 dpid = '6' + str( i ).zfill( 3 )
364 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
365 elif i == 28:
366 ip = nodes[ 0 ].ip_address # ONOS1
367 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
368 else:
369 main.log.error( "You didn't write an else statement for " +
370 "switch s" + str( i ) )
Jon Hallc9eabec2015-06-10 14:33:14 -0700371 roleCall = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -0700372 # Assign switch
373 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
374 # TODO: make this controller dynamic
375 roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
376 ip )
Jon Hall390696c2015-05-05 17:13:41 -0700377 ipList.append( ip )
378 deviceList.append( deviceId )
Jon Hall58c76b72015-02-23 11:09:24 -0800379 except ( AttributeError, AssertionError ):
380 main.log.exception( "Something is wrong with ONOS device view" )
381 main.log.info( main.ONOScli1.devices() )
Jon Hall6aec96b2015-01-19 14:49:31 -0800382 utilities.assert_equals(
383 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800384 actual=roleCall,
Jon Hall6aec96b2015-01-19 14:49:31 -0800385 onpass="Re-assigned switch mastership to designated controller",
Jon Hall8f89dda2015-01-22 16:03:33 -0800386 onfail="Something wrong with deviceRole calls" )
Jon Hall94fd0472014-12-08 11:52:42 -0800387
Jon Hall390696c2015-05-05 17:13:41 -0700388 main.step( "Check mastership was correctly assigned" )
389 roleCheck = main.TRUE
390 # NOTE: This is due to the fact that device mastership change is not
391 # atomic and is actually a multi step process
392 time.sleep( 5 )
393 for i in range( len( ipList ) ):
394 ip = ipList[i]
395 deviceId = deviceList[i]
396 # Check assignment
397 master = main.ONOScli1.getRole( deviceId ).get( 'master' )
398 if ip in master:
399 roleCheck = roleCheck and main.TRUE
400 else:
401 roleCheck = roleCheck and main.FALSE
402 main.log.error( "Error, controller " + ip + " is not" +
403 " master " + "of device " +
404 str( deviceId ) + ". Master is " +
405 repr( master ) + "." )
Jon Hall6aec96b2015-01-19 14:49:31 -0800406 utilities.assert_equals(
407 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800408 actual=roleCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800409 onpass="Switches were successfully reassigned to designated " +
410 "controller",
411 onfail="Switches were not successfully reassigned" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800412
Jon Hall6aec96b2015-01-19 14:49:31 -0800413 def CASE3( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800414 """
415 Assign intents
Jon Hall73cf9cc2014-11-20 22:28:38 -0800416 """
417 import time
Jon Hallfebb1c72015-03-05 13:30:09 -0800418 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700419 assert numControllers, "numControllers not defined"
420 assert main, "main not defined"
421 assert utilities.assert_equals, "utilities.assert_equals not defined"
422 assert CLIs, "CLIs not defined"
423 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -0800424 main.case( "Adding host Intents" )
Jon Hallfeff3082015-05-19 10:23:26 -0700425 main.caseExplaination = "Discover hosts by using pingall then " +\
426 "assign predetermined host-to-host intents." +\
427 " After installation, check that the intent" +\
428 " is distributed to all nodes and the state" +\
429 " is INSTALLED"
Jon Hall73cf9cc2014-11-20 22:28:38 -0800430
Jon Hall6aec96b2015-01-19 14:49:31 -0800431 # install onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700432 main.step( "Install reactive forwarding app" )
433 installResults = CLIs[0].activateApp( "org.onosproject.fwd" )
434 utilities.assert_equals( expect=main.TRUE, actual=installResults,
435 onpass="Install fwd successful",
436 onfail="Install fwd failed" )
Jon Halla9d26da2015-03-30 16:45:32 -0700437
Jon Hallfeff3082015-05-19 10:23:26 -0700438 main.step( "Check app ids" )
Jon Halla9d26da2015-03-30 16:45:32 -0700439 appCheck = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700440 threads = []
441 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700442 t = main.Thread( target=CLIs[i].appToIDCheck,
443 name="appToIDCheck-" + str( i ),
444 args=[] )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700445 threads.append( t )
446 t.start()
447
448 for t in threads:
449 t.join()
Jon Halla9d26da2015-03-30 16:45:32 -0700450 appCheck = appCheck and t.result
Jon Halla9d26da2015-03-30 16:45:32 -0700451 if appCheck != main.TRUE:
452 main.log.warn( CLIs[0].apps() )
453 main.log.warn( CLIs[0].appIDs() )
Jon Hall390696c2015-05-05 17:13:41 -0700454 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
455 onpass="App Ids seem to be correct",
456 onfail="Something is wrong with app Ids" )
Jon Hall94fd0472014-12-08 11:52:42 -0800457
Jon Hallfeff3082015-05-19 10:23:26 -0700458 main.step( "Discovering Hosts( Via pingall for now )" )
459 # FIXME: Once we have a host discovery mechanism, use that instead
Jon Hall6aec96b2015-01-19 14:49:31 -0800460 # REACTIVE FWD test
Jon Hall8f89dda2015-01-22 16:03:33 -0800461 pingResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700462 for i in range(2): # Retry if pingall fails first time
463 time1 = time.time()
464 pingResult = main.Mininet1.pingall()
465 utilities.assert_equals(
466 expect=main.TRUE,
467 actual=pingResult,
468 onpass="Reactive Pingall test passed",
Jon Hall390696c2015-05-05 17:13:41 -0700469 onfail="Reactive Pingall failed, " +
470 "one or more ping pairs failed" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700471 time2 = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700472 main.log.info( "Time for pingall: %2f seconds" %
473 ( time2 - time1 ) )
474 # timeout for fwd flows
475 time.sleep( 11 )
Jon Hall6aec96b2015-01-19 14:49:31 -0800476 # uninstall onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700477 main.step( "Uninstall reactive forwarding app" )
478 uninstallResult = CLIs[0].deactivateApp( "org.onosproject.fwd" )
479 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
480 onpass="Uninstall fwd successful",
481 onfail="Uninstall fwd failed" )
Jon Hallfeff3082015-05-19 10:23:26 -0700482
483 main.step( "Check app ids" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700484 threads = []
Jon Hallfeff3082015-05-19 10:23:26 -0700485 appCheck2 = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700486 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700487 t = main.Thread( target=CLIs[i].appToIDCheck,
488 name="appToIDCheck-" + str( i ),
489 args=[] )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700490 threads.append( t )
491 t.start()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800492
Jon Hall5cfd23c2015-03-19 11:40:57 -0700493 for t in threads:
494 t.join()
Jon Hallfeff3082015-05-19 10:23:26 -0700495 appCheck2 = appCheck2 and t.result
496 if appCheck2 != main.TRUE:
Jon Halla9d26da2015-03-30 16:45:32 -0700497 main.log.warn( CLIs[0].apps() )
498 main.log.warn( CLIs[0].appIDs() )
Jon Hallfeff3082015-05-19 10:23:26 -0700499 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
Jon Hall390696c2015-05-05 17:13:41 -0700500 onpass="App Ids seem to be correct",
501 onfail="Something is wrong with app Ids" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700502
Jon Hallfeff3082015-05-19 10:23:26 -0700503 main.step( "Add host intents via cli" )
Jon Hall58c76b72015-02-23 11:09:24 -0800504 intentIds = []
Jon Hall6aec96b2015-01-19 14:49:31 -0800505 # TODO: move the host numbers to params
Jon Hall58c76b72015-02-23 11:09:24 -0800506 # Maybe look at all the paths we ping?
Jon Hall8f89dda2015-01-22 16:03:33 -0800507 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800508 hostResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800509 for i in range( 8, 18 ):
510 main.log.info( "Adding host intent between h" + str( i ) +
511 " and h" + str( i + 10 ) )
512 host1 = "00:00:00:00:00:" + \
513 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
514 host2 = "00:00:00:00:00:" + \
515 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800516 # NOTE: getHost can return None
517 host1Dict = main.ONOScli1.getHost( host1 )
518 host2Dict = main.ONOScli1.getHost( host2 )
519 host1Id = None
520 host2Id = None
521 if host1Dict and host2Dict:
522 host1Id = host1Dict.get( 'id', None )
523 host2Id = host2Dict.get( 'id', None )
Jon Hall8f89dda2015-01-22 16:03:33 -0800524 if host1Id and host2Id:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700525 nodeNum = ( i % 7 )
526 tmpId = CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
Jon Hall63604932015-02-26 17:09:50 -0800527 if tmpId:
528 main.log.info( "Added intent with id: " + tmpId )
529 intentIds.append( tmpId )
530 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700531 main.log.error( "addHostIntent returned: " +
532 repr( tmpId ) )
Jon Hall669173b2014-12-17 11:36:30 -0800533 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700534 main.log.error( "Error, getHost() failed for h" + str( i ) +
535 " and/or h" + str( i + 10 ) )
536 hosts = CLIs[ 0 ].hosts()
537 main.log.warn( "Hosts output: " )
538 try:
539 main.log.warn( json.dumps( json.loads( hosts ),
540 sort_keys=True,
541 indent=4,
542 separators=( ',', ': ' ) ) )
543 except ( ValueError, TypeError ):
544 main.log.warn( repr( hosts ) )
Jon Hall58c76b72015-02-23 11:09:24 -0800545 hostResult = main.FALSE
Jon Hallfeff3082015-05-19 10:23:26 -0700546 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
547 onpass="Found a host id for each host",
548 onfail="Error looking up host ids" )
549
Jon Halla9d26da2015-03-30 16:45:32 -0700550 intentStart = time.time()
Jon Hall58c76b72015-02-23 11:09:24 -0800551 onosIds = main.ONOScli1.getAllIntentsId()
552 main.log.info( "Submitted intents: " + str( intentIds ) )
553 main.log.info( "Intents in ONOS: " + str( onosIds ) )
554 for intent in intentIds:
555 if intent in onosIds:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700556 pass # intent submitted is in onos
Jon Hall58c76b72015-02-23 11:09:24 -0800557 else:
558 intentAddResult = False
Jon Halla9d26da2015-03-30 16:45:32 -0700559 if intentAddResult:
560 intentStop = time.time()
561 else:
562 intentStop = None
Jon Hall1b8f54a2015-02-04 13:24:20 -0800563 # Print the intent states
Jon Hall58c76b72015-02-23 11:09:24 -0800564 intents = main.ONOScli1.intents()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800565 intentStates = []
Jon Hall5cfd23c2015-03-19 11:40:57 -0700566 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800567 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
568 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700569 try:
570 for intent in json.loads( intents ):
571 state = intent.get( 'state', None )
572 if "INSTALLED" not in state:
573 installedCheck = False
574 intentId = intent.get( 'id', None )
575 intentStates.append( ( intentId, state ) )
576 except ( ValueError, TypeError ):
577 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800578 # add submitted intents not in the store
579 tmplist = [ i for i, s in intentStates ]
580 missingIntents = False
581 for i in intentIds:
582 if i not in tmplist:
583 intentStates.append( ( i, " - " ) )
584 missingIntents = True
585 intentStates.sort()
586 for i, s in intentStates:
587 count += 1
588 main.log.info( "%-6s%-15s%-15s" %
589 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700590 leaders = main.ONOScli1.leaders()
591 try:
Jon Hallc9eabec2015-06-10 14:33:14 -0700592 missing = False
Jon Hall5cfd23c2015-03-19 11:40:57 -0700593 if leaders:
594 parsedLeaders = json.loads( leaders )
595 main.log.warn( json.dumps( parsedLeaders,
596 sort_keys=True,
597 indent=4,
598 separators=( ',', ': ' ) ) )
599 # check for all intent partitions
Jon Hall5cfd23c2015-03-19 11:40:57 -0700600 topics = []
601 for i in range( 14 ):
602 topics.append( "intent-partition-" + str( i ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700603 main.log.debug( topics )
604 ONOStopics = [ j['topic'] for j in parsedLeaders ]
605 for topic in topics:
606 if topic not in ONOStopics:
607 main.log.error( "Error: " + topic +
608 " not in leaders" )
Jon Hallc9eabec2015-06-10 14:33:14 -0700609 missing = True
Jon Hall5cfd23c2015-03-19 11:40:57 -0700610 else:
611 main.log.error( "leaders() returned None" )
612 except ( ValueError, TypeError ):
613 main.log.exception( "Error parsing leaders" )
614 main.log.error( repr( leaders ) )
Jon Hallc9eabec2015-06-10 14:33:14 -0700615 # Check all nodes
616 if missing:
617 for node in CLIs:
618 response = node.leaders( jsonFormat=False)
619 main.log.warn( str( node.name ) + " leaders output: \n" +
620 str( response ) )
621
Jon Hall5cfd23c2015-03-19 11:40:57 -0700622 partitions = main.ONOScli1.partitions()
623 try:
624 if partitions :
625 parsedPartitions = json.loads( partitions )
626 main.log.warn( json.dumps( parsedPartitions,
627 sort_keys=True,
628 indent=4,
629 separators=( ',', ': ' ) ) )
630 # TODO check for a leader in all paritions
631 # TODO check for consistency among nodes
632 else:
633 main.log.error( "partitions() returned None" )
634 except ( ValueError, TypeError ):
635 main.log.exception( "Error parsing partitions" )
636 main.log.error( repr( partitions ) )
Jon Hall63604932015-02-26 17:09:50 -0800637 pendingMap = main.ONOScli1.pendingMap()
Jon Hall5cfd23c2015-03-19 11:40:57 -0700638 try:
639 if pendingMap :
640 parsedPending = json.loads( pendingMap )
641 main.log.warn( json.dumps( parsedPending,
642 sort_keys=True,
643 indent=4,
644 separators=( ',', ': ' ) ) )
645 # TODO check something here?
646 else:
647 main.log.error( "pendingMap() returned None" )
648 except ( ValueError, TypeError ):
649 main.log.exception( "Error parsing pending map" )
650 main.log.error( repr( pendingMap ) )
651
Jon Hallfeff3082015-05-19 10:23:26 -0700652 intentAddResult = bool( intentAddResult and not missingIntents and
653 installedCheck )
654 if not intentAddResult:
655 main.log.error( "Error in pushing host intents to ONOS" )
656
Jon Hall390696c2015-05-05 17:13:41 -0700657 main.step( "Intent Anti-Entropy dispersion" )
Jon Halla9d26da2015-03-30 16:45:32 -0700658 for i in range(100):
Jon Hall390696c2015-05-05 17:13:41 -0700659 correct = True
Jon Halla9d26da2015-03-30 16:45:32 -0700660 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Hall390696c2015-05-05 17:13:41 -0700661 for cli in CLIs:
662 onosIds = []
663 ids = cli.getAllIntentsId()
664 onosIds.append( ids )
665 main.log.debug( "Intents in " + cli.name + ": " +
666 str( sorted( onosIds ) ) )
667 if sorted( ids ) != sorted( intentIds ):
Jon Hallb6a54872015-06-12 14:02:42 -0700668 main.log.warn( "Set of intent IDs doesn't match" )
Jon Hall390696c2015-05-05 17:13:41 -0700669 correct = False
Jon Hall40d2cbd2015-06-03 16:24:29 -0700670 break
671 else:
672 intents = json.loads( cli.intents() )
673 for intent in intents:
674 if intent[ 'state' ] != "INSTALLED":
Jon Hallc9eabec2015-06-10 14:33:14 -0700675 main.log.warn( "Intent " + intent[ 'id' ] +
676 " is " + intent[ 'state' ] )
Jon Hall40d2cbd2015-06-03 16:24:29 -0700677 correct = False
678 break
Jon Hall390696c2015-05-05 17:13:41 -0700679 if correct:
Jon Halla9d26da2015-03-30 16:45:32 -0700680 break
681 else:
682 time.sleep(1)
Jon Halla9d26da2015-03-30 16:45:32 -0700683 if not intentStop:
684 intentStop = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700685 global gossipTime
Jon Halla9d26da2015-03-30 16:45:32 -0700686 gossipTime = intentStop - intentStart
687 main.log.info( "It took about " + str( gossipTime ) +
Jon Hall390696c2015-05-05 17:13:41 -0700688 " seconds for all intents to appear in each node" )
Jon Halla9d26da2015-03-30 16:45:32 -0700689 # FIXME: make this time configurable/calculate based off of number of
690 # nodes and gossip rounds
691 utilities.assert_greater_equals(
Jon Hall390696c2015-05-05 17:13:41 -0700692 expect=40, actual=gossipTime,
Jon Halla9d26da2015-03-30 16:45:32 -0700693 onpass="ECM anti-entropy for intents worked within " +
694 "expected time",
695 onfail="Intent ECM anti-entropy took too long" )
Jon Hall390696c2015-05-05 17:13:41 -0700696 if gossipTime <= 40:
Jon Hall678f4512015-03-31 09:48:31 -0700697 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800698
Jon Hall63604932015-02-26 17:09:50 -0800699 if not intentAddResult or "key" in pendingMap:
Jon Hall58c76b72015-02-23 11:09:24 -0800700 import time
Jon Hall63604932015-02-26 17:09:50 -0800701 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800702 main.log.info( "Sleeping 60 seconds to see if intents are found" )
703 time.sleep( 60 )
704 onosIds = main.ONOScli1.getAllIntentsId()
705 main.log.info( "Submitted intents: " + str( intentIds ) )
706 main.log.info( "Intents in ONOS: " + str( onosIds ) )
707 # Print the intent states
708 intents = main.ONOScli1.intents()
709 intentStates = []
710 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
711 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700712 try:
713 for intent in json.loads( intents ):
714 # Iter through intents of a node
715 state = intent.get( 'state', None )
716 if "INSTALLED" not in state:
717 installedCheck = False
718 intentId = intent.get( 'id', None )
719 intentStates.append( ( intentId, state ) )
720 except ( ValueError, TypeError ):
721 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800722 # add submitted intents not in the store
723 tmplist = [ i for i, s in intentStates ]
724 for i in intentIds:
725 if i not in tmplist:
726 intentStates.append( ( i, " - " ) )
727 intentStates.sort()
728 for i, s in intentStates:
729 count += 1
730 main.log.info( "%-6s%-15s%-15s" %
731 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700732 leaders = main.ONOScli1.leaders()
733 try:
Jon Hallc9eabec2015-06-10 14:33:14 -0700734 missing = False
Jon Hall5cfd23c2015-03-19 11:40:57 -0700735 if leaders:
736 parsedLeaders = json.loads( leaders )
737 main.log.warn( json.dumps( parsedLeaders,
738 sort_keys=True,
739 indent=4,
740 separators=( ',', ': ' ) ) )
741 # check for all intent partitions
742 # check for election
743 topics = []
744 for i in range( 14 ):
745 topics.append( "intent-partition-" + str( i ) )
746 # FIXME: this should only be after we start the app
747 topics.append( "org.onosproject.election" )
748 main.log.debug( topics )
749 ONOStopics = [ j['topic'] for j in parsedLeaders ]
750 for topic in topics:
751 if topic not in ONOStopics:
752 main.log.error( "Error: " + topic +
753 " not in leaders" )
Jon Hallc9eabec2015-06-10 14:33:14 -0700754 missing = True
Jon Hall5cfd23c2015-03-19 11:40:57 -0700755 else:
756 main.log.error( "leaders() returned None" )
757 except ( ValueError, TypeError ):
758 main.log.exception( "Error parsing leaders" )
759 main.log.error( repr( leaders ) )
Jon Hallc9eabec2015-06-10 14:33:14 -0700760 # Check all nodes
761 if missing:
762 for node in CLIs:
763 response = node.leaders( jsonFormat=False)
764 main.log.warn( str( node.name ) + " leaders output: \n" +
765 str( response ) )
766
Jon Hall5cfd23c2015-03-19 11:40:57 -0700767 partitions = main.ONOScli1.partitions()
768 try:
769 if partitions :
770 parsedPartitions = json.loads( partitions )
771 main.log.warn( json.dumps( parsedPartitions,
772 sort_keys=True,
773 indent=4,
774 separators=( ',', ': ' ) ) )
775 # TODO check for a leader in all paritions
776 # TODO check for consistency among nodes
777 else:
778 main.log.error( "partitions() returned None" )
779 except ( ValueError, TypeError ):
780 main.log.exception( "Error parsing partitions" )
781 main.log.error( repr( partitions ) )
782 pendingMap = main.ONOScli1.pendingMap()
783 try:
784 if pendingMap :
785 parsedPending = json.loads( pendingMap )
786 main.log.warn( json.dumps( parsedPending,
787 sort_keys=True,
788 indent=4,
789 separators=( ',', ': ' ) ) )
790 # TODO check something here?
791 else:
792 main.log.error( "pendingMap() returned None" )
793 except ( ValueError, TypeError ):
794 main.log.exception( "Error parsing pending map" )
795 main.log.error( repr( pendingMap ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800796
Jon Hall6aec96b2015-01-19 14:49:31 -0800797 def CASE4( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800798 """
799 Ping across added host intents
800 """
Jon Hallfebb1c72015-03-05 13:30:09 -0800801 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700802 import time
803 assert numControllers, "numControllers not defined"
804 assert main, "main not defined"
805 assert utilities.assert_equals, "utilities.assert_equals not defined"
806 assert CLIs, "CLIs not defined"
807 assert nodes, "nodes not defined"
Jon Hallfeff3082015-05-19 10:23:26 -0700808 main.case( "Verify connectivity by sendind traffic across Intents" )
809 main.caseExplaination = "Ping across added host intents to check " +\
810 "functionality and check the state of " +\
811 "the intent"
812 main.step( "Ping across added host intents" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800813 PingResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800814 for i in range( 8, 18 ):
Jon Hall21270ac2015-02-16 17:59:55 -0800815 ping = main.Mininet1.pingHost( src="h" + str( i ),
816 target="h" + str( i + 10 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800817 PingResult = PingResult and ping
Jon Hall6aec96b2015-01-19 14:49:31 -0800818 if ping == main.FALSE:
819 main.log.warn( "Ping failed between h" + str( i ) +
820 " and h" + str( i + 10 ) )
821 elif ping == main.TRUE:
822 main.log.info( "Ping test passed!" )
Jon Hall21270ac2015-02-16 17:59:55 -0800823 # Don't set PingResult or you'd override failures
Jon Hall8f89dda2015-01-22 16:03:33 -0800824 if PingResult == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -0700825 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -0800826 "Intents have not been installed correctly, pings failed." )
Jon Hall58c76b72015-02-23 11:09:24 -0800827 # TODO: pretty print
Jon Hall5cfd23c2015-03-19 11:40:57 -0700828 main.log.warn( "ONOS1 intents: " )
829 try:
830 tmpIntents = main.ONOScli1.intents()
831 main.log.warn( json.dumps( json.loads( tmpIntents ),
832 sort_keys=True,
833 indent=4,
834 separators=( ',', ': ' ) ) )
835 except ( ValueError, TypeError ):
836 main.log.warn( repr( tmpIntents ) )
Jon Hall6aec96b2015-01-19 14:49:31 -0800837 utilities.assert_equals(
838 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800839 actual=PingResult,
Jon Hall6aec96b2015-01-19 14:49:31 -0800840 onpass="Intents have been installed correctly and pings work",
841 onfail="Intents have not been installed correctly, pings failed." )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800842
Jon Hallfeff3082015-05-19 10:23:26 -0700843 main.step( "Check Intent state" )
Jon Hall40d2cbd2015-06-03 16:24:29 -0700844 installedCheck = False
Jon Hallc9eabec2015-06-10 14:33:14 -0700845 loopCount = 0
846 while not installedCheck and loopCount < 40:
Jon Hall40d2cbd2015-06-03 16:24:29 -0700847 installedCheck = True
848 # Print the intent states
849 intents = main.ONOScli1.intents()
850 intentStates = []
851 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
852 count = 0
853 # Iter through intents of a node
854 try:
855 for intent in json.loads( intents ):
856 state = intent.get( 'state', None )
857 if "INSTALLED" not in state:
858 installedCheck = False
859 intentId = intent.get( 'id', None )
860 intentStates.append( ( intentId, state ) )
861 except ( ValueError, TypeError ):
862 main.log.exception( "Error parsing intents." )
863 # Print states
864 intentStates.sort()
865 for i, s in intentStates:
866 count += 1
867 main.log.info( "%-6s%-15s%-15s" %
868 ( str( count ), str( i ), str( s ) ) )
869 if not installedCheck:
870 time.sleep( 1 )
Jon Hallc9eabec2015-06-10 14:33:14 -0700871 loopCount += 1
Jon Hallfeff3082015-05-19 10:23:26 -0700872 utilities.assert_equals( expect=True, actual=installedCheck,
873 onpass="Intents are all INSTALLED",
Jon Hall40d2cbd2015-06-03 16:24:29 -0700874 onfail="Intents are not all in " +
Jon Hallfeff3082015-05-19 10:23:26 -0700875 "INSTALLED state" )
876
877 main.step( "Check leadership of topics" )
878 leaders = main.ONOScli1.leaders()
879 topicCheck = main.TRUE
880 try:
881 if leaders:
882 parsedLeaders = json.loads( leaders )
883 main.log.warn( json.dumps( parsedLeaders,
884 sort_keys=True,
885 indent=4,
886 separators=( ',', ': ' ) ) )
887 # check for all intent partitions
888 # check for election
889 # TODO: Look at Devices as topics now that it uses this system
890 topics = []
891 for i in range( 14 ):
892 topics.append( "intent-partition-" + str( i ) )
893 # FIXME: this should only be after we start the app
894 # FIXME: topics.append( "org.onosproject.election" )
895 # Print leaders output
896 main.log.debug( topics )
897 ONOStopics = [ j['topic'] for j in parsedLeaders ]
898 for topic in topics:
899 if topic not in ONOStopics:
900 main.log.error( "Error: " + topic +
901 " not in leaders" )
902 topicCheck = main.FALSE
903 else:
904 main.log.error( "leaders() returned None" )
905 topicCheck = main.FALSE
906 except ( ValueError, TypeError ):
907 topicCheck = main.FALSE
908 main.log.exception( "Error parsing leaders" )
909 main.log.error( repr( leaders ) )
910 # TODO: Check for a leader of these topics
Jon Hallc9eabec2015-06-10 14:33:14 -0700911 # Check all nodes
912 if topicCheck:
913 for node in CLIs:
914 response = node.leaders( jsonFormat=False)
915 main.log.warn( str( node.name ) + " leaders output: \n" +
916 str( response ) )
917
Jon Hallfeff3082015-05-19 10:23:26 -0700918 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
919 onpass="intent Partitions is in leaders",
920 onfail="Some topics were lost " )
921 # Print partitions
922 partitions = main.ONOScli1.partitions()
923 try:
924 if partitions :
925 parsedPartitions = json.loads( partitions )
926 main.log.warn( json.dumps( parsedPartitions,
927 sort_keys=True,
928 indent=4,
929 separators=( ',', ': ' ) ) )
930 # TODO check for a leader in all paritions
931 # TODO check for consistency among nodes
932 else:
933 main.log.error( "partitions() returned None" )
934 except ( ValueError, TypeError ):
935 main.log.exception( "Error parsing partitions" )
936 main.log.error( repr( partitions ) )
937 # Print Pending Map
938 pendingMap = main.ONOScli1.pendingMap()
939 try:
940 if pendingMap :
941 parsedPending = json.loads( pendingMap )
942 main.log.warn( json.dumps( parsedPending,
943 sort_keys=True,
944 indent=4,
945 separators=( ',', ': ' ) ) )
946 # TODO check something here?
947 else:
948 main.log.error( "pendingMap() returned None" )
949 except ( ValueError, TypeError ):
950 main.log.exception( "Error parsing pending map" )
951 main.log.error( repr( pendingMap ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700952
Jon Hall63604932015-02-26 17:09:50 -0800953 if not installedCheck:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700954 main.log.info( "Waiting 60 seconds to see if the state of " +
955 "intents change" )
Jon Hall63604932015-02-26 17:09:50 -0800956 time.sleep( 60 )
957 # Print the intent states
958 intents = main.ONOScli1.intents()
959 intentStates = []
960 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
961 count = 0
962 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700963 try:
964 for intent in json.loads( intents ):
965 state = intent.get( 'state', None )
966 if "INSTALLED" not in state:
967 installedCheck = False
968 intentId = intent.get( 'id', None )
969 intentStates.append( ( intentId, state ) )
970 except ( ValueError, TypeError ):
971 main.log.exception( "Error parsing intents." )
Jon Hall63604932015-02-26 17:09:50 -0800972 intentStates.sort()
973 for i, s in intentStates:
974 count += 1
975 main.log.info( "%-6s%-15s%-15s" %
976 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700977 leaders = main.ONOScli1.leaders()
978 try:
Jon Hallc9eabec2015-06-10 14:33:14 -0700979 missing = False
Jon Hall5cfd23c2015-03-19 11:40:57 -0700980 if leaders:
981 parsedLeaders = json.loads( leaders )
982 main.log.warn( json.dumps( parsedLeaders,
983 sort_keys=True,
984 indent=4,
985 separators=( ',', ': ' ) ) )
986 # check for all intent partitions
987 # check for election
988 topics = []
989 for i in range( 14 ):
990 topics.append( "intent-partition-" + str( i ) )
991 # FIXME: this should only be after we start the app
992 topics.append( "org.onosproject.election" )
993 main.log.debug( topics )
994 ONOStopics = [ j['topic'] for j in parsedLeaders ]
995 for topic in topics:
996 if topic not in ONOStopics:
997 main.log.error( "Error: " + topic +
998 " not in leaders" )
Jon Hallc9eabec2015-06-10 14:33:14 -0700999 missing = True
Jon Hall5cfd23c2015-03-19 11:40:57 -07001000 else:
1001 main.log.error( "leaders() returned None" )
1002 except ( ValueError, TypeError ):
1003 main.log.exception( "Error parsing leaders" )
1004 main.log.error( repr( leaders ) )
Jon Hallc9eabec2015-06-10 14:33:14 -07001005 if missing:
1006 for node in CLIs:
1007 response = node.leaders( jsonFormat=False)
1008 main.log.warn( str( node.name ) + " leaders output: \n" +
1009 str( response ) )
1010
Jon Hall5cfd23c2015-03-19 11:40:57 -07001011 partitions = main.ONOScli1.partitions()
1012 try:
1013 if partitions :
1014 parsedPartitions = json.loads( partitions )
1015 main.log.warn( json.dumps( parsedPartitions,
1016 sort_keys=True,
1017 indent=4,
1018 separators=( ',', ': ' ) ) )
1019 # TODO check for a leader in all paritions
1020 # TODO check for consistency among nodes
1021 else:
1022 main.log.error( "partitions() returned None" )
1023 except ( ValueError, TypeError ):
1024 main.log.exception( "Error parsing partitions" )
1025 main.log.error( repr( partitions ) )
1026 pendingMap = main.ONOScli1.pendingMap()
1027 try:
1028 if pendingMap :
1029 parsedPending = json.loads( pendingMap )
1030 main.log.warn( json.dumps( parsedPending,
1031 sort_keys=True,
1032 indent=4,
1033 separators=( ',', ': ' ) ) )
1034 # TODO check something here?
1035 else:
1036 main.log.error( "pendingMap() returned None" )
1037 except ( ValueError, TypeError ):
1038 main.log.exception( "Error parsing pending map" )
1039 main.log.error( repr( pendingMap ) )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001040 # Print flowrules
1041 main.log.debug( CLIs[0].flows( jsonFormat=False ) )
Jon Hallfeff3082015-05-19 10:23:26 -07001042 main.step( "Wait a minute then ping again" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001043 # the wait is above
Jon Hallfeff3082015-05-19 10:23:26 -07001044 PingResult = main.TRUE
1045 for i in range( 8, 18 ):
1046 ping = main.Mininet1.pingHost( src="h" + str( i ),
1047 target="h" + str( i + 10 ) )
1048 PingResult = PingResult and ping
1049 if ping == main.FALSE:
1050 main.log.warn( "Ping failed between h" + str( i ) +
1051 " and h" + str( i + 10 ) )
1052 elif ping == main.TRUE:
1053 main.log.info( "Ping test passed!" )
1054 # Don't set PingResult or you'd override failures
1055 if PingResult == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001056 main.log.error(
Jon Hallfeff3082015-05-19 10:23:26 -07001057 "Intents have not been installed correctly, pings failed." )
1058 # TODO: pretty print
1059 main.log.warn( "ONOS1 intents: " )
1060 try:
1061 tmpIntents = main.ONOScli1.intents()
1062 main.log.warn( json.dumps( json.loads( tmpIntents ),
1063 sort_keys=True,
1064 indent=4,
1065 separators=( ',', ': ' ) ) )
1066 except ( ValueError, TypeError ):
1067 main.log.warn( repr( tmpIntents ) )
1068 utilities.assert_equals(
1069 expect=main.TRUE,
1070 actual=PingResult,
1071 onpass="Intents have been installed correctly and pings work",
1072 onfail="Intents have not been installed correctly, pings failed." )
1073
Jon Hall6aec96b2015-01-19 14:49:31 -08001074 def CASE5( self, main ):
1075 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001076 Reading state of ONOS
Jon Hall6aec96b2015-01-19 14:49:31 -08001077 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001078 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001079 import time
1080 assert numControllers, "numControllers not defined"
1081 assert main, "main not defined"
1082 assert utilities.assert_equals, "utilities.assert_equals not defined"
1083 assert CLIs, "CLIs not defined"
1084 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001085 # assumes that sts is already in you PYTHONPATH
1086 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -08001087
Jon Hall6aec96b2015-01-19 14:49:31 -08001088 main.case( "Setting up and gathering data for current state" )
1089 # The general idea for this test case is to pull the state of
1090 # ( intents,flows, topology,... ) from each ONOS node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001091 # We can then compare them with each other and also with past states
Jon Hall73cf9cc2014-11-20 22:28:38 -08001092
Jon Hall5cfd23c2015-03-19 11:40:57 -07001093 main.step( "Check that each switch has a master" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001094 global mastershipState
Jon Hall5cfd23c2015-03-19 11:40:57 -07001095 mastershipState = '[]'
Jon Hall94fd0472014-12-08 11:52:42 -08001096
Jon Hall6aec96b2015-01-19 14:49:31 -08001097 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -07001098 rolesNotNull = main.TRUE
1099 threads = []
1100 for i in range( numControllers ):
1101 t = main.Thread( target=CLIs[i].rolesNotNull,
1102 name="rolesNotNull-" + str( i ),
1103 args=[] )
1104 threads.append( t )
1105 t.start()
1106
1107 for t in threads:
1108 t.join()
1109 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001110 utilities.assert_equals(
1111 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001112 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001113 onpass="Each device has a master",
1114 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001115
Jon Hall5cfd23c2015-03-19 11:40:57 -07001116 main.step( "Get the Mastership of each switch from each controller" )
1117 ONOSMastership = []
1118 mastershipCheck = main.FALSE
1119 consistentMastership = True
1120 rolesResults = True
1121 threads = []
1122 for i in range( numControllers ):
1123 t = main.Thread( target=CLIs[i].roles,
1124 name="roles-" + str( i ),
1125 args=[] )
1126 threads.append( t )
1127 t.start()
1128
1129 for t in threads:
1130 t.join()
1131 ONOSMastership.append( t.result )
1132
1133 for i in range( numControllers ):
1134 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001135 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001136 " roles" )
1137 main.log.warn(
1138 "ONOS" + str( i + 1 ) + " mastership response: " +
1139 repr( ONOSMastership[i] ) )
1140 rolesResults = False
1141 utilities.assert_equals(
1142 expect=True,
1143 actual=rolesResults,
1144 onpass="No error in reading roles output",
1145 onfail="Error in reading roles from ONOS" )
1146
1147 main.step( "Check for consistency in roles from each controller" )
1148 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001149 main.log.info(
Jon Hall6aec96b2015-01-19 14:49:31 -08001150 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001151 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001152 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001153 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001154 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001155 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001156 onpass="Switch roles are consistent across all ONOS nodes",
1157 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001158
Jon Hall5cfd23c2015-03-19 11:40:57 -07001159 if rolesResults and not consistentMastership:
1160 for i in range( numControllers ):
1161 try:
1162 main.log.warn(
1163 "ONOS" + str( i + 1 ) + " roles: ",
1164 json.dumps(
1165 json.loads( ONOSMastership[ i ] ),
1166 sort_keys=True,
1167 indent=4,
1168 separators=( ',', ': ' ) ) )
1169 except ( ValueError, TypeError ):
1170 main.log.warn( repr( ONOSMastership[ i ] ) )
1171 elif rolesResults and consistentMastership:
1172 mastershipCheck = main.TRUE
1173 mastershipState = ONOSMastership[ 0 ]
1174
Jon Hall6aec96b2015-01-19 14:49:31 -08001175 main.step( "Get the intents from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001176 global intentState
1177 intentState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001178 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001179 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001180 consistentIntents = True
1181 intentsResults = True
1182 threads = []
1183 for i in range( numControllers ):
1184 t = main.Thread( target=CLIs[i].intents,
1185 name="intents-" + str( i ),
1186 args=[],
1187 kwargs={ 'jsonFormat': True } )
1188 threads.append( t )
1189 t.start()
1190
1191 for t in threads:
1192 t.join()
1193 ONOSIntents.append( t.result )
1194
1195 for i in range( numControllers ):
1196 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001197 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001198 " intents" )
1199 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1200 repr( ONOSIntents[ i ] ) )
1201 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001202 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001203 expect=True,
1204 actual=intentsResults,
1205 onpass="No error in reading intents output",
1206 onfail="Error in reading intents from ONOS" )
1207
1208 main.step( "Check for consistency in Intents from each controller" )
1209 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001210 main.log.info( "Intents are consistent across all ONOS " +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001211 "nodes" )
1212 else:
1213 consistentIntents = False
Jon Hall40d2cbd2015-06-03 16:24:29 -07001214 main.log.error( "Intents not consistent" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001215 utilities.assert_equals(
1216 expect=True,
1217 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001218 onpass="Intents are consistent across all ONOS nodes",
1219 onfail="ONOS nodes have different views of intents" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001220
Jon Hall390696c2015-05-05 17:13:41 -07001221 if intentsResults:
1222 # Try to make it easy to figure out what is happening
1223 #
1224 # Intent ONOS1 ONOS2 ...
1225 # 0x01 INSTALLED INSTALLING
1226 # ... ... ...
1227 # ... ... ...
1228 title = " Id"
1229 for n in range( numControllers ):
1230 title += " " * 10 + "ONOS" + str( n + 1 )
1231 main.log.warn( title )
1232 # get all intent keys in the cluster
1233 keys = []
1234 for nodeStr in ONOSIntents:
1235 node = json.loads( nodeStr )
1236 for intent in node:
1237 keys.append( intent.get( 'id' ) )
1238 keys = set( keys )
1239 for key in keys:
1240 row = "%-13s" % key
1241 for nodeStr in ONOSIntents:
1242 node = json.loads( nodeStr )
1243 for intent in node:
1244 if intent.get( 'id', "Error" ) == key:
1245 row += "%-15s" % intent.get( 'state' )
1246 main.log.warn( row )
1247 # End table view
1248
Jon Hall5cfd23c2015-03-19 11:40:57 -07001249 if intentsResults and not consistentIntents:
Jon Hall390696c2015-05-05 17:13:41 -07001250 # print the json objects
Jon Hall5cfd23c2015-03-19 11:40:57 -07001251 n = len(ONOSIntents)
Jon Hall390696c2015-05-05 17:13:41 -07001252 main.log.debug( "ONOS" + str( n ) + " intents: " )
1253 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1254 sort_keys=True,
1255 indent=4,
1256 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001257 for i in range( numControllers ):
1258 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
Jon Hall390696c2015-05-05 17:13:41 -07001259 main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
1260 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1261 sort_keys=True,
1262 indent=4,
1263 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001264 else:
Jon Hall390696c2015-05-05 17:13:41 -07001265 main.log.debug( nodes[ i ].name + " intents match ONOS" +
1266 str( n ) + " intents" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001267 elif intentsResults and consistentIntents:
1268 intentCheck = main.TRUE
1269 intentState = ONOSIntents[ 0 ]
1270
Jon Hall6aec96b2015-01-19 14:49:31 -08001271 main.step( "Get the flows from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001272 global flowState
1273 flowState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001274 ONOSFlows = []
1275 ONOSFlowsJson = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001276 flowCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001277 consistentFlows = True
1278 flowsResults = True
1279 threads = []
1280 for i in range( numControllers ):
1281 t = main.Thread( target=CLIs[i].flows,
1282 name="flows-" + str( i ),
1283 args=[],
1284 kwargs={ 'jsonFormat': True } )
1285 threads.append( t )
1286 t.start()
1287
Jon Halla9d26da2015-03-30 16:45:32 -07001288 # NOTE: Flows command can take some time to run
Jon Hall5cfd23c2015-03-19 11:40:57 -07001289 time.sleep(30)
1290 for t in threads:
1291 t.join()
1292 result = t.result
1293 ONOSFlows.append( result )
1294
1295 for i in range( numControllers ):
1296 num = str( i + 1 )
1297 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001298 main.log.error( "Error in getting ONOS" + num + " flows" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001299 main.log.warn( "ONOS" + num + " flows response: " +
1300 repr( ONOSFlows[ i ] ) )
1301 flowsResults = False
1302 ONOSFlowsJson.append( None )
Jon Hall58c76b72015-02-23 11:09:24 -08001303 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001304 try:
1305 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1306 except ( ValueError, TypeError ):
1307 # FIXME: change this to log.error?
1308 main.log.exception( "Error in parsing ONOS" + num +
1309 " response as json." )
1310 main.log.error( repr( ONOSFlows[ i ] ) )
1311 ONOSFlowsJson.append( None )
1312 flowsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001313 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001314 expect=True,
1315 actual=flowsResults,
1316 onpass="No error in reading flows output",
1317 onfail="Error in reading flows from ONOS" )
1318
1319 main.step( "Check for consistency in Flows from each controller" )
1320 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1321 if all( tmp ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001322 main.log.info( "Flow count is consistent across all ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001323 else:
1324 consistentFlows = False
1325 utilities.assert_equals(
1326 expect=True,
1327 actual=consistentFlows,
Jon Hall6aec96b2015-01-19 14:49:31 -08001328 onpass="The flow count is consistent across all ONOS nodes",
1329 onfail="ONOS nodes have different flow counts" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001330
Jon Hall5cfd23c2015-03-19 11:40:57 -07001331 if flowsResults and not consistentFlows:
1332 for i in range( numControllers ):
1333 try:
1334 main.log.warn(
1335 "ONOS" + str( i + 1 ) + " flows: " +
1336 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1337 indent=4, separators=( ',', ': ' ) ) )
1338 except ( ValueError, TypeError ):
1339 main.log.warn(
1340 "ONOS" + str( i + 1 ) + " flows: " +
1341 repr( ONOSFlows[ i ] ) )
1342 elif flowsResults and consistentFlows:
1343 flowCheck = main.TRUE
1344 flowState = ONOSFlows[ 0 ]
1345
Jon Hall6aec96b2015-01-19 14:49:31 -08001346 main.step( "Get the OF Table entries" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001347 global flows
Jon Hall6aec96b2015-01-19 14:49:31 -08001348 flows = []
1349 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001350 flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001351 if flowCheck == main.FALSE:
1352 for table in flows:
1353 main.log.warn( table )
Jon Hall6aec96b2015-01-19 14:49:31 -08001354 # TODO: Compare switch flow tables with ONOS flow tables
Jon Hall73cf9cc2014-11-20 22:28:38 -08001355
Jon Hall6aec96b2015-01-19 14:49:31 -08001356 main.step( "Start continuous pings" )
1357 main.Mininet2.pingLong(
1358 src=main.params[ 'PING' ][ 'source1' ],
1359 target=main.params[ 'PING' ][ 'target1' ],
1360 pingTime=500 )
1361 main.Mininet2.pingLong(
1362 src=main.params[ 'PING' ][ 'source2' ],
1363 target=main.params[ 'PING' ][ 'target2' ],
1364 pingTime=500 )
1365 main.Mininet2.pingLong(
1366 src=main.params[ 'PING' ][ 'source3' ],
1367 target=main.params[ 'PING' ][ 'target3' ],
1368 pingTime=500 )
1369 main.Mininet2.pingLong(
1370 src=main.params[ 'PING' ][ 'source4' ],
1371 target=main.params[ 'PING' ][ 'target4' ],
1372 pingTime=500 )
1373 main.Mininet2.pingLong(
1374 src=main.params[ 'PING' ][ 'source5' ],
1375 target=main.params[ 'PING' ][ 'target5' ],
1376 pingTime=500 )
1377 main.Mininet2.pingLong(
1378 src=main.params[ 'PING' ][ 'source6' ],
1379 target=main.params[ 'PING' ][ 'target6' ],
1380 pingTime=500 )
1381 main.Mininet2.pingLong(
1382 src=main.params[ 'PING' ][ 'source7' ],
1383 target=main.params[ 'PING' ][ 'target7' ],
1384 pingTime=500 )
1385 main.Mininet2.pingLong(
1386 src=main.params[ 'PING' ][ 'source8' ],
1387 target=main.params[ 'PING' ][ 'target8' ],
1388 pingTime=500 )
1389 main.Mininet2.pingLong(
1390 src=main.params[ 'PING' ][ 'source9' ],
1391 target=main.params[ 'PING' ][ 'target9' ],
1392 pingTime=500 )
1393 main.Mininet2.pingLong(
1394 src=main.params[ 'PING' ][ 'source10' ],
1395 target=main.params[ 'PING' ][ 'target10' ],
1396 pingTime=500 )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001397
Jon Hall6aec96b2015-01-19 14:49:31 -08001398 main.step( "Collecting topology information from ONOS" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001399 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001400 threads = []
1401 for i in range( numControllers ):
1402 t = main.Thread( target=CLIs[i].devices,
1403 name="devices-" + str( i ),
1404 args=[ ] )
1405 threads.append( t )
1406 t.start()
1407
1408 for t in threads:
1409 t.join()
1410 devices.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001411 hosts = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001412 threads = []
1413 for i in range( numControllers ):
1414 t = main.Thread( target=CLIs[i].hosts,
1415 name="hosts-" + str( i ),
1416 args=[ ] )
1417 threads.append( t )
1418 t.start()
1419
1420 for t in threads:
1421 t.join()
1422 try:
1423 hosts.append( json.loads( t.result ) )
1424 except ( ValueError, TypeError ):
1425 # FIXME: better handling of this, print which node
1426 # Maybe use thread name?
1427 main.log.exception( "Error parsing json output of hosts" )
1428 # FIXME: should this be an empty json object instead?
1429 hosts.append( None )
1430
Jon Hall73cf9cc2014-11-20 22:28:38 -08001431 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001432 threads = []
1433 for i in range( numControllers ):
1434 t = main.Thread( target=CLIs[i].ports,
1435 name="ports-" + str( i ),
1436 args=[ ] )
1437 threads.append( t )
1438 t.start()
1439
1440 for t in threads:
1441 t.join()
1442 ports.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001443 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001444 threads = []
1445 for i in range( numControllers ):
1446 t = main.Thread( target=CLIs[i].links,
1447 name="links-" + str( i ),
1448 args=[ ] )
1449 threads.append( t )
1450 t.start()
1451
1452 for t in threads:
1453 t.join()
1454 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001455 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001456 threads = []
1457 for i in range( numControllers ):
1458 t = main.Thread( target=CLIs[i].clusters,
1459 name="clusters-" + str( i ),
1460 args=[ ] )
1461 threads.append( t )
1462 t.start()
1463
1464 for t in threads:
1465 t.join()
1466 clusters.append( t.result )
Jon Hall529a37f2015-01-28 10:02:00 -08001467 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001468
Jon Hall6aec96b2015-01-19 14:49:31 -08001469 # hosts
Jon Hall390696c2015-05-05 17:13:41 -07001470 main.step( "Host view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001471 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001472 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001473 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001474 if "Error" not in hosts[ controller ]:
1475 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001476 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001477 else: # hosts not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07001478 main.log.error( "hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001479 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001480 " is inconsistent with ONOS1" )
1481 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001482 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001483
1484 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001485 main.log.error( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001486 controllerStr )
1487 consistentHostsResult = main.FALSE
1488 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001489 " hosts response: " +
1490 repr( hosts[ controller ] ) )
1491 utilities.assert_equals(
1492 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001493 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001494 onpass="Hosts view is consistent across all ONOS nodes",
1495 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001496
Jon Hall390696c2015-05-05 17:13:41 -07001497 main.step( "Each host has an IP address" )
Jon Hall58c76b72015-02-23 11:09:24 -08001498 ipResult = main.TRUE
1499 for controller in range( 0, len( hosts ) ):
1500 controllerStr = str( controller + 1 )
1501 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07001502 if not host.get( 'ipAddresses', [ ] ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001503 main.log.error( "DEBUG:Error with host ips on controller" +
1504 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001505 ipResult = main.FALSE
1506 utilities.assert_equals(
1507 expect=main.TRUE,
1508 actual=ipResult,
1509 onpass="The ips of the hosts aren't empty",
1510 onfail="The ip of at least one host is missing" )
1511
Jon Hall6aec96b2015-01-19 14:49:31 -08001512 # Strongly connected clusters of devices
Jon Hall390696c2015-05-05 17:13:41 -07001513 main.step( "Cluster view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001514 consistentClustersResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001515 for controller in range( len( clusters ) ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001516 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001517 if "Error" not in clusters[ controller ]:
1518 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001519 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001520 else: # clusters not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07001521 main.log.error( "clusters from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001522 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001523 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001524
1525 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001526 main.log.error( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001527 "from ONOS" + controllerStr )
1528 consistentClustersResult = main.FALSE
1529 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001530 " clusters response: " +
1531 repr( clusters[ controller ] ) )
1532 utilities.assert_equals(
1533 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001534 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001535 onpass="Clusters view is consistent across all ONOS nodes",
1536 onfail="ONOS nodes have different views of clusters" )
1537 # there should always only be one cluster
Jon Hall390696c2015-05-05 17:13:41 -07001538 main.step( "Cluster view correct across ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001539 try:
1540 numClusters = len( json.loads( clusters[ 0 ] ) )
1541 except ( ValueError, TypeError ):
1542 main.log.exception( "Error parsing clusters[0]: " +
1543 repr( clusters[ 0 ] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001544 clusterResults = main.FALSE
1545 if numClusters == 1:
1546 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001547 utilities.assert_equals(
1548 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08001549 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08001550 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08001551 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08001552
Jon Hall6aec96b2015-01-19 14:49:31 -08001553 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001554 devicesResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08001555 linksResults = main.TRUE
Jon Hallb6a54872015-06-12 14:02:42 -07001556 hostsResults = main.TRUE
1557 mnSwitches = main.Mininet1.getSwitches()
1558 mnLinks = main.Mininet1.getLinks()
1559 mnHosts = main.Mininet1.getHosts()
Jon Hall8f89dda2015-01-22 16:03:33 -08001560 for controller in range( numControllers ):
1561 controllerStr = str( controller + 1 )
Jon Hallb6a54872015-06-12 14:02:42 -07001562 if devices[ controller ] and ports[ controller ] and\
1563 "Error" not in devices[ controller ] and\
1564 "Error" not in ports[ controller ]:
1565
Jon Hall8f89dda2015-01-22 16:03:33 -08001566 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hallb6a54872015-06-12 14:02:42 -07001567 mnSwitches,
1568 json.loads( devices[ controller ] ),
1569 json.loads( ports[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001570 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001571 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001572 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001573 actual=currentDevicesResult,
1574 onpass="ONOS" + controllerStr +
1575 " Switches view is correct",
1576 onfail="ONOS" + controllerStr +
1577 " Switches view is incorrect" )
Jon Hallb6a54872015-06-12 14:02:42 -07001578 if links[ controller ] and "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001579 currentLinksResult = main.Mininet1.compareLinks(
Jon Hallb6a54872015-06-12 14:02:42 -07001580 mnSwitches, mnLinks,
1581 json.loads( links[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001582 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001583 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001584 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001585 actual=currentLinksResult,
1586 onpass="ONOS" + controllerStr +
1587 " links view is correct",
1588 onfail="ONOS" + controllerStr +
1589 " links view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001590
Jon Hallb6a54872015-06-12 14:02:42 -07001591 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1592 currentHostsResult = main.Mininet1.compareHosts(
1593 mnHosts,
1594 hosts[ controller ] )
1595 else:
1596 currentHostsResult = main.FALSE
1597 utilities.assert_equals( expect=main.TRUE,
1598 actual=currentHostsResult,
1599 onpass="ONOS" + controllerStr +
1600 " hosts exist in Mininet",
1601 onfail="ONOS" + controllerStr +
1602 " hosts don't match Mininet" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001603
Jon Hallb6a54872015-06-12 14:02:42 -07001604 devicesResults = devicesResults and currentDevicesResult
1605 linksResults = linksResults and currentLinksResult
1606 hostsResults = hostsResults and currentHostsResult
1607
1608 main.step( "Device information is correct" )
1609 utilities.assert_equals(
1610 expect=main.TRUE,
1611 actual=devicesResults,
1612 onpass="Device information is correct",
1613 onfail="Device information is incorrect" )
1614
1615 main.step( "Links are correct" )
1616 utilities.assert_equals(
1617 expect=main.TRUE,
1618 actual=linksResults,
1619 onpass="Link are correct",
1620 onfail="Links are incorrect" )
1621
1622 main.step( "Hosts are correct" )
1623 utilities.assert_equals(
1624 expect=main.TRUE,
1625 actual=hostsResults,
1626 onpass="Hosts are correct",
1627 onfail="Hosts are incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001628
Jon Hall6aec96b2015-01-19 14:49:31 -08001629 def CASE6( self, main ):
1630 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001631 The Failure case.
Jon Hall6aec96b2015-01-19 14:49:31 -08001632 """
Jon Hall94fd0472014-12-08 11:52:42 -08001633 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001634 assert numControllers, "numControllers not defined"
1635 assert main, "main not defined"
1636 assert utilities.assert_equals, "utilities.assert_equals not defined"
1637 assert CLIs, "CLIs not defined"
1638 assert nodes, "nodes not defined"
Jon Hall5cfd23c2015-03-19 11:40:57 -07001639 main.case( "Restart minority of ONOS nodes" )
Jon Hall390696c2015-05-05 17:13:41 -07001640 main.step( "Killing 3 ONOS nodes" )
Jon Hallfeff3082015-05-19 10:23:26 -07001641 killTime = time.time()
Jon Hall390696c2015-05-05 17:13:41 -07001642 # TODO: Randomize these nodes or base this on partitions
Jon Hall5cfd23c2015-03-19 11:40:57 -07001643 # TODO: use threads in this case
Jon Hall390696c2015-05-05 17:13:41 -07001644 killResults = main.ONOSbench.onosKill( nodes[0].ip_address )
Jon Hall6aec96b2015-01-19 14:49:31 -08001645 time.sleep( 10 )
Jon Hall390696c2015-05-05 17:13:41 -07001646 killResults = killResults and\
1647 main.ONOSbench.onosKill( nodes[1].ip_address )
Jon Hall6aec96b2015-01-19 14:49:31 -08001648 time.sleep( 10 )
Jon Hall390696c2015-05-05 17:13:41 -07001649 killResults = killResults and\
1650 main.ONOSbench.onosKill( nodes[2].ip_address )
1651 utilities.assert_equals( expect=main.TRUE, actual=killResults,
1652 onpass="ONOS Killed successfully",
1653 onfail="ONOS kill NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001654
Jon Hall6aec96b2015-01-19 14:49:31 -08001655 main.step( "Checking if ONOS is up yet" )
Jon Hallffb386d2014-11-21 13:43:38 -08001656 count = 0
Jon Hall8f89dda2015-01-22 16:03:33 -08001657 onosIsupResult = main.FALSE
1658 while onosIsupResult == main.FALSE and count < 10:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001659 onos1Isup = main.ONOSbench.isup( nodes[0].ip_address )
1660 onos2Isup = main.ONOSbench.isup( nodes[1].ip_address )
1661 onos3Isup = main.ONOSbench.isup( nodes[2].ip_address )
Jon Hall8f89dda2015-01-22 16:03:33 -08001662 onosIsupResult = onos1Isup and onos2Isup and onos3Isup
Jon Hallffb386d2014-11-21 13:43:38 -08001663 count = count + 1
Jon Hall73cf9cc2014-11-20 22:28:38 -08001664 # TODO: if it becomes an issue, we can retry this step a few times
Jon Hall390696c2015-05-05 17:13:41 -07001665 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1666 onpass="ONOS restarted successfully",
1667 onfail="ONOS restart NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001668
Jon Hall390696c2015-05-05 17:13:41 -07001669 main.step( "Restarting ONOS CLIs" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001670 cliResult1 = main.ONOScli1.startOnosCli( nodes[0].ip_address )
1671 cliResult2 = main.ONOScli2.startOnosCli( nodes[1].ip_address )
1672 cliResult3 = main.ONOScli3.startOnosCli( nodes[2].ip_address )
Jon Hall8f89dda2015-01-22 16:03:33 -08001673 cliResults = cliResult1 and cliResult2 and cliResult3
Jon Hall390696c2015-05-05 17:13:41 -07001674 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1675 onpass="ONOS cli restarted",
1676 onfail="ONOS cli did not restart" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001677
Jon Hall21270ac2015-02-16 17:59:55 -08001678 # Grab the time of restart so we chan check how long the gossip
1679 # protocol has had time to work
Jon Hallfeff3082015-05-19 10:23:26 -07001680 main.restartTime = time.time() - killTime
1681 main.log.debug( "Restart time: " + str( main.restartTime ) )
1682 '''
1683 # FIXME: revisit test plan for election with madan
1684 # Rerun for election on restarted nodes
1685 run1 = CLIs[0].electionTestRun()
1686 run2 = CLIs[1].electionTestRun()
1687 run3 = CLIs[2].electionTestRun()
1688 runResults = run1 and run2 and run3
1689 utilities.assert_equals( expect=main.TRUE, actual=runResults,
1690 onpass="Reran for election",
1691 onfail="Failed to rerun for election" )
1692 '''
1693 # TODO: MAke this configurable. Also, we are breaking the above timer
1694 time.sleep( 60 )
1695 main.log.debug( CLIs[0].nodes( jsonFormat=False ) )
1696 main.log.debug( CLIs[0].leaders( jsonFormat=False ) )
1697 main.log.debug( CLIs[0].partitions( jsonFormat=False ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001698
Jon Hall6aec96b2015-01-19 14:49:31 -08001699 def CASE7( self, main ):
1700 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001701 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -08001702 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001703 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001704 assert numControllers, "numControllers not defined"
1705 assert main, "main not defined"
1706 assert utilities.assert_equals, "utilities.assert_equals not defined"
1707 assert CLIs, "CLIs not defined"
1708 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001709 main.case( "Running ONOS Constant State Tests" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001710
Jon Hall5cfd23c2015-03-19 11:40:57 -07001711 main.step( "Check that each switch has a master" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001712 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -07001713 rolesNotNull = main.TRUE
1714 threads = []
1715 for i in range( numControllers ):
1716 t = main.Thread( target=CLIs[i].rolesNotNull,
1717 name="rolesNotNull-" + str( i ),
1718 args=[ ] )
1719 threads.append( t )
1720 t.start()
1721
1722 for t in threads:
1723 t.join()
1724 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001725 utilities.assert_equals(
1726 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001727 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001728 onpass="Each device has a master",
1729 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001730
Jon Hall390696c2015-05-05 17:13:41 -07001731 main.step( "Read device roles from ONOS" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001732 ONOSMastership = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001733 consistentMastership = True
1734 rolesResults = True
1735 threads = []
1736 for i in range( numControllers ):
1737 t = main.Thread( target=CLIs[i].roles,
1738 name="roles-" + str( i ),
1739 args=[] )
1740 threads.append( t )
1741 t.start()
1742
1743 for t in threads:
1744 t.join()
1745 ONOSMastership.append( t.result )
1746
1747 for i in range( numControllers ):
1748 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001749 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001750 " roles" )
1751 main.log.warn(
1752 "ONOS" + str( i + 1 ) + " mastership response: " +
1753 repr( ONOSMastership[i] ) )
1754 rolesResults = False
1755 utilities.assert_equals(
1756 expect=True,
1757 actual=rolesResults,
1758 onpass="No error in reading roles output",
1759 onfail="Error in reading roles from ONOS" )
1760
1761 main.step( "Check for consistency in roles from each controller" )
1762 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001763 main.log.info(
Jon Hall6aec96b2015-01-19 14:49:31 -08001764 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001765 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001766 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001767 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001768 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001769 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001770 onpass="Switch roles are consistent across all ONOS nodes",
1771 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001772
Jon Hall5cfd23c2015-03-19 11:40:57 -07001773 if rolesResults and not consistentMastership:
1774 for i in range( numControllers ):
1775 main.log.warn(
1776 "ONOS" + str( i + 1 ) + " roles: ",
1777 json.dumps(
1778 json.loads( ONOSMastership[ i ] ),
1779 sort_keys=True,
1780 indent=4,
1781 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001782
Jon Hallfeff3082015-05-19 10:23:26 -07001783 # NOTE: we expect mastership to change on controller failure
1784 '''
Jon Hall73cf9cc2014-11-20 22:28:38 -08001785 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -08001786 main.step( description2 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001787 try:
1788 currentJson = json.loads( ONOSMastership[0] )
1789 oldJson = json.loads( mastershipState )
1790 except ( ValueError, TypeError ):
1791 main.log.exception( "Something is wrong with parsing " +
1792 "ONOSMastership[0] or mastershipState" )
1793 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1794 main.log.error( "mastershipState" + repr( mastershipState ) )
1795 main.cleanup()
1796 main.exit()
Jon Hall8f89dda2015-01-22 16:03:33 -08001797 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001798 for i in range( 1, 29 ):
1799 switchDPID = str(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001800 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001801 current = [ switch[ 'master' ] for switch in currentJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001802 if switchDPID in switch[ 'id' ] ]
Jon Hall8f89dda2015-01-22 16:03:33 -08001803 old = [ switch[ 'master' ] for switch in oldJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001804 if switchDPID in switch[ 'id' ] ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08001805 if current == old:
Jon Hall8f89dda2015-01-22 16:03:33 -08001806 mastershipCheck = mastershipCheck and main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001807 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001808 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall8f89dda2015-01-22 16:03:33 -08001809 mastershipCheck = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001810 utilities.assert_equals(
1811 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001812 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -08001813 onpass="Mastership of Switches was not changed",
1814 onfail="Mastership of some switches changed" )
Jon Hallfeff3082015-05-19 10:23:26 -07001815 '''
Jon Hall73cf9cc2014-11-20 22:28:38 -08001816
Jon Hall58c76b72015-02-23 11:09:24 -08001817 main.step( "Get the intents and compare across all nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001818 ONOSIntents = []
Jon Hall58c76b72015-02-23 11:09:24 -08001819 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001820 consistentIntents = True
1821 intentsResults = True
1822 threads = []
1823 for i in range( numControllers ):
1824 t = main.Thread( target=CLIs[i].intents,
1825 name="intents-" + str( i ),
1826 args=[],
1827 kwargs={ 'jsonFormat': True } )
1828 threads.append( t )
1829 t.start()
1830
1831 for t in threads:
1832 t.join()
1833 ONOSIntents.append( t.result )
1834
1835 for i in range( numControllers ):
1836 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001837 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001838 " intents" )
1839 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1840 repr( ONOSIntents[ i ] ) )
1841 intentsResults = False
Jon Hall58c76b72015-02-23 11:09:24 -08001842 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001843 expect=True,
1844 actual=intentsResults,
1845 onpass="No error in reading intents output",
1846 onfail="Error in reading intents from ONOS" )
1847
1848 main.step( "Check for consistency in Intents from each controller" )
1849 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001850 main.log.info( "Intents are consistent across all ONOS " +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001851 "nodes" )
1852 else:
1853 consistentIntents = False
Jon Hall390696c2015-05-05 17:13:41 -07001854
1855 # Try to make it easy to figure out what is happening
1856 #
1857 # Intent ONOS1 ONOS2 ...
1858 # 0x01 INSTALLED INSTALLING
1859 # ... ... ...
1860 # ... ... ...
1861 title = " ID"
1862 for n in range( numControllers ):
1863 title += " " * 10 + "ONOS" + str( n + 1 )
1864 main.log.warn( title )
1865 # get all intent keys in the cluster
1866 keys = []
1867 for nodeStr in ONOSIntents:
1868 node = json.loads( nodeStr )
1869 for intent in node:
1870 keys.append( intent.get( 'id' ) )
1871 keys = set( keys )
1872 for key in keys:
1873 row = "%-13s" % key
1874 for nodeStr in ONOSIntents:
1875 node = json.loads( nodeStr )
1876 for intent in node:
1877 if intent.get( 'id' ) == key:
1878 row += "%-15s" % intent.get( 'state' )
1879 main.log.warn( row )
1880 # End table view
1881
Jon Hall5cfd23c2015-03-19 11:40:57 -07001882 utilities.assert_equals(
1883 expect=True,
1884 actual=consistentIntents,
Jon Hall58c76b72015-02-23 11:09:24 -08001885 onpass="Intents are consistent across all ONOS nodes",
1886 onfail="ONOS nodes have different views of intents" )
Jon Hall58c76b72015-02-23 11:09:24 -08001887 intentStates = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001888 for node in ONOSIntents: # Iter through ONOS nodes
Jon Hall58c76b72015-02-23 11:09:24 -08001889 nodeStates = []
1890 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001891 try:
1892 for intent in json.loads( node ):
1893 nodeStates.append( intent[ 'state' ] )
1894 except ( ValueError, TypeError ):
1895 main.log.exception( "Error in parsing intents" )
1896 main.log.error( repr( node ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001897 intentStates.append( nodeStates )
1898 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1899 main.log.info( dict( out ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001900
Jon Hall5cfd23c2015-03-19 11:40:57 -07001901 if intentsResults and not consistentIntents:
1902 for i in range( numControllers ):
1903 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1904 main.log.warn( json.dumps(
1905 json.loads( ONOSIntents[ i ] ),
1906 sort_keys=True,
1907 indent=4,
1908 separators=( ',', ': ' ) ) )
1909 elif intentsResults and consistentIntents:
1910 intentCheck = main.TRUE
1911
Jon Hall58c76b72015-02-23 11:09:24 -08001912 # NOTE: Store has no durability, so intents are lost across system
1913 # restarts
1914 main.step( "Compare current intents with intents before the failure" )
1915 # NOTE: this requires case 5 to pass for intentState to be set.
1916 # maybe we should stop the test if that fails?
Jon Hall40d2cbd2015-06-03 16:24:29 -07001917 sameIntents = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001918 if intentState and intentState == ONOSIntents[ 0 ]:
Jon Hall21270ac2015-02-16 17:59:55 -08001919 sameIntents = main.TRUE
Jon Hallfeff3082015-05-19 10:23:26 -07001920 main.log.info( "Intents are consistent with before failure" )
Jon Hall58c76b72015-02-23 11:09:24 -08001921 # TODO: possibly the states have changed? we may need to figure out
Jon Hall5cfd23c2015-03-19 11:40:57 -07001922 # what the acceptable states are
Jon Hall40d2cbd2015-06-03 16:24:29 -07001923 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
1924 sameIntents = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08001925 try:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001926 before = json.loads( intentState )
1927 after = json.loads( ONOSIntents[ 0 ] )
1928 for intent in before:
1929 if intent not in after:
1930 sameIntents = main.FALSE
Jon Hallc9eabec2015-06-10 14:33:14 -07001931 main.log.debug( "Intent is not currently in ONOS " +
Jon Hall40d2cbd2015-06-03 16:24:29 -07001932 "(at least in the same form):" )
1933 main.log.debug( json.dumps( intent ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001934 except ( ValueError, TypeError ):
1935 main.log.exception( "Exception printing intents" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001936 main.log.debug( repr( ONOSIntents[0] ) )
1937 main.log.debug( repr( intentState ) )
1938 if sameIntents == main.FALSE:
1939 try:
1940 main.log.debug( "ONOS intents before: " )
1941 main.log.debug( json.dumps( json.loads( intentState ),
1942 sort_keys=True, indent=4,
1943 separators=( ',', ': ' ) ) )
1944 main.log.debug( "Current ONOS intents: " )
1945 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1946 sort_keys=True, indent=4,
1947 separators=( ',', ': ' ) ) )
1948 except ( ValueError, TypeError ):
1949 main.log.exception( "Exception printing intents" )
1950 main.log.debug( repr( ONOSIntents[0] ) )
1951 main.log.debug( repr( intentState ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001952 utilities.assert_equals(
1953 expect=main.TRUE,
1954 actual=sameIntents,
1955 onpass="Intents are consistent with before failure",
1956 onfail="The Intents changed during failure" )
1957 intentCheck = intentCheck and sameIntents
Jon Hall21270ac2015-02-16 17:59:55 -08001958
Jon Hall58c76b72015-02-23 11:09:24 -08001959 main.step( "Get the OF Table entries and compare to before " +
1960 "component failure" )
1961 FlowTables = main.TRUE
1962 flows2 = []
1963 for i in range( 28 ):
1964 main.log.info( "Checking flow table on s" + str( i + 1 ) )
1965 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
1966 flows2.append( tmpFlows )
1967 tempResult = main.Mininet2.flowComp(
1968 flow1=flows[ i ],
1969 flow2=tmpFlows )
1970 FlowTables = FlowTables and tempResult
1971 if FlowTables == main.FALSE:
1972 main.log.info( "Differences in flow table for switch: s" +
1973 str( i + 1 ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001974 utilities.assert_equals(
1975 expect=main.TRUE,
1976 actual=FlowTables,
1977 onpass="No changes were found in the flow tables",
1978 onfail="Changes were found in the flow tables" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001979
Jon Hall6aec96b2015-01-19 14:49:31 -08001980 main.step( "Check the continuous pings to ensure that no packets " +
1981 "were dropped during component failure" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001982 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
1983 main.params[ 'TESTONIP' ] )
Jon Hall8f89dda2015-01-22 16:03:33 -08001984 LossInPings = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001985 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
1986 for i in range( 8, 18 ):
1987 main.log.info(
1988 "Checking for a loss in pings along flow from s" +
1989 str( i ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001990 LossInPings = main.Mininet2.checkForLoss(
Jon Hall6aec96b2015-01-19 14:49:31 -08001991 "/tmp/ping.h" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001992 str( i ) ) or LossInPings
1993 if LossInPings == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001994 main.log.info( "Loss in ping detected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001995 elif LossInPings == main.ERROR:
Jon Hall6aec96b2015-01-19 14:49:31 -08001996 main.log.info( "There are multiple mininet process running" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001997 elif LossInPings == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001998 main.log.info( "No Loss in the pings" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001999 main.log.info( "No loss of dataplane connectivity" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002000 utilities.assert_equals(
2001 expect=main.FALSE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002002 actual=LossInPings,
Jon Hall6aec96b2015-01-19 14:49:31 -08002003 onpass="No Loss of connectivity",
2004 onfail="Loss of dataplane connectivity detected" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002005
Jon Hall390696c2015-05-05 17:13:41 -07002006 main.step( "Leadership Election is still functional" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002007 # Test of LeadershipElection
Jon Hall8f89dda2015-01-22 16:03:33 -08002008 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002009 # FIXME: make sure this matches nodes that were restarted
2010 restarted = [ nodes[0].ip_address, nodes[1].ip_address,
2011 nodes[2].ip_address ]
Jon Hall390696c2015-05-05 17:13:41 -07002012
Jon Hall8f89dda2015-01-22 16:03:33 -08002013 leaderResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002014 for cli in CLIs:
2015 leaderN = cli.electionTestLeader()
Jon Hall8f89dda2015-01-22 16:03:33 -08002016 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002017 if leaderN == main.FALSE:
Jon Hallfeff3082015-05-19 10:23:26 -07002018 # error in response
Jon Hall40d2cbd2015-06-03 16:24:29 -07002019 main.log.error( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002020 "electionTestLeader function, check the" +
Jon Hall6aec96b2015-01-19 14:49:31 -08002021 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002022 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002023 elif leaderN is None:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002024 main.log.error( cli.name +
Jon Hall6aec96b2015-01-19 14:49:31 -08002025 " shows no leader for the election-app was" +
2026 " elected after the old one died" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002027 leaderResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002028 elif leaderN in restarted:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002029 main.log.error( cli.name + " shows " + str( leaderN ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002030 " as leader for the election-app, but it " +
2031 "was restarted" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002032 leaderResult = main.FALSE
2033 if len( set( leaderList ) ) != 1:
2034 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002035 main.log.error(
2036 "Inconsistent view of leader for the election test app" )
2037 # TODO: print the list
Jon Hall6aec96b2015-01-19 14:49:31 -08002038 utilities.assert_equals(
2039 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002040 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002041 onpass="Leadership election passed",
2042 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002043
Jon Hall6aec96b2015-01-19 14:49:31 -08002044 def CASE8( self, main ):
2045 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002046 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -08002047 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002048 import sys
Jon Hall6aec96b2015-01-19 14:49:31 -08002049 # FIXME add this path to params
2050 sys.path.append( "/home/admin/sts" )
2051 # assumes that sts is already in you PYTHONPATH
2052 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -08002053 import json
2054 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002055 assert numControllers, "numControllers not defined"
2056 assert main, "main not defined"
2057 assert utilities.assert_equals, "utilities.assert_equals not defined"
2058 assert CLIs, "CLIs not defined"
2059 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08002060
Jon Hallfeff3082015-05-19 10:23:26 -07002061 main.case( "Compare ONOS Topology view to Mininet topology" )
2062 main.caseExplaination = "Compare topology objects between Mininet" +\
2063 " and ONOS"
Jon Hall73cf9cc2014-11-20 22:28:38 -08002064
Jon Hallfeff3082015-05-19 10:23:26 -07002065 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002066 devicesResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08002067 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08002068 hostsResults = main.TRUE
Jon Hallc9eabec2015-06-10 14:33:14 -07002069 hostAttachmentResults = True
Jon Hall8f89dda2015-01-22 16:03:33 -08002070 topoResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08002071 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -08002072 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -08002073 main.step( "Collecting topology information from ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002074 startTime = time.time()
Jon Hall21270ac2015-02-16 17:59:55 -08002075 # Give time for Gossip to work
Jon Hall8f89dda2015-01-22 16:03:33 -08002076 while topoResult == main.FALSE and elapsed < 60:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002077 count += 1
Jon Hall8f89dda2015-01-22 16:03:33 -08002078 cliStart = time.time()
Jon Hall94fd0472014-12-08 11:52:42 -08002079 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002080 threads = []
2081 for i in range( numControllers ):
2082 t = main.Thread( target=CLIs[i].devices,
2083 name="devices-" + str( i ),
2084 args=[ ] )
2085 threads.append( t )
2086 t.start()
2087
2088 for t in threads:
2089 t.join()
2090 devices.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002091 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -08002092 ipResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002093 threads = []
2094 for i in range( numControllers ):
2095 t = main.Thread( target=CLIs[i].hosts,
2096 name="hosts-" + str( i ),
2097 args=[ ] )
2098 threads.append( t )
2099 t.start()
2100
2101 for t in threads:
2102 t.join()
2103 try:
2104 hosts.append( json.loads( t.result ) )
2105 except ( ValueError, TypeError ):
2106 main.log.exception( "Error parsing hosts results" )
2107 main.log.error( repr( t.result ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08002108 for controller in range( 0, len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08002109 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08002110 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07002111 if host is None or host.get( 'ipAddresses', [] ) == []:
Jon Hall6aec96b2015-01-19 14:49:31 -08002112 main.log.error(
Jon Hall40d2cbd2015-06-03 16:24:29 -07002113 "DEBUG:Error with host ipAddresses on controller" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002114 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08002115 ipResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002116 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002117 threads = []
2118 for i in range( numControllers ):
2119 t = main.Thread( target=CLIs[i].ports,
2120 name="ports-" + str( i ),
2121 args=[ ] )
2122 threads.append( t )
2123 t.start()
2124
2125 for t in threads:
2126 t.join()
2127 ports.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002128 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002129 threads = []
2130 for i in range( numControllers ):
2131 t = main.Thread( target=CLIs[i].links,
2132 name="links-" + str( i ),
2133 args=[ ] )
2134 threads.append( t )
2135 t.start()
2136
2137 for t in threads:
2138 t.join()
2139 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002140 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002141 threads = []
2142 for i in range( numControllers ):
2143 t = main.Thread( target=CLIs[i].clusters,
2144 name="clusters-" + str( i ),
2145 args=[ ] )
2146 threads.append( t )
2147 t.start()
2148
2149 for t in threads:
2150 t.join()
2151 clusters.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002152
Jon Hall8f89dda2015-01-22 16:03:33 -08002153 elapsed = time.time() - startTime
2154 cliTime = time.time() - cliStart
Jon Hallc9eabec2015-06-10 14:33:14 -07002155 print "Elapsed time: " + str( elapsed )
Jon Hall8f89dda2015-01-22 16:03:33 -08002156 print "CLI time: " + str( cliTime )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002157
Jon Hallb6a54872015-06-12 14:02:42 -07002158 mnSwitches = main.Mininet1.getSwitches()
2159 mnLinks = main.Mininet1.getLinks()
2160 mnHosts = main.Mininet1.getHosts()
Jon Hall8f89dda2015-01-22 16:03:33 -08002161 for controller in range( numControllers ):
2162 controllerStr = str( controller + 1 )
Jon Hallb6a54872015-06-12 14:02:42 -07002163 if devices[ controller ] and ports[ controller ] and\
2164 "Error" not in devices[ controller ] and\
2165 "Error" not in ports[ controller ]:
2166
Jon Hall8f89dda2015-01-22 16:03:33 -08002167 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hallb6a54872015-06-12 14:02:42 -07002168 mnSwitches,
2169 json.loads( devices[ controller ] ),
2170 json.loads( ports[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002171 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002172 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002173 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002174 actual=currentDevicesResult,
2175 onpass="ONOS" + controllerStr +
2176 " Switches view is correct",
2177 onfail="ONOS" + controllerStr +
2178 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002179
Jon Hallb6a54872015-06-12 14:02:42 -07002180 if links[ controller ] and "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08002181 currentLinksResult = main.Mininet1.compareLinks(
Jon Hallb6a54872015-06-12 14:02:42 -07002182 mnSwitches, mnLinks,
2183 json.loads( links[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002184 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002185 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002186 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002187 actual=currentLinksResult,
2188 onpass="ONOS" + controllerStr +
2189 " links view is correct",
2190 onfail="ONOS" + controllerStr +
2191 " links view is incorrect" )
2192
2193 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2194 currentHostsResult = main.Mininet1.compareHosts(
Jon Hallb6a54872015-06-12 14:02:42 -07002195 mnHosts,
2196 hosts[ controller ] )
Jon Hall58c76b72015-02-23 11:09:24 -08002197 else:
2198 currentHostsResult = main.FALSE
2199 utilities.assert_equals( expect=main.TRUE,
2200 actual=currentHostsResult,
2201 onpass="ONOS" + controllerStr +
2202 " hosts exist in Mininet",
2203 onfail="ONOS" + controllerStr +
2204 " hosts don't match Mininet" )
Jon Hallc9eabec2015-06-10 14:33:14 -07002205 # CHECKING HOST ATTACHMENT POINTS
2206 hostAttachment = True
Jon Hallb6a54872015-06-12 14:02:42 -07002207 zeroHosts = False
Jon Hallc9eabec2015-06-10 14:33:14 -07002208 # FIXME: topo-HA/obelisk specific mappings:
2209 # key is mac and value is dpid
2210 mappings = {}
2211 for i in range( 1, 29 ): # hosts 1 through 28
2212 # set up correct variables:
2213 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2214 if i == 1:
2215 deviceId = "1000".zfill(16)
2216 elif i == 2:
2217 deviceId = "2000".zfill(16)
2218 elif i == 3:
2219 deviceId = "3000".zfill(16)
2220 elif i == 4:
2221 deviceId = "3004".zfill(16)
2222 elif i == 5:
2223 deviceId = "5000".zfill(16)
2224 elif i == 6:
2225 deviceId = "6000".zfill(16)
2226 elif i == 7:
2227 deviceId = "6007".zfill(16)
2228 elif i >= 8 and i <= 17:
2229 dpid = '3' + str( i ).zfill( 3 )
2230 deviceId = dpid.zfill(16)
2231 elif i >= 18 and i <= 27:
2232 dpid = '6' + str( i ).zfill( 3 )
2233 deviceId = dpid.zfill(16)
2234 elif i == 28:
2235 deviceId = "2800".zfill(16)
2236 mappings[ macId ] = deviceId
2237 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2238 if hosts[ controller ] == []:
2239 main.log.warn( "There are no hosts discovered" )
Jon Hallb6a54872015-06-12 14:02:42 -07002240 zeroHosts = True
Jon Hallc9eabec2015-06-10 14:33:14 -07002241 else:
2242 for host in hosts[ controller ]:
2243 mac = None
2244 location = None
2245 device = None
2246 port = None
2247 try:
2248 mac = host.get( 'mac' )
2249 assert mac, "mac field could not be found for this host object"
Jon Hall58c76b72015-02-23 11:09:24 -08002250
Jon Hallc9eabec2015-06-10 14:33:14 -07002251 location = host.get( 'location' )
2252 assert location, "location field could not be found for this host object"
2253
2254 # Trim the protocol identifier off deviceId
2255 device = str( location.get( 'elementId' ) ).split(':')[1]
2256 assert device, "elementId field could not be found for this host location object"
2257
2258 port = location.get( 'port' )
2259 assert port, "port field could not be found for this host location object"
2260
2261 # Now check if this matches where they should be
2262 if mac and device and port:
2263 if str( port ) != "1":
2264 main.log.error( "The attachment port is incorrect for " +
2265 "host " + str( mac ) +
2266 ". Expected: 1 Actual: " + str( port) )
2267 hostAttachment = False
2268 if device != mappings[ str( mac ) ]:
2269 main.log.error( "The attachment device is incorrect for " +
2270 "host " + str( mac ) +
2271 ". Expected: " + mappings[ str( mac ) ] +
2272 " Actual: " + device )
2273 hostAttachment = False
2274 else:
2275 hostAttachment = False
2276 except AssertionError:
2277 main.log.exception( "Json object not as expected" )
2278 main.log.error( repr( host ) )
2279 hostAttachment = False
2280 else:
2281 main.log.error( "No hosts json output or \"Error\"" +
2282 " in output. hosts = " +
2283 repr( hosts[ controller ] ) )
Jon Hallb6a54872015-06-12 14:02:42 -07002284 if zeroHosts is False:
Jon Hallc9eabec2015-06-10 14:33:14 -07002285 hostAttachment = True
2286
2287 # END CHECKING HOST ATTACHMENT POINTS
Jon Hall58c76b72015-02-23 11:09:24 -08002288 devicesResults = devicesResults and currentDevicesResult
Jon Hall58c76b72015-02-23 11:09:24 -08002289 linksResults = linksResults and currentLinksResult
2290 hostsResults = hostsResults and currentHostsResult
Jon Hallb6a54872015-06-12 14:02:42 -07002291 hostAttachmentResults = hostAttachmentResults and\
2292 hostAttachment
Jon Hall94fd0472014-12-08 11:52:42 -08002293
Jon Hallc9eabec2015-06-10 14:33:14 -07002294 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08002295
Jon Hallc9eabec2015-06-10 14:33:14 -07002296 # hosts
2297 main.step( "Hosts view is consistent across all ONOS nodes" )
2298 consistentHostsResult = main.TRUE
2299 for controller in range( len( hosts ) ):
2300 controllerStr = str( controller + 1 )
2301 if "Error" not in hosts[ controller ]:
2302 if hosts[ controller ] == hosts[ 0 ]:
2303 continue
2304 else: # hosts not consistent
2305 main.log.error( "hosts from ONOS" + controllerStr +
2306 " is inconsistent with ONOS1" )
2307 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08002308 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002309
Jon Hallc9eabec2015-06-10 14:33:14 -07002310 else:
2311 main.log.error( "Error in getting ONOS hosts from ONOS" +
2312 controllerStr )
2313 consistentHostsResult = main.FALSE
2314 main.log.warn( "ONOS" + controllerStr +
2315 " hosts response: " +
2316 repr( hosts[ controller ] ) )
2317 utilities.assert_equals(
2318 expect=main.TRUE,
2319 actual=consistentHostsResult,
2320 onpass="Hosts view is consistent across all ONOS nodes",
2321 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08002322
Jon Hallc9eabec2015-06-10 14:33:14 -07002323 main.step( "Hosts information is correct" )
2324 hostsResults = hostsResults and ipResult
2325 utilities.assert_equals(
2326 expect=main.TRUE,
2327 actual=hostsResults,
2328 onpass="Host information is correct",
2329 onfail="Host information is incorrect" )
2330
2331 main.step( "Host attachment points to the network" )
2332 utilities.assert_equals(
2333 expect=True,
2334 actual=hostAttachmentResults,
2335 onpass="Hosts are correctly attached to the network",
2336 onfail="ONOS did not correctly attach hosts to the network" )
2337
2338 # Strongly connected clusters of devices
2339 main.step( "Clusters view is consistent across all ONOS nodes" )
2340 consistentClustersResult = main.TRUE
2341 for controller in range( len( clusters ) ):
2342 controllerStr = str( controller + 1 )
2343 if "Error" not in clusters[ controller ]:
2344 if clusters[ controller ] == clusters[ 0 ]:
2345 continue
2346 else: # clusters not consistent
2347 main.log.error( "clusters from ONOS" +
2348 controllerStr +
2349 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002350 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002351
Jon Hallc9eabec2015-06-10 14:33:14 -07002352 else:
2353 main.log.error( "Error in getting dataplane clusters " +
2354 "from ONOS" + controllerStr )
2355 consistentClustersResult = main.FALSE
2356 main.log.warn( "ONOS" + controllerStr +
2357 " clusters response: " +
2358 repr( clusters[ controller ] ) )
2359 utilities.assert_equals(
2360 expect=main.TRUE,
2361 actual=consistentClustersResult,
2362 onpass="Clusters view is consistent across all ONOS nodes",
2363 onfail="ONOS nodes have different views of clusters" )
2364
2365 main.step( "There is only one SCC" )
2366 # there should always only be one cluster
2367 try:
2368 numClusters = len( json.loads( clusters[ 0 ] ) )
2369 except ( ValueError, TypeError ):
2370 main.log.exception( "Error parsing clusters[0]: " +
2371 repr( clusters[0] ) )
2372 clusterResults = main.FALSE
2373 if numClusters == 1:
2374 clusterResults = main.TRUE
2375 utilities.assert_equals(
2376 expect=1,
2377 actual=numClusters,
2378 onpass="ONOS shows 1 SCC",
2379 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2380
Jon Hallb6a54872015-06-12 14:02:42 -07002381 topoResult = ( devicesResults and linksResults
Jon Hallc9eabec2015-06-10 14:33:14 -07002382 and hostsResults and consistentHostsResult
2383 and consistentClustersResult and clusterResults
2384 and ipResult and hostAttachmentResults )
Jon Hall94fd0472014-12-08 11:52:42 -08002385
Jon Hall8f89dda2015-01-22 16:03:33 -08002386 topoResult = topoResult and int( count <= 2 )
2387 note = "note it takes about " + str( int( cliTime ) ) + \
2388 " seconds for the test to make all the cli calls to fetch " +\
2389 "the topology from each ONOS instance"
Jon Hall1b8f54a2015-02-04 13:24:20 -08002390 main.log.info(
Jon Hall8f89dda2015-01-22 16:03:33 -08002391 "Very crass estimate for topology discovery/convergence( " +
2392 str( note ) + " ): " + str( elapsed ) + " seconds, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002393 str( count ) + " tries" )
Jon Hallc9eabec2015-06-10 14:33:14 -07002394
2395 main.step( "Device information is correct" )
2396 utilities.assert_equals(
2397 expect=main.TRUE,
2398 actual=devicesResults,
2399 onpass="Device information is correct",
2400 onfail="Device information is incorrect" )
2401
Jon Hallc9eabec2015-06-10 14:33:14 -07002402 main.step( "Links are correct" )
2403 utilities.assert_equals(
2404 expect=main.TRUE,
2405 actual=linksResults,
2406 onpass="Link are correct",
2407 onfail="Links are incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002408
Jon Halla9d26da2015-03-30 16:45:32 -07002409 # FIXME: move this to an ONOS state case
2410 main.step( "Checking ONOS nodes" )
2411 nodesOutput = []
Jon Hall390696c2015-05-05 17:13:41 -07002412 nodeResults = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002413 threads = []
2414 for i in range( numControllers ):
2415 t = main.Thread( target=CLIs[i].nodes,
2416 name="nodes-" + str( i ),
2417 args=[ ] )
2418 threads.append( t )
2419 t.start()
2420
2421 for t in threads:
2422 t.join()
2423 nodesOutput.append( t.result )
2424 ips = [ node.ip_address for node in nodes ]
2425 for i in nodesOutput:
2426 try:
2427 current = json.loads( i )
2428 for node in current:
Jon Hall390696c2015-05-05 17:13:41 -07002429 currentResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002430 if node['ip'] in ips: # node in nodes() output is in cell
2431 if node['state'] == 'ACTIVE':
Jon Hall390696c2015-05-05 17:13:41 -07002432 currentResult = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002433 else:
2434 main.log.error( "Error in ONOS node availability" )
2435 main.log.error(
2436 json.dumps( current,
2437 sort_keys=True,
2438 indent=4,
2439 separators=( ',', ': ' ) ) )
2440 break
Jon Hall390696c2015-05-05 17:13:41 -07002441 nodeResults = nodeResults and currentResult
Jon Halla9d26da2015-03-30 16:45:32 -07002442 except ( ValueError, TypeError ):
2443 main.log.error( "Error parsing nodes output" )
2444 main.log.warn( repr( i ) )
Jon Hall390696c2015-05-05 17:13:41 -07002445 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2446 onpass="Nodes check successful",
2447 onfail="Nodes check NOT successful" )
Jon Halla9d26da2015-03-30 16:45:32 -07002448
Jon Hall6aec96b2015-01-19 14:49:31 -08002449 def CASE9( self, main ):
2450 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002451 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -08002452 """
2453 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002454 assert numControllers, "numControllers not defined"
2455 assert main, "main not defined"
2456 assert utilities.assert_equals, "utilities.assert_equals not defined"
2457 assert CLIs, "CLIs not defined"
2458 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002459 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002460
Jon Hall8f89dda2015-01-22 16:03:33 -08002461 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002462
Jon Hall6aec96b2015-01-19 14:49:31 -08002463 description = "Turn off a link to ensure that Link Discovery " +\
Jon Hall58c76b72015-02-23 11:09:24 -08002464 "is working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002465 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002466
Jon Hall6aec96b2015-01-19 14:49:31 -08002467 main.step( "Kill Link between s3 and s28" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002468 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
Jon Hall58c76b72015-02-23 11:09:24 -08002469 main.log.info( "Waiting " + str( linkSleep ) +
2470 " seconds for link down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002471 time.sleep( linkSleep )
2472 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002473 onpass="Link down successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002474 onfail="Failed to bring link down" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002475 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002476
Jon Hall6aec96b2015-01-19 14:49:31 -08002477 def CASE10( self, main ):
2478 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002479 Link s3-s28 up
Jon Hall6aec96b2015-01-19 14:49:31 -08002480 """
2481 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002482 assert numControllers, "numControllers not defined"
2483 assert main, "main not defined"
2484 assert utilities.assert_equals, "utilities.assert_equals not defined"
2485 assert CLIs, "CLIs not defined"
2486 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002487 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002488
Jon Hall8f89dda2015-01-22 16:03:33 -08002489 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002490
Jon Hall6aec96b2015-01-19 14:49:31 -08002491 description = "Restore a link to ensure that Link Discovery is " + \
Jon Hall63604932015-02-26 17:09:50 -08002492 "working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002493 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002494
Jon Hall6aec96b2015-01-19 14:49:31 -08002495 main.step( "Bring link between s3 and s28 back up" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002496 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
Jon Hall58c76b72015-02-23 11:09:24 -08002497 main.log.info( "Waiting " + str( linkSleep ) +
2498 " seconds for link up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002499 time.sleep( linkSleep )
2500 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002501 onpass="Link up successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002502 onfail="Failed to bring link up" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002503 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002504
Jon Hall6aec96b2015-01-19 14:49:31 -08002505 def CASE11( self, main ):
2506 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002507 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -08002508 """
2509 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002510 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002511 assert numControllers, "numControllers not defined"
2512 assert main, "main not defined"
2513 assert utilities.assert_equals, "utilities.assert_equals not defined"
2514 assert CLIs, "CLIs not defined"
2515 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08002516
Jon Hall8f89dda2015-01-22 16:03:33 -08002517 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002518
2519 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002520 main.case( description )
2521 switch = main.params[ 'kill' ][ 'switch' ]
2522 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08002523
Jon Hall6aec96b2015-01-19 14:49:31 -08002524 # TODO: Make this switch parameterizable
2525 main.step( "Kill " + switch )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002526 main.log.info( "Deleting " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002527 main.Mininet1.delSwitch( switch )
2528 main.log.info( "Waiting " + str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002529 " seconds for switch down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002530 time.sleep( switchSleep )
2531 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002532 # Peek at the deleted switch
2533 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002534 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002535 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -08002536 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002537 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002538 onpass="Kill switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002539 onfail="Failed to kill switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002540
Jon Hall6aec96b2015-01-19 14:49:31 -08002541 def CASE12( self, main ):
2542 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002543 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -08002544 """
2545 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002546 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002547 assert numControllers, "numControllers not defined"
2548 assert main, "main not defined"
2549 assert utilities.assert_equals, "utilities.assert_equals not defined"
2550 assert CLIs, "CLIs not defined"
2551 assert nodes, "nodes not defined"
2552 assert ONOS1Port, "ONOS1Port not defined"
2553 assert ONOS2Port, "ONOS2Port not defined"
2554 assert ONOS3Port, "ONOS3Port not defined"
2555 assert ONOS4Port, "ONOS4Port not defined"
2556 assert ONOS5Port, "ONOS5Port not defined"
2557 assert ONOS6Port, "ONOS6Port not defined"
2558 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall669173b2014-12-17 11:36:30 -08002559
Jon Hall8f89dda2015-01-22 16:03:33 -08002560 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall6aec96b2015-01-19 14:49:31 -08002561 switch = main.params[ 'kill' ][ 'switch' ]
2562 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2563 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002564 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002565 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002566
Jon Hall6aec96b2015-01-19 14:49:31 -08002567 main.step( "Add back " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002568 main.Mininet1.addSwitch( switch, dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002569 for peer in links:
Jon Hall8f89dda2015-01-22 16:03:33 -08002570 main.Mininet1.addLink( switch, peer )
Jon Hall58c76b72015-02-23 11:09:24 -08002571 main.Mininet1.assignSwController( sw=switch.split( 's' )[ 1 ],
2572 count=numControllers,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002573 ip1=nodes[ 0 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002574 port1=ONOS1Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002575 ip2=nodes[ 1 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002576 port2=ONOS2Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002577 ip3=nodes[ 2 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002578 port3=ONOS3Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002579 ip4=nodes[ 3 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002580 port4=ONOS4Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002581 ip5=nodes[ 4 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002582 port5=ONOS5Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002583 ip6=nodes[ 5 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002584 port6=ONOS6Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002585 ip7=nodes[ 6 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002586 port7=ONOS7Port )
2587 main.log.info( "Waiting " + str( switchSleep ) +
2588 " seconds for switch up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002589 time.sleep( switchSleep )
2590 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002591 # Peek at the deleted switch
2592 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002593 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002594 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002595 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002596 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002597 onpass="add switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002598 onfail="Failed to add switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002599
Jon Hall6aec96b2015-01-19 14:49:31 -08002600 def CASE13( self, main ):
2601 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002602 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -08002603 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002604 import os
2605 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002606 assert numControllers, "numControllers not defined"
2607 assert main, "main not defined"
2608 assert utilities.assert_equals, "utilities.assert_equals not defined"
2609 assert CLIs, "CLIs not defined"
2610 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002611
2612 # printing colors to terminal
Jon Hall5cfd23c2015-03-19 11:40:57 -07002613 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2614 'blue': '\033[94m', 'green': '\033[92m',
2615 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
Jon Hall40d2cbd2015-06-03 16:24:29 -07002616 main.case( "Test Cleanup" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002617 main.step( "Killing tcpdumps" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002618 main.Mininet2.stopTcpdump()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002619
Jon Hall6aec96b2015-01-19 14:49:31 -08002620 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002621 testname = main.TEST
Jon Hall8f89dda2015-01-22 16:03:33 -08002622 teststationUser = main.params[ 'TESTONUSER' ]
2623 teststationIP = main.params[ 'TESTONIP' ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002624 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -08002625 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -08002626 # FIXME: scp
2627 # mn files
2628 # TODO: Load these from params
2629 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002630 logFolder = "/opt/onos/log/"
2631 logFiles = [ "karaf.log", "karaf.log.1" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002632 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002633 dstDir = "~/packet_captures/"
2634 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002635 for node in nodes:
2636 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2637 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002638 teststationUser + "@" +
2639 teststationIP + ":" +
2640 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002641 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002642 main.ONOSbench.handle.expect( "\$" )
2643
Jon Hall6aec96b2015-01-19 14:49:31 -08002644 # std*.log's
2645 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002646 logFolder = "/opt/onos/var/"
2647 logFiles = [ "stderr.log", "stdout.log" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002648 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002649 dstDir = "~/packet_captures/"
2650 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002651 for node in nodes:
2652 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2653 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002654 teststationUser + "@" +
2655 teststationIP + ":" +
2656 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002657 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002658 main.ONOSbench.handle.expect( "\$" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002659 # sleep so scp can finish
2660 time.sleep( 10 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002661
2662 main.step( "Stopping Mininet" )
Jon Hall390696c2015-05-05 17:13:41 -07002663 mnResult = main.Mininet1.stopNet()
2664 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2665 onpass="Mininet stopped",
2666 onfail="MN cleanup NOT successful" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002667
2668 main.step( "Checking ONOS Logs for errors" )
2669 for node in nodes:
2670 print colors[ 'purple' ] + "Checking logs for errors on " + \
2671 node.name + ":" + colors[ 'end' ]
Jon Hall40d2cbd2015-06-03 16:24:29 -07002672 print main.ONOSbench.checkLogs( node.ip_address, restart=True )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002673
Jon Hall6aec96b2015-01-19 14:49:31 -08002674 main.step( "Packing and rotating pcap archives" )
2675 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002676
Jon Hallfeff3082015-05-19 10:23:26 -07002677 try:
2678 timerLog = open( main.logdir + "/Timers.csv", 'w')
2679 # Overwrite with empty line and close
Jon Hall40d2cbd2015-06-03 16:24:29 -07002680 labels = "Gossip Intents, Restart"
2681 data = str( gossipTime ) + ", " + str( main.restartTime )
2682 timerLog.write( labels + "\n" + data )
Jon Hallfeff3082015-05-19 10:23:26 -07002683 timerLog.close()
2684 except NameError, e:
2685 main.log.exception(e)
2686
Jon Hall6aec96b2015-01-19 14:49:31 -08002687 def CASE14( self, main ):
2688 """
Jon Hall669173b2014-12-17 11:36:30 -08002689 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -08002690 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07002691 assert numControllers, "numControllers not defined"
2692 assert main, "main not defined"
2693 assert utilities.assert_equals, "utilities.assert_equals not defined"
2694 assert CLIs, "CLIs not defined"
2695 assert nodes, "nodes not defined"
2696
Jon Hall390696c2015-05-05 17:13:41 -07002697 main.case("Start Leadership Election app")
2698 main.step( "Install leadership election app" )
Jon Hallfeff3082015-05-19 10:23:26 -07002699 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
2700 utilities.assert_equals(
2701 expect=main.TRUE,
2702 actual=appResult,
2703 onpass="Election app installed",
2704 onfail="Something went wrong with installing Leadership election" )
2705
2706 main.step( "Run for election on each node" )
2707 leaderResult = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002708 leaders = []
2709 for cli in CLIs:
Jon Hall390696c2015-05-05 17:13:41 -07002710 cli.electionTestRun()
2711 for cli in CLIs:
Jon Halla9d26da2015-03-30 16:45:32 -07002712 leader = cli.electionTestLeader()
2713 if leader is None or leader == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002714 main.log.error( cli.name + ": Leader for the election app " +
Jon Halla9d26da2015-03-30 16:45:32 -07002715 "should be an ONOS node, instead got '" +
2716 str( leader ) + "'" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002717 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002718 leaders.append( leader )
Jon Hall6aec96b2015-01-19 14:49:31 -08002719 utilities.assert_equals(
2720 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002721 actual=leaderResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002722 onpass="Successfully ran for leadership",
2723 onfail="Failed to run for leadership" )
2724
2725 main.step( "Check that each node shows the same leader" )
2726 sameLeader = main.TRUE
2727 if len( set( leaders ) ) != 1:
2728 sameLeader = main.FALSE
2729 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2730 str( leaders ) )
2731 utilities.assert_equals(
2732 expect=main.TRUE,
2733 actual=sameLeader,
2734 onpass="Leadership is consistent for the election topic",
2735 onfail="Nodes have different leaders" )
Jon Hall669173b2014-12-17 11:36:30 -08002736
Jon Hall6aec96b2015-01-19 14:49:31 -08002737 def CASE15( self, main ):
2738 """
Jon Hall669173b2014-12-17 11:36:30 -08002739 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08002740 """
Jon Hall390696c2015-05-05 17:13:41 -07002741 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002742 assert numControllers, "numControllers not defined"
2743 assert main, "main not defined"
2744 assert utilities.assert_equals, "utilities.assert_equals not defined"
2745 assert CLIs, "CLIs not defined"
2746 assert nodes, "nodes not defined"
2747
Jon Hall8f89dda2015-01-22 16:03:33 -08002748 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002749 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08002750 main.case( description )
Jon Hallfeff3082015-05-19 10:23:26 -07002751
2752 main.step( "Check that each node shows the same leader" )
2753 sameLeader = main.TRUE
2754 leaders = []
2755 for cli in CLIs:
2756 leader = cli.electionTestLeader()
2757 leaders.append( leader )
2758 if len( set( leaders ) ) != 1:
2759 sameLeader = main.FALSE
2760 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2761 str( leaders ) )
2762 utilities.assert_equals(
2763 expect=main.TRUE,
2764 actual=sameLeader,
2765 onpass="Leadership is consistent for the election topic",
2766 onfail="Nodes have different leaders" )
2767
Jon Hall6aec96b2015-01-19 14:49:31 -08002768 main.step( "Find current leader and withdraw" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002769 leader = main.ONOScli1.electionTestLeader()
Jon Halla9d26da2015-03-30 16:45:32 -07002770 # do some sanity checking on leader before using it
Jon Hall8f89dda2015-01-22 16:03:33 -08002771 withdrawResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002772 if leader is None or leader == main.FALSE:
Jon Hallfeff3082015-05-19 10:23:26 -07002773 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002774 "Leader for the election app should be an ONOS node," +
Jon Hall58c76b72015-02-23 11:09:24 -08002775 "instead got '" + str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002776 leaderResult = main.FALSE
Jon Hall63604932015-02-26 17:09:50 -08002777 oldLeader = None
Jon Hall5cfd23c2015-03-19 11:40:57 -07002778 for i in range( len( CLIs ) ):
2779 if leader == nodes[ i ].ip_address:
2780 oldLeader = CLIs[ i ]
2781 break
Jon Halla9d26da2015-03-30 16:45:32 -07002782 else: # FOR/ELSE statement
Jon Hall5cfd23c2015-03-19 11:40:57 -07002783 main.log.error( "Leader election, could not find current leader" )
Jon Hall63604932015-02-26 17:09:50 -08002784 if oldLeader:
2785 withdrawResult = oldLeader.electionTestWithdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08002786 utilities.assert_equals(
2787 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002788 actual=withdrawResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002789 onpass="Node was withdrawn from election",
2790 onfail="Node was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08002791
Jon Hall6aec96b2015-01-19 14:49:31 -08002792 main.step( "Make sure new leader is elected" )
Jon Halla9d26da2015-03-30 16:45:32 -07002793 # FIXME: use threads
Jon Hall8f89dda2015-01-22 16:03:33 -08002794 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002795 for cli in CLIs:
2796 leaderN = cli.electionTestLeader()
2797 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002798 if leaderN == leader:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002799 main.log.error( cli.name + " still sees " + str( leader ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002800 " as leader after they withdrew" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002801 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002802 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002803 # error in response
2804 # TODO: add check for "Command not found:" in the driver, this
Jon Hall5cfd23c2015-03-19 11:40:57 -07002805 # means the app isn't loaded
Jon Hall40d2cbd2015-06-03 16:24:29 -07002806 main.log.error( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002807 "electionTestLeader function, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002808 "check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002809 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002810 elif leaderN is None:
2811 # node may not have recieved the event yet
Jon Hall390696c2015-05-05 17:13:41 -07002812 time.sleep(7)
Jon Halla9d26da2015-03-30 16:45:32 -07002813 leaderN = cli.electionTestLeader()
2814 leaderList.pop()
2815 leaderList.append( leaderN )
Jon Hall8f89dda2015-01-22 16:03:33 -08002816 consistentLeader = main.FALSE
2817 if len( set( leaderList ) ) == 1:
Jon Hall6aec96b2015-01-19 14:49:31 -08002818 main.log.info( "Each Election-app sees '" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002819 str( leaderList[ 0 ] ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002820 "' as the leader" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002821 consistentLeader = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002822 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002823 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002824 "Inconsistent responses for leader of Election-app:" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002825 for n in range( len( leaderList ) ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07002826 main.log.error( "ONOS" + str( n + 1 ) + " response: " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002827 str( leaderList[ n ] ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002828 leaderResult = leaderResult and consistentLeader
Jon Hall6aec96b2015-01-19 14:49:31 -08002829 utilities.assert_equals(
2830 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002831 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002832 onpass="Leadership election passed",
2833 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002834
Jon Hall58c76b72015-02-23 11:09:24 -08002835 main.step( "Run for election on old leader( just so everyone " +
2836 "is in the hat )" )
Jon Hall63604932015-02-26 17:09:50 -08002837 if oldLeader:
2838 runResult = oldLeader.electionTestRun()
2839 else:
2840 runResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002841 utilities.assert_equals(
2842 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002843 actual=runResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002844 onpass="App re-ran for election",
2845 onfail="App failed to run for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002846
Jon Hallfeff3082015-05-19 10:23:26 -07002847 main.step( "Leader did not change when old leader re-ran" )
Jon Hall390696c2015-05-05 17:13:41 -07002848 afterRun = main.ONOScli1.electionTestLeader()
2849 # verify leader didn't just change
2850 if afterRun == leaderList[ 0 ]:
2851 afterResult = main.TRUE
2852 else:
2853 afterResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002854
Jon Hall6aec96b2015-01-19 14:49:31 -08002855 utilities.assert_equals(
2856 expect=main.TRUE,
Jon Hall390696c2015-05-05 17:13:41 -07002857 actual=afterResult,
2858 onpass="Old leader successfully re-ran for election",
Jon Hall6aec96b2015-01-19 14:49:31 -08002859 onfail="Something went wrong with Leadership election after " +
2860 "the old leader re-ran for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002861
Jon Hall390696c2015-05-05 17:13:41 -07002862 def CASE16( self, main ):
2863 """
2864 Install Distributed Primitives app
2865 """
Jon Hall40d2cbd2015-06-03 16:24:29 -07002866 import time
Jon Hall390696c2015-05-05 17:13:41 -07002867 assert numControllers, "numControllers not defined"
2868 assert main, "main not defined"
2869 assert utilities.assert_equals, "utilities.assert_equals not defined"
2870 assert CLIs, "CLIs not defined"
2871 assert nodes, "nodes not defined"
2872
2873 # Variables for the distributed primitives tests
2874 global pCounterName
2875 global iCounterName
2876 global pCounterValue
2877 global iCounterValue
2878 global onosSet
2879 global onosSetName
2880 pCounterName = "TestON-Partitions"
2881 iCounterName = "TestON-inMemory"
2882 pCounterValue = 0
2883 iCounterValue = 0
2884 onosSet = set([])
2885 onosSetName = "TestON-set"
2886
2887 description = "Install Primitives app"
2888 main.case( description )
2889 main.step( "Install Primitives app" )
2890 appName = "org.onosproject.distributedprimitives"
2891 appResults = CLIs[0].activateApp( appName )
2892 utilities.assert_equals( expect=main.TRUE,
2893 actual=appResults,
2894 onpass="Primitives app activated",
2895 onfail="Primitives app not activated" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002896 time.sleep( 5 ) # To allow all nodes to activate
Jon Hall390696c2015-05-05 17:13:41 -07002897
2898 def CASE17( self, main ):
2899 """
2900 Check for basic functionality with distributed primitives
2901 """
Jon Hallc9eabec2015-06-10 14:33:14 -07002902 import json
Jon Hall390696c2015-05-05 17:13:41 -07002903 # Make sure variables are defined/set
2904 assert numControllers, "numControllers not defined"
2905 assert main, "main not defined"
2906 assert utilities.assert_equals, "utilities.assert_equals not defined"
2907 assert CLIs, "CLIs not defined"
2908 assert nodes, "nodes not defined"
2909 assert pCounterName, "pCounterName not defined"
2910 assert iCounterName, "iCounterName not defined"
2911 assert onosSetName, "onosSetName not defined"
2912 # NOTE: assert fails if value is 0/None/Empty/False
2913 try:
2914 pCounterValue
2915 except NameError:
2916 main.log.error( "pCounterValue not defined, setting to 0" )
2917 pCounterValue = 0
2918 try:
2919 iCounterValue
2920 except NameError:
2921 main.log.error( "iCounterValue not defined, setting to 0" )
2922 iCounterValue = 0
2923 try:
2924 onosSet
2925 except NameError:
2926 main.log.error( "onosSet not defined, setting to empty Set" )
2927 onosSet = set([])
2928 # Variables for the distributed primitives tests. These are local only
2929 addValue = "a"
2930 addAllValue = "a b c d e f"
2931 retainValue = "c d e f"
2932
2933 description = "Check for basic functionality with distributed " +\
2934 "primitives"
2935 main.case( description )
2936 main.caseExplaination = "Test the methods of the distributed primitives (counters and sets) throught the cli"
2937 # DISTRIBUTED ATOMIC COUNTERS
2938 main.step( "Increment and get a default counter on each node" )
2939 pCounters = []
2940 threads = []
Jon Hallfeff3082015-05-19 10:23:26 -07002941 addedPValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002942 for i in range( numControllers ):
2943 t = main.Thread( target=CLIs[i].counterTestIncrement,
2944 name="counterIncrement-" + str( i ),
2945 args=[ pCounterName ] )
2946 pCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002947 addedPValues.append( pCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002948 threads.append( t )
2949 t.start()
2950
2951 for t in threads:
2952 t.join()
2953 pCounters.append( t.result )
2954 # Check that counter incremented numController times
2955 pCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002956 for i in addedPValues:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002957 tmpResult = i in pCounters
Jon Hallfeff3082015-05-19 10:23:26 -07002958 pCounterResults = pCounterResults and tmpResult
2959 if not tmpResult:
2960 main.log.error( str( i ) + " is not in partitioned "
2961 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002962 utilities.assert_equals( expect=True,
2963 actual=pCounterResults,
2964 onpass="Default counter incremented",
2965 onfail="Error incrementing default" +
2966 " counter" )
2967
2968 main.step( "Increment and get an in memory counter on each node" )
2969 iCounters = []
Jon Hallfeff3082015-05-19 10:23:26 -07002970 addedIValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002971 threads = []
2972 for i in range( numControllers ):
2973 t = main.Thread( target=CLIs[i].counterTestIncrement,
2974 name="icounterIncrement-" + str( i ),
2975 args=[ iCounterName ],
2976 kwargs={ "inMemory": True } )
2977 iCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002978 addedIValues.append( iCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002979 threads.append( t )
2980 t.start()
2981
2982 for t in threads:
2983 t.join()
2984 iCounters.append( t.result )
2985 # Check that counter incremented numController times
2986 iCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002987 for i in addedIValues:
2988 tmpResult = i in iCounters
2989 iCounterResults = iCounterResults and tmpResult
2990 if not tmpResult:
2991 main.log.error( str( i ) + " is not in the in-memory "
2992 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002993 utilities.assert_equals( expect=True,
2994 actual=iCounterResults,
2995 onpass="In memory counter incremented",
2996 onfail="Error incrementing in memory" +
2997 " counter" )
2998
2999 main.step( "Check counters are consistant across nodes" )
3000 onosCounters = []
3001 threads = []
3002 for i in range( numControllers ):
3003 t = main.Thread( target=CLIs[i].counters,
3004 name="counters-" + str( i ) )
3005 threads.append( t )
3006 t.start()
3007 for t in threads:
3008 t.join()
3009 onosCounters.append( t.result )
3010 tmp = [ i == onosCounters[ 0 ] for i in onosCounters ]
3011 if all( tmp ):
3012 main.log.info( "Counters are consistent across all nodes" )
3013 consistentCounterResults = main.TRUE
3014 else:
3015 main.log.error( "Counters are not consistent across all nodes" )
3016 consistentCounterResults = main.FALSE
3017 utilities.assert_equals( expect=main.TRUE,
3018 actual=consistentCounterResults,
3019 onpass="ONOS counters are consistent " +
3020 "across nodes",
3021 onfail="ONOS Counters are inconsistent " +
3022 "across nodes" )
3023
3024 main.step( "Counters we added have the correct values" )
3025 correctResults = main.TRUE
3026 for i in range( numControllers ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07003027 current = json.loads( onosCounters[i] )
3028 pValue = None
3029 iValue = None
Jon Hall390696c2015-05-05 17:13:41 -07003030 try:
Jon Hall40d2cbd2015-06-03 16:24:29 -07003031 for database in current:
3032 partitioned = database.get( 'partitionedDatabaseCounters' )
3033 if partitioned:
3034 for value in partitioned:
3035 if value.get( 'name' ) == pCounterName:
3036 pValue = value.get( 'value' )
3037 break
3038 inMemory = database.get( 'inMemoryDatabaseCounters' )
3039 if inMemory:
3040 for value in inMemory:
3041 if value.get( 'name' ) == iCounterName:
3042 iValue = value.get( 'value' )
3043 break
Jon Hall390696c2015-05-05 17:13:41 -07003044 except AttributeError, e:
3045 main.log.error( "ONOS" + str( i + 1 ) + " counters result " +
3046 "is not as expected" )
3047 correctResults = main.FALSE
Jon Hall40d2cbd2015-06-03 16:24:29 -07003048 if pValue == pCounterValue:
3049 main.log.info( "Partitioned counter value is correct" )
3050 else:
3051 main.log.error( "Partitioned counter value is incorrect," +
3052 " expected value: " + str( pCounterValue )
3053 + " current value: " + str( pValue ) )
3054 correctResults = main.FALSE
3055 if iValue == iCounterValue:
3056 main.log.info( "In memory counter value is correct" )
3057 else:
3058 main.log.error( "In memory counter value is incorrect, " +
3059 "expected value: " + str( iCounterValue ) +
3060 " current value: " + str( iValue ) )
3061 correctResults = main.FALSE
Jon Hall390696c2015-05-05 17:13:41 -07003062 utilities.assert_equals( expect=main.TRUE,
3063 actual=correctResults,
3064 onpass="Added counters are correct",
3065 onfail="Added counters are incorrect" )
3066 # DISTRIBUTED SETS
3067 main.step( "Distributed Set get" )
3068 size = len( onosSet )
3069 getResponses = []
3070 threads = []
3071 for i in range( numControllers ):
3072 t = main.Thread( target=CLIs[i].setTestGet,
3073 name="setTestGet-" + str( i ),
3074 args=[ onosSetName ] )
3075 threads.append( t )
3076 t.start()
3077 for t in threads:
3078 t.join()
3079 getResponses.append( t.result )
3080
3081 getResults = main.TRUE
3082 for i in range( numControllers ):
3083 if isinstance( getResponses[ i ], list):
3084 current = set( getResponses[ i ] )
3085 if len( current ) == len( getResponses[ i ] ):
3086 # no repeats
3087 if onosSet != current:
3088 main.log.error( "ONOS" + str( i + 1 ) +
3089 " has incorrect view" +
3090 " of set " + onosSetName + ":\n" +
3091 str( getResponses[ i ] ) )
3092 main.log.debug( "Expected: " + str( onosSet ) )
3093 main.log.debug( "Actual: " + str( current ) )
3094 getResults = main.FALSE
3095 else:
3096 # error, set is not a set
3097 main.log.error( "ONOS" + str( i + 1 ) +
3098 " has repeat elements in" +
3099 " set " + onosSetName + ":\n" +
3100 str( getResponses[ i ] ) )
3101 getResults = main.FALSE
3102 elif getResponses[ i ] == main.ERROR:
3103 getResults = main.FALSE
3104 utilities.assert_equals( expect=main.TRUE,
3105 actual=getResults,
3106 onpass="Set elements are correct",
3107 onfail="Set elements are incorrect" )
3108
3109 main.step( "Distributed Set size" )
3110 sizeResponses = []
3111 threads = []
3112 for i in range( numControllers ):
3113 t = main.Thread( target=CLIs[i].setTestSize,
3114 name="setTestSize-" + str( i ),
3115 args=[ onosSetName ] )
3116 threads.append( t )
3117 t.start()
3118 for t in threads:
3119 t.join()
3120 sizeResponses.append( t.result )
3121
3122 sizeResults = main.TRUE
3123 for i in range( numControllers ):
3124 if size != sizeResponses[ i ]:
3125 sizeResults = main.FALSE
3126 main.log.error( "ONOS" + str( i + 1 ) +
3127 " expected a size of " + str( size ) +
3128 " for set " + onosSetName +
3129 " but got " + str( sizeResponses[ i ] ) )
3130 utilities.assert_equals( expect=main.TRUE,
3131 actual=sizeResults,
3132 onpass="Set sizes are correct",
3133 onfail="Set sizes are incorrect" )
3134
3135 main.step( "Distributed Set add()" )
3136 onosSet.add( addValue )
3137 addResponses = []
3138 threads = []
3139 for i in range( numControllers ):
3140 t = main.Thread( target=CLIs[i].setTestAdd,
3141 name="setTestAdd-" + str( i ),
3142 args=[ onosSetName, addValue ] )
3143 threads.append( t )
3144 t.start()
3145 for t in threads:
3146 t.join()
3147 addResponses.append( t.result )
3148
3149 # main.TRUE = successfully changed the set
3150 # main.FALSE = action resulted in no change in set
3151 # main.ERROR - Some error in executing the function
3152 addResults = main.TRUE
3153 for i in range( numControllers ):
3154 if addResponses[ i ] == main.TRUE:
3155 # All is well
3156 pass
3157 elif addResponses[ i ] == main.FALSE:
3158 # Already in set, probably fine
3159 pass
3160 elif addResponses[ i ] == main.ERROR:
3161 # Error in execution
3162 addResults = main.FALSE
3163 else:
3164 # unexpected result
3165 addResults = main.FALSE
3166 if addResults != main.TRUE:
3167 main.log.error( "Error executing set add" )
3168
3169 # Check if set is still correct
3170 size = len( onosSet )
3171 getResponses = []
3172 threads = []
3173 for i in range( numControllers ):
3174 t = main.Thread( target=CLIs[i].setTestGet,
3175 name="setTestGet-" + str( i ),
3176 args=[ onosSetName ] )
3177 threads.append( t )
3178 t.start()
3179 for t in threads:
3180 t.join()
3181 getResponses.append( t.result )
3182 getResults = main.TRUE
3183 for i in range( numControllers ):
3184 if isinstance( getResponses[ i ], list):
3185 current = set( getResponses[ i ] )
3186 if len( current ) == len( getResponses[ i ] ):
3187 # no repeats
3188 if onosSet != current:
3189 main.log.error( "ONOS" + str( i + 1 ) +
3190 " has incorrect view" +
3191 " of set " + onosSetName + ":\n" +
3192 str( getResponses[ i ] ) )
3193 main.log.debug( "Expected: " + str( onosSet ) )
3194 main.log.debug( "Actual: " + str( current ) )
3195 getResults = main.FALSE
3196 else:
3197 # error, set is not a set
3198 main.log.error( "ONOS" + str( i + 1 ) +
3199 " has repeat elements in" +
3200 " set " + onosSetName + ":\n" +
3201 str( getResponses[ i ] ) )
3202 getResults = main.FALSE
3203 elif getResponses[ i ] == main.ERROR:
3204 getResults = main.FALSE
3205 sizeResponses = []
3206 threads = []
3207 for i in range( numControllers ):
3208 t = main.Thread( target=CLIs[i].setTestSize,
3209 name="setTestSize-" + str( i ),
3210 args=[ onosSetName ] )
3211 threads.append( t )
3212 t.start()
3213 for t in threads:
3214 t.join()
3215 sizeResponses.append( t.result )
3216 sizeResults = main.TRUE
3217 for i in range( numControllers ):
3218 if size != sizeResponses[ i ]:
3219 sizeResults = main.FALSE
3220 main.log.error( "ONOS" + str( i + 1 ) +
3221 " expected a size of " + str( size ) +
3222 " for set " + onosSetName +
3223 " but got " + str( sizeResponses[ i ] ) )
3224 addResults = addResults and getResults and sizeResults
3225 utilities.assert_equals( expect=main.TRUE,
3226 actual=addResults,
3227 onpass="Set add correct",
3228 onfail="Set add was incorrect" )
3229
3230 main.step( "Distributed Set addAll()" )
3231 onosSet.update( addAllValue.split() )
3232 addResponses = []
3233 threads = []
3234 for i in range( numControllers ):
3235 t = main.Thread( target=CLIs[i].setTestAdd,
3236 name="setTestAddAll-" + str( i ),
3237 args=[ onosSetName, addAllValue ] )
3238 threads.append( t )
3239 t.start()
3240 for t in threads:
3241 t.join()
3242 addResponses.append( t.result )
3243
3244 # main.TRUE = successfully changed the set
3245 # main.FALSE = action resulted in no change in set
3246 # main.ERROR - Some error in executing the function
3247 addAllResults = main.TRUE
3248 for i in range( numControllers ):
3249 if addResponses[ i ] == main.TRUE:
3250 # All is well
3251 pass
3252 elif addResponses[ i ] == main.FALSE:
3253 # Already in set, probably fine
3254 pass
3255 elif addResponses[ i ] == main.ERROR:
3256 # Error in execution
3257 addAllResults = main.FALSE
3258 else:
3259 # unexpected result
3260 addAllResults = main.FALSE
3261 if addAllResults != main.TRUE:
3262 main.log.error( "Error executing set addAll" )
3263
3264 # Check if set is still correct
3265 size = len( onosSet )
3266 getResponses = []
3267 threads = []
3268 for i in range( numControllers ):
3269 t = main.Thread( target=CLIs[i].setTestGet,
3270 name="setTestGet-" + str( i ),
3271 args=[ onosSetName ] )
3272 threads.append( t )
3273 t.start()
3274 for t in threads:
3275 t.join()
3276 getResponses.append( t.result )
3277 getResults = main.TRUE
3278 for i in range( numControllers ):
3279 if isinstance( getResponses[ i ], list):
3280 current = set( getResponses[ i ] )
3281 if len( current ) == len( getResponses[ i ] ):
3282 # no repeats
3283 if onosSet != current:
3284 main.log.error( "ONOS" + str( i + 1 ) +
3285 " has incorrect view" +
3286 " of set " + onosSetName + ":\n" +
3287 str( getResponses[ i ] ) )
3288 main.log.debug( "Expected: " + str( onosSet ) )
3289 main.log.debug( "Actual: " + str( current ) )
3290 getResults = main.FALSE
3291 else:
3292 # error, set is not a set
3293 main.log.error( "ONOS" + str( i + 1 ) +
3294 " has repeat elements in" +
3295 " set " + onosSetName + ":\n" +
3296 str( getResponses[ i ] ) )
3297 getResults = main.FALSE
3298 elif getResponses[ i ] == main.ERROR:
3299 getResults = main.FALSE
3300 sizeResponses = []
3301 threads = []
3302 for i in range( numControllers ):
3303 t = main.Thread( target=CLIs[i].setTestSize,
3304 name="setTestSize-" + str( i ),
3305 args=[ onosSetName ] )
3306 threads.append( t )
3307 t.start()
3308 for t in threads:
3309 t.join()
3310 sizeResponses.append( t.result )
3311 sizeResults = main.TRUE
3312 for i in range( numControllers ):
3313 if size != sizeResponses[ i ]:
3314 sizeResults = main.FALSE
3315 main.log.error( "ONOS" + str( i + 1 ) +
3316 " expected a size of " + str( size ) +
3317 " for set " + onosSetName +
3318 " but got " + str( sizeResponses[ i ] ) )
3319 addAllResults = addAllResults and getResults and sizeResults
3320 utilities.assert_equals( expect=main.TRUE,
3321 actual=addAllResults,
3322 onpass="Set addAll correct",
3323 onfail="Set addAll was incorrect" )
3324
3325 main.step( "Distributed Set contains()" )
3326 containsResponses = []
3327 threads = []
3328 for i in range( numControllers ):
3329 t = main.Thread( target=CLIs[i].setTestGet,
3330 name="setContains-" + str( i ),
3331 args=[ onosSetName ],
3332 kwargs={ "values": addValue } )
3333 threads.append( t )
3334 t.start()
3335 for t in threads:
3336 t.join()
3337 # NOTE: This is the tuple
3338 containsResponses.append( t.result )
3339
3340 containsResults = main.TRUE
3341 for i in range( numControllers ):
3342 if containsResponses[ i ] == main.ERROR:
3343 containsResults = main.FALSE
3344 else:
3345 containsResults = containsResults and\
3346 containsResponses[ i ][ 1 ]
3347 utilities.assert_equals( expect=main.TRUE,
3348 actual=containsResults,
3349 onpass="Set contains is functional",
3350 onfail="Set contains failed" )
3351
3352 main.step( "Distributed Set containsAll()" )
3353 containsAllResponses = []
3354 threads = []
3355 for i in range( numControllers ):
3356 t = main.Thread( target=CLIs[i].setTestGet,
3357 name="setContainsAll-" + str( i ),
3358 args=[ onosSetName ],
3359 kwargs={ "values": addAllValue } )
3360 threads.append( t )
3361 t.start()
3362 for t in threads:
3363 t.join()
3364 # NOTE: This is the tuple
3365 containsAllResponses.append( t.result )
3366
3367 containsAllResults = main.TRUE
3368 for i in range( numControllers ):
3369 if containsResponses[ i ] == main.ERROR:
3370 containsResults = main.FALSE
3371 else:
3372 containsResults = containsResults and\
3373 containsResponses[ i ][ 1 ]
3374 utilities.assert_equals( expect=main.TRUE,
3375 actual=containsAllResults,
3376 onpass="Set containsAll is functional",
3377 onfail="Set containsAll failed" )
3378
3379 main.step( "Distributed Set remove()" )
3380 onosSet.remove( addValue )
3381 removeResponses = []
3382 threads = []
3383 for i in range( numControllers ):
3384 t = main.Thread( target=CLIs[i].setTestRemove,
3385 name="setTestRemove-" + str( i ),
3386 args=[ onosSetName, addValue ] )
3387 threads.append( t )
3388 t.start()
3389 for t in threads:
3390 t.join()
3391 removeResponses.append( t.result )
3392
3393 # main.TRUE = successfully changed the set
3394 # main.FALSE = action resulted in no change in set
3395 # main.ERROR - Some error in executing the function
3396 removeResults = main.TRUE
3397 for i in range( numControllers ):
3398 if removeResponses[ i ] == main.TRUE:
3399 # All is well
3400 pass
3401 elif removeResponses[ i ] == main.FALSE:
3402 # not in set, probably fine
3403 pass
3404 elif removeResponses[ i ] == main.ERROR:
3405 # Error in execution
3406 removeResults = main.FALSE
3407 else:
3408 # unexpected result
3409 removeResults = main.FALSE
3410 if removeResults != main.TRUE:
3411 main.log.error( "Error executing set remove" )
3412
3413 # Check if set is still correct
3414 size = len( onosSet )
3415 getResponses = []
3416 threads = []
3417 for i in range( numControllers ):
3418 t = main.Thread( target=CLIs[i].setTestGet,
3419 name="setTestGet-" + str( i ),
3420 args=[ onosSetName ] )
3421 threads.append( t )
3422 t.start()
3423 for t in threads:
3424 t.join()
3425 getResponses.append( t.result )
3426 getResults = main.TRUE
3427 for i in range( numControllers ):
3428 if isinstance( getResponses[ i ], list):
3429 current = set( getResponses[ i ] )
3430 if len( current ) == len( getResponses[ i ] ):
3431 # no repeats
3432 if onosSet != current:
3433 main.log.error( "ONOS" + str( i + 1 ) +
3434 " has incorrect view" +
3435 " of set " + onosSetName + ":\n" +
3436 str( getResponses[ i ] ) )
3437 main.log.debug( "Expected: " + str( onosSet ) )
3438 main.log.debug( "Actual: " + str( current ) )
3439 getResults = main.FALSE
3440 else:
3441 # error, set is not a set
3442 main.log.error( "ONOS" + str( i + 1 ) +
3443 " has repeat elements in" +
3444 " set " + onosSetName + ":\n" +
3445 str( getResponses[ i ] ) )
3446 getResults = main.FALSE
3447 elif getResponses[ i ] == main.ERROR:
3448 getResults = main.FALSE
3449 sizeResponses = []
3450 threads = []
3451 for i in range( numControllers ):
3452 t = main.Thread( target=CLIs[i].setTestSize,
3453 name="setTestSize-" + str( i ),
3454 args=[ onosSetName ] )
3455 threads.append( t )
3456 t.start()
3457 for t in threads:
3458 t.join()
3459 sizeResponses.append( t.result )
3460 sizeResults = main.TRUE
3461 for i in range( numControllers ):
3462 if size != sizeResponses[ i ]:
3463 sizeResults = main.FALSE
3464 main.log.error( "ONOS" + str( i + 1 ) +
3465 " expected a size of " + str( size ) +
3466 " for set " + onosSetName +
3467 " but got " + str( sizeResponses[ i ] ) )
3468 removeResults = removeResults and getResults and sizeResults
3469 utilities.assert_equals( expect=main.TRUE,
3470 actual=removeResults,
3471 onpass="Set remove correct",
3472 onfail="Set remove was incorrect" )
3473
3474 main.step( "Distributed Set removeAll()" )
3475 onosSet.difference_update( addAllValue.split() )
3476 removeAllResponses = []
3477 threads = []
3478 try:
3479 for i in range( numControllers ):
3480 t = main.Thread( target=CLIs[i].setTestRemove,
3481 name="setTestRemoveAll-" + str( i ),
3482 args=[ onosSetName, addAllValue ] )
3483 threads.append( t )
3484 t.start()
3485 for t in threads:
3486 t.join()
3487 removeAllResponses.append( t.result )
3488 except Exception, e:
3489 main.log.exception(e)
3490
3491 # main.TRUE = successfully changed the set
3492 # main.FALSE = action resulted in no change in set
3493 # main.ERROR - Some error in executing the function
3494 removeAllResults = main.TRUE
3495 for i in range( numControllers ):
3496 if removeAllResponses[ i ] == main.TRUE:
3497 # All is well
3498 pass
3499 elif removeAllResponses[ i ] == main.FALSE:
3500 # not in set, probably fine
3501 pass
3502 elif removeAllResponses[ i ] == main.ERROR:
3503 # Error in execution
3504 removeAllResults = main.FALSE
3505 else:
3506 # unexpected result
3507 removeAllResults = main.FALSE
3508 if removeAllResults != main.TRUE:
3509 main.log.error( "Error executing set removeAll" )
3510
3511 # Check if set is still correct
3512 size = len( onosSet )
3513 getResponses = []
3514 threads = []
3515 for i in range( numControllers ):
3516 t = main.Thread( target=CLIs[i].setTestGet,
3517 name="setTestGet-" + str( i ),
3518 args=[ onosSetName ] )
3519 threads.append( t )
3520 t.start()
3521 for t in threads:
3522 t.join()
3523 getResponses.append( t.result )
3524 getResults = main.TRUE
3525 for i in range( numControllers ):
3526 if isinstance( getResponses[ i ], list):
3527 current = set( getResponses[ i ] )
3528 if len( current ) == len( getResponses[ i ] ):
3529 # no repeats
3530 if onosSet != current:
3531 main.log.error( "ONOS" + str( i + 1 ) +
3532 " has incorrect view" +
3533 " of set " + onosSetName + ":\n" +
3534 str( getResponses[ i ] ) )
3535 main.log.debug( "Expected: " + str( onosSet ) )
3536 main.log.debug( "Actual: " + str( current ) )
3537 getResults = main.FALSE
3538 else:
3539 # error, set is not a set
3540 main.log.error( "ONOS" + str( i + 1 ) +
3541 " has repeat elements in" +
3542 " set " + onosSetName + ":\n" +
3543 str( getResponses[ i ] ) )
3544 getResults = main.FALSE
3545 elif getResponses[ i ] == main.ERROR:
3546 getResults = main.FALSE
3547 sizeResponses = []
3548 threads = []
3549 for i in range( numControllers ):
3550 t = main.Thread( target=CLIs[i].setTestSize,
3551 name="setTestSize-" + str( i ),
3552 args=[ onosSetName ] )
3553 threads.append( t )
3554 t.start()
3555 for t in threads:
3556 t.join()
3557 sizeResponses.append( t.result )
3558 sizeResults = main.TRUE
3559 for i in range( numControllers ):
3560 if size != sizeResponses[ i ]:
3561 sizeResults = main.FALSE
3562 main.log.error( "ONOS" + str( i + 1 ) +
3563 " expected a size of " + str( size ) +
3564 " for set " + onosSetName +
3565 " but got " + str( sizeResponses[ i ] ) )
3566 removeAllResults = removeAllResults and getResults and sizeResults
3567 utilities.assert_equals( expect=main.TRUE,
3568 actual=removeAllResults,
3569 onpass="Set removeAll correct",
3570 onfail="Set removeAll was incorrect" )
3571
3572 main.step( "Distributed Set addAll()" )
3573 onosSet.update( addAllValue.split() )
3574 addResponses = []
3575 threads = []
3576 for i in range( numControllers ):
3577 t = main.Thread( target=CLIs[i].setTestAdd,
3578 name="setTestAddAll-" + str( i ),
3579 args=[ onosSetName, addAllValue ] )
3580 threads.append( t )
3581 t.start()
3582 for t in threads:
3583 t.join()
3584 addResponses.append( t.result )
3585
3586 # main.TRUE = successfully changed the set
3587 # main.FALSE = action resulted in no change in set
3588 # main.ERROR - Some error in executing the function
3589 addAllResults = main.TRUE
3590 for i in range( numControllers ):
3591 if addResponses[ i ] == main.TRUE:
3592 # All is well
3593 pass
3594 elif addResponses[ i ] == main.FALSE:
3595 # Already in set, probably fine
3596 pass
3597 elif addResponses[ i ] == main.ERROR:
3598 # Error in execution
3599 addAllResults = main.FALSE
3600 else:
3601 # unexpected result
3602 addAllResults = main.FALSE
3603 if addAllResults != main.TRUE:
3604 main.log.error( "Error executing set addAll" )
3605
3606 # Check if set is still correct
3607 size = len( onosSet )
3608 getResponses = []
3609 threads = []
3610 for i in range( numControllers ):
3611 t = main.Thread( target=CLIs[i].setTestGet,
3612 name="setTestGet-" + str( i ),
3613 args=[ onosSetName ] )
3614 threads.append( t )
3615 t.start()
3616 for t in threads:
3617 t.join()
3618 getResponses.append( t.result )
3619 getResults = main.TRUE
3620 for i in range( numControllers ):
3621 if isinstance( getResponses[ i ], list):
3622 current = set( getResponses[ i ] )
3623 if len( current ) == len( getResponses[ i ] ):
3624 # no repeats
3625 if onosSet != current:
3626 main.log.error( "ONOS" + str( i + 1 ) +
3627 " has incorrect view" +
3628 " of set " + onosSetName + ":\n" +
3629 str( getResponses[ i ] ) )
3630 main.log.debug( "Expected: " + str( onosSet ) )
3631 main.log.debug( "Actual: " + str( current ) )
3632 getResults = main.FALSE
3633 else:
3634 # error, set is not a set
3635 main.log.error( "ONOS" + str( i + 1 ) +
3636 " has repeat elements in" +
3637 " set " + onosSetName + ":\n" +
3638 str( getResponses[ i ] ) )
3639 getResults = main.FALSE
3640 elif getResponses[ i ] == main.ERROR:
3641 getResults = main.FALSE
3642 sizeResponses = []
3643 threads = []
3644 for i in range( numControllers ):
3645 t = main.Thread( target=CLIs[i].setTestSize,
3646 name="setTestSize-" + str( i ),
3647 args=[ onosSetName ] )
3648 threads.append( t )
3649 t.start()
3650 for t in threads:
3651 t.join()
3652 sizeResponses.append( t.result )
3653 sizeResults = main.TRUE
3654 for i in range( numControllers ):
3655 if size != sizeResponses[ i ]:
3656 sizeResults = main.FALSE
3657 main.log.error( "ONOS" + str( i + 1 ) +
3658 " expected a size of " + str( size ) +
3659 " for set " + onosSetName +
3660 " but got " + str( sizeResponses[ i ] ) )
3661 addAllResults = addAllResults and getResults and sizeResults
3662 utilities.assert_equals( expect=main.TRUE,
3663 actual=addAllResults,
3664 onpass="Set addAll correct",
3665 onfail="Set addAll was incorrect" )
3666
3667 main.step( "Distributed Set clear()" )
3668 onosSet.clear()
3669 clearResponses = []
3670 threads = []
3671 for i in range( numControllers ):
3672 t = main.Thread( target=CLIs[i].setTestRemove,
3673 name="setTestClear-" + str( i ),
3674 args=[ onosSetName, " "], # Values doesn't matter
3675 kwargs={ "clear": True } )
3676 threads.append( t )
3677 t.start()
3678 for t in threads:
3679 t.join()
3680 clearResponses.append( t.result )
3681
3682 # main.TRUE = successfully changed the set
3683 # main.FALSE = action resulted in no change in set
3684 # main.ERROR - Some error in executing the function
3685 clearResults = main.TRUE
3686 for i in range( numControllers ):
3687 if clearResponses[ i ] == main.TRUE:
3688 # All is well
3689 pass
3690 elif clearResponses[ i ] == main.FALSE:
3691 # Nothing set, probably fine
3692 pass
3693 elif clearResponses[ i ] == main.ERROR:
3694 # Error in execution
3695 clearResults = main.FALSE
3696 else:
3697 # unexpected result
3698 clearResults = main.FALSE
3699 if clearResults != main.TRUE:
3700 main.log.error( "Error executing set clear" )
3701
3702 # Check if set is still correct
3703 size = len( onosSet )
3704 getResponses = []
3705 threads = []
3706 for i in range( numControllers ):
3707 t = main.Thread( target=CLIs[i].setTestGet,
3708 name="setTestGet-" + str( i ),
3709 args=[ onosSetName ] )
3710 threads.append( t )
3711 t.start()
3712 for t in threads:
3713 t.join()
3714 getResponses.append( t.result )
3715 getResults = main.TRUE
3716 for i in range( numControllers ):
3717 if isinstance( getResponses[ i ], list):
3718 current = set( getResponses[ i ] )
3719 if len( current ) == len( getResponses[ i ] ):
3720 # no repeats
3721 if onosSet != current:
3722 main.log.error( "ONOS" + str( i + 1 ) +
3723 " has incorrect view" +
3724 " of set " + onosSetName + ":\n" +
3725 str( getResponses[ i ] ) )
3726 main.log.debug( "Expected: " + str( onosSet ) )
3727 main.log.debug( "Actual: " + str( current ) )
3728 getResults = main.FALSE
3729 else:
3730 # error, set is not a set
3731 main.log.error( "ONOS" + str( i + 1 ) +
3732 " has repeat elements in" +
3733 " set " + onosSetName + ":\n" +
3734 str( getResponses[ i ] ) )
3735 getResults = main.FALSE
3736 elif getResponses[ i ] == main.ERROR:
3737 getResults = main.FALSE
3738 sizeResponses = []
3739 threads = []
3740 for i in range( numControllers ):
3741 t = main.Thread( target=CLIs[i].setTestSize,
3742 name="setTestSize-" + str( i ),
3743 args=[ onosSetName ] )
3744 threads.append( t )
3745 t.start()
3746 for t in threads:
3747 t.join()
3748 sizeResponses.append( t.result )
3749 sizeResults = main.TRUE
3750 for i in range( numControllers ):
3751 if size != sizeResponses[ i ]:
3752 sizeResults = main.FALSE
3753 main.log.error( "ONOS" + str( i + 1 ) +
3754 " expected a size of " + str( size ) +
3755 " for set " + onosSetName +
3756 " but got " + str( sizeResponses[ i ] ) )
3757 clearResults = clearResults and getResults and sizeResults
3758 utilities.assert_equals( expect=main.TRUE,
3759 actual=clearResults,
3760 onpass="Set clear correct",
3761 onfail="Set clear was incorrect" )
3762
3763 main.step( "Distributed Set addAll()" )
3764 onosSet.update( addAllValue.split() )
3765 addResponses = []
3766 threads = []
3767 for i in range( numControllers ):
3768 t = main.Thread( target=CLIs[i].setTestAdd,
3769 name="setTestAddAll-" + str( i ),
3770 args=[ onosSetName, addAllValue ] )
3771 threads.append( t )
3772 t.start()
3773 for t in threads:
3774 t.join()
3775 addResponses.append( t.result )
3776
3777 # main.TRUE = successfully changed the set
3778 # main.FALSE = action resulted in no change in set
3779 # main.ERROR - Some error in executing the function
3780 addAllResults = main.TRUE
3781 for i in range( numControllers ):
3782 if addResponses[ i ] == main.TRUE:
3783 # All is well
3784 pass
3785 elif addResponses[ i ] == main.FALSE:
3786 # Already in set, probably fine
3787 pass
3788 elif addResponses[ i ] == main.ERROR:
3789 # Error in execution
3790 addAllResults = main.FALSE
3791 else:
3792 # unexpected result
3793 addAllResults = main.FALSE
3794 if addAllResults != main.TRUE:
3795 main.log.error( "Error executing set addAll" )
3796
3797 # Check if set is still correct
3798 size = len( onosSet )
3799 getResponses = []
3800 threads = []
3801 for i in range( numControllers ):
3802 t = main.Thread( target=CLIs[i].setTestGet,
3803 name="setTestGet-" + str( i ),
3804 args=[ onosSetName ] )
3805 threads.append( t )
3806 t.start()
3807 for t in threads:
3808 t.join()
3809 getResponses.append( t.result )
3810 getResults = main.TRUE
3811 for i in range( numControllers ):
3812 if isinstance( getResponses[ i ], list):
3813 current = set( getResponses[ i ] )
3814 if len( current ) == len( getResponses[ i ] ):
3815 # no repeats
3816 if onosSet != current:
3817 main.log.error( "ONOS" + str( i + 1 ) +
3818 " has incorrect view" +
3819 " of set " + onosSetName + ":\n" +
3820 str( getResponses[ i ] ) )
3821 main.log.debug( "Expected: " + str( onosSet ) )
3822 main.log.debug( "Actual: " + str( current ) )
3823 getResults = main.FALSE
3824 else:
3825 # error, set is not a set
3826 main.log.error( "ONOS" + str( i + 1 ) +
3827 " has repeat elements in" +
3828 " set " + onosSetName + ":\n" +
3829 str( getResponses[ i ] ) )
3830 getResults = main.FALSE
3831 elif getResponses[ i ] == main.ERROR:
3832 getResults = main.FALSE
3833 sizeResponses = []
3834 threads = []
3835 for i in range( numControllers ):
3836 t = main.Thread( target=CLIs[i].setTestSize,
3837 name="setTestSize-" + str( i ),
3838 args=[ onosSetName ] )
3839 threads.append( t )
3840 t.start()
3841 for t in threads:
3842 t.join()
3843 sizeResponses.append( t.result )
3844 sizeResults = main.TRUE
3845 for i in range( numControllers ):
3846 if size != sizeResponses[ i ]:
3847 sizeResults = main.FALSE
3848 main.log.error( "ONOS" + str( i + 1 ) +
3849 " expected a size of " + str( size ) +
3850 " for set " + onosSetName +
3851 " but got " + str( sizeResponses[ i ] ) )
3852 addAllResults = addAllResults and getResults and sizeResults
3853 utilities.assert_equals( expect=main.TRUE,
3854 actual=addAllResults,
3855 onpass="Set addAll correct",
3856 onfail="Set addAll was incorrect" )
3857
3858 main.step( "Distributed Set retain()" )
3859 onosSet.intersection_update( retainValue.split() )
3860 retainResponses = []
3861 threads = []
3862 for i in range( numControllers ):
3863 t = main.Thread( target=CLIs[i].setTestRemove,
3864 name="setTestRetain-" + str( i ),
3865 args=[ onosSetName, retainValue ],
3866 kwargs={ "retain": True } )
3867 threads.append( t )
3868 t.start()
3869 for t in threads:
3870 t.join()
3871 retainResponses.append( t.result )
3872
3873 # main.TRUE = successfully changed the set
3874 # main.FALSE = action resulted in no change in set
3875 # main.ERROR - Some error in executing the function
3876 retainResults = main.TRUE
3877 for i in range( numControllers ):
3878 if retainResponses[ i ] == main.TRUE:
3879 # All is well
3880 pass
3881 elif retainResponses[ i ] == main.FALSE:
3882 # Already in set, probably fine
3883 pass
3884 elif retainResponses[ i ] == main.ERROR:
3885 # Error in execution
3886 retainResults = main.FALSE
3887 else:
3888 # unexpected result
3889 retainResults = main.FALSE
3890 if retainResults != main.TRUE:
3891 main.log.error( "Error executing set retain" )
3892
3893 # Check if set is still correct
3894 size = len( onosSet )
3895 getResponses = []
3896 threads = []
3897 for i in range( numControllers ):
3898 t = main.Thread( target=CLIs[i].setTestGet,
3899 name="setTestGet-" + str( i ),
3900 args=[ onosSetName ] )
3901 threads.append( t )
3902 t.start()
3903 for t in threads:
3904 t.join()
3905 getResponses.append( t.result )
3906 getResults = main.TRUE
3907 for i in range( numControllers ):
3908 if isinstance( getResponses[ i ], list):
3909 current = set( getResponses[ i ] )
3910 if len( current ) == len( getResponses[ i ] ):
3911 # no repeats
3912 if onosSet != current:
3913 main.log.error( "ONOS" + str( i + 1 ) +
3914 " has incorrect view" +
3915 " of set " + onosSetName + ":\n" +
3916 str( getResponses[ i ] ) )
3917 main.log.debug( "Expected: " + str( onosSet ) )
3918 main.log.debug( "Actual: " + str( current ) )
3919 getResults = main.FALSE
3920 else:
3921 # error, set is not a set
3922 main.log.error( "ONOS" + str( i + 1 ) +
3923 " has repeat elements in" +
3924 " set " + onosSetName + ":\n" +
3925 str( getResponses[ i ] ) )
3926 getResults = main.FALSE
3927 elif getResponses[ i ] == main.ERROR:
3928 getResults = main.FALSE
3929 sizeResponses = []
3930 threads = []
3931 for i in range( numControllers ):
3932 t = main.Thread( target=CLIs[i].setTestSize,
3933 name="setTestSize-" + str( i ),
3934 args=[ onosSetName ] )
3935 threads.append( t )
3936 t.start()
3937 for t in threads:
3938 t.join()
3939 sizeResponses.append( t.result )
3940 sizeResults = main.TRUE
3941 for i in range( numControllers ):
3942 if size != sizeResponses[ i ]:
3943 sizeResults = main.FALSE
3944 main.log.error( "ONOS" + str( i + 1 ) +
3945 " expected a size of " +
3946 str( size ) + " for set " + onosSetName +
3947 " but got " + str( sizeResponses[ i ] ) )
3948 retainResults = retainResults and getResults and sizeResults
3949 utilities.assert_equals( expect=main.TRUE,
3950 actual=retainResults,
3951 onpass="Set retain correct",
3952 onfail="Set retain was incorrect" )
3953