blob: 6a601b2d4939334ce52f47f6b63bab43ea7e5389 [file] [log] [blame]
Jon Hall6aec96b2015-01-19 14:49:31 -08001"""
Jon Hall73cf9cc2014-11-20 22:28:38 -08002Description: This test is to determine if ONOS can handle
3 a minority of it's nodes restarting
4
5List of test cases:
6CASE1: Compile ONOS and push it to the test machines
Jon Hallc9eabec2015-06-10 14:33:14 -07007CASE2: Assign devices to controllers
8CASE21: Assign mastership to controllers
Jon Hall73cf9cc2014-11-20 22:28:38 -08009CASE3: Assign intents
10CASE4: Ping across added host intents
11CASE5: Reading state of ONOS
12CASE6: The Failure case.
13CASE7: Check state after control plane failure
14CASE8: Compare topo
15CASE9: Link s3-s28 down
16CASE10: Link s3-s28 up
17CASE11: Switch down
18CASE12: Switch up
19CASE13: Clean up
Jon Hall669173b2014-12-17 11:36:30 -080020CASE14: start election app on all onos nodes
21CASE15: Check that Leadership Election is still functional
Jon Hall390696c2015-05-05 17:13:41 -070022CASE16: Install Distributed Primitives app
23CASE17: Check for basic functionality with distributed primitives
Jon Hall6aec96b2015-01-19 14:49:31 -080024"""
Jon Hall8f89dda2015-01-22 16:03:33 -080025
26
Jon Hall73cf9cc2014-11-20 22:28:38 -080027class HATestMinorityRestart:
28
Jon Hall6aec96b2015-01-19 14:49:31 -080029 def __init__( self ):
Jon Hall73cf9cc2014-11-20 22:28:38 -080030 self.default = ''
31
Jon Hall6aec96b2015-01-19 14:49:31 -080032 def CASE1( self, main ):
33 """
Jon Hall73cf9cc2014-11-20 22:28:38 -080034 CASE1 is to compile ONOS and push it to the test machines
35
36 Startup sequence:
Jon Hall73cf9cc2014-11-20 22:28:38 -080037 cell <name>
38 onos-verify-cell
39 NOTE: temporary - onos-remove-raft-logs
Jon Hall58c76b72015-02-23 11:09:24 -080040 onos-uninstall
41 start mininet
42 git pull
43 mvn clean install
44 onos-package
Jon Hall73cf9cc2014-11-20 22:28:38 -080045 onos-install -f
46 onos-wait-for-start
Jon Hall58c76b72015-02-23 11:09:24 -080047 start cli sessions
48 start tcpdump
Jon Hall6aec96b2015-01-19 14:49:31 -080049 """
Jon Hall40d2cbd2015-06-03 16:24:29 -070050 main.log.info( "ONOS HA test: Restart minority of ONOS nodes - " +
Jon Hall390696c2015-05-05 17:13:41 -070051 "initialization" )
Jon Hall6aec96b2015-01-19 14:49:31 -080052 main.case( "Setting up test environment" )
Jon Hallfeff3082015-05-19 10:23:26 -070053 main.caseExplaination = "Setup the test environment including " +\
54 "installing ONOS, starting Mininet and ONOS" +\
55 "cli sessions."
Jon Hall6aec96b2015-01-19 14:49:31 -080056 # TODO: save all the timers and output them for plotting
Jon Hall73cf9cc2014-11-20 22:28:38 -080057
Jon Hall5cfd23c2015-03-19 11:40:57 -070058 # load some variables from the params file
Jon Hall8f89dda2015-01-22 16:03:33 -080059 PULLCODE = False
Jon Hall6aec96b2015-01-19 14:49:31 -080060 if main.params[ 'Git' ] == 'True':
Jon Hall8f89dda2015-01-22 16:03:33 -080061 PULLCODE = True
Jon Hall529a37f2015-01-28 10:02:00 -080062 gitBranch = main.params[ 'branch' ]
Jon Hall8f89dda2015-01-22 16:03:33 -080063 cellName = main.params[ 'ENV' ][ 'cellName' ]
Jon Hall6aec96b2015-01-19 14:49:31 -080064
65 # set global variables
Jon Hall8f89dda2015-01-22 16:03:33 -080066 global ONOS1Port
Jon Hall8f89dda2015-01-22 16:03:33 -080067 global ONOS2Port
Jon Hall8f89dda2015-01-22 16:03:33 -080068 global ONOS3Port
Jon Hall8f89dda2015-01-22 16:03:33 -080069 global ONOS4Port
Jon Hall8f89dda2015-01-22 16:03:33 -080070 global ONOS5Port
Jon Hall8f89dda2015-01-22 16:03:33 -080071 global ONOS6Port
Jon Hall8f89dda2015-01-22 16:03:33 -080072 global ONOS7Port
73 global numControllers
Jon Hall8f89dda2015-01-22 16:03:33 -080074 numControllers = int( main.params[ 'num_controllers' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -080075
Jon Hall5cfd23c2015-03-19 11:40:57 -070076 # FIXME: just get controller port from params?
77 # TODO: do we really need all these?
78 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
79 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
80 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
81 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
82 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
83 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
84 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
85
86 global CLIs
87 CLIs = []
88 global nodes
89 nodes = []
90 for i in range( 1, numControllers + 1 ):
91 CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
92 nodes.append( getattr( main, 'ONOS' + str( i ) ) )
93
Jon Hall6aec96b2015-01-19 14:49:31 -080094 main.step( "Applying cell variable to environment" )
Jon Hall8f89dda2015-01-22 16:03:33 -080095 cellResult = main.ONOSbench.setCell( cellName )
96 verifyResult = main.ONOSbench.verifyCell()
Jon Hall73cf9cc2014-11-20 22:28:38 -080097
Jon Hall6aec96b2015-01-19 14:49:31 -080098 # FIXME:this is short term fix
Jon Hall40d2cbd2015-06-03 16:24:29 -070099 main.log.info( "Removing raft logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800100 main.ONOSbench.onosRemoveRaftLogs()
Jon Hall5cfd23c2015-03-19 11:40:57 -0700101
Jon Hall40d2cbd2015-06-03 16:24:29 -0700102 main.log.info( "Uninstalling ONOS" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700103 for node in nodes:
104 main.ONOSbench.onosUninstall( node.ip_address )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800105
Jon Hall390696c2015-05-05 17:13:41 -0700106 # Make sure ONOS is DEAD
Jon Hall40d2cbd2015-06-03 16:24:29 -0700107 main.log.info( "Killing any ONOS processes" )
Jon Hall390696c2015-05-05 17:13:41 -0700108 killResults = main.TRUE
109 for node in nodes:
110 killed = main.ONOSbench.onosKill( node.ip_address )
111 killResults = killResults and killed
112
Jon Hall8f89dda2015-01-22 16:03:33 -0800113 cleanInstallResult = main.TRUE
114 gitPullResult = main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800115
Jon Hall97f31752015-02-04 12:01:04 -0800116 main.step( "Starting Mininet" )
Jon Hall390696c2015-05-05 17:13:41 -0700117 mnResult = main.Mininet1.startNet( )
118 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
119 onpass="Mininet Started",
120 onfail="Error starting Mininet" )
Jon Hall97f31752015-02-04 12:01:04 -0800121
Jon Hallfeff3082015-05-19 10:23:26 -0700122 main.step( "Git checkout and pull " + gitBranch )
Jon Hall8f89dda2015-01-22 16:03:33 -0800123 if PULLCODE:
Jon Hall529a37f2015-01-28 10:02:00 -0800124 main.ONOSbench.gitCheckout( gitBranch )
Jon Hall8f89dda2015-01-22 16:03:33 -0800125 gitPullResult = main.ONOSbench.gitPull()
Jon Hall390696c2015-05-05 17:13:41 -0700126 # values of 1 or 3 are good
127 utilities.assert_lesser( expect=0, actual=gitPullResult,
128 onpass="Git pull successful",
129 onfail="Git pull failed" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800130 main.ONOSbench.getVersion( report=True )
Jon Hallfeff3082015-05-19 10:23:26 -0700131
132 main.step( "Using mvn clean install" )
133 cleanInstallResult = main.TRUE
Jon Hall40d2cbd2015-06-03 16:24:29 -0700134 if PULLCODE and gitPullResult == main.TRUE:
Jon Hallfeff3082015-05-19 10:23:26 -0700135 cleanInstallResult = main.ONOSbench.cleanInstall()
Jon Hall40d2cbd2015-06-03 16:24:29 -0700136 else:
137 main.log.warn( "Did not pull new code so skipping mvn " +
138 "clean install" )
Jon Hallfeff3082015-05-19 10:23:26 -0700139 utilities.assert_equals( expect=main.TRUE,
140 actual=cleanInstallResult,
141 onpass="MCI successful",
142 onfail="MCI failed" )
Jon Hall390696c2015-05-05 17:13:41 -0700143 # GRAPHS
144 # NOTE: important params here:
145 # job = name of Jenkins job
146 # Plot Name = Plot-HA, only can be used if multiple plots
147 # index = The number of the graph under plot name
148 job = "HAMinorityRestart"
Jon Hall40d2cbd2015-06-03 16:24:29 -0700149 plotName = "Plot-HA"
Jon Hall390696c2015-05-05 17:13:41 -0700150 graphs = '<ac:structured-macro ac:name="html">\n'
151 graphs += '<ac:plain-text-body><![CDATA[\n'
152 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
Jon Hall40d2cbd2015-06-03 16:24:29 -0700153 '/plot/' + plotName + '/getPlot?index=0' +\
154 '&width=500&height=300"' +\
Jon Hall390696c2015-05-05 17:13:41 -0700155 'noborder="0" width="500" height="300" scrolling="yes" ' +\
156 'seamless="seamless"></iframe>\n'
157 graphs += ']]></ac:plain-text-body>\n'
158 graphs += '</ac:structured-macro>\n'
159 main.log.wiki(graphs)
Jon Hall73cf9cc2014-11-20 22:28:38 -0800160
Jon Hall6aec96b2015-01-19 14:49:31 -0800161 main.step( "Creating ONOS package" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800162 packageResult = main.ONOSbench.onosPackage()
Jon Hall390696c2015-05-05 17:13:41 -0700163 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
164 onpass="ONOS package successful",
165 onfail="ONOS package failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800166
Jon Hall6aec96b2015-01-19 14:49:31 -0800167 main.step( "Installing ONOS package" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700168 onosInstallResult = main.TRUE
169 for node in nodes:
170 tmpResult = main.ONOSbench.onosInstall( options="-f",
171 node=node.ip_address )
172 onosInstallResult = onosInstallResult and tmpResult
Jon Hall390696c2015-05-05 17:13:41 -0700173 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
174 onpass="ONOS install successful",
175 onfail="ONOS install failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800176
Jon Hall6aec96b2015-01-19 14:49:31 -0800177 main.step( "Checking if ONOS is up yet" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800178 for i in range( 2 ):
Jon Hall5cfd23c2015-03-19 11:40:57 -0700179 onosIsupResult = main.TRUE
180 for node in nodes:
181 started = main.ONOSbench.isup( node.ip_address )
182 if not started:
Jon Hall40d2cbd2015-06-03 16:24:29 -0700183 main.log.error( node.name + " didn't start!" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700184 main.ONOSbench.onosStop( node.ip_address )
185 main.ONOSbench.onosStart( node.ip_address )
186 onosIsupResult = onosIsupResult and started
Jon Hall8f89dda2015-01-22 16:03:33 -0800187 if onosIsupResult == main.TRUE:
Jon Hall94fd0472014-12-08 11:52:42 -0800188 break
Jon Hall390696c2015-05-05 17:13:41 -0700189 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
190 onpass="ONOS startup successful",
191 onfail="ONOS startup failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800192
Jon Hall5cfd23c2015-03-19 11:40:57 -0700193 main.log.step( "Starting ONOS CLI sessions" )
194 cliResults = main.TRUE
195 threads = []
196 for i in range( numControllers ):
197 t = main.Thread( target=CLIs[i].startOnosCli,
198 name="startOnosCli-" + str( i ),
199 args=[nodes[i].ip_address] )
200 threads.append( t )
201 t.start()
202
203 for t in threads:
204 t.join()
205 cliResults = cliResults and t.result
Jon Hall390696c2015-05-05 17:13:41 -0700206 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
207 onpass="ONOS cli startup successful",
208 onfail="ONOS cli startup failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800209
Jon Hall40d2cbd2015-06-03 16:24:29 -0700210 if main.params[ 'tcpdump' ].lower() == "true":
211 main.step( "Start Packet Capture MN" )
212 main.Mininet2.startTcpdump(
213 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
214 + "-MN.pcap",
215 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
216 port=main.params[ 'MNtcpdump' ][ 'port' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800217
Jon Hall390696c2015-05-05 17:13:41 -0700218 main.step( "App Ids check" )
Jon Halla9d26da2015-03-30 16:45:32 -0700219 appCheck = main.TRUE
220 threads = []
221 for i in range( numControllers ):
222 t = main.Thread( target=CLIs[i].appToIDCheck,
223 name="appToIDCheck-" + str( i ),
224 args=[] )
225 threads.append( t )
226 t.start()
227
228 for t in threads:
229 t.join()
230 appCheck = appCheck and t.result
Jon Halla9d26da2015-03-30 16:45:32 -0700231 if appCheck != main.TRUE:
232 main.log.warn( CLIs[0].apps() )
233 main.log.warn( CLIs[0].appIDs() )
Jon Hall390696c2015-05-05 17:13:41 -0700234 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
235 onpass="App Ids seem to be correct",
236 onfail="Something is wrong with app Ids" )
Jon Halla9d26da2015-03-30 16:45:32 -0700237
Jon Hallfeff3082015-05-19 10:23:26 -0700238 if cliResults == main.FALSE:
239 main.log.error( "Failed to start ONOS, stopping test" )
Jon Hall94fd0472014-12-08 11:52:42 -0800240 main.cleanup()
241 main.exit()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800242
Jon Hall6aec96b2015-01-19 14:49:31 -0800243 def CASE2( self, main ):
244 """
Jon Hallc9eabec2015-06-10 14:33:14 -0700245 Assign devices to controllers
Jon Hall6aec96b2015-01-19 14:49:31 -0800246 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800247 import re
Jon Hall390696c2015-05-05 17:13:41 -0700248 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -0700249 assert numControllers, "numControllers not defined"
250 assert main, "main not defined"
251 assert utilities.assert_equals, "utilities.assert_equals not defined"
252 assert CLIs, "CLIs not defined"
253 assert nodes, "nodes not defined"
254 assert ONOS1Port, "ONOS1Port not defined"
255 assert ONOS2Port, "ONOS2Port not defined"
256 assert ONOS3Port, "ONOS3Port not defined"
257 assert ONOS4Port, "ONOS4Port not defined"
258 assert ONOS5Port, "ONOS5Port not defined"
259 assert ONOS6Port, "ONOS6Port not defined"
260 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -0800261
Jon Hallc9eabec2015-06-10 14:33:14 -0700262 main.case( "Assigning devices to controllers" )
Jon Hallfeff3082015-05-19 10:23:26 -0700263 main.caseExplaination = "Assign switches to ONOS using 'ovs-vsctl' " +\
264 "and check that an ONOS node becomes the " +\
Jon Hallc9eabec2015-06-10 14:33:14 -0700265 "master of the device."
Jon Hall6aec96b2015-01-19 14:49:31 -0800266 main.step( "Assign switches to controllers" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800267
Jon Hall0f523f22015-07-06 09:31:09 -0700268 ipList = []
269 for i in range( numControllers ):
270 ipList.append( nodes[ i ].ip_address )
271 swList = []
Jon Hall6aec96b2015-01-19 14:49:31 -0800272 for i in range( 1, 29 ):
Jon Hall0f523f22015-07-06 09:31:09 -0700273 swList.append( "s" + str( i ) )
274 main.Mininet1.assignSwController( sw=swList, ip=ipList )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800275
Jon Hall8f89dda2015-01-22 16:03:33 -0800276 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800277 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800278 response = main.Mininet1.getSwController( "s" + str( i ) )
Jon Hallffb386d2014-11-21 13:43:38 -0800279 try:
Jon Hall6aec96b2015-01-19 14:49:31 -0800280 main.log.info( str( response ) )
Jon Hallfebb1c72015-03-05 13:30:09 -0800281 except Exception:
Jon Hall6aec96b2015-01-19 14:49:31 -0800282 main.log.info( repr( response ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700283 for node in nodes:
284 if re.search( "tcp:" + node.ip_address, response ):
285 mastershipCheck = mastershipCheck and main.TRUE
286 else:
Jon Halla9d26da2015-03-30 16:45:32 -0700287 main.log.error( "Error, node " + node.ip_address + " is " +
288 "not in the list of controllers s" +
289 str( i ) + " is connecting to." )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700290 mastershipCheck = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -0800291 utilities.assert_equals(
292 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800293 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800294 onpass="Switch mastership assigned correctly",
295 onfail="Switches not assigned correctly to controllers" )
Jon Hall390696c2015-05-05 17:13:41 -0700296
Jon Hallc9eabec2015-06-10 14:33:14 -0700297 def CASE21( self, main ):
298 """
299 Assign mastership to controllers
300 """
301 import re
302 import time
303 assert numControllers, "numControllers not defined"
304 assert main, "main not defined"
305 assert utilities.assert_equals, "utilities.assert_equals not defined"
306 assert CLIs, "CLIs not defined"
307 assert nodes, "nodes not defined"
308 assert ONOS1Port, "ONOS1Port not defined"
309 assert ONOS2Port, "ONOS2Port not defined"
310 assert ONOS3Port, "ONOS3Port not defined"
311 assert ONOS4Port, "ONOS4Port not defined"
312 assert ONOS5Port, "ONOS5Port not defined"
313 assert ONOS6Port, "ONOS6Port not defined"
314 assert ONOS7Port, "ONOS7Port not defined"
315
316 main.case( "Assigning Controller roles for switches" )
317 main.caseExplaination = "Check that ONOS is connected to each " +\
318 "device. Then manually assign" +\
319 " mastership to specific ONOS nodes using" +\
320 " 'device-role'"
Jon Hall390696c2015-05-05 17:13:41 -0700321 main.step( "Assign mastership of switches to specific controllers" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800322 # Manually assign mastership to the controller we want
Jon Hall8f89dda2015-01-22 16:03:33 -0800323 roleCall = main.TRUE
Jon Hall390696c2015-05-05 17:13:41 -0700324
325 ipList = [ ]
326 deviceList = []
Jon Hall58c76b72015-02-23 11:09:24 -0800327 try:
Jon Halla9d26da2015-03-30 16:45:32 -0700328 for i in range( 1, 29 ): # switches 1 through 28
329 # set up correct variables:
330 if i == 1:
331 ip = nodes[ 0 ].ip_address # ONOS1
332 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
333 elif i == 2:
334 ip = nodes[ 1 ].ip_address # ONOS2
335 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
336 elif i == 3:
337 ip = nodes[ 1 ].ip_address # ONOS2
338 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
339 elif i == 4:
340 ip = nodes[ 3 ].ip_address # ONOS4
341 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
342 elif i == 5:
343 ip = nodes[ 2 ].ip_address # ONOS3
344 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
345 elif i == 6:
346 ip = nodes[ 2 ].ip_address # ONOS3
347 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
348 elif i == 7:
349 ip = nodes[ 5 ].ip_address # ONOS6
350 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
351 elif i >= 8 and i <= 17:
352 ip = nodes[ 4 ].ip_address # ONOS5
353 dpid = '3' + str( i ).zfill( 3 )
354 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
355 elif i >= 18 and i <= 27:
356 ip = nodes[ 6 ].ip_address # ONOS7
357 dpid = '6' + str( i ).zfill( 3 )
358 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
359 elif i == 28:
360 ip = nodes[ 0 ].ip_address # ONOS1
361 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
362 else:
363 main.log.error( "You didn't write an else statement for " +
364 "switch s" + str( i ) )
Jon Hallc9eabec2015-06-10 14:33:14 -0700365 roleCall = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -0700366 # Assign switch
367 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
368 # TODO: make this controller dynamic
369 roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
370 ip )
Jon Hall390696c2015-05-05 17:13:41 -0700371 ipList.append( ip )
372 deviceList.append( deviceId )
Jon Hall58c76b72015-02-23 11:09:24 -0800373 except ( AttributeError, AssertionError ):
374 main.log.exception( "Something is wrong with ONOS device view" )
375 main.log.info( main.ONOScli1.devices() )
Jon Hall6aec96b2015-01-19 14:49:31 -0800376 utilities.assert_equals(
377 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800378 actual=roleCall,
Jon Hall6aec96b2015-01-19 14:49:31 -0800379 onpass="Re-assigned switch mastership to designated controller",
Jon Hall8f89dda2015-01-22 16:03:33 -0800380 onfail="Something wrong with deviceRole calls" )
Jon Hall94fd0472014-12-08 11:52:42 -0800381
Jon Hall390696c2015-05-05 17:13:41 -0700382 main.step( "Check mastership was correctly assigned" )
383 roleCheck = main.TRUE
384 # NOTE: This is due to the fact that device mastership change is not
385 # atomic and is actually a multi step process
386 time.sleep( 5 )
387 for i in range( len( ipList ) ):
388 ip = ipList[i]
389 deviceId = deviceList[i]
390 # Check assignment
391 master = main.ONOScli1.getRole( deviceId ).get( 'master' )
392 if ip in master:
393 roleCheck = roleCheck and main.TRUE
394 else:
395 roleCheck = roleCheck and main.FALSE
396 main.log.error( "Error, controller " + ip + " is not" +
397 " master " + "of device " +
398 str( deviceId ) + ". Master is " +
399 repr( master ) + "." )
Jon Hall6aec96b2015-01-19 14:49:31 -0800400 utilities.assert_equals(
401 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800402 actual=roleCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800403 onpass="Switches were successfully reassigned to designated " +
404 "controller",
405 onfail="Switches were not successfully reassigned" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800406
Jon Hall6aec96b2015-01-19 14:49:31 -0800407 def CASE3( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800408 """
409 Assign intents
Jon Hall73cf9cc2014-11-20 22:28:38 -0800410 """
411 import time
Jon Hallfebb1c72015-03-05 13:30:09 -0800412 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700413 assert numControllers, "numControllers not defined"
414 assert main, "main not defined"
415 assert utilities.assert_equals, "utilities.assert_equals not defined"
416 assert CLIs, "CLIs not defined"
417 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -0800418 main.case( "Adding host Intents" )
Jon Hallfeff3082015-05-19 10:23:26 -0700419 main.caseExplaination = "Discover hosts by using pingall then " +\
420 "assign predetermined host-to-host intents." +\
421 " After installation, check that the intent" +\
422 " is distributed to all nodes and the state" +\
423 " is INSTALLED"
Jon Hall73cf9cc2014-11-20 22:28:38 -0800424
Jon Hall6aec96b2015-01-19 14:49:31 -0800425 # install onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700426 main.step( "Install reactive forwarding app" )
427 installResults = CLIs[0].activateApp( "org.onosproject.fwd" )
428 utilities.assert_equals( expect=main.TRUE, actual=installResults,
429 onpass="Install fwd successful",
430 onfail="Install fwd failed" )
Jon Halla9d26da2015-03-30 16:45:32 -0700431
Jon Hallfeff3082015-05-19 10:23:26 -0700432 main.step( "Check app ids" )
Jon Halla9d26da2015-03-30 16:45:32 -0700433 appCheck = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700434 threads = []
435 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700436 t = main.Thread( target=CLIs[i].appToIDCheck,
437 name="appToIDCheck-" + str( i ),
438 args=[] )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700439 threads.append( t )
440 t.start()
441
442 for t in threads:
443 t.join()
Jon Halla9d26da2015-03-30 16:45:32 -0700444 appCheck = appCheck and t.result
Jon Halla9d26da2015-03-30 16:45:32 -0700445 if appCheck != main.TRUE:
446 main.log.warn( CLIs[0].apps() )
447 main.log.warn( CLIs[0].appIDs() )
Jon Hall390696c2015-05-05 17:13:41 -0700448 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
449 onpass="App Ids seem to be correct",
450 onfail="Something is wrong with app Ids" )
Jon Hall94fd0472014-12-08 11:52:42 -0800451
Jon Hallfeff3082015-05-19 10:23:26 -0700452 main.step( "Discovering Hosts( Via pingall for now )" )
453 # FIXME: Once we have a host discovery mechanism, use that instead
Jon Hall6aec96b2015-01-19 14:49:31 -0800454 # REACTIVE FWD test
Jon Hall8f89dda2015-01-22 16:03:33 -0800455 pingResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700456 for i in range(2): # Retry if pingall fails first time
457 time1 = time.time()
458 pingResult = main.Mininet1.pingall()
Jon Hall0f523f22015-07-06 09:31:09 -0700459 if i == 0:
460 utilities.assert_equals(
461 expect=main.TRUE,
462 actual=pingResult,
463 onpass="Reactive Pingall test passed",
464 onfail="Reactive Pingall failed, " +
465 "one or more ping pairs failed" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700466 time2 = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700467 main.log.info( "Time for pingall: %2f seconds" %
468 ( time2 - time1 ) )
469 # timeout for fwd flows
470 time.sleep( 11 )
Jon Hall6aec96b2015-01-19 14:49:31 -0800471 # uninstall onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700472 main.step( "Uninstall reactive forwarding app" )
473 uninstallResult = CLIs[0].deactivateApp( "org.onosproject.fwd" )
474 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
475 onpass="Uninstall fwd successful",
476 onfail="Uninstall fwd failed" )
Jon Hallfeff3082015-05-19 10:23:26 -0700477
478 main.step( "Check app ids" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700479 threads = []
Jon Hallfeff3082015-05-19 10:23:26 -0700480 appCheck2 = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700481 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700482 t = main.Thread( target=CLIs[i].appToIDCheck,
483 name="appToIDCheck-" + str( i ),
484 args=[] )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700485 threads.append( t )
486 t.start()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800487
Jon Hall5cfd23c2015-03-19 11:40:57 -0700488 for t in threads:
489 t.join()
Jon Hallfeff3082015-05-19 10:23:26 -0700490 appCheck2 = appCheck2 and t.result
491 if appCheck2 != main.TRUE:
Jon Halla9d26da2015-03-30 16:45:32 -0700492 main.log.warn( CLIs[0].apps() )
493 main.log.warn( CLIs[0].appIDs() )
Jon Hallfeff3082015-05-19 10:23:26 -0700494 utilities.assert_equals( expect=main.TRUE, actual=appCheck2,
Jon Hall390696c2015-05-05 17:13:41 -0700495 onpass="App Ids seem to be correct",
496 onfail="Something is wrong with app Ids" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700497
Jon Hallfeff3082015-05-19 10:23:26 -0700498 main.step( "Add host intents via cli" )
Jon Hall58c76b72015-02-23 11:09:24 -0800499 intentIds = []
Jon Hall6aec96b2015-01-19 14:49:31 -0800500 # TODO: move the host numbers to params
Jon Hall58c76b72015-02-23 11:09:24 -0800501 # Maybe look at all the paths we ping?
Jon Hall8f89dda2015-01-22 16:03:33 -0800502 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800503 hostResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800504 for i in range( 8, 18 ):
505 main.log.info( "Adding host intent between h" + str( i ) +
506 " and h" + str( i + 10 ) )
507 host1 = "00:00:00:00:00:" + \
508 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
509 host2 = "00:00:00:00:00:" + \
510 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800511 # NOTE: getHost can return None
512 host1Dict = main.ONOScli1.getHost( host1 )
513 host2Dict = main.ONOScli1.getHost( host2 )
514 host1Id = None
515 host2Id = None
516 if host1Dict and host2Dict:
517 host1Id = host1Dict.get( 'id', None )
518 host2Id = host2Dict.get( 'id', None )
Jon Hall8f89dda2015-01-22 16:03:33 -0800519 if host1Id and host2Id:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700520 nodeNum = ( i % 7 )
521 tmpId = CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
Jon Hall63604932015-02-26 17:09:50 -0800522 if tmpId:
523 main.log.info( "Added intent with id: " + tmpId )
524 intentIds.append( tmpId )
525 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700526 main.log.error( "addHostIntent returned: " +
527 repr( tmpId ) )
Jon Hall669173b2014-12-17 11:36:30 -0800528 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700529 main.log.error( "Error, getHost() failed for h" + str( i ) +
530 " and/or h" + str( i + 10 ) )
531 hosts = CLIs[ 0 ].hosts()
532 main.log.warn( "Hosts output: " )
533 try:
534 main.log.warn( json.dumps( json.loads( hosts ),
535 sort_keys=True,
536 indent=4,
537 separators=( ',', ': ' ) ) )
538 except ( ValueError, TypeError ):
539 main.log.warn( repr( hosts ) )
Jon Hall58c76b72015-02-23 11:09:24 -0800540 hostResult = main.FALSE
Jon Hallfeff3082015-05-19 10:23:26 -0700541 utilities.assert_equals( expect=main.TRUE, actual=hostResult,
542 onpass="Found a host id for each host",
543 onfail="Error looking up host ids" )
544
Jon Halla9d26da2015-03-30 16:45:32 -0700545 intentStart = time.time()
Jon Hall58c76b72015-02-23 11:09:24 -0800546 onosIds = main.ONOScli1.getAllIntentsId()
547 main.log.info( "Submitted intents: " + str( intentIds ) )
548 main.log.info( "Intents in ONOS: " + str( onosIds ) )
549 for intent in intentIds:
550 if intent in onosIds:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700551 pass # intent submitted is in onos
Jon Hall58c76b72015-02-23 11:09:24 -0800552 else:
553 intentAddResult = False
Jon Halla9d26da2015-03-30 16:45:32 -0700554 if intentAddResult:
555 intentStop = time.time()
556 else:
557 intentStop = None
Jon Hall1b8f54a2015-02-04 13:24:20 -0800558 # Print the intent states
Jon Hall58c76b72015-02-23 11:09:24 -0800559 intents = main.ONOScli1.intents()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800560 intentStates = []
Jon Hall5cfd23c2015-03-19 11:40:57 -0700561 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800562 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
563 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700564 try:
565 for intent in json.loads( intents ):
566 state = intent.get( 'state', None )
567 if "INSTALLED" not in state:
568 installedCheck = False
569 intentId = intent.get( 'id', None )
570 intentStates.append( ( intentId, state ) )
571 except ( ValueError, TypeError ):
572 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800573 # add submitted intents not in the store
574 tmplist = [ i for i, s in intentStates ]
575 missingIntents = False
576 for i in intentIds:
577 if i not in tmplist:
578 intentStates.append( ( i, " - " ) )
579 missingIntents = True
580 intentStates.sort()
581 for i, s in intentStates:
582 count += 1
583 main.log.info( "%-6s%-15s%-15s" %
584 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700585 leaders = main.ONOScli1.leaders()
586 try:
Jon Hallc9eabec2015-06-10 14:33:14 -0700587 missing = False
Jon Hall5cfd23c2015-03-19 11:40:57 -0700588 if leaders:
589 parsedLeaders = json.loads( leaders )
590 main.log.warn( json.dumps( parsedLeaders,
591 sort_keys=True,
592 indent=4,
593 separators=( ',', ': ' ) ) )
594 # check for all intent partitions
Jon Hall5cfd23c2015-03-19 11:40:57 -0700595 topics = []
596 for i in range( 14 ):
597 topics.append( "intent-partition-" + str( i ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700598 main.log.debug( topics )
599 ONOStopics = [ j['topic'] for j in parsedLeaders ]
600 for topic in topics:
601 if topic not in ONOStopics:
602 main.log.error( "Error: " + topic +
603 " not in leaders" )
Jon Hallc9eabec2015-06-10 14:33:14 -0700604 missing = True
Jon Hall5cfd23c2015-03-19 11:40:57 -0700605 else:
606 main.log.error( "leaders() returned None" )
607 except ( ValueError, TypeError ):
608 main.log.exception( "Error parsing leaders" )
609 main.log.error( repr( leaders ) )
Jon Hallc9eabec2015-06-10 14:33:14 -0700610 # Check all nodes
611 if missing:
612 for node in CLIs:
613 response = node.leaders( jsonFormat=False)
614 main.log.warn( str( node.name ) + " leaders output: \n" +
615 str( response ) )
616
Jon Hall5cfd23c2015-03-19 11:40:57 -0700617 partitions = main.ONOScli1.partitions()
618 try:
619 if partitions :
620 parsedPartitions = json.loads( partitions )
621 main.log.warn( json.dumps( parsedPartitions,
622 sort_keys=True,
623 indent=4,
624 separators=( ',', ': ' ) ) )
625 # TODO check for a leader in all paritions
626 # TODO check for consistency among nodes
627 else:
628 main.log.error( "partitions() returned None" )
629 except ( ValueError, TypeError ):
630 main.log.exception( "Error parsing partitions" )
631 main.log.error( repr( partitions ) )
Jon Hall63604932015-02-26 17:09:50 -0800632 pendingMap = main.ONOScli1.pendingMap()
Jon Hall5cfd23c2015-03-19 11:40:57 -0700633 try:
634 if pendingMap :
635 parsedPending = json.loads( pendingMap )
636 main.log.warn( json.dumps( parsedPending,
637 sort_keys=True,
638 indent=4,
639 separators=( ',', ': ' ) ) )
640 # TODO check something here?
641 else:
642 main.log.error( "pendingMap() returned None" )
643 except ( ValueError, TypeError ):
644 main.log.exception( "Error parsing pending map" )
645 main.log.error( repr( pendingMap ) )
646
Jon Hallfeff3082015-05-19 10:23:26 -0700647 intentAddResult = bool( intentAddResult and not missingIntents and
648 installedCheck )
649 if not intentAddResult:
650 main.log.error( "Error in pushing host intents to ONOS" )
651
Jon Hall390696c2015-05-05 17:13:41 -0700652 main.step( "Intent Anti-Entropy dispersion" )
Jon Halla9d26da2015-03-30 16:45:32 -0700653 for i in range(100):
Jon Hall390696c2015-05-05 17:13:41 -0700654 correct = True
Jon Halla9d26da2015-03-30 16:45:32 -0700655 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Hall390696c2015-05-05 17:13:41 -0700656 for cli in CLIs:
657 onosIds = []
658 ids = cli.getAllIntentsId()
659 onosIds.append( ids )
660 main.log.debug( "Intents in " + cli.name + ": " +
661 str( sorted( onosIds ) ) )
662 if sorted( ids ) != sorted( intentIds ):
Jon Hallafa8a472015-06-12 14:02:42 -0700663 main.log.warn( "Set of intent IDs doesn't match" )
Jon Hall390696c2015-05-05 17:13:41 -0700664 correct = False
Jon Hall40d2cbd2015-06-03 16:24:29 -0700665 break
666 else:
667 intents = json.loads( cli.intents() )
668 for intent in intents:
669 if intent[ 'state' ] != "INSTALLED":
Jon Hallc9eabec2015-06-10 14:33:14 -0700670 main.log.warn( "Intent " + intent[ 'id' ] +
671 " is " + intent[ 'state' ] )
Jon Hall40d2cbd2015-06-03 16:24:29 -0700672 correct = False
673 break
Jon Hall390696c2015-05-05 17:13:41 -0700674 if correct:
Jon Halla9d26da2015-03-30 16:45:32 -0700675 break
676 else:
677 time.sleep(1)
Jon Halla9d26da2015-03-30 16:45:32 -0700678 if not intentStop:
679 intentStop = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700680 global gossipTime
Jon Halla9d26da2015-03-30 16:45:32 -0700681 gossipTime = intentStop - intentStart
682 main.log.info( "It took about " + str( gossipTime ) +
Jon Hall390696c2015-05-05 17:13:41 -0700683 " seconds for all intents to appear in each node" )
Jon Halla9d26da2015-03-30 16:45:32 -0700684 # FIXME: make this time configurable/calculate based off of number of
685 # nodes and gossip rounds
686 utilities.assert_greater_equals(
Jon Hall390696c2015-05-05 17:13:41 -0700687 expect=40, actual=gossipTime,
Jon Halla9d26da2015-03-30 16:45:32 -0700688 onpass="ECM anti-entropy for intents worked within " +
689 "expected time",
690 onfail="Intent ECM anti-entropy took too long" )
Jon Hall390696c2015-05-05 17:13:41 -0700691 if gossipTime <= 40:
Jon Hall678f4512015-03-31 09:48:31 -0700692 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800693
Jon Hall63604932015-02-26 17:09:50 -0800694 if not intentAddResult or "key" in pendingMap:
Jon Hall58c76b72015-02-23 11:09:24 -0800695 import time
Jon Hall63604932015-02-26 17:09:50 -0800696 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800697 main.log.info( "Sleeping 60 seconds to see if intents are found" )
698 time.sleep( 60 )
699 onosIds = main.ONOScli1.getAllIntentsId()
700 main.log.info( "Submitted intents: " + str( intentIds ) )
701 main.log.info( "Intents in ONOS: " + str( onosIds ) )
702 # Print the intent states
703 intents = main.ONOScli1.intents()
704 intentStates = []
705 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
706 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700707 try:
708 for intent in json.loads( intents ):
709 # Iter through intents of a node
710 state = intent.get( 'state', None )
711 if "INSTALLED" not in state:
712 installedCheck = False
713 intentId = intent.get( 'id', None )
714 intentStates.append( ( intentId, state ) )
715 except ( ValueError, TypeError ):
716 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800717 # add submitted intents not in the store
718 tmplist = [ i for i, s in intentStates ]
719 for i in intentIds:
720 if i not in tmplist:
721 intentStates.append( ( i, " - " ) )
722 intentStates.sort()
723 for i, s in intentStates:
724 count += 1
725 main.log.info( "%-6s%-15s%-15s" %
726 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700727 leaders = main.ONOScli1.leaders()
728 try:
Jon Hallc9eabec2015-06-10 14:33:14 -0700729 missing = False
Jon Hall5cfd23c2015-03-19 11:40:57 -0700730 if leaders:
731 parsedLeaders = json.loads( leaders )
732 main.log.warn( json.dumps( parsedLeaders,
733 sort_keys=True,
734 indent=4,
735 separators=( ',', ': ' ) ) )
736 # check for all intent partitions
737 # check for election
738 topics = []
739 for i in range( 14 ):
740 topics.append( "intent-partition-" + str( i ) )
741 # FIXME: this should only be after we start the app
742 topics.append( "org.onosproject.election" )
743 main.log.debug( topics )
744 ONOStopics = [ j['topic'] for j in parsedLeaders ]
745 for topic in topics:
746 if topic not in ONOStopics:
747 main.log.error( "Error: " + topic +
748 " not in leaders" )
Jon Hallc9eabec2015-06-10 14:33:14 -0700749 missing = True
Jon Hall5cfd23c2015-03-19 11:40:57 -0700750 else:
751 main.log.error( "leaders() returned None" )
752 except ( ValueError, TypeError ):
753 main.log.exception( "Error parsing leaders" )
754 main.log.error( repr( leaders ) )
Jon Hallc9eabec2015-06-10 14:33:14 -0700755 # Check all nodes
756 if missing:
757 for node in CLIs:
758 response = node.leaders( jsonFormat=False)
759 main.log.warn( str( node.name ) + " leaders output: \n" +
760 str( response ) )
761
Jon Hall5cfd23c2015-03-19 11:40:57 -0700762 partitions = main.ONOScli1.partitions()
763 try:
764 if partitions :
765 parsedPartitions = json.loads( partitions )
766 main.log.warn( json.dumps( parsedPartitions,
767 sort_keys=True,
768 indent=4,
769 separators=( ',', ': ' ) ) )
770 # TODO check for a leader in all paritions
771 # TODO check for consistency among nodes
772 else:
773 main.log.error( "partitions() returned None" )
774 except ( ValueError, TypeError ):
775 main.log.exception( "Error parsing partitions" )
776 main.log.error( repr( partitions ) )
777 pendingMap = main.ONOScli1.pendingMap()
778 try:
779 if pendingMap :
780 parsedPending = json.loads( pendingMap )
781 main.log.warn( json.dumps( parsedPending,
782 sort_keys=True,
783 indent=4,
784 separators=( ',', ': ' ) ) )
785 # TODO check something here?
786 else:
787 main.log.error( "pendingMap() returned None" )
788 except ( ValueError, TypeError ):
789 main.log.exception( "Error parsing pending map" )
790 main.log.error( repr( pendingMap ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800791
Jon Hall6aec96b2015-01-19 14:49:31 -0800792 def CASE4( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800793 """
794 Ping across added host intents
795 """
Jon Hallfebb1c72015-03-05 13:30:09 -0800796 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700797 import time
798 assert numControllers, "numControllers not defined"
799 assert main, "main not defined"
800 assert utilities.assert_equals, "utilities.assert_equals not defined"
801 assert CLIs, "CLIs not defined"
802 assert nodes, "nodes not defined"
Jon Hallfeff3082015-05-19 10:23:26 -0700803 main.case( "Verify connectivity by sendind traffic across Intents" )
804 main.caseExplaination = "Ping across added host intents to check " +\
805 "functionality and check the state of " +\
806 "the intent"
807 main.step( "Ping across added host intents" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800808 PingResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800809 for i in range( 8, 18 ):
Jon Hall21270ac2015-02-16 17:59:55 -0800810 ping = main.Mininet1.pingHost( src="h" + str( i ),
811 target="h" + str( i + 10 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800812 PingResult = PingResult and ping
Jon Hall6aec96b2015-01-19 14:49:31 -0800813 if ping == main.FALSE:
814 main.log.warn( "Ping failed between h" + str( i ) +
815 " and h" + str( i + 10 ) )
816 elif ping == main.TRUE:
817 main.log.info( "Ping test passed!" )
Jon Hall21270ac2015-02-16 17:59:55 -0800818 # Don't set PingResult or you'd override failures
Jon Hall8f89dda2015-01-22 16:03:33 -0800819 if PingResult == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -0700820 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -0800821 "Intents have not been installed correctly, pings failed." )
Jon Hall58c76b72015-02-23 11:09:24 -0800822 # TODO: pretty print
Jon Hall5cfd23c2015-03-19 11:40:57 -0700823 main.log.warn( "ONOS1 intents: " )
824 try:
825 tmpIntents = main.ONOScli1.intents()
826 main.log.warn( json.dumps( json.loads( tmpIntents ),
827 sort_keys=True,
828 indent=4,
829 separators=( ',', ': ' ) ) )
830 except ( ValueError, TypeError ):
831 main.log.warn( repr( tmpIntents ) )
Jon Hall6aec96b2015-01-19 14:49:31 -0800832 utilities.assert_equals(
833 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800834 actual=PingResult,
Jon Hall6aec96b2015-01-19 14:49:31 -0800835 onpass="Intents have been installed correctly and pings work",
836 onfail="Intents have not been installed correctly, pings failed." )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800837
Jon Hallfeff3082015-05-19 10:23:26 -0700838 main.step( "Check Intent state" )
Jon Hall40d2cbd2015-06-03 16:24:29 -0700839 installedCheck = False
Jon Hallc9eabec2015-06-10 14:33:14 -0700840 loopCount = 0
841 while not installedCheck and loopCount < 40:
Jon Hall40d2cbd2015-06-03 16:24:29 -0700842 installedCheck = True
843 # Print the intent states
844 intents = main.ONOScli1.intents()
845 intentStates = []
846 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
847 count = 0
848 # Iter through intents of a node
849 try:
850 for intent in json.loads( intents ):
851 state = intent.get( 'state', None )
852 if "INSTALLED" not in state:
853 installedCheck = False
854 intentId = intent.get( 'id', None )
855 intentStates.append( ( intentId, state ) )
856 except ( ValueError, TypeError ):
857 main.log.exception( "Error parsing intents." )
858 # Print states
859 intentStates.sort()
860 for i, s in intentStates:
861 count += 1
862 main.log.info( "%-6s%-15s%-15s" %
863 ( str( count ), str( i ), str( s ) ) )
864 if not installedCheck:
865 time.sleep( 1 )
Jon Hallc9eabec2015-06-10 14:33:14 -0700866 loopCount += 1
Jon Hallfeff3082015-05-19 10:23:26 -0700867 utilities.assert_equals( expect=True, actual=installedCheck,
868 onpass="Intents are all INSTALLED",
Jon Hall40d2cbd2015-06-03 16:24:29 -0700869 onfail="Intents are not all in " +
Jon Hallfeff3082015-05-19 10:23:26 -0700870 "INSTALLED state" )
871
872 main.step( "Check leadership of topics" )
873 leaders = main.ONOScli1.leaders()
874 topicCheck = main.TRUE
875 try:
876 if leaders:
877 parsedLeaders = json.loads( leaders )
878 main.log.warn( json.dumps( parsedLeaders,
879 sort_keys=True,
880 indent=4,
881 separators=( ',', ': ' ) ) )
882 # check for all intent partitions
883 # check for election
884 # TODO: Look at Devices as topics now that it uses this system
885 topics = []
886 for i in range( 14 ):
887 topics.append( "intent-partition-" + str( i ) )
888 # FIXME: this should only be after we start the app
889 # FIXME: topics.append( "org.onosproject.election" )
890 # Print leaders output
891 main.log.debug( topics )
892 ONOStopics = [ j['topic'] for j in parsedLeaders ]
893 for topic in topics:
894 if topic not in ONOStopics:
895 main.log.error( "Error: " + topic +
896 " not in leaders" )
897 topicCheck = main.FALSE
898 else:
899 main.log.error( "leaders() returned None" )
900 topicCheck = main.FALSE
901 except ( ValueError, TypeError ):
902 topicCheck = main.FALSE
903 main.log.exception( "Error parsing leaders" )
904 main.log.error( repr( leaders ) )
905 # TODO: Check for a leader of these topics
Jon Hallc9eabec2015-06-10 14:33:14 -0700906 # Check all nodes
907 if topicCheck:
908 for node in CLIs:
909 response = node.leaders( jsonFormat=False)
910 main.log.warn( str( node.name ) + " leaders output: \n" +
911 str( response ) )
912
Jon Hallfeff3082015-05-19 10:23:26 -0700913 utilities.assert_equals( expect=main.TRUE, actual=topicCheck,
914 onpass="intent Partitions is in leaders",
915 onfail="Some topics were lost " )
916 # Print partitions
917 partitions = main.ONOScli1.partitions()
918 try:
919 if partitions :
920 parsedPartitions = json.loads( partitions )
921 main.log.warn( json.dumps( parsedPartitions,
922 sort_keys=True,
923 indent=4,
924 separators=( ',', ': ' ) ) )
925 # TODO check for a leader in all paritions
926 # TODO check for consistency among nodes
927 else:
928 main.log.error( "partitions() returned None" )
929 except ( ValueError, TypeError ):
930 main.log.exception( "Error parsing partitions" )
931 main.log.error( repr( partitions ) )
932 # Print Pending Map
933 pendingMap = main.ONOScli1.pendingMap()
934 try:
935 if pendingMap :
936 parsedPending = json.loads( pendingMap )
937 main.log.warn( json.dumps( parsedPending,
938 sort_keys=True,
939 indent=4,
940 separators=( ',', ': ' ) ) )
941 # TODO check something here?
942 else:
943 main.log.error( "pendingMap() returned None" )
944 except ( ValueError, TypeError ):
945 main.log.exception( "Error parsing pending map" )
946 main.log.error( repr( pendingMap ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700947
Jon Hall63604932015-02-26 17:09:50 -0800948 if not installedCheck:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700949 main.log.info( "Waiting 60 seconds to see if the state of " +
950 "intents change" )
Jon Hall63604932015-02-26 17:09:50 -0800951 time.sleep( 60 )
952 # Print the intent states
953 intents = main.ONOScli1.intents()
954 intentStates = []
955 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
956 count = 0
957 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700958 try:
959 for intent in json.loads( intents ):
960 state = intent.get( 'state', None )
961 if "INSTALLED" not in state:
962 installedCheck = False
963 intentId = intent.get( 'id', None )
964 intentStates.append( ( intentId, state ) )
965 except ( ValueError, TypeError ):
966 main.log.exception( "Error parsing intents." )
Jon Hall63604932015-02-26 17:09:50 -0800967 intentStates.sort()
968 for i, s in intentStates:
969 count += 1
970 main.log.info( "%-6s%-15s%-15s" %
971 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700972 leaders = main.ONOScli1.leaders()
973 try:
Jon Hallc9eabec2015-06-10 14:33:14 -0700974 missing = False
Jon Hall5cfd23c2015-03-19 11:40:57 -0700975 if leaders:
976 parsedLeaders = json.loads( leaders )
977 main.log.warn( json.dumps( parsedLeaders,
978 sort_keys=True,
979 indent=4,
980 separators=( ',', ': ' ) ) )
981 # check for all intent partitions
982 # check for election
983 topics = []
984 for i in range( 14 ):
985 topics.append( "intent-partition-" + str( i ) )
986 # FIXME: this should only be after we start the app
987 topics.append( "org.onosproject.election" )
988 main.log.debug( topics )
989 ONOStopics = [ j['topic'] for j in parsedLeaders ]
990 for topic in topics:
991 if topic not in ONOStopics:
992 main.log.error( "Error: " + topic +
993 " not in leaders" )
Jon Hallc9eabec2015-06-10 14:33:14 -0700994 missing = True
Jon Hall5cfd23c2015-03-19 11:40:57 -0700995 else:
996 main.log.error( "leaders() returned None" )
997 except ( ValueError, TypeError ):
998 main.log.exception( "Error parsing leaders" )
999 main.log.error( repr( leaders ) )
Jon Hallc9eabec2015-06-10 14:33:14 -07001000 if missing:
1001 for node in CLIs:
1002 response = node.leaders( jsonFormat=False)
1003 main.log.warn( str( node.name ) + " leaders output: \n" +
1004 str( response ) )
1005
Jon Hall5cfd23c2015-03-19 11:40:57 -07001006 partitions = main.ONOScli1.partitions()
1007 try:
1008 if partitions :
1009 parsedPartitions = json.loads( partitions )
1010 main.log.warn( json.dumps( parsedPartitions,
1011 sort_keys=True,
1012 indent=4,
1013 separators=( ',', ': ' ) ) )
1014 # TODO check for a leader in all paritions
1015 # TODO check for consistency among nodes
1016 else:
1017 main.log.error( "partitions() returned None" )
1018 except ( ValueError, TypeError ):
1019 main.log.exception( "Error parsing partitions" )
1020 main.log.error( repr( partitions ) )
1021 pendingMap = main.ONOScli1.pendingMap()
1022 try:
1023 if pendingMap :
1024 parsedPending = json.loads( pendingMap )
1025 main.log.warn( json.dumps( parsedPending,
1026 sort_keys=True,
1027 indent=4,
1028 separators=( ',', ': ' ) ) )
1029 # TODO check something here?
1030 else:
1031 main.log.error( "pendingMap() returned None" )
1032 except ( ValueError, TypeError ):
1033 main.log.exception( "Error parsing pending map" )
1034 main.log.error( repr( pendingMap ) )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001035 # Print flowrules
1036 main.log.debug( CLIs[0].flows( jsonFormat=False ) )
Jon Hallfeff3082015-05-19 10:23:26 -07001037 main.step( "Wait a minute then ping again" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001038 # the wait is above
Jon Hallfeff3082015-05-19 10:23:26 -07001039 PingResult = main.TRUE
1040 for i in range( 8, 18 ):
1041 ping = main.Mininet1.pingHost( src="h" + str( i ),
1042 target="h" + str( i + 10 ) )
1043 PingResult = PingResult and ping
1044 if ping == main.FALSE:
1045 main.log.warn( "Ping failed between h" + str( i ) +
1046 " and h" + str( i + 10 ) )
1047 elif ping == main.TRUE:
1048 main.log.info( "Ping test passed!" )
1049 # Don't set PingResult or you'd override failures
1050 if PingResult == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001051 main.log.error(
Jon Hallfeff3082015-05-19 10:23:26 -07001052 "Intents have not been installed correctly, pings failed." )
1053 # TODO: pretty print
1054 main.log.warn( "ONOS1 intents: " )
1055 try:
1056 tmpIntents = main.ONOScli1.intents()
1057 main.log.warn( json.dumps( json.loads( tmpIntents ),
1058 sort_keys=True,
1059 indent=4,
1060 separators=( ',', ': ' ) ) )
1061 except ( ValueError, TypeError ):
1062 main.log.warn( repr( tmpIntents ) )
1063 utilities.assert_equals(
1064 expect=main.TRUE,
1065 actual=PingResult,
1066 onpass="Intents have been installed correctly and pings work",
1067 onfail="Intents have not been installed correctly, pings failed." )
1068
Jon Hall6aec96b2015-01-19 14:49:31 -08001069 def CASE5( self, main ):
1070 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001071 Reading state of ONOS
Jon Hall6aec96b2015-01-19 14:49:31 -08001072 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001073 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001074 import time
1075 assert numControllers, "numControllers not defined"
1076 assert main, "main not defined"
1077 assert utilities.assert_equals, "utilities.assert_equals not defined"
1078 assert CLIs, "CLIs not defined"
1079 assert nodes, "nodes not defined"
Jon Hallb87f3db2015-07-06 03:10:27 -07001080 # assumes that sts is already in you PYTHONPATH
1081 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -08001082
Jon Hall6aec96b2015-01-19 14:49:31 -08001083 main.case( "Setting up and gathering data for current state" )
1084 # The general idea for this test case is to pull the state of
1085 # ( intents,flows, topology,... ) from each ONOS node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001086 # We can then compare them with each other and also with past states
Jon Hall73cf9cc2014-11-20 22:28:38 -08001087
Jon Hall5cfd23c2015-03-19 11:40:57 -07001088 main.step( "Check that each switch has a master" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001089 global mastershipState
Jon Hall5cfd23c2015-03-19 11:40:57 -07001090 mastershipState = '[]'
Jon Hall94fd0472014-12-08 11:52:42 -08001091
Jon Hall6aec96b2015-01-19 14:49:31 -08001092 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -07001093 rolesNotNull = main.TRUE
1094 threads = []
1095 for i in range( numControllers ):
1096 t = main.Thread( target=CLIs[i].rolesNotNull,
1097 name="rolesNotNull-" + str( i ),
1098 args=[] )
1099 threads.append( t )
1100 t.start()
1101
1102 for t in threads:
1103 t.join()
1104 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001105 utilities.assert_equals(
1106 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001107 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001108 onpass="Each device has a master",
1109 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001110
Jon Hall5cfd23c2015-03-19 11:40:57 -07001111 main.step( "Get the Mastership of each switch from each controller" )
1112 ONOSMastership = []
1113 mastershipCheck = main.FALSE
1114 consistentMastership = True
1115 rolesResults = True
1116 threads = []
1117 for i in range( numControllers ):
1118 t = main.Thread( target=CLIs[i].roles,
1119 name="roles-" + str( i ),
1120 args=[] )
1121 threads.append( t )
1122 t.start()
1123
1124 for t in threads:
1125 t.join()
1126 ONOSMastership.append( t.result )
1127
1128 for i in range( numControllers ):
1129 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001130 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001131 " roles" )
1132 main.log.warn(
1133 "ONOS" + str( i + 1 ) + " mastership response: " +
1134 repr( ONOSMastership[i] ) )
1135 rolesResults = False
1136 utilities.assert_equals(
1137 expect=True,
1138 actual=rolesResults,
1139 onpass="No error in reading roles output",
1140 onfail="Error in reading roles from ONOS" )
1141
1142 main.step( "Check for consistency in roles from each controller" )
1143 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001144 main.log.info(
Jon Hall6aec96b2015-01-19 14:49:31 -08001145 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001146 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001147 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001148 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001149 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001150 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001151 onpass="Switch roles are consistent across all ONOS nodes",
1152 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001153
Jon Hall5cfd23c2015-03-19 11:40:57 -07001154 if rolesResults and not consistentMastership:
1155 for i in range( numControllers ):
1156 try:
1157 main.log.warn(
1158 "ONOS" + str( i + 1 ) + " roles: ",
1159 json.dumps(
1160 json.loads( ONOSMastership[ i ] ),
1161 sort_keys=True,
1162 indent=4,
1163 separators=( ',', ': ' ) ) )
1164 except ( ValueError, TypeError ):
1165 main.log.warn( repr( ONOSMastership[ i ] ) )
1166 elif rolesResults and consistentMastership:
1167 mastershipCheck = main.TRUE
1168 mastershipState = ONOSMastership[ 0 ]
1169
Jon Hall6aec96b2015-01-19 14:49:31 -08001170 main.step( "Get the intents from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001171 global intentState
1172 intentState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001173 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001174 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001175 consistentIntents = True
1176 intentsResults = True
1177 threads = []
1178 for i in range( numControllers ):
1179 t = main.Thread( target=CLIs[i].intents,
1180 name="intents-" + str( i ),
1181 args=[],
1182 kwargs={ 'jsonFormat': True } )
1183 threads.append( t )
1184 t.start()
1185
1186 for t in threads:
1187 t.join()
1188 ONOSIntents.append( t.result )
1189
1190 for i in range( numControllers ):
1191 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001192 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001193 " intents" )
1194 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1195 repr( ONOSIntents[ i ] ) )
1196 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001197 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001198 expect=True,
1199 actual=intentsResults,
1200 onpass="No error in reading intents output",
1201 onfail="Error in reading intents from ONOS" )
1202
1203 main.step( "Check for consistency in Intents from each controller" )
1204 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001205 main.log.info( "Intents are consistent across all ONOS " +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001206 "nodes" )
1207 else:
1208 consistentIntents = False
Jon Hall40d2cbd2015-06-03 16:24:29 -07001209 main.log.error( "Intents not consistent" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001210 utilities.assert_equals(
1211 expect=True,
1212 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001213 onpass="Intents are consistent across all ONOS nodes",
1214 onfail="ONOS nodes have different views of intents" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001215
Jon Hall390696c2015-05-05 17:13:41 -07001216 if intentsResults:
1217 # Try to make it easy to figure out what is happening
1218 #
1219 # Intent ONOS1 ONOS2 ...
1220 # 0x01 INSTALLED INSTALLING
1221 # ... ... ...
1222 # ... ... ...
1223 title = " Id"
1224 for n in range( numControllers ):
1225 title += " " * 10 + "ONOS" + str( n + 1 )
1226 main.log.warn( title )
1227 # get all intent keys in the cluster
1228 keys = []
1229 for nodeStr in ONOSIntents:
1230 node = json.loads( nodeStr )
1231 for intent in node:
1232 keys.append( intent.get( 'id' ) )
1233 keys = set( keys )
1234 for key in keys:
1235 row = "%-13s" % key
1236 for nodeStr in ONOSIntents:
1237 node = json.loads( nodeStr )
1238 for intent in node:
1239 if intent.get( 'id', "Error" ) == key:
1240 row += "%-15s" % intent.get( 'state' )
1241 main.log.warn( row )
1242 # End table view
1243
Jon Hall5cfd23c2015-03-19 11:40:57 -07001244 if intentsResults and not consistentIntents:
Jon Hall390696c2015-05-05 17:13:41 -07001245 # print the json objects
Jon Hall5cfd23c2015-03-19 11:40:57 -07001246 n = len(ONOSIntents)
Jon Hall390696c2015-05-05 17:13:41 -07001247 main.log.debug( "ONOS" + str( n ) + " intents: " )
1248 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1249 sort_keys=True,
1250 indent=4,
1251 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001252 for i in range( numControllers ):
1253 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
Jon Hall390696c2015-05-05 17:13:41 -07001254 main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
1255 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1256 sort_keys=True,
1257 indent=4,
1258 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001259 else:
Jon Hall390696c2015-05-05 17:13:41 -07001260 main.log.debug( nodes[ i ].name + " intents match ONOS" +
1261 str( n ) + " intents" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001262 elif intentsResults and consistentIntents:
1263 intentCheck = main.TRUE
1264 intentState = ONOSIntents[ 0 ]
1265
Jon Hall6aec96b2015-01-19 14:49:31 -08001266 main.step( "Get the flows from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001267 global flowState
1268 flowState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001269 ONOSFlows = []
1270 ONOSFlowsJson = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001271 flowCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001272 consistentFlows = True
1273 flowsResults = True
1274 threads = []
1275 for i in range( numControllers ):
1276 t = main.Thread( target=CLIs[i].flows,
1277 name="flows-" + str( i ),
1278 args=[],
1279 kwargs={ 'jsonFormat': True } )
1280 threads.append( t )
1281 t.start()
1282
Jon Halla9d26da2015-03-30 16:45:32 -07001283 # NOTE: Flows command can take some time to run
Jon Hall5cfd23c2015-03-19 11:40:57 -07001284 time.sleep(30)
1285 for t in threads:
1286 t.join()
1287 result = t.result
1288 ONOSFlows.append( result )
1289
1290 for i in range( numControllers ):
1291 num = str( i + 1 )
1292 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001293 main.log.error( "Error in getting ONOS" + num + " flows" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001294 main.log.warn( "ONOS" + num + " flows response: " +
1295 repr( ONOSFlows[ i ] ) )
1296 flowsResults = False
1297 ONOSFlowsJson.append( None )
Jon Hall58c76b72015-02-23 11:09:24 -08001298 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001299 try:
1300 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1301 except ( ValueError, TypeError ):
1302 # FIXME: change this to log.error?
1303 main.log.exception( "Error in parsing ONOS" + num +
1304 " response as json." )
1305 main.log.error( repr( ONOSFlows[ i ] ) )
1306 ONOSFlowsJson.append( None )
1307 flowsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001308 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001309 expect=True,
1310 actual=flowsResults,
1311 onpass="No error in reading flows output",
1312 onfail="Error in reading flows from ONOS" )
1313
1314 main.step( "Check for consistency in Flows from each controller" )
1315 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1316 if all( tmp ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001317 main.log.info( "Flow count is consistent across all ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001318 else:
1319 consistentFlows = False
1320 utilities.assert_equals(
1321 expect=True,
1322 actual=consistentFlows,
Jon Hall6aec96b2015-01-19 14:49:31 -08001323 onpass="The flow count is consistent across all ONOS nodes",
1324 onfail="ONOS nodes have different flow counts" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001325
Jon Hall5cfd23c2015-03-19 11:40:57 -07001326 if flowsResults and not consistentFlows:
1327 for i in range( numControllers ):
1328 try:
1329 main.log.warn(
1330 "ONOS" + str( i + 1 ) + " flows: " +
1331 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1332 indent=4, separators=( ',', ': ' ) ) )
1333 except ( ValueError, TypeError ):
1334 main.log.warn(
1335 "ONOS" + str( i + 1 ) + " flows: " +
1336 repr( ONOSFlows[ i ] ) )
1337 elif flowsResults and consistentFlows:
1338 flowCheck = main.TRUE
1339 flowState = ONOSFlows[ 0 ]
1340
Jon Hall6aec96b2015-01-19 14:49:31 -08001341 main.step( "Get the OF Table entries" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001342 global flows
Jon Hall6aec96b2015-01-19 14:49:31 -08001343 flows = []
1344 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001345 flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001346 if flowCheck == main.FALSE:
1347 for table in flows:
1348 main.log.warn( table )
Jon Hall6aec96b2015-01-19 14:49:31 -08001349 # TODO: Compare switch flow tables with ONOS flow tables
Jon Hall73cf9cc2014-11-20 22:28:38 -08001350
Jon Hall6aec96b2015-01-19 14:49:31 -08001351 main.step( "Start continuous pings" )
1352 main.Mininet2.pingLong(
1353 src=main.params[ 'PING' ][ 'source1' ],
1354 target=main.params[ 'PING' ][ 'target1' ],
1355 pingTime=500 )
1356 main.Mininet2.pingLong(
1357 src=main.params[ 'PING' ][ 'source2' ],
1358 target=main.params[ 'PING' ][ 'target2' ],
1359 pingTime=500 )
1360 main.Mininet2.pingLong(
1361 src=main.params[ 'PING' ][ 'source3' ],
1362 target=main.params[ 'PING' ][ 'target3' ],
1363 pingTime=500 )
1364 main.Mininet2.pingLong(
1365 src=main.params[ 'PING' ][ 'source4' ],
1366 target=main.params[ 'PING' ][ 'target4' ],
1367 pingTime=500 )
1368 main.Mininet2.pingLong(
1369 src=main.params[ 'PING' ][ 'source5' ],
1370 target=main.params[ 'PING' ][ 'target5' ],
1371 pingTime=500 )
1372 main.Mininet2.pingLong(
1373 src=main.params[ 'PING' ][ 'source6' ],
1374 target=main.params[ 'PING' ][ 'target6' ],
1375 pingTime=500 )
1376 main.Mininet2.pingLong(
1377 src=main.params[ 'PING' ][ 'source7' ],
1378 target=main.params[ 'PING' ][ 'target7' ],
1379 pingTime=500 )
1380 main.Mininet2.pingLong(
1381 src=main.params[ 'PING' ][ 'source8' ],
1382 target=main.params[ 'PING' ][ 'target8' ],
1383 pingTime=500 )
1384 main.Mininet2.pingLong(
1385 src=main.params[ 'PING' ][ 'source9' ],
1386 target=main.params[ 'PING' ][ 'target9' ],
1387 pingTime=500 )
1388 main.Mininet2.pingLong(
1389 src=main.params[ 'PING' ][ 'source10' ],
1390 target=main.params[ 'PING' ][ 'target10' ],
1391 pingTime=500 )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001392
Jon Hall6aec96b2015-01-19 14:49:31 -08001393 main.step( "Collecting topology information from ONOS" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001394 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001395 threads = []
1396 for i in range( numControllers ):
1397 t = main.Thread( target=CLIs[i].devices,
1398 name="devices-" + str( i ),
1399 args=[ ] )
1400 threads.append( t )
1401 t.start()
1402
1403 for t in threads:
1404 t.join()
1405 devices.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001406 hosts = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001407 threads = []
1408 for i in range( numControllers ):
1409 t = main.Thread( target=CLIs[i].hosts,
1410 name="hosts-" + str( i ),
1411 args=[ ] )
1412 threads.append( t )
1413 t.start()
1414
1415 for t in threads:
1416 t.join()
1417 try:
1418 hosts.append( json.loads( t.result ) )
1419 except ( ValueError, TypeError ):
1420 # FIXME: better handling of this, print which node
1421 # Maybe use thread name?
1422 main.log.exception( "Error parsing json output of hosts" )
1423 # FIXME: should this be an empty json object instead?
1424 hosts.append( None )
1425
Jon Hall73cf9cc2014-11-20 22:28:38 -08001426 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001427 threads = []
1428 for i in range( numControllers ):
1429 t = main.Thread( target=CLIs[i].ports,
1430 name="ports-" + str( i ),
1431 args=[ ] )
1432 threads.append( t )
1433 t.start()
1434
1435 for t in threads:
1436 t.join()
1437 ports.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001438 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001439 threads = []
1440 for i in range( numControllers ):
1441 t = main.Thread( target=CLIs[i].links,
1442 name="links-" + str( i ),
1443 args=[ ] )
1444 threads.append( t )
1445 t.start()
1446
1447 for t in threads:
1448 t.join()
1449 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001450 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001451 threads = []
1452 for i in range( numControllers ):
1453 t = main.Thread( target=CLIs[i].clusters,
1454 name="clusters-" + str( i ),
1455 args=[ ] )
1456 threads.append( t )
1457 t.start()
1458
1459 for t in threads:
1460 t.join()
1461 clusters.append( t.result )
Jon Hall529a37f2015-01-28 10:02:00 -08001462 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001463
Jon Hall6aec96b2015-01-19 14:49:31 -08001464 # hosts
Jon Hall390696c2015-05-05 17:13:41 -07001465 main.step( "Host view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001466 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001467 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001468 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001469 if "Error" not in hosts[ controller ]:
1470 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001471 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001472 else: # hosts not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07001473 main.log.error( "hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001474 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001475 " is inconsistent with ONOS1" )
1476 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001477 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001478
1479 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001480 main.log.error( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001481 controllerStr )
1482 consistentHostsResult = main.FALSE
1483 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001484 " hosts response: " +
1485 repr( hosts[ controller ] ) )
1486 utilities.assert_equals(
1487 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001488 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001489 onpass="Hosts view is consistent across all ONOS nodes",
1490 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001491
Jon Hall390696c2015-05-05 17:13:41 -07001492 main.step( "Each host has an IP address" )
Jon Hall58c76b72015-02-23 11:09:24 -08001493 ipResult = main.TRUE
1494 for controller in range( 0, len( hosts ) ):
1495 controllerStr = str( controller + 1 )
1496 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07001497 if not host.get( 'ipAddresses', [ ] ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001498 main.log.error( "DEBUG:Error with host ips on controller" +
1499 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001500 ipResult = main.FALSE
1501 utilities.assert_equals(
1502 expect=main.TRUE,
1503 actual=ipResult,
1504 onpass="The ips of the hosts aren't empty",
1505 onfail="The ip of at least one host is missing" )
1506
Jon Hall6aec96b2015-01-19 14:49:31 -08001507 # Strongly connected clusters of devices
Jon Hall390696c2015-05-05 17:13:41 -07001508 main.step( "Cluster view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001509 consistentClustersResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001510 for controller in range( len( clusters ) ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001511 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001512 if "Error" not in clusters[ controller ]:
1513 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001514 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001515 else: # clusters not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07001516 main.log.error( "clusters from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001517 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001518 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001519
1520 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001521 main.log.error( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001522 "from ONOS" + controllerStr )
1523 consistentClustersResult = main.FALSE
1524 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001525 " clusters response: " +
1526 repr( clusters[ controller ] ) )
1527 utilities.assert_equals(
1528 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001529 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001530 onpass="Clusters view is consistent across all ONOS nodes",
1531 onfail="ONOS nodes have different views of clusters" )
1532 # there should always only be one cluster
Jon Hall390696c2015-05-05 17:13:41 -07001533 main.step( "Cluster view correct across ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001534 try:
1535 numClusters = len( json.loads( clusters[ 0 ] ) )
1536 except ( ValueError, TypeError ):
1537 main.log.exception( "Error parsing clusters[0]: " +
1538 repr( clusters[ 0 ] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001539 clusterResults = main.FALSE
1540 if numClusters == 1:
1541 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001542 utilities.assert_equals(
1543 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08001544 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08001545 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08001546 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08001547
Jon Hall6aec96b2015-01-19 14:49:31 -08001548 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001549 devicesResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08001550 linksResults = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07001551 hostsResults = main.TRUE
1552 mnSwitches = main.Mininet1.getSwitches()
1553 mnLinks = main.Mininet1.getLinks()
1554 mnHosts = main.Mininet1.getHosts()
Jon Hall8f89dda2015-01-22 16:03:33 -08001555 for controller in range( numControllers ):
1556 controllerStr = str( controller + 1 )
Jon Hallafa8a472015-06-12 14:02:42 -07001557 if devices[ controller ] and ports[ controller ] and\
1558 "Error" not in devices[ controller ] and\
1559 "Error" not in ports[ controller ]:
1560
Jon Hall8f89dda2015-01-22 16:03:33 -08001561 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hallafa8a472015-06-12 14:02:42 -07001562 mnSwitches,
1563 json.loads( devices[ controller ] ),
1564 json.loads( ports[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001565 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001566 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001567 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001568 actual=currentDevicesResult,
1569 onpass="ONOS" + controllerStr +
1570 " Switches view is correct",
1571 onfail="ONOS" + controllerStr +
1572 " Switches view is incorrect" )
Jon Hallafa8a472015-06-12 14:02:42 -07001573 if links[ controller ] and "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001574 currentLinksResult = main.Mininet1.compareLinks(
Jon Hallafa8a472015-06-12 14:02:42 -07001575 mnSwitches, mnLinks,
1576 json.loads( links[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001577 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001578 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001579 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001580 actual=currentLinksResult,
1581 onpass="ONOS" + controllerStr +
1582 " links view is correct",
1583 onfail="ONOS" + controllerStr +
1584 " links view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001585
Jon Hallafa8a472015-06-12 14:02:42 -07001586 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1587 currentHostsResult = main.Mininet1.compareHosts(
1588 mnHosts,
1589 hosts[ controller ] )
1590 else:
1591 currentHostsResult = main.FALSE
1592 utilities.assert_equals( expect=main.TRUE,
1593 actual=currentHostsResult,
1594 onpass="ONOS" + controllerStr +
1595 " hosts exist in Mininet",
1596 onfail="ONOS" + controllerStr +
1597 " hosts don't match Mininet" )
Jon Hallb6a54872015-06-12 14:02:42 -07001598
Jon Hallafa8a472015-06-12 14:02:42 -07001599 devicesResults = devicesResults and currentDevicesResult
1600 linksResults = linksResults and currentLinksResult
1601 hostsResults = hostsResults and currentHostsResult
1602
1603 main.step( "Device information is correct" )
1604 utilities.assert_equals(
1605 expect=main.TRUE,
1606 actual=devicesResults,
1607 onpass="Device information is correct",
1608 onfail="Device information is incorrect" )
1609
1610 main.step( "Links are correct" )
1611 utilities.assert_equals(
1612 expect=main.TRUE,
1613 actual=linksResults,
1614 onpass="Link are correct",
1615 onfail="Links are incorrect" )
1616
1617 main.step( "Hosts are correct" )
1618 utilities.assert_equals(
1619 expect=main.TRUE,
1620 actual=hostsResults,
1621 onpass="Hosts are correct",
1622 onfail="Hosts are incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001623
Jon Hall6aec96b2015-01-19 14:49:31 -08001624 def CASE6( self, main ):
1625 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001626 The Failure case.
Jon Hall6aec96b2015-01-19 14:49:31 -08001627 """
Jon Hall94fd0472014-12-08 11:52:42 -08001628 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001629 assert numControllers, "numControllers not defined"
1630 assert main, "main not defined"
1631 assert utilities.assert_equals, "utilities.assert_equals not defined"
1632 assert CLIs, "CLIs not defined"
1633 assert nodes, "nodes not defined"
Jon Hall5cfd23c2015-03-19 11:40:57 -07001634 main.case( "Restart minority of ONOS nodes" )
Jon Hall390696c2015-05-05 17:13:41 -07001635 main.step( "Killing 3 ONOS nodes" )
Jon Hallfeff3082015-05-19 10:23:26 -07001636 killTime = time.time()
Jon Hall390696c2015-05-05 17:13:41 -07001637 # TODO: Randomize these nodes or base this on partitions
Jon Hall5cfd23c2015-03-19 11:40:57 -07001638 # TODO: use threads in this case
Jon Hall390696c2015-05-05 17:13:41 -07001639 killResults = main.ONOSbench.onosKill( nodes[0].ip_address )
Jon Hall6aec96b2015-01-19 14:49:31 -08001640 time.sleep( 10 )
Jon Hall390696c2015-05-05 17:13:41 -07001641 killResults = killResults and\
1642 main.ONOSbench.onosKill( nodes[1].ip_address )
Jon Hall6aec96b2015-01-19 14:49:31 -08001643 time.sleep( 10 )
Jon Hall390696c2015-05-05 17:13:41 -07001644 killResults = killResults and\
1645 main.ONOSbench.onosKill( nodes[2].ip_address )
1646 utilities.assert_equals( expect=main.TRUE, actual=killResults,
1647 onpass="ONOS Killed successfully",
1648 onfail="ONOS kill NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001649
Jon Hall6aec96b2015-01-19 14:49:31 -08001650 main.step( "Checking if ONOS is up yet" )
Jon Hallffb386d2014-11-21 13:43:38 -08001651 count = 0
Jon Hall8f89dda2015-01-22 16:03:33 -08001652 onosIsupResult = main.FALSE
1653 while onosIsupResult == main.FALSE and count < 10:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001654 onos1Isup = main.ONOSbench.isup( nodes[0].ip_address )
1655 onos2Isup = main.ONOSbench.isup( nodes[1].ip_address )
1656 onos3Isup = main.ONOSbench.isup( nodes[2].ip_address )
Jon Hall8f89dda2015-01-22 16:03:33 -08001657 onosIsupResult = onos1Isup and onos2Isup and onos3Isup
Jon Hallffb386d2014-11-21 13:43:38 -08001658 count = count + 1
Jon Hall73cf9cc2014-11-20 22:28:38 -08001659 # TODO: if it becomes an issue, we can retry this step a few times
Jon Hall390696c2015-05-05 17:13:41 -07001660 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1661 onpass="ONOS restarted successfully",
1662 onfail="ONOS restart NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001663
Jon Hall390696c2015-05-05 17:13:41 -07001664 main.step( "Restarting ONOS CLIs" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001665 cliResult1 = main.ONOScli1.startOnosCli( nodes[0].ip_address )
1666 cliResult2 = main.ONOScli2.startOnosCli( nodes[1].ip_address )
1667 cliResult3 = main.ONOScli3.startOnosCli( nodes[2].ip_address )
Jon Hall8f89dda2015-01-22 16:03:33 -08001668 cliResults = cliResult1 and cliResult2 and cliResult3
Jon Hall390696c2015-05-05 17:13:41 -07001669 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1670 onpass="ONOS cli restarted",
1671 onfail="ONOS cli did not restart" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001672
Jon Hall21270ac2015-02-16 17:59:55 -08001673 # Grab the time of restart so we chan check how long the gossip
1674 # protocol has had time to work
Jon Hallfeff3082015-05-19 10:23:26 -07001675 main.restartTime = time.time() - killTime
1676 main.log.debug( "Restart time: " + str( main.restartTime ) )
1677 '''
1678 # FIXME: revisit test plan for election with madan
1679 # Rerun for election on restarted nodes
1680 run1 = CLIs[0].electionTestRun()
1681 run2 = CLIs[1].electionTestRun()
1682 run3 = CLIs[2].electionTestRun()
1683 runResults = run1 and run2 and run3
1684 utilities.assert_equals( expect=main.TRUE, actual=runResults,
1685 onpass="Reran for election",
1686 onfail="Failed to rerun for election" )
1687 '''
1688 # TODO: MAke this configurable. Also, we are breaking the above timer
1689 time.sleep( 60 )
1690 main.log.debug( CLIs[0].nodes( jsonFormat=False ) )
1691 main.log.debug( CLIs[0].leaders( jsonFormat=False ) )
1692 main.log.debug( CLIs[0].partitions( jsonFormat=False ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001693
Jon Hall6aec96b2015-01-19 14:49:31 -08001694 def CASE7( self, main ):
1695 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001696 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -08001697 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001698 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001699 assert numControllers, "numControllers not defined"
1700 assert main, "main not defined"
1701 assert utilities.assert_equals, "utilities.assert_equals not defined"
1702 assert CLIs, "CLIs not defined"
1703 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001704 main.case( "Running ONOS Constant State Tests" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001705
Jon Hall5cfd23c2015-03-19 11:40:57 -07001706 main.step( "Check that each switch has a master" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001707 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -07001708 rolesNotNull = main.TRUE
1709 threads = []
1710 for i in range( numControllers ):
1711 t = main.Thread( target=CLIs[i].rolesNotNull,
1712 name="rolesNotNull-" + str( i ),
1713 args=[ ] )
1714 threads.append( t )
1715 t.start()
1716
1717 for t in threads:
1718 t.join()
1719 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001720 utilities.assert_equals(
1721 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001722 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001723 onpass="Each device has a master",
1724 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001725
Jon Hall390696c2015-05-05 17:13:41 -07001726 main.step( "Read device roles from ONOS" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001727 ONOSMastership = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001728 consistentMastership = True
1729 rolesResults = True
1730 threads = []
1731 for i in range( numControllers ):
1732 t = main.Thread( target=CLIs[i].roles,
1733 name="roles-" + str( i ),
1734 args=[] )
1735 threads.append( t )
1736 t.start()
1737
1738 for t in threads:
1739 t.join()
1740 ONOSMastership.append( t.result )
1741
1742 for i in range( numControllers ):
1743 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001744 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001745 " roles" )
1746 main.log.warn(
1747 "ONOS" + str( i + 1 ) + " mastership response: " +
1748 repr( ONOSMastership[i] ) )
1749 rolesResults = False
1750 utilities.assert_equals(
1751 expect=True,
1752 actual=rolesResults,
1753 onpass="No error in reading roles output",
1754 onfail="Error in reading roles from ONOS" )
1755
1756 main.step( "Check for consistency in roles from each controller" )
1757 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001758 main.log.info(
Jon Hall6aec96b2015-01-19 14:49:31 -08001759 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001760 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001761 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001762 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001763 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001764 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001765 onpass="Switch roles are consistent across all ONOS nodes",
1766 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001767
Jon Hall5cfd23c2015-03-19 11:40:57 -07001768 if rolesResults and not consistentMastership:
1769 for i in range( numControllers ):
1770 main.log.warn(
1771 "ONOS" + str( i + 1 ) + " roles: ",
1772 json.dumps(
1773 json.loads( ONOSMastership[ i ] ),
1774 sort_keys=True,
1775 indent=4,
1776 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001777
Jon Hallfeff3082015-05-19 10:23:26 -07001778 # NOTE: we expect mastership to change on controller failure
1779 '''
Jon Hall73cf9cc2014-11-20 22:28:38 -08001780 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -08001781 main.step( description2 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001782 try:
1783 currentJson = json.loads( ONOSMastership[0] )
1784 oldJson = json.loads( mastershipState )
1785 except ( ValueError, TypeError ):
1786 main.log.exception( "Something is wrong with parsing " +
1787 "ONOSMastership[0] or mastershipState" )
1788 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1789 main.log.error( "mastershipState" + repr( mastershipState ) )
1790 main.cleanup()
1791 main.exit()
Jon Hall8f89dda2015-01-22 16:03:33 -08001792 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001793 for i in range( 1, 29 ):
1794 switchDPID = str(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001795 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001796 current = [ switch[ 'master' ] for switch in currentJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001797 if switchDPID in switch[ 'id' ] ]
Jon Hall8f89dda2015-01-22 16:03:33 -08001798 old = [ switch[ 'master' ] for switch in oldJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001799 if switchDPID in switch[ 'id' ] ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08001800 if current == old:
Jon Hall8f89dda2015-01-22 16:03:33 -08001801 mastershipCheck = mastershipCheck and main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001802 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001803 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall8f89dda2015-01-22 16:03:33 -08001804 mastershipCheck = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001805 utilities.assert_equals(
1806 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001807 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -08001808 onpass="Mastership of Switches was not changed",
1809 onfail="Mastership of some switches changed" )
Jon Hallfeff3082015-05-19 10:23:26 -07001810 '''
Jon Hall73cf9cc2014-11-20 22:28:38 -08001811
Jon Hall58c76b72015-02-23 11:09:24 -08001812 main.step( "Get the intents and compare across all nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001813 ONOSIntents = []
Jon Hall58c76b72015-02-23 11:09:24 -08001814 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001815 consistentIntents = True
1816 intentsResults = True
1817 threads = []
1818 for i in range( numControllers ):
1819 t = main.Thread( target=CLIs[i].intents,
1820 name="intents-" + str( i ),
1821 args=[],
1822 kwargs={ 'jsonFormat': True } )
1823 threads.append( t )
1824 t.start()
1825
1826 for t in threads:
1827 t.join()
1828 ONOSIntents.append( t.result )
1829
1830 for i in range( numControllers ):
1831 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001832 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001833 " intents" )
1834 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1835 repr( ONOSIntents[ i ] ) )
1836 intentsResults = False
Jon Hall58c76b72015-02-23 11:09:24 -08001837 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001838 expect=True,
1839 actual=intentsResults,
1840 onpass="No error in reading intents output",
1841 onfail="Error in reading intents from ONOS" )
1842
1843 main.step( "Check for consistency in Intents from each controller" )
1844 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001845 main.log.info( "Intents are consistent across all ONOS " +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001846 "nodes" )
1847 else:
1848 consistentIntents = False
Jon Hall390696c2015-05-05 17:13:41 -07001849
1850 # Try to make it easy to figure out what is happening
1851 #
1852 # Intent ONOS1 ONOS2 ...
1853 # 0x01 INSTALLED INSTALLING
1854 # ... ... ...
1855 # ... ... ...
1856 title = " ID"
1857 for n in range( numControllers ):
1858 title += " " * 10 + "ONOS" + str( n + 1 )
1859 main.log.warn( title )
1860 # get all intent keys in the cluster
1861 keys = []
1862 for nodeStr in ONOSIntents:
1863 node = json.loads( nodeStr )
1864 for intent in node:
1865 keys.append( intent.get( 'id' ) )
1866 keys = set( keys )
1867 for key in keys:
1868 row = "%-13s" % key
1869 for nodeStr in ONOSIntents:
1870 node = json.loads( nodeStr )
1871 for intent in node:
1872 if intent.get( 'id' ) == key:
1873 row += "%-15s" % intent.get( 'state' )
1874 main.log.warn( row )
1875 # End table view
1876
Jon Hall5cfd23c2015-03-19 11:40:57 -07001877 utilities.assert_equals(
1878 expect=True,
1879 actual=consistentIntents,
Jon Hall58c76b72015-02-23 11:09:24 -08001880 onpass="Intents are consistent across all ONOS nodes",
1881 onfail="ONOS nodes have different views of intents" )
Jon Hall58c76b72015-02-23 11:09:24 -08001882 intentStates = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001883 for node in ONOSIntents: # Iter through ONOS nodes
Jon Hall58c76b72015-02-23 11:09:24 -08001884 nodeStates = []
1885 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001886 try:
1887 for intent in json.loads( node ):
1888 nodeStates.append( intent[ 'state' ] )
1889 except ( ValueError, TypeError ):
1890 main.log.exception( "Error in parsing intents" )
1891 main.log.error( repr( node ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001892 intentStates.append( nodeStates )
1893 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1894 main.log.info( dict( out ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001895
Jon Hall5cfd23c2015-03-19 11:40:57 -07001896 if intentsResults and not consistentIntents:
1897 for i in range( numControllers ):
1898 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1899 main.log.warn( json.dumps(
1900 json.loads( ONOSIntents[ i ] ),
1901 sort_keys=True,
1902 indent=4,
1903 separators=( ',', ': ' ) ) )
1904 elif intentsResults and consistentIntents:
1905 intentCheck = main.TRUE
1906
Jon Hall58c76b72015-02-23 11:09:24 -08001907 # NOTE: Store has no durability, so intents are lost across system
1908 # restarts
1909 main.step( "Compare current intents with intents before the failure" )
1910 # NOTE: this requires case 5 to pass for intentState to be set.
1911 # maybe we should stop the test if that fails?
Jon Hall40d2cbd2015-06-03 16:24:29 -07001912 sameIntents = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001913 if intentState and intentState == ONOSIntents[ 0 ]:
Jon Hall21270ac2015-02-16 17:59:55 -08001914 sameIntents = main.TRUE
Jon Hallfeff3082015-05-19 10:23:26 -07001915 main.log.info( "Intents are consistent with before failure" )
Jon Hall58c76b72015-02-23 11:09:24 -08001916 # TODO: possibly the states have changed? we may need to figure out
Jon Hall5cfd23c2015-03-19 11:40:57 -07001917 # what the acceptable states are
Jon Hall40d2cbd2015-06-03 16:24:29 -07001918 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
1919 sameIntents = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08001920 try:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001921 before = json.loads( intentState )
1922 after = json.loads( ONOSIntents[ 0 ] )
1923 for intent in before:
1924 if intent not in after:
1925 sameIntents = main.FALSE
Jon Hallc9eabec2015-06-10 14:33:14 -07001926 main.log.debug( "Intent is not currently in ONOS " +
Jon Hall40d2cbd2015-06-03 16:24:29 -07001927 "(at least in the same form):" )
1928 main.log.debug( json.dumps( intent ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001929 except ( ValueError, TypeError ):
1930 main.log.exception( "Exception printing intents" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001931 main.log.debug( repr( ONOSIntents[0] ) )
1932 main.log.debug( repr( intentState ) )
1933 if sameIntents == main.FALSE:
1934 try:
1935 main.log.debug( "ONOS intents before: " )
1936 main.log.debug( json.dumps( json.loads( intentState ),
1937 sort_keys=True, indent=4,
1938 separators=( ',', ': ' ) ) )
1939 main.log.debug( "Current ONOS intents: " )
1940 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1941 sort_keys=True, indent=4,
1942 separators=( ',', ': ' ) ) )
1943 except ( ValueError, TypeError ):
1944 main.log.exception( "Exception printing intents" )
1945 main.log.debug( repr( ONOSIntents[0] ) )
1946 main.log.debug( repr( intentState ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001947 utilities.assert_equals(
1948 expect=main.TRUE,
1949 actual=sameIntents,
1950 onpass="Intents are consistent with before failure",
1951 onfail="The Intents changed during failure" )
1952 intentCheck = intentCheck and sameIntents
Jon Hall21270ac2015-02-16 17:59:55 -08001953
Jon Hall58c76b72015-02-23 11:09:24 -08001954 main.step( "Get the OF Table entries and compare to before " +
1955 "component failure" )
1956 FlowTables = main.TRUE
1957 flows2 = []
1958 for i in range( 28 ):
1959 main.log.info( "Checking flow table on s" + str( i + 1 ) )
1960 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
1961 flows2.append( tmpFlows )
1962 tempResult = main.Mininet2.flowComp(
1963 flow1=flows[ i ],
1964 flow2=tmpFlows )
1965 FlowTables = FlowTables and tempResult
1966 if FlowTables == main.FALSE:
1967 main.log.info( "Differences in flow table for switch: s" +
1968 str( i + 1 ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001969 utilities.assert_equals(
1970 expect=main.TRUE,
1971 actual=FlowTables,
1972 onpass="No changes were found in the flow tables",
1973 onfail="Changes were found in the flow tables" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001974
Jon Hall6aec96b2015-01-19 14:49:31 -08001975 main.step( "Check the continuous pings to ensure that no packets " +
1976 "were dropped during component failure" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001977 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
1978 main.params[ 'TESTONIP' ] )
Jon Hall8f89dda2015-01-22 16:03:33 -08001979 LossInPings = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001980 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
1981 for i in range( 8, 18 ):
1982 main.log.info(
1983 "Checking for a loss in pings along flow from s" +
1984 str( i ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001985 LossInPings = main.Mininet2.checkForLoss(
Jon Hall6aec96b2015-01-19 14:49:31 -08001986 "/tmp/ping.h" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001987 str( i ) ) or LossInPings
1988 if LossInPings == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001989 main.log.info( "Loss in ping detected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001990 elif LossInPings == main.ERROR:
Jon Hall6aec96b2015-01-19 14:49:31 -08001991 main.log.info( "There are multiple mininet process running" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001992 elif LossInPings == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001993 main.log.info( "No Loss in the pings" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001994 main.log.info( "No loss of dataplane connectivity" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001995 utilities.assert_equals(
1996 expect=main.FALSE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001997 actual=LossInPings,
Jon Hall6aec96b2015-01-19 14:49:31 -08001998 onpass="No Loss of connectivity",
1999 onfail="Loss of dataplane connectivity detected" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002000
Jon Hall390696c2015-05-05 17:13:41 -07002001 main.step( "Leadership Election is still functional" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002002 # Test of LeadershipElection
Jon Hall8f89dda2015-01-22 16:03:33 -08002003 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002004 # FIXME: make sure this matches nodes that were restarted
2005 restarted = [ nodes[0].ip_address, nodes[1].ip_address,
2006 nodes[2].ip_address ]
Jon Hall390696c2015-05-05 17:13:41 -07002007
Jon Hall8f89dda2015-01-22 16:03:33 -08002008 leaderResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002009 for cli in CLIs:
2010 leaderN = cli.electionTestLeader()
Jon Hall8f89dda2015-01-22 16:03:33 -08002011 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002012 if leaderN == main.FALSE:
Jon Hallfeff3082015-05-19 10:23:26 -07002013 # error in response
Jon Hall40d2cbd2015-06-03 16:24:29 -07002014 main.log.error( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002015 "electionTestLeader function, check the" +
Jon Hall6aec96b2015-01-19 14:49:31 -08002016 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002017 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002018 elif leaderN is None:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002019 main.log.error( cli.name +
Jon Hall6aec96b2015-01-19 14:49:31 -08002020 " shows no leader for the election-app was" +
2021 " elected after the old one died" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002022 leaderResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002023 elif leaderN in restarted:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002024 main.log.error( cli.name + " shows " + str( leaderN ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002025 " as leader for the election-app, but it " +
2026 "was restarted" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002027 leaderResult = main.FALSE
2028 if len( set( leaderList ) ) != 1:
2029 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002030 main.log.error(
2031 "Inconsistent view of leader for the election test app" )
2032 # TODO: print the list
Jon Hall6aec96b2015-01-19 14:49:31 -08002033 utilities.assert_equals(
2034 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002035 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002036 onpass="Leadership election passed",
2037 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002038
Jon Hall6aec96b2015-01-19 14:49:31 -08002039 def CASE8( self, main ):
2040 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002041 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -08002042 """
Jon Hallb87f3db2015-07-06 03:10:27 -07002043 import sys
2044 # FIXME add this path to params
2045 sys.path.append( "/home/admin/sts" )
2046 # assumes that sts is already in you PYTHONPATH
2047 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -08002048 import json
2049 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002050 assert numControllers, "numControllers not defined"
2051 assert main, "main not defined"
2052 assert utilities.assert_equals, "utilities.assert_equals not defined"
2053 assert CLIs, "CLIs not defined"
2054 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08002055
Jon Hallfeff3082015-05-19 10:23:26 -07002056 main.case( "Compare ONOS Topology view to Mininet topology" )
2057 main.caseExplaination = "Compare topology objects between Mininet" +\
2058 " and ONOS"
Jon Hall73cf9cc2014-11-20 22:28:38 -08002059
Jon Hallfeff3082015-05-19 10:23:26 -07002060 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002061 devicesResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08002062 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08002063 hostsResults = main.TRUE
Jon Hallc9eabec2015-06-10 14:33:14 -07002064 hostAttachmentResults = True
Jon Hall8f89dda2015-01-22 16:03:33 -08002065 topoResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08002066 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -08002067 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -08002068 main.step( "Collecting topology information from ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002069 startTime = time.time()
Jon Hall21270ac2015-02-16 17:59:55 -08002070 # Give time for Gossip to work
Jon Hall8f89dda2015-01-22 16:03:33 -08002071 while topoResult == main.FALSE and elapsed < 60:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002072 count += 1
Jon Hall8f89dda2015-01-22 16:03:33 -08002073 cliStart = time.time()
Jon Hall94fd0472014-12-08 11:52:42 -08002074 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002075 threads = []
2076 for i in range( numControllers ):
2077 t = main.Thread( target=CLIs[i].devices,
2078 name="devices-" + str( i ),
2079 args=[ ] )
2080 threads.append( t )
2081 t.start()
2082
2083 for t in threads:
2084 t.join()
2085 devices.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002086 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -08002087 ipResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002088 threads = []
2089 for i in range( numControllers ):
2090 t = main.Thread( target=CLIs[i].hosts,
2091 name="hosts-" + str( i ),
2092 args=[ ] )
2093 threads.append( t )
2094 t.start()
2095
2096 for t in threads:
2097 t.join()
2098 try:
2099 hosts.append( json.loads( t.result ) )
2100 except ( ValueError, TypeError ):
2101 main.log.exception( "Error parsing hosts results" )
2102 main.log.error( repr( t.result ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08002103 for controller in range( 0, len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08002104 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08002105 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07002106 if host is None or host.get( 'ipAddresses', [] ) == []:
Jon Hall6aec96b2015-01-19 14:49:31 -08002107 main.log.error(
Jon Hall40d2cbd2015-06-03 16:24:29 -07002108 "DEBUG:Error with host ipAddresses on controller" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002109 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08002110 ipResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002111 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002112 threads = []
2113 for i in range( numControllers ):
2114 t = main.Thread( target=CLIs[i].ports,
2115 name="ports-" + str( i ),
2116 args=[ ] )
2117 threads.append( t )
2118 t.start()
2119
2120 for t in threads:
2121 t.join()
2122 ports.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002123 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002124 threads = []
2125 for i in range( numControllers ):
2126 t = main.Thread( target=CLIs[i].links,
2127 name="links-" + str( i ),
2128 args=[ ] )
2129 threads.append( t )
2130 t.start()
2131
2132 for t in threads:
2133 t.join()
2134 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002135 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002136 threads = []
2137 for i in range( numControllers ):
2138 t = main.Thread( target=CLIs[i].clusters,
2139 name="clusters-" + str( i ),
2140 args=[ ] )
2141 threads.append( t )
2142 t.start()
2143
2144 for t in threads:
2145 t.join()
2146 clusters.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002147
Jon Hall8f89dda2015-01-22 16:03:33 -08002148 elapsed = time.time() - startTime
2149 cliTime = time.time() - cliStart
Jon Hallc9eabec2015-06-10 14:33:14 -07002150 print "Elapsed time: " + str( elapsed )
Jon Hall8f89dda2015-01-22 16:03:33 -08002151 print "CLI time: " + str( cliTime )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002152
Jon Hallafa8a472015-06-12 14:02:42 -07002153 mnSwitches = main.Mininet1.getSwitches()
2154 mnLinks = main.Mininet1.getLinks()
2155 mnHosts = main.Mininet1.getHosts()
Jon Hall8f89dda2015-01-22 16:03:33 -08002156 for controller in range( numControllers ):
2157 controllerStr = str( controller + 1 )
Jon Hallafa8a472015-06-12 14:02:42 -07002158 if devices[ controller ] and ports[ controller ] and\
2159 "Error" not in devices[ controller ] and\
2160 "Error" not in ports[ controller ]:
2161
Jon Hall8f89dda2015-01-22 16:03:33 -08002162 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hallafa8a472015-06-12 14:02:42 -07002163 mnSwitches,
2164 json.loads( devices[ controller ] ),
2165 json.loads( ports[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002166 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002167 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002168 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002169 actual=currentDevicesResult,
2170 onpass="ONOS" + controllerStr +
2171 " Switches view is correct",
2172 onfail="ONOS" + controllerStr +
2173 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002174
Jon Hallafa8a472015-06-12 14:02:42 -07002175 if links[ controller ] and "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08002176 currentLinksResult = main.Mininet1.compareLinks(
Jon Hallafa8a472015-06-12 14:02:42 -07002177 mnSwitches, mnLinks,
2178 json.loads( links[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002179 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002180 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002181 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002182 actual=currentLinksResult,
2183 onpass="ONOS" + controllerStr +
2184 " links view is correct",
2185 onfail="ONOS" + controllerStr +
2186 " links view is incorrect" )
2187
2188 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2189 currentHostsResult = main.Mininet1.compareHosts(
Jon Hallafa8a472015-06-12 14:02:42 -07002190 mnHosts,
2191 hosts[ controller ] )
Jon Hall58c76b72015-02-23 11:09:24 -08002192 else:
2193 currentHostsResult = main.FALSE
2194 utilities.assert_equals( expect=main.TRUE,
2195 actual=currentHostsResult,
2196 onpass="ONOS" + controllerStr +
2197 " hosts exist in Mininet",
2198 onfail="ONOS" + controllerStr +
2199 " hosts don't match Mininet" )
Jon Hallc9eabec2015-06-10 14:33:14 -07002200 # CHECKING HOST ATTACHMENT POINTS
2201 hostAttachment = True
Jon Hallafa8a472015-06-12 14:02:42 -07002202 zeroHosts = False
Jon Hallc9eabec2015-06-10 14:33:14 -07002203 # FIXME: topo-HA/obelisk specific mappings:
2204 # key is mac and value is dpid
2205 mappings = {}
2206 for i in range( 1, 29 ): # hosts 1 through 28
2207 # set up correct variables:
2208 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2209 if i == 1:
2210 deviceId = "1000".zfill(16)
2211 elif i == 2:
2212 deviceId = "2000".zfill(16)
2213 elif i == 3:
2214 deviceId = "3000".zfill(16)
2215 elif i == 4:
2216 deviceId = "3004".zfill(16)
2217 elif i == 5:
2218 deviceId = "5000".zfill(16)
2219 elif i == 6:
2220 deviceId = "6000".zfill(16)
2221 elif i == 7:
2222 deviceId = "6007".zfill(16)
2223 elif i >= 8 and i <= 17:
2224 dpid = '3' + str( i ).zfill( 3 )
2225 deviceId = dpid.zfill(16)
2226 elif i >= 18 and i <= 27:
2227 dpid = '6' + str( i ).zfill( 3 )
2228 deviceId = dpid.zfill(16)
2229 elif i == 28:
2230 deviceId = "2800".zfill(16)
2231 mappings[ macId ] = deviceId
2232 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2233 if hosts[ controller ] == []:
2234 main.log.warn( "There are no hosts discovered" )
Jon Hallafa8a472015-06-12 14:02:42 -07002235 zeroHosts = True
Jon Hallc9eabec2015-06-10 14:33:14 -07002236 else:
2237 for host in hosts[ controller ]:
2238 mac = None
2239 location = None
2240 device = None
2241 port = None
2242 try:
2243 mac = host.get( 'mac' )
2244 assert mac, "mac field could not be found for this host object"
Jon Hall58c76b72015-02-23 11:09:24 -08002245
Jon Hallc9eabec2015-06-10 14:33:14 -07002246 location = host.get( 'location' )
2247 assert location, "location field could not be found for this host object"
2248
2249 # Trim the protocol identifier off deviceId
2250 device = str( location.get( 'elementId' ) ).split(':')[1]
2251 assert device, "elementId field could not be found for this host location object"
2252
2253 port = location.get( 'port' )
2254 assert port, "port field could not be found for this host location object"
2255
2256 # Now check if this matches where they should be
2257 if mac and device and port:
2258 if str( port ) != "1":
2259 main.log.error( "The attachment port is incorrect for " +
2260 "host " + str( mac ) +
2261 ". Expected: 1 Actual: " + str( port) )
2262 hostAttachment = False
2263 if device != mappings[ str( mac ) ]:
2264 main.log.error( "The attachment device is incorrect for " +
2265 "host " + str( mac ) +
2266 ". Expected: " + mappings[ str( mac ) ] +
2267 " Actual: " + device )
2268 hostAttachment = False
2269 else:
2270 hostAttachment = False
2271 except AssertionError:
2272 main.log.exception( "Json object not as expected" )
2273 main.log.error( repr( host ) )
2274 hostAttachment = False
2275 else:
2276 main.log.error( "No hosts json output or \"Error\"" +
2277 " in output. hosts = " +
2278 repr( hosts[ controller ] ) )
Jon Hallafa8a472015-06-12 14:02:42 -07002279 if zeroHosts is False:
Jon Hallc9eabec2015-06-10 14:33:14 -07002280 hostAttachment = True
2281
2282 # END CHECKING HOST ATTACHMENT POINTS
Jon Hall58c76b72015-02-23 11:09:24 -08002283 devicesResults = devicesResults and currentDevicesResult
Jon Hall58c76b72015-02-23 11:09:24 -08002284 linksResults = linksResults and currentLinksResult
2285 hostsResults = hostsResults and currentHostsResult
Jon Hallafa8a472015-06-12 14:02:42 -07002286 hostAttachmentResults = hostAttachmentResults and\
2287 hostAttachment
Jon Hall94fd0472014-12-08 11:52:42 -08002288
Jon Hallc9eabec2015-06-10 14:33:14 -07002289 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08002290
Jon Hallc9eabec2015-06-10 14:33:14 -07002291 # hosts
2292 main.step( "Hosts view is consistent across all ONOS nodes" )
2293 consistentHostsResult = main.TRUE
2294 for controller in range( len( hosts ) ):
2295 controllerStr = str( controller + 1 )
2296 if "Error" not in hosts[ controller ]:
2297 if hosts[ controller ] == hosts[ 0 ]:
2298 continue
2299 else: # hosts not consistent
2300 main.log.error( "hosts from ONOS" + controllerStr +
2301 " is inconsistent with ONOS1" )
2302 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08002303 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002304
Jon Hallc9eabec2015-06-10 14:33:14 -07002305 else:
2306 main.log.error( "Error in getting ONOS hosts from ONOS" +
2307 controllerStr )
2308 consistentHostsResult = main.FALSE
2309 main.log.warn( "ONOS" + controllerStr +
2310 " hosts response: " +
2311 repr( hosts[ controller ] ) )
2312 utilities.assert_equals(
2313 expect=main.TRUE,
2314 actual=consistentHostsResult,
2315 onpass="Hosts view is consistent across all ONOS nodes",
2316 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08002317
Jon Hallc9eabec2015-06-10 14:33:14 -07002318 main.step( "Hosts information is correct" )
2319 hostsResults = hostsResults and ipResult
2320 utilities.assert_equals(
2321 expect=main.TRUE,
2322 actual=hostsResults,
2323 onpass="Host information is correct",
2324 onfail="Host information is incorrect" )
2325
2326 main.step( "Host attachment points to the network" )
2327 utilities.assert_equals(
2328 expect=True,
2329 actual=hostAttachmentResults,
2330 onpass="Hosts are correctly attached to the network",
2331 onfail="ONOS did not correctly attach hosts to the network" )
2332
2333 # Strongly connected clusters of devices
2334 main.step( "Clusters view is consistent across all ONOS nodes" )
2335 consistentClustersResult = main.TRUE
2336 for controller in range( len( clusters ) ):
2337 controllerStr = str( controller + 1 )
2338 if "Error" not in clusters[ controller ]:
2339 if clusters[ controller ] == clusters[ 0 ]:
2340 continue
2341 else: # clusters not consistent
2342 main.log.error( "clusters from ONOS" +
2343 controllerStr +
2344 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002345 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002346
Jon Hallc9eabec2015-06-10 14:33:14 -07002347 else:
2348 main.log.error( "Error in getting dataplane clusters " +
2349 "from ONOS" + controllerStr )
2350 consistentClustersResult = main.FALSE
2351 main.log.warn( "ONOS" + controllerStr +
2352 " clusters response: " +
2353 repr( clusters[ controller ] ) )
2354 utilities.assert_equals(
2355 expect=main.TRUE,
2356 actual=consistentClustersResult,
2357 onpass="Clusters view is consistent across all ONOS nodes",
2358 onfail="ONOS nodes have different views of clusters" )
2359
2360 main.step( "There is only one SCC" )
2361 # there should always only be one cluster
2362 try:
2363 numClusters = len( json.loads( clusters[ 0 ] ) )
2364 except ( ValueError, TypeError ):
2365 main.log.exception( "Error parsing clusters[0]: " +
2366 repr( clusters[0] ) )
2367 clusterResults = main.FALSE
2368 if numClusters == 1:
2369 clusterResults = main.TRUE
2370 utilities.assert_equals(
2371 expect=1,
2372 actual=numClusters,
2373 onpass="ONOS shows 1 SCC",
2374 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2375
Jon Hallafa8a472015-06-12 14:02:42 -07002376 topoResult = ( devicesResults and linksResults
Jon Hallc9eabec2015-06-10 14:33:14 -07002377 and hostsResults and consistentHostsResult
2378 and consistentClustersResult and clusterResults
2379 and ipResult and hostAttachmentResults )
Jon Hall94fd0472014-12-08 11:52:42 -08002380
Jon Hall8f89dda2015-01-22 16:03:33 -08002381 topoResult = topoResult and int( count <= 2 )
2382 note = "note it takes about " + str( int( cliTime ) ) + \
2383 " seconds for the test to make all the cli calls to fetch " +\
2384 "the topology from each ONOS instance"
Jon Hall1b8f54a2015-02-04 13:24:20 -08002385 main.log.info(
Jon Hall8f89dda2015-01-22 16:03:33 -08002386 "Very crass estimate for topology discovery/convergence( " +
2387 str( note ) + " ): " + str( elapsed ) + " seconds, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002388 str( count ) + " tries" )
Jon Hallc9eabec2015-06-10 14:33:14 -07002389
2390 main.step( "Device information is correct" )
2391 utilities.assert_equals(
2392 expect=main.TRUE,
2393 actual=devicesResults,
2394 onpass="Device information is correct",
2395 onfail="Device information is incorrect" )
2396
Jon Hallc9eabec2015-06-10 14:33:14 -07002397 main.step( "Links are correct" )
2398 utilities.assert_equals(
2399 expect=main.TRUE,
2400 actual=linksResults,
2401 onpass="Link are correct",
2402 onfail="Links are incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002403
Jon Halla9d26da2015-03-30 16:45:32 -07002404 # FIXME: move this to an ONOS state case
2405 main.step( "Checking ONOS nodes" )
2406 nodesOutput = []
Jon Hall390696c2015-05-05 17:13:41 -07002407 nodeResults = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002408 threads = []
2409 for i in range( numControllers ):
2410 t = main.Thread( target=CLIs[i].nodes,
2411 name="nodes-" + str( i ),
2412 args=[ ] )
2413 threads.append( t )
2414 t.start()
2415
2416 for t in threads:
2417 t.join()
2418 nodesOutput.append( t.result )
2419 ips = [ node.ip_address for node in nodes ]
2420 for i in nodesOutput:
2421 try:
2422 current = json.loads( i )
2423 for node in current:
Jon Hall390696c2015-05-05 17:13:41 -07002424 currentResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002425 if node['ip'] in ips: # node in nodes() output is in cell
2426 if node['state'] == 'ACTIVE':
Jon Hall390696c2015-05-05 17:13:41 -07002427 currentResult = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002428 else:
2429 main.log.error( "Error in ONOS node availability" )
2430 main.log.error(
2431 json.dumps( current,
2432 sort_keys=True,
2433 indent=4,
2434 separators=( ',', ': ' ) ) )
2435 break
Jon Hall390696c2015-05-05 17:13:41 -07002436 nodeResults = nodeResults and currentResult
Jon Halla9d26da2015-03-30 16:45:32 -07002437 except ( ValueError, TypeError ):
2438 main.log.error( "Error parsing nodes output" )
2439 main.log.warn( repr( i ) )
Jon Hall390696c2015-05-05 17:13:41 -07002440 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2441 onpass="Nodes check successful",
2442 onfail="Nodes check NOT successful" )
Jon Halla9d26da2015-03-30 16:45:32 -07002443
Jon Hall6aec96b2015-01-19 14:49:31 -08002444 def CASE9( self, main ):
2445 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002446 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -08002447 """
2448 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002449 assert numControllers, "numControllers not defined"
2450 assert main, "main not defined"
2451 assert utilities.assert_equals, "utilities.assert_equals not defined"
2452 assert CLIs, "CLIs not defined"
2453 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002454 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002455
Jon Hall8f89dda2015-01-22 16:03:33 -08002456 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002457
Jon Hall6aec96b2015-01-19 14:49:31 -08002458 description = "Turn off a link to ensure that Link Discovery " +\
Jon Hall58c76b72015-02-23 11:09:24 -08002459 "is working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002460 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002461
Jon Hall6aec96b2015-01-19 14:49:31 -08002462 main.step( "Kill Link between s3 and s28" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002463 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
Jon Hall58c76b72015-02-23 11:09:24 -08002464 main.log.info( "Waiting " + str( linkSleep ) +
2465 " seconds for link down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002466 time.sleep( linkSleep )
2467 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002468 onpass="Link down successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002469 onfail="Failed to bring link down" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002470 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002471
Jon Hall6aec96b2015-01-19 14:49:31 -08002472 def CASE10( self, main ):
2473 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002474 Link s3-s28 up
Jon Hall6aec96b2015-01-19 14:49:31 -08002475 """
2476 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002477 assert numControllers, "numControllers not defined"
2478 assert main, "main not defined"
2479 assert utilities.assert_equals, "utilities.assert_equals not defined"
2480 assert CLIs, "CLIs not defined"
2481 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002482 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002483
Jon Hall8f89dda2015-01-22 16:03:33 -08002484 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002485
Jon Hall6aec96b2015-01-19 14:49:31 -08002486 description = "Restore a link to ensure that Link Discovery is " + \
Jon Hall63604932015-02-26 17:09:50 -08002487 "working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002488 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002489
Jon Hall6aec96b2015-01-19 14:49:31 -08002490 main.step( "Bring link between s3 and s28 back up" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002491 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
Jon Hall58c76b72015-02-23 11:09:24 -08002492 main.log.info( "Waiting " + str( linkSleep ) +
2493 " seconds for link up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002494 time.sleep( linkSleep )
2495 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002496 onpass="Link up successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002497 onfail="Failed to bring link up" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002498 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002499
Jon Hall6aec96b2015-01-19 14:49:31 -08002500 def CASE11( self, main ):
2501 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002502 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -08002503 """
2504 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002505 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002506 assert numControllers, "numControllers not defined"
2507 assert main, "main not defined"
2508 assert utilities.assert_equals, "utilities.assert_equals not defined"
2509 assert CLIs, "CLIs not defined"
2510 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08002511
Jon Hall8f89dda2015-01-22 16:03:33 -08002512 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002513
2514 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002515 main.case( description )
2516 switch = main.params[ 'kill' ][ 'switch' ]
2517 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08002518
Jon Hall6aec96b2015-01-19 14:49:31 -08002519 # TODO: Make this switch parameterizable
2520 main.step( "Kill " + switch )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002521 main.log.info( "Deleting " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002522 main.Mininet1.delSwitch( switch )
2523 main.log.info( "Waiting " + str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002524 " seconds for switch down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002525 time.sleep( switchSleep )
2526 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002527 # Peek at the deleted switch
2528 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002529 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002530 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -08002531 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002532 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002533 onpass="Kill switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002534 onfail="Failed to kill switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002535
Jon Hall6aec96b2015-01-19 14:49:31 -08002536 def CASE12( self, main ):
2537 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002538 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -08002539 """
2540 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002541 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002542 assert numControllers, "numControllers not defined"
2543 assert main, "main not defined"
2544 assert utilities.assert_equals, "utilities.assert_equals not defined"
2545 assert CLIs, "CLIs not defined"
2546 assert nodes, "nodes not defined"
2547 assert ONOS1Port, "ONOS1Port not defined"
2548 assert ONOS2Port, "ONOS2Port not defined"
2549 assert ONOS3Port, "ONOS3Port not defined"
2550 assert ONOS4Port, "ONOS4Port not defined"
2551 assert ONOS5Port, "ONOS5Port not defined"
2552 assert ONOS6Port, "ONOS6Port not defined"
2553 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall669173b2014-12-17 11:36:30 -08002554
Jon Hall8f89dda2015-01-22 16:03:33 -08002555 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall6aec96b2015-01-19 14:49:31 -08002556 switch = main.params[ 'kill' ][ 'switch' ]
2557 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2558 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002559 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002560 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002561
Jon Hall6aec96b2015-01-19 14:49:31 -08002562 main.step( "Add back " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002563 main.Mininet1.addSwitch( switch, dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002564 for peer in links:
Jon Hall8f89dda2015-01-22 16:03:33 -08002565 main.Mininet1.addLink( switch, peer )
Jon Hall0f523f22015-07-06 09:31:09 -07002566 ipList = []
2567 for i in range( numControllers ):
2568 ipList.append( nodes[ i ].ip_address )
2569 main.Mininet1.assignSwController( sw=switch, ip=ipList )
Jon Hall58c76b72015-02-23 11:09:24 -08002570 main.log.info( "Waiting " + str( switchSleep ) +
2571 " seconds for switch up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002572 time.sleep( switchSleep )
2573 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002574 # Peek at the deleted switch
2575 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002576 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002577 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002578 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002579 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002580 onpass="add switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002581 onfail="Failed to add switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002582
Jon Hall6aec96b2015-01-19 14:49:31 -08002583 def CASE13( self, main ):
2584 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002585 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -08002586 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002587 import os
2588 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002589 assert numControllers, "numControllers not defined"
2590 assert main, "main not defined"
2591 assert utilities.assert_equals, "utilities.assert_equals not defined"
2592 assert CLIs, "CLIs not defined"
2593 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002594
2595 # printing colors to terminal
Jon Hall5cfd23c2015-03-19 11:40:57 -07002596 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2597 'blue': '\033[94m', 'green': '\033[92m',
2598 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
Jon Hall40d2cbd2015-06-03 16:24:29 -07002599 main.case( "Test Cleanup" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002600 main.step( "Killing tcpdumps" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002601 main.Mininet2.stopTcpdump()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002602
Jon Hall6aec96b2015-01-19 14:49:31 -08002603 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002604 testname = main.TEST
Jon Hall8f89dda2015-01-22 16:03:33 -08002605 teststationUser = main.params[ 'TESTONUSER' ]
2606 teststationIP = main.params[ 'TESTONIP' ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002607 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -08002608 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -08002609 # FIXME: scp
2610 # mn files
2611 # TODO: Load these from params
2612 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002613 logFolder = "/opt/onos/log/"
2614 logFiles = [ "karaf.log", "karaf.log.1" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002615 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002616 dstDir = "~/packet_captures/"
2617 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002618 for node in nodes:
2619 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2620 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002621 teststationUser + "@" +
2622 teststationIP + ":" +
2623 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002624 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002625 main.ONOSbench.handle.expect( "\$" )
2626
Jon Hall6aec96b2015-01-19 14:49:31 -08002627 # std*.log's
2628 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002629 logFolder = "/opt/onos/var/"
2630 logFiles = [ "stderr.log", "stdout.log" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002631 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002632 dstDir = "~/packet_captures/"
2633 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002634 for node in nodes:
2635 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2636 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002637 teststationUser + "@" +
2638 teststationIP + ":" +
2639 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002640 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002641 main.ONOSbench.handle.expect( "\$" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002642 # sleep so scp can finish
2643 time.sleep( 10 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002644
2645 main.step( "Stopping Mininet" )
Jon Hall390696c2015-05-05 17:13:41 -07002646 mnResult = main.Mininet1.stopNet()
2647 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2648 onpass="Mininet stopped",
2649 onfail="MN cleanup NOT successful" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002650
2651 main.step( "Checking ONOS Logs for errors" )
2652 for node in nodes:
2653 print colors[ 'purple' ] + "Checking logs for errors on " + \
2654 node.name + ":" + colors[ 'end' ]
Jon Hall40d2cbd2015-06-03 16:24:29 -07002655 print main.ONOSbench.checkLogs( node.ip_address, restart=True )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002656
Jon Hall6aec96b2015-01-19 14:49:31 -08002657 main.step( "Packing and rotating pcap archives" )
2658 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002659
Jon Hallfeff3082015-05-19 10:23:26 -07002660 try:
2661 timerLog = open( main.logdir + "/Timers.csv", 'w')
2662 # Overwrite with empty line and close
Jon Hall40d2cbd2015-06-03 16:24:29 -07002663 labels = "Gossip Intents, Restart"
2664 data = str( gossipTime ) + ", " + str( main.restartTime )
2665 timerLog.write( labels + "\n" + data )
Jon Hallfeff3082015-05-19 10:23:26 -07002666 timerLog.close()
2667 except NameError, e:
2668 main.log.exception(e)
2669
Jon Hall6aec96b2015-01-19 14:49:31 -08002670 def CASE14( self, main ):
2671 """
Jon Hall669173b2014-12-17 11:36:30 -08002672 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -08002673 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07002674 assert numControllers, "numControllers not defined"
2675 assert main, "main not defined"
2676 assert utilities.assert_equals, "utilities.assert_equals not defined"
2677 assert CLIs, "CLIs not defined"
2678 assert nodes, "nodes not defined"
2679
Jon Hall390696c2015-05-05 17:13:41 -07002680 main.case("Start Leadership Election app")
2681 main.step( "Install leadership election app" )
Jon Hallfeff3082015-05-19 10:23:26 -07002682 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
2683 utilities.assert_equals(
2684 expect=main.TRUE,
2685 actual=appResult,
2686 onpass="Election app installed",
2687 onfail="Something went wrong with installing Leadership election" )
2688
2689 main.step( "Run for election on each node" )
2690 leaderResult = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002691 leaders = []
2692 for cli in CLIs:
Jon Hall390696c2015-05-05 17:13:41 -07002693 cli.electionTestRun()
2694 for cli in CLIs:
Jon Halla9d26da2015-03-30 16:45:32 -07002695 leader = cli.electionTestLeader()
2696 if leader is None or leader == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002697 main.log.error( cli.name + ": Leader for the election app " +
Jon Halla9d26da2015-03-30 16:45:32 -07002698 "should be an ONOS node, instead got '" +
2699 str( leader ) + "'" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002700 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002701 leaders.append( leader )
Jon Hall6aec96b2015-01-19 14:49:31 -08002702 utilities.assert_equals(
2703 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002704 actual=leaderResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002705 onpass="Successfully ran for leadership",
2706 onfail="Failed to run for leadership" )
2707
2708 main.step( "Check that each node shows the same leader" )
2709 sameLeader = main.TRUE
2710 if len( set( leaders ) ) != 1:
2711 sameLeader = main.FALSE
2712 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2713 str( leaders ) )
2714 utilities.assert_equals(
2715 expect=main.TRUE,
2716 actual=sameLeader,
2717 onpass="Leadership is consistent for the election topic",
2718 onfail="Nodes have different leaders" )
Jon Hall669173b2014-12-17 11:36:30 -08002719
Jon Hall6aec96b2015-01-19 14:49:31 -08002720 def CASE15( self, main ):
2721 """
Jon Hall669173b2014-12-17 11:36:30 -08002722 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08002723 """
Jon Hall390696c2015-05-05 17:13:41 -07002724 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002725 assert numControllers, "numControllers not defined"
2726 assert main, "main not defined"
2727 assert utilities.assert_equals, "utilities.assert_equals not defined"
2728 assert CLIs, "CLIs not defined"
2729 assert nodes, "nodes not defined"
2730
Jon Hall8f89dda2015-01-22 16:03:33 -08002731 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002732 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08002733 main.case( description )
Jon Hallfeff3082015-05-19 10:23:26 -07002734
2735 main.step( "Check that each node shows the same leader" )
2736 sameLeader = main.TRUE
2737 leaders = []
2738 for cli in CLIs:
2739 leader = cli.electionTestLeader()
2740 leaders.append( leader )
2741 if len( set( leaders ) ) != 1:
2742 sameLeader = main.FALSE
2743 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2744 str( leaders ) )
2745 utilities.assert_equals(
2746 expect=main.TRUE,
2747 actual=sameLeader,
2748 onpass="Leadership is consistent for the election topic",
2749 onfail="Nodes have different leaders" )
2750
Jon Hall6aec96b2015-01-19 14:49:31 -08002751 main.step( "Find current leader and withdraw" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002752 leader = main.ONOScli1.electionTestLeader()
Jon Halla9d26da2015-03-30 16:45:32 -07002753 # do some sanity checking on leader before using it
Jon Hall8f89dda2015-01-22 16:03:33 -08002754 withdrawResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002755 if leader is None or leader == main.FALSE:
Jon Hallfeff3082015-05-19 10:23:26 -07002756 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002757 "Leader for the election app should be an ONOS node," +
Jon Hall58c76b72015-02-23 11:09:24 -08002758 "instead got '" + str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002759 leaderResult = main.FALSE
Jon Hall63604932015-02-26 17:09:50 -08002760 oldLeader = None
Jon Hall5cfd23c2015-03-19 11:40:57 -07002761 for i in range( len( CLIs ) ):
2762 if leader == nodes[ i ].ip_address:
2763 oldLeader = CLIs[ i ]
2764 break
Jon Halla9d26da2015-03-30 16:45:32 -07002765 else: # FOR/ELSE statement
Jon Hall5cfd23c2015-03-19 11:40:57 -07002766 main.log.error( "Leader election, could not find current leader" )
Jon Hall63604932015-02-26 17:09:50 -08002767 if oldLeader:
2768 withdrawResult = oldLeader.electionTestWithdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08002769 utilities.assert_equals(
2770 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002771 actual=withdrawResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002772 onpass="Node was withdrawn from election",
2773 onfail="Node was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08002774
Jon Hall6aec96b2015-01-19 14:49:31 -08002775 main.step( "Make sure new leader is elected" )
Jon Halla9d26da2015-03-30 16:45:32 -07002776 # FIXME: use threads
Jon Hall8f89dda2015-01-22 16:03:33 -08002777 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002778 for cli in CLIs:
2779 leaderN = cli.electionTestLeader()
2780 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002781 if leaderN == leader:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002782 main.log.error( cli.name + " still sees " + str( leader ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002783 " as leader after they withdrew" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002784 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002785 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002786 # error in response
2787 # TODO: add check for "Command not found:" in the driver, this
Jon Hall5cfd23c2015-03-19 11:40:57 -07002788 # means the app isn't loaded
Jon Hall40d2cbd2015-06-03 16:24:29 -07002789 main.log.error( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002790 "electionTestLeader function, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002791 "check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002792 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002793 elif leaderN is None:
2794 # node may not have recieved the event yet
Jon Hall390696c2015-05-05 17:13:41 -07002795 time.sleep(7)
Jon Halla9d26da2015-03-30 16:45:32 -07002796 leaderN = cli.electionTestLeader()
2797 leaderList.pop()
2798 leaderList.append( leaderN )
Jon Hall8f89dda2015-01-22 16:03:33 -08002799 consistentLeader = main.FALSE
2800 if len( set( leaderList ) ) == 1:
Jon Hall6aec96b2015-01-19 14:49:31 -08002801 main.log.info( "Each Election-app sees '" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002802 str( leaderList[ 0 ] ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002803 "' as the leader" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002804 consistentLeader = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002805 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002806 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002807 "Inconsistent responses for leader of Election-app:" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002808 for n in range( len( leaderList ) ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07002809 main.log.error( "ONOS" + str( n + 1 ) + " response: " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002810 str( leaderList[ n ] ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002811 leaderResult = leaderResult and consistentLeader
Jon Hall6aec96b2015-01-19 14:49:31 -08002812 utilities.assert_equals(
2813 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002814 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002815 onpass="Leadership election passed",
2816 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002817
Jon Hall58c76b72015-02-23 11:09:24 -08002818 main.step( "Run for election on old leader( just so everyone " +
2819 "is in the hat )" )
Jon Hall63604932015-02-26 17:09:50 -08002820 if oldLeader:
2821 runResult = oldLeader.electionTestRun()
2822 else:
2823 runResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002824 utilities.assert_equals(
2825 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002826 actual=runResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002827 onpass="App re-ran for election",
2828 onfail="App failed to run for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002829
Jon Hallfeff3082015-05-19 10:23:26 -07002830 main.step( "Leader did not change when old leader re-ran" )
Jon Hall390696c2015-05-05 17:13:41 -07002831 afterRun = main.ONOScli1.electionTestLeader()
2832 # verify leader didn't just change
2833 if afterRun == leaderList[ 0 ]:
2834 afterResult = main.TRUE
2835 else:
2836 afterResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002837
Jon Hall6aec96b2015-01-19 14:49:31 -08002838 utilities.assert_equals(
2839 expect=main.TRUE,
Jon Hall390696c2015-05-05 17:13:41 -07002840 actual=afterResult,
2841 onpass="Old leader successfully re-ran for election",
Jon Hall6aec96b2015-01-19 14:49:31 -08002842 onfail="Something went wrong with Leadership election after " +
2843 "the old leader re-ran for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002844
Jon Hall390696c2015-05-05 17:13:41 -07002845 def CASE16( self, main ):
2846 """
2847 Install Distributed Primitives app
2848 """
Jon Hall40d2cbd2015-06-03 16:24:29 -07002849 import time
Jon Hall390696c2015-05-05 17:13:41 -07002850 assert numControllers, "numControllers not defined"
2851 assert main, "main not defined"
2852 assert utilities.assert_equals, "utilities.assert_equals not defined"
2853 assert CLIs, "CLIs not defined"
2854 assert nodes, "nodes not defined"
2855
2856 # Variables for the distributed primitives tests
2857 global pCounterName
2858 global iCounterName
2859 global pCounterValue
2860 global iCounterValue
2861 global onosSet
2862 global onosSetName
2863 pCounterName = "TestON-Partitions"
2864 iCounterName = "TestON-inMemory"
2865 pCounterValue = 0
2866 iCounterValue = 0
2867 onosSet = set([])
2868 onosSetName = "TestON-set"
2869
2870 description = "Install Primitives app"
2871 main.case( description )
2872 main.step( "Install Primitives app" )
2873 appName = "org.onosproject.distributedprimitives"
2874 appResults = CLIs[0].activateApp( appName )
2875 utilities.assert_equals( expect=main.TRUE,
2876 actual=appResults,
2877 onpass="Primitives app activated",
2878 onfail="Primitives app not activated" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002879 time.sleep( 5 ) # To allow all nodes to activate
Jon Hall390696c2015-05-05 17:13:41 -07002880
2881 def CASE17( self, main ):
2882 """
2883 Check for basic functionality with distributed primitives
2884 """
Jon Hallc9eabec2015-06-10 14:33:14 -07002885 import json
Jon Hall390696c2015-05-05 17:13:41 -07002886 # Make sure variables are defined/set
2887 assert numControllers, "numControllers not defined"
2888 assert main, "main not defined"
2889 assert utilities.assert_equals, "utilities.assert_equals not defined"
2890 assert CLIs, "CLIs not defined"
2891 assert nodes, "nodes not defined"
2892 assert pCounterName, "pCounterName not defined"
2893 assert iCounterName, "iCounterName not defined"
2894 assert onosSetName, "onosSetName not defined"
2895 # NOTE: assert fails if value is 0/None/Empty/False
2896 try:
2897 pCounterValue
2898 except NameError:
2899 main.log.error( "pCounterValue not defined, setting to 0" )
2900 pCounterValue = 0
2901 try:
2902 iCounterValue
2903 except NameError:
2904 main.log.error( "iCounterValue not defined, setting to 0" )
2905 iCounterValue = 0
2906 try:
2907 onosSet
2908 except NameError:
2909 main.log.error( "onosSet not defined, setting to empty Set" )
2910 onosSet = set([])
2911 # Variables for the distributed primitives tests. These are local only
2912 addValue = "a"
2913 addAllValue = "a b c d e f"
2914 retainValue = "c d e f"
2915
2916 description = "Check for basic functionality with distributed " +\
2917 "primitives"
2918 main.case( description )
2919 main.caseExplaination = "Test the methods of the distributed primitives (counters and sets) throught the cli"
2920 # DISTRIBUTED ATOMIC COUNTERS
2921 main.step( "Increment and get a default counter on each node" )
2922 pCounters = []
2923 threads = []
Jon Hallfeff3082015-05-19 10:23:26 -07002924 addedPValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002925 for i in range( numControllers ):
2926 t = main.Thread( target=CLIs[i].counterTestIncrement,
2927 name="counterIncrement-" + str( i ),
2928 args=[ pCounterName ] )
2929 pCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002930 addedPValues.append( pCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002931 threads.append( t )
2932 t.start()
2933
2934 for t in threads:
2935 t.join()
2936 pCounters.append( t.result )
2937 # Check that counter incremented numController times
2938 pCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002939 for i in addedPValues:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002940 tmpResult = i in pCounters
Jon Hallfeff3082015-05-19 10:23:26 -07002941 pCounterResults = pCounterResults and tmpResult
2942 if not tmpResult:
2943 main.log.error( str( i ) + " is not in partitioned "
2944 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002945 utilities.assert_equals( expect=True,
2946 actual=pCounterResults,
2947 onpass="Default counter incremented",
2948 onfail="Error incrementing default" +
2949 " counter" )
2950
2951 main.step( "Increment and get an in memory counter on each node" )
2952 iCounters = []
Jon Hallfeff3082015-05-19 10:23:26 -07002953 addedIValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002954 threads = []
2955 for i in range( numControllers ):
2956 t = main.Thread( target=CLIs[i].counterTestIncrement,
2957 name="icounterIncrement-" + str( i ),
2958 args=[ iCounterName ],
2959 kwargs={ "inMemory": True } )
2960 iCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002961 addedIValues.append( iCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002962 threads.append( t )
2963 t.start()
2964
2965 for t in threads:
2966 t.join()
2967 iCounters.append( t.result )
2968 # Check that counter incremented numController times
2969 iCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002970 for i in addedIValues:
2971 tmpResult = i in iCounters
2972 iCounterResults = iCounterResults and tmpResult
2973 if not tmpResult:
2974 main.log.error( str( i ) + " is not in the in-memory "
2975 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002976 utilities.assert_equals( expect=True,
2977 actual=iCounterResults,
2978 onpass="In memory counter incremented",
2979 onfail="Error incrementing in memory" +
2980 " counter" )
2981
2982 main.step( "Check counters are consistant across nodes" )
2983 onosCounters = []
2984 threads = []
2985 for i in range( numControllers ):
2986 t = main.Thread( target=CLIs[i].counters,
2987 name="counters-" + str( i ) )
2988 threads.append( t )
2989 t.start()
2990 for t in threads:
2991 t.join()
2992 onosCounters.append( t.result )
2993 tmp = [ i == onosCounters[ 0 ] for i in onosCounters ]
2994 if all( tmp ):
2995 main.log.info( "Counters are consistent across all nodes" )
2996 consistentCounterResults = main.TRUE
2997 else:
2998 main.log.error( "Counters are not consistent across all nodes" )
2999 consistentCounterResults = main.FALSE
3000 utilities.assert_equals( expect=main.TRUE,
3001 actual=consistentCounterResults,
3002 onpass="ONOS counters are consistent " +
3003 "across nodes",
3004 onfail="ONOS Counters are inconsistent " +
3005 "across nodes" )
3006
3007 main.step( "Counters we added have the correct values" )
3008 correctResults = main.TRUE
3009 for i in range( numControllers ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07003010 current = json.loads( onosCounters[i] )
3011 pValue = None
3012 iValue = None
Jon Hall390696c2015-05-05 17:13:41 -07003013 try:
Jon Hall40d2cbd2015-06-03 16:24:29 -07003014 for database in current:
3015 partitioned = database.get( 'partitionedDatabaseCounters' )
3016 if partitioned:
3017 for value in partitioned:
3018 if value.get( 'name' ) == pCounterName:
3019 pValue = value.get( 'value' )
3020 break
3021 inMemory = database.get( 'inMemoryDatabaseCounters' )
3022 if inMemory:
3023 for value in inMemory:
3024 if value.get( 'name' ) == iCounterName:
3025 iValue = value.get( 'value' )
3026 break
Jon Hall390696c2015-05-05 17:13:41 -07003027 except AttributeError, e:
3028 main.log.error( "ONOS" + str( i + 1 ) + " counters result " +
3029 "is not as expected" )
3030 correctResults = main.FALSE
Jon Hall40d2cbd2015-06-03 16:24:29 -07003031 if pValue == pCounterValue:
3032 main.log.info( "Partitioned counter value is correct" )
3033 else:
3034 main.log.error( "Partitioned counter value is incorrect," +
3035 " expected value: " + str( pCounterValue )
3036 + " current value: " + str( pValue ) )
3037 correctResults = main.FALSE
3038 if iValue == iCounterValue:
3039 main.log.info( "In memory counter value is correct" )
3040 else:
3041 main.log.error( "In memory counter value is incorrect, " +
3042 "expected value: " + str( iCounterValue ) +
3043 " current value: " + str( iValue ) )
3044 correctResults = main.FALSE
Jon Hall390696c2015-05-05 17:13:41 -07003045 utilities.assert_equals( expect=main.TRUE,
3046 actual=correctResults,
3047 onpass="Added counters are correct",
3048 onfail="Added counters are incorrect" )
3049 # DISTRIBUTED SETS
3050 main.step( "Distributed Set get" )
3051 size = len( onosSet )
3052 getResponses = []
3053 threads = []
3054 for i in range( numControllers ):
3055 t = main.Thread( target=CLIs[i].setTestGet,
3056 name="setTestGet-" + str( i ),
3057 args=[ onosSetName ] )
3058 threads.append( t )
3059 t.start()
3060 for t in threads:
3061 t.join()
3062 getResponses.append( t.result )
3063
3064 getResults = main.TRUE
3065 for i in range( numControllers ):
3066 if isinstance( getResponses[ i ], list):
3067 current = set( getResponses[ i ] )
3068 if len( current ) == len( getResponses[ i ] ):
3069 # no repeats
3070 if onosSet != current:
3071 main.log.error( "ONOS" + str( i + 1 ) +
3072 " has incorrect view" +
3073 " of set " + onosSetName + ":\n" +
3074 str( getResponses[ i ] ) )
3075 main.log.debug( "Expected: " + str( onosSet ) )
3076 main.log.debug( "Actual: " + str( current ) )
3077 getResults = main.FALSE
3078 else:
3079 # error, set is not a set
3080 main.log.error( "ONOS" + str( i + 1 ) +
3081 " has repeat elements in" +
3082 " set " + onosSetName + ":\n" +
3083 str( getResponses[ i ] ) )
3084 getResults = main.FALSE
3085 elif getResponses[ i ] == main.ERROR:
3086 getResults = main.FALSE
3087 utilities.assert_equals( expect=main.TRUE,
3088 actual=getResults,
3089 onpass="Set elements are correct",
3090 onfail="Set elements are incorrect" )
3091
3092 main.step( "Distributed Set size" )
3093 sizeResponses = []
3094 threads = []
3095 for i in range( numControllers ):
3096 t = main.Thread( target=CLIs[i].setTestSize,
3097 name="setTestSize-" + str( i ),
3098 args=[ onosSetName ] )
3099 threads.append( t )
3100 t.start()
3101 for t in threads:
3102 t.join()
3103 sizeResponses.append( t.result )
3104
3105 sizeResults = main.TRUE
3106 for i in range( numControllers ):
3107 if size != sizeResponses[ i ]:
3108 sizeResults = main.FALSE
3109 main.log.error( "ONOS" + str( i + 1 ) +
3110 " expected a size of " + str( size ) +
3111 " for set " + onosSetName +
3112 " but got " + str( sizeResponses[ i ] ) )
3113 utilities.assert_equals( expect=main.TRUE,
3114 actual=sizeResults,
3115 onpass="Set sizes are correct",
3116 onfail="Set sizes are incorrect" )
3117
3118 main.step( "Distributed Set add()" )
3119 onosSet.add( addValue )
3120 addResponses = []
3121 threads = []
3122 for i in range( numControllers ):
3123 t = main.Thread( target=CLIs[i].setTestAdd,
3124 name="setTestAdd-" + str( i ),
3125 args=[ onosSetName, addValue ] )
3126 threads.append( t )
3127 t.start()
3128 for t in threads:
3129 t.join()
3130 addResponses.append( t.result )
3131
3132 # main.TRUE = successfully changed the set
3133 # main.FALSE = action resulted in no change in set
3134 # main.ERROR - Some error in executing the function
3135 addResults = main.TRUE
3136 for i in range( numControllers ):
3137 if addResponses[ i ] == main.TRUE:
3138 # All is well
3139 pass
3140 elif addResponses[ i ] == main.FALSE:
3141 # Already in set, probably fine
3142 pass
3143 elif addResponses[ i ] == main.ERROR:
3144 # Error in execution
3145 addResults = main.FALSE
3146 else:
3147 # unexpected result
3148 addResults = main.FALSE
3149 if addResults != main.TRUE:
3150 main.log.error( "Error executing set add" )
3151
3152 # Check if set is still correct
3153 size = len( onosSet )
3154 getResponses = []
3155 threads = []
3156 for i in range( numControllers ):
3157 t = main.Thread( target=CLIs[i].setTestGet,
3158 name="setTestGet-" + str( i ),
3159 args=[ onosSetName ] )
3160 threads.append( t )
3161 t.start()
3162 for t in threads:
3163 t.join()
3164 getResponses.append( t.result )
3165 getResults = main.TRUE
3166 for i in range( numControllers ):
3167 if isinstance( getResponses[ i ], list):
3168 current = set( getResponses[ i ] )
3169 if len( current ) == len( getResponses[ i ] ):
3170 # no repeats
3171 if onosSet != current:
3172 main.log.error( "ONOS" + str( i + 1 ) +
3173 " has incorrect view" +
3174 " of set " + onosSetName + ":\n" +
3175 str( getResponses[ i ] ) )
3176 main.log.debug( "Expected: " + str( onosSet ) )
3177 main.log.debug( "Actual: " + str( current ) )
3178 getResults = main.FALSE
3179 else:
3180 # error, set is not a set
3181 main.log.error( "ONOS" + str( i + 1 ) +
3182 " has repeat elements in" +
3183 " set " + onosSetName + ":\n" +
3184 str( getResponses[ i ] ) )
3185 getResults = main.FALSE
3186 elif getResponses[ i ] == main.ERROR:
3187 getResults = main.FALSE
3188 sizeResponses = []
3189 threads = []
3190 for i in range( numControllers ):
3191 t = main.Thread( target=CLIs[i].setTestSize,
3192 name="setTestSize-" + str( i ),
3193 args=[ onosSetName ] )
3194 threads.append( t )
3195 t.start()
3196 for t in threads:
3197 t.join()
3198 sizeResponses.append( t.result )
3199 sizeResults = main.TRUE
3200 for i in range( numControllers ):
3201 if size != sizeResponses[ i ]:
3202 sizeResults = main.FALSE
3203 main.log.error( "ONOS" + str( i + 1 ) +
3204 " expected a size of " + str( size ) +
3205 " for set " + onosSetName +
3206 " but got " + str( sizeResponses[ i ] ) )
3207 addResults = addResults and getResults and sizeResults
3208 utilities.assert_equals( expect=main.TRUE,
3209 actual=addResults,
3210 onpass="Set add correct",
3211 onfail="Set add was incorrect" )
3212
3213 main.step( "Distributed Set addAll()" )
3214 onosSet.update( addAllValue.split() )
3215 addResponses = []
3216 threads = []
3217 for i in range( numControllers ):
3218 t = main.Thread( target=CLIs[i].setTestAdd,
3219 name="setTestAddAll-" + str( i ),
3220 args=[ onosSetName, addAllValue ] )
3221 threads.append( t )
3222 t.start()
3223 for t in threads:
3224 t.join()
3225 addResponses.append( t.result )
3226
3227 # main.TRUE = successfully changed the set
3228 # main.FALSE = action resulted in no change in set
3229 # main.ERROR - Some error in executing the function
3230 addAllResults = main.TRUE
3231 for i in range( numControllers ):
3232 if addResponses[ i ] == main.TRUE:
3233 # All is well
3234 pass
3235 elif addResponses[ i ] == main.FALSE:
3236 # Already in set, probably fine
3237 pass
3238 elif addResponses[ i ] == main.ERROR:
3239 # Error in execution
3240 addAllResults = main.FALSE
3241 else:
3242 # unexpected result
3243 addAllResults = main.FALSE
3244 if addAllResults != main.TRUE:
3245 main.log.error( "Error executing set addAll" )
3246
3247 # Check if set is still correct
3248 size = len( onosSet )
3249 getResponses = []
3250 threads = []
3251 for i in range( numControllers ):
3252 t = main.Thread( target=CLIs[i].setTestGet,
3253 name="setTestGet-" + str( i ),
3254 args=[ onosSetName ] )
3255 threads.append( t )
3256 t.start()
3257 for t in threads:
3258 t.join()
3259 getResponses.append( t.result )
3260 getResults = main.TRUE
3261 for i in range( numControllers ):
3262 if isinstance( getResponses[ i ], list):
3263 current = set( getResponses[ i ] )
3264 if len( current ) == len( getResponses[ i ] ):
3265 # no repeats
3266 if onosSet != current:
3267 main.log.error( "ONOS" + str( i + 1 ) +
3268 " has incorrect view" +
3269 " of set " + onosSetName + ":\n" +
3270 str( getResponses[ i ] ) )
3271 main.log.debug( "Expected: " + str( onosSet ) )
3272 main.log.debug( "Actual: " + str( current ) )
3273 getResults = main.FALSE
3274 else:
3275 # error, set is not a set
3276 main.log.error( "ONOS" + str( i + 1 ) +
3277 " has repeat elements in" +
3278 " set " + onosSetName + ":\n" +
3279 str( getResponses[ i ] ) )
3280 getResults = main.FALSE
3281 elif getResponses[ i ] == main.ERROR:
3282 getResults = main.FALSE
3283 sizeResponses = []
3284 threads = []
3285 for i in range( numControllers ):
3286 t = main.Thread( target=CLIs[i].setTestSize,
3287 name="setTestSize-" + str( i ),
3288 args=[ onosSetName ] )
3289 threads.append( t )
3290 t.start()
3291 for t in threads:
3292 t.join()
3293 sizeResponses.append( t.result )
3294 sizeResults = main.TRUE
3295 for i in range( numControllers ):
3296 if size != sizeResponses[ i ]:
3297 sizeResults = main.FALSE
3298 main.log.error( "ONOS" + str( i + 1 ) +
3299 " expected a size of " + str( size ) +
3300 " for set " + onosSetName +
3301 " but got " + str( sizeResponses[ i ] ) )
3302 addAllResults = addAllResults and getResults and sizeResults
3303 utilities.assert_equals( expect=main.TRUE,
3304 actual=addAllResults,
3305 onpass="Set addAll correct",
3306 onfail="Set addAll was incorrect" )
3307
3308 main.step( "Distributed Set contains()" )
3309 containsResponses = []
3310 threads = []
3311 for i in range( numControllers ):
3312 t = main.Thread( target=CLIs[i].setTestGet,
3313 name="setContains-" + str( i ),
3314 args=[ onosSetName ],
3315 kwargs={ "values": addValue } )
3316 threads.append( t )
3317 t.start()
3318 for t in threads:
3319 t.join()
3320 # NOTE: This is the tuple
3321 containsResponses.append( t.result )
3322
3323 containsResults = main.TRUE
3324 for i in range( numControllers ):
3325 if containsResponses[ i ] == main.ERROR:
3326 containsResults = main.FALSE
3327 else:
3328 containsResults = containsResults and\
3329 containsResponses[ i ][ 1 ]
3330 utilities.assert_equals( expect=main.TRUE,
3331 actual=containsResults,
3332 onpass="Set contains is functional",
3333 onfail="Set contains failed" )
3334
3335 main.step( "Distributed Set containsAll()" )
3336 containsAllResponses = []
3337 threads = []
3338 for i in range( numControllers ):
3339 t = main.Thread( target=CLIs[i].setTestGet,
3340 name="setContainsAll-" + str( i ),
3341 args=[ onosSetName ],
3342 kwargs={ "values": addAllValue } )
3343 threads.append( t )
3344 t.start()
3345 for t in threads:
3346 t.join()
3347 # NOTE: This is the tuple
3348 containsAllResponses.append( t.result )
3349
3350 containsAllResults = main.TRUE
3351 for i in range( numControllers ):
3352 if containsResponses[ i ] == main.ERROR:
3353 containsResults = main.FALSE
3354 else:
3355 containsResults = containsResults and\
3356 containsResponses[ i ][ 1 ]
3357 utilities.assert_equals( expect=main.TRUE,
3358 actual=containsAllResults,
3359 onpass="Set containsAll is functional",
3360 onfail="Set containsAll failed" )
3361
3362 main.step( "Distributed Set remove()" )
3363 onosSet.remove( addValue )
3364 removeResponses = []
3365 threads = []
3366 for i in range( numControllers ):
3367 t = main.Thread( target=CLIs[i].setTestRemove,
3368 name="setTestRemove-" + str( i ),
3369 args=[ onosSetName, addValue ] )
3370 threads.append( t )
3371 t.start()
3372 for t in threads:
3373 t.join()
3374 removeResponses.append( t.result )
3375
3376 # main.TRUE = successfully changed the set
3377 # main.FALSE = action resulted in no change in set
3378 # main.ERROR - Some error in executing the function
3379 removeResults = main.TRUE
3380 for i in range( numControllers ):
3381 if removeResponses[ i ] == main.TRUE:
3382 # All is well
3383 pass
3384 elif removeResponses[ i ] == main.FALSE:
3385 # not in set, probably fine
3386 pass
3387 elif removeResponses[ i ] == main.ERROR:
3388 # Error in execution
3389 removeResults = main.FALSE
3390 else:
3391 # unexpected result
3392 removeResults = main.FALSE
3393 if removeResults != main.TRUE:
3394 main.log.error( "Error executing set remove" )
3395
3396 # Check if set is still correct
3397 size = len( onosSet )
3398 getResponses = []
3399 threads = []
3400 for i in range( numControllers ):
3401 t = main.Thread( target=CLIs[i].setTestGet,
3402 name="setTestGet-" + str( i ),
3403 args=[ onosSetName ] )
3404 threads.append( t )
3405 t.start()
3406 for t in threads:
3407 t.join()
3408 getResponses.append( t.result )
3409 getResults = main.TRUE
3410 for i in range( numControllers ):
3411 if isinstance( getResponses[ i ], list):
3412 current = set( getResponses[ i ] )
3413 if len( current ) == len( getResponses[ i ] ):
3414 # no repeats
3415 if onosSet != current:
3416 main.log.error( "ONOS" + str( i + 1 ) +
3417 " has incorrect view" +
3418 " of set " + onosSetName + ":\n" +
3419 str( getResponses[ i ] ) )
3420 main.log.debug( "Expected: " + str( onosSet ) )
3421 main.log.debug( "Actual: " + str( current ) )
3422 getResults = main.FALSE
3423 else:
3424 # error, set is not a set
3425 main.log.error( "ONOS" + str( i + 1 ) +
3426 " has repeat elements in" +
3427 " set " + onosSetName + ":\n" +
3428 str( getResponses[ i ] ) )
3429 getResults = main.FALSE
3430 elif getResponses[ i ] == main.ERROR:
3431 getResults = main.FALSE
3432 sizeResponses = []
3433 threads = []
3434 for i in range( numControllers ):
3435 t = main.Thread( target=CLIs[i].setTestSize,
3436 name="setTestSize-" + str( i ),
3437 args=[ onosSetName ] )
3438 threads.append( t )
3439 t.start()
3440 for t in threads:
3441 t.join()
3442 sizeResponses.append( t.result )
3443 sizeResults = main.TRUE
3444 for i in range( numControllers ):
3445 if size != sizeResponses[ i ]:
3446 sizeResults = main.FALSE
3447 main.log.error( "ONOS" + str( i + 1 ) +
3448 " expected a size of " + str( size ) +
3449 " for set " + onosSetName +
3450 " but got " + str( sizeResponses[ i ] ) )
3451 removeResults = removeResults and getResults and sizeResults
3452 utilities.assert_equals( expect=main.TRUE,
3453 actual=removeResults,
3454 onpass="Set remove correct",
3455 onfail="Set remove was incorrect" )
3456
3457 main.step( "Distributed Set removeAll()" )
3458 onosSet.difference_update( addAllValue.split() )
3459 removeAllResponses = []
3460 threads = []
3461 try:
3462 for i in range( numControllers ):
3463 t = main.Thread( target=CLIs[i].setTestRemove,
3464 name="setTestRemoveAll-" + str( i ),
3465 args=[ onosSetName, addAllValue ] )
3466 threads.append( t )
3467 t.start()
3468 for t in threads:
3469 t.join()
3470 removeAllResponses.append( t.result )
3471 except Exception, e:
3472 main.log.exception(e)
3473
3474 # main.TRUE = successfully changed the set
3475 # main.FALSE = action resulted in no change in set
3476 # main.ERROR - Some error in executing the function
3477 removeAllResults = main.TRUE
3478 for i in range( numControllers ):
3479 if removeAllResponses[ i ] == main.TRUE:
3480 # All is well
3481 pass
3482 elif removeAllResponses[ i ] == main.FALSE:
3483 # not in set, probably fine
3484 pass
3485 elif removeAllResponses[ i ] == main.ERROR:
3486 # Error in execution
3487 removeAllResults = main.FALSE
3488 else:
3489 # unexpected result
3490 removeAllResults = main.FALSE
3491 if removeAllResults != main.TRUE:
3492 main.log.error( "Error executing set removeAll" )
3493
3494 # Check if set is still correct
3495 size = len( onosSet )
3496 getResponses = []
3497 threads = []
3498 for i in range( numControllers ):
3499 t = main.Thread( target=CLIs[i].setTestGet,
3500 name="setTestGet-" + str( i ),
3501 args=[ onosSetName ] )
3502 threads.append( t )
3503 t.start()
3504 for t in threads:
3505 t.join()
3506 getResponses.append( t.result )
3507 getResults = main.TRUE
3508 for i in range( numControllers ):
3509 if isinstance( getResponses[ i ], list):
3510 current = set( getResponses[ i ] )
3511 if len( current ) == len( getResponses[ i ] ):
3512 # no repeats
3513 if onosSet != current:
3514 main.log.error( "ONOS" + str( i + 1 ) +
3515 " has incorrect view" +
3516 " of set " + onosSetName + ":\n" +
3517 str( getResponses[ i ] ) )
3518 main.log.debug( "Expected: " + str( onosSet ) )
3519 main.log.debug( "Actual: " + str( current ) )
3520 getResults = main.FALSE
3521 else:
3522 # error, set is not a set
3523 main.log.error( "ONOS" + str( i + 1 ) +
3524 " has repeat elements in" +
3525 " set " + onosSetName + ":\n" +
3526 str( getResponses[ i ] ) )
3527 getResults = main.FALSE
3528 elif getResponses[ i ] == main.ERROR:
3529 getResults = main.FALSE
3530 sizeResponses = []
3531 threads = []
3532 for i in range( numControllers ):
3533 t = main.Thread( target=CLIs[i].setTestSize,
3534 name="setTestSize-" + str( i ),
3535 args=[ onosSetName ] )
3536 threads.append( t )
3537 t.start()
3538 for t in threads:
3539 t.join()
3540 sizeResponses.append( t.result )
3541 sizeResults = main.TRUE
3542 for i in range( numControllers ):
3543 if size != sizeResponses[ i ]:
3544 sizeResults = main.FALSE
3545 main.log.error( "ONOS" + str( i + 1 ) +
3546 " expected a size of " + str( size ) +
3547 " for set " + onosSetName +
3548 " but got " + str( sizeResponses[ i ] ) )
3549 removeAllResults = removeAllResults and getResults and sizeResults
3550 utilities.assert_equals( expect=main.TRUE,
3551 actual=removeAllResults,
3552 onpass="Set removeAll correct",
3553 onfail="Set removeAll was incorrect" )
3554
3555 main.step( "Distributed Set addAll()" )
3556 onosSet.update( addAllValue.split() )
3557 addResponses = []
3558 threads = []
3559 for i in range( numControllers ):
3560 t = main.Thread( target=CLIs[i].setTestAdd,
3561 name="setTestAddAll-" + str( i ),
3562 args=[ onosSetName, addAllValue ] )
3563 threads.append( t )
3564 t.start()
3565 for t in threads:
3566 t.join()
3567 addResponses.append( t.result )
3568
3569 # main.TRUE = successfully changed the set
3570 # main.FALSE = action resulted in no change in set
3571 # main.ERROR - Some error in executing the function
3572 addAllResults = main.TRUE
3573 for i in range( numControllers ):
3574 if addResponses[ i ] == main.TRUE:
3575 # All is well
3576 pass
3577 elif addResponses[ i ] == main.FALSE:
3578 # Already in set, probably fine
3579 pass
3580 elif addResponses[ i ] == main.ERROR:
3581 # Error in execution
3582 addAllResults = main.FALSE
3583 else:
3584 # unexpected result
3585 addAllResults = main.FALSE
3586 if addAllResults != main.TRUE:
3587 main.log.error( "Error executing set addAll" )
3588
3589 # Check if set is still correct
3590 size = len( onosSet )
3591 getResponses = []
3592 threads = []
3593 for i in range( numControllers ):
3594 t = main.Thread( target=CLIs[i].setTestGet,
3595 name="setTestGet-" + str( i ),
3596 args=[ onosSetName ] )
3597 threads.append( t )
3598 t.start()
3599 for t in threads:
3600 t.join()
3601 getResponses.append( t.result )
3602 getResults = main.TRUE
3603 for i in range( numControllers ):
3604 if isinstance( getResponses[ i ], list):
3605 current = set( getResponses[ i ] )
3606 if len( current ) == len( getResponses[ i ] ):
3607 # no repeats
3608 if onosSet != current:
3609 main.log.error( "ONOS" + str( i + 1 ) +
3610 " has incorrect view" +
3611 " of set " + onosSetName + ":\n" +
3612 str( getResponses[ i ] ) )
3613 main.log.debug( "Expected: " + str( onosSet ) )
3614 main.log.debug( "Actual: " + str( current ) )
3615 getResults = main.FALSE
3616 else:
3617 # error, set is not a set
3618 main.log.error( "ONOS" + str( i + 1 ) +
3619 " has repeat elements in" +
3620 " set " + onosSetName + ":\n" +
3621 str( getResponses[ i ] ) )
3622 getResults = main.FALSE
3623 elif getResponses[ i ] == main.ERROR:
3624 getResults = main.FALSE
3625 sizeResponses = []
3626 threads = []
3627 for i in range( numControllers ):
3628 t = main.Thread( target=CLIs[i].setTestSize,
3629 name="setTestSize-" + str( i ),
3630 args=[ onosSetName ] )
3631 threads.append( t )
3632 t.start()
3633 for t in threads:
3634 t.join()
3635 sizeResponses.append( t.result )
3636 sizeResults = main.TRUE
3637 for i in range( numControllers ):
3638 if size != sizeResponses[ i ]:
3639 sizeResults = main.FALSE
3640 main.log.error( "ONOS" + str( i + 1 ) +
3641 " expected a size of " + str( size ) +
3642 " for set " + onosSetName +
3643 " but got " + str( sizeResponses[ i ] ) )
3644 addAllResults = addAllResults and getResults and sizeResults
3645 utilities.assert_equals( expect=main.TRUE,
3646 actual=addAllResults,
3647 onpass="Set addAll correct",
3648 onfail="Set addAll was incorrect" )
3649
3650 main.step( "Distributed Set clear()" )
3651 onosSet.clear()
3652 clearResponses = []
3653 threads = []
3654 for i in range( numControllers ):
3655 t = main.Thread( target=CLIs[i].setTestRemove,
3656 name="setTestClear-" + str( i ),
3657 args=[ onosSetName, " "], # Values doesn't matter
3658 kwargs={ "clear": True } )
3659 threads.append( t )
3660 t.start()
3661 for t in threads:
3662 t.join()
3663 clearResponses.append( t.result )
3664
3665 # main.TRUE = successfully changed the set
3666 # main.FALSE = action resulted in no change in set
3667 # main.ERROR - Some error in executing the function
3668 clearResults = main.TRUE
3669 for i in range( numControllers ):
3670 if clearResponses[ i ] == main.TRUE:
3671 # All is well
3672 pass
3673 elif clearResponses[ i ] == main.FALSE:
3674 # Nothing set, probably fine
3675 pass
3676 elif clearResponses[ i ] == main.ERROR:
3677 # Error in execution
3678 clearResults = main.FALSE
3679 else:
3680 # unexpected result
3681 clearResults = main.FALSE
3682 if clearResults != main.TRUE:
3683 main.log.error( "Error executing set clear" )
3684
3685 # Check if set is still correct
3686 size = len( onosSet )
3687 getResponses = []
3688 threads = []
3689 for i in range( numControllers ):
3690 t = main.Thread( target=CLIs[i].setTestGet,
3691 name="setTestGet-" + str( i ),
3692 args=[ onosSetName ] )
3693 threads.append( t )
3694 t.start()
3695 for t in threads:
3696 t.join()
3697 getResponses.append( t.result )
3698 getResults = main.TRUE
3699 for i in range( numControllers ):
3700 if isinstance( getResponses[ i ], list):
3701 current = set( getResponses[ i ] )
3702 if len( current ) == len( getResponses[ i ] ):
3703 # no repeats
3704 if onosSet != current:
3705 main.log.error( "ONOS" + str( i + 1 ) +
3706 " has incorrect view" +
3707 " of set " + onosSetName + ":\n" +
3708 str( getResponses[ i ] ) )
3709 main.log.debug( "Expected: " + str( onosSet ) )
3710 main.log.debug( "Actual: " + str( current ) )
3711 getResults = main.FALSE
3712 else:
3713 # error, set is not a set
3714 main.log.error( "ONOS" + str( i + 1 ) +
3715 " has repeat elements in" +
3716 " set " + onosSetName + ":\n" +
3717 str( getResponses[ i ] ) )
3718 getResults = main.FALSE
3719 elif getResponses[ i ] == main.ERROR:
3720 getResults = main.FALSE
3721 sizeResponses = []
3722 threads = []
3723 for i in range( numControllers ):
3724 t = main.Thread( target=CLIs[i].setTestSize,
3725 name="setTestSize-" + str( i ),
3726 args=[ onosSetName ] )
3727 threads.append( t )
3728 t.start()
3729 for t in threads:
3730 t.join()
3731 sizeResponses.append( t.result )
3732 sizeResults = main.TRUE
3733 for i in range( numControllers ):
3734 if size != sizeResponses[ i ]:
3735 sizeResults = main.FALSE
3736 main.log.error( "ONOS" + str( i + 1 ) +
3737 " expected a size of " + str( size ) +
3738 " for set " + onosSetName +
3739 " but got " + str( sizeResponses[ i ] ) )
3740 clearResults = clearResults and getResults and sizeResults
3741 utilities.assert_equals( expect=main.TRUE,
3742 actual=clearResults,
3743 onpass="Set clear correct",
3744 onfail="Set clear was incorrect" )
3745
3746 main.step( "Distributed Set addAll()" )
3747 onosSet.update( addAllValue.split() )
3748 addResponses = []
3749 threads = []
3750 for i in range( numControllers ):
3751 t = main.Thread( target=CLIs[i].setTestAdd,
3752 name="setTestAddAll-" + str( i ),
3753 args=[ onosSetName, addAllValue ] )
3754 threads.append( t )
3755 t.start()
3756 for t in threads:
3757 t.join()
3758 addResponses.append( t.result )
3759
3760 # main.TRUE = successfully changed the set
3761 # main.FALSE = action resulted in no change in set
3762 # main.ERROR - Some error in executing the function
3763 addAllResults = main.TRUE
3764 for i in range( numControllers ):
3765 if addResponses[ i ] == main.TRUE:
3766 # All is well
3767 pass
3768 elif addResponses[ i ] == main.FALSE:
3769 # Already in set, probably fine
3770 pass
3771 elif addResponses[ i ] == main.ERROR:
3772 # Error in execution
3773 addAllResults = main.FALSE
3774 else:
3775 # unexpected result
3776 addAllResults = main.FALSE
3777 if addAllResults != main.TRUE:
3778 main.log.error( "Error executing set addAll" )
3779
3780 # Check if set is still correct
3781 size = len( onosSet )
3782 getResponses = []
3783 threads = []
3784 for i in range( numControllers ):
3785 t = main.Thread( target=CLIs[i].setTestGet,
3786 name="setTestGet-" + str( i ),
3787 args=[ onosSetName ] )
3788 threads.append( t )
3789 t.start()
3790 for t in threads:
3791 t.join()
3792 getResponses.append( t.result )
3793 getResults = main.TRUE
3794 for i in range( numControllers ):
3795 if isinstance( getResponses[ i ], list):
3796 current = set( getResponses[ i ] )
3797 if len( current ) == len( getResponses[ i ] ):
3798 # no repeats
3799 if onosSet != current:
3800 main.log.error( "ONOS" + str( i + 1 ) +
3801 " has incorrect view" +
3802 " of set " + onosSetName + ":\n" +
3803 str( getResponses[ i ] ) )
3804 main.log.debug( "Expected: " + str( onosSet ) )
3805 main.log.debug( "Actual: " + str( current ) )
3806 getResults = main.FALSE
3807 else:
3808 # error, set is not a set
3809 main.log.error( "ONOS" + str( i + 1 ) +
3810 " has repeat elements in" +
3811 " set " + onosSetName + ":\n" +
3812 str( getResponses[ i ] ) )
3813 getResults = main.FALSE
3814 elif getResponses[ i ] == main.ERROR:
3815 getResults = main.FALSE
3816 sizeResponses = []
3817 threads = []
3818 for i in range( numControllers ):
3819 t = main.Thread( target=CLIs[i].setTestSize,
3820 name="setTestSize-" + str( i ),
3821 args=[ onosSetName ] )
3822 threads.append( t )
3823 t.start()
3824 for t in threads:
3825 t.join()
3826 sizeResponses.append( t.result )
3827 sizeResults = main.TRUE
3828 for i in range( numControllers ):
3829 if size != sizeResponses[ i ]:
3830 sizeResults = main.FALSE
3831 main.log.error( "ONOS" + str( i + 1 ) +
3832 " expected a size of " + str( size ) +
3833 " for set " + onosSetName +
3834 " but got " + str( sizeResponses[ i ] ) )
3835 addAllResults = addAllResults and getResults and sizeResults
3836 utilities.assert_equals( expect=main.TRUE,
3837 actual=addAllResults,
3838 onpass="Set addAll correct",
3839 onfail="Set addAll was incorrect" )
3840
3841 main.step( "Distributed Set retain()" )
3842 onosSet.intersection_update( retainValue.split() )
3843 retainResponses = []
3844 threads = []
3845 for i in range( numControllers ):
3846 t = main.Thread( target=CLIs[i].setTestRemove,
3847 name="setTestRetain-" + str( i ),
3848 args=[ onosSetName, retainValue ],
3849 kwargs={ "retain": True } )
3850 threads.append( t )
3851 t.start()
3852 for t in threads:
3853 t.join()
3854 retainResponses.append( t.result )
3855
3856 # main.TRUE = successfully changed the set
3857 # main.FALSE = action resulted in no change in set
3858 # main.ERROR - Some error in executing the function
3859 retainResults = main.TRUE
3860 for i in range( numControllers ):
3861 if retainResponses[ i ] == main.TRUE:
3862 # All is well
3863 pass
3864 elif retainResponses[ i ] == main.FALSE:
3865 # Already in set, probably fine
3866 pass
3867 elif retainResponses[ i ] == main.ERROR:
3868 # Error in execution
3869 retainResults = main.FALSE
3870 else:
3871 # unexpected result
3872 retainResults = main.FALSE
3873 if retainResults != main.TRUE:
3874 main.log.error( "Error executing set retain" )
3875
3876 # Check if set is still correct
3877 size = len( onosSet )
3878 getResponses = []
3879 threads = []
3880 for i in range( numControllers ):
3881 t = main.Thread( target=CLIs[i].setTestGet,
3882 name="setTestGet-" + str( i ),
3883 args=[ onosSetName ] )
3884 threads.append( t )
3885 t.start()
3886 for t in threads:
3887 t.join()
3888 getResponses.append( t.result )
3889 getResults = main.TRUE
3890 for i in range( numControllers ):
3891 if isinstance( getResponses[ i ], list):
3892 current = set( getResponses[ i ] )
3893 if len( current ) == len( getResponses[ i ] ):
3894 # no repeats
3895 if onosSet != current:
3896 main.log.error( "ONOS" + str( i + 1 ) +
3897 " has incorrect view" +
3898 " of set " + onosSetName + ":\n" +
3899 str( getResponses[ i ] ) )
3900 main.log.debug( "Expected: " + str( onosSet ) )
3901 main.log.debug( "Actual: " + str( current ) )
3902 getResults = main.FALSE
3903 else:
3904 # error, set is not a set
3905 main.log.error( "ONOS" + str( i + 1 ) +
3906 " has repeat elements in" +
3907 " set " + onosSetName + ":\n" +
3908 str( getResponses[ i ] ) )
3909 getResults = main.FALSE
3910 elif getResponses[ i ] == main.ERROR:
3911 getResults = main.FALSE
3912 sizeResponses = []
3913 threads = []
3914 for i in range( numControllers ):
3915 t = main.Thread( target=CLIs[i].setTestSize,
3916 name="setTestSize-" + str( i ),
3917 args=[ onosSetName ] )
3918 threads.append( t )
3919 t.start()
3920 for t in threads:
3921 t.join()
3922 sizeResponses.append( t.result )
3923 sizeResults = main.TRUE
3924 for i in range( numControllers ):
3925 if size != sizeResponses[ i ]:
3926 sizeResults = main.FALSE
3927 main.log.error( "ONOS" + str( i + 1 ) +
3928 " expected a size of " +
3929 str( size ) + " for set " + onosSetName +
3930 " but got " + str( sizeResponses[ i ] ) )
3931 retainResults = retainResults and getResults and sizeResults
3932 utilities.assert_equals( expect=main.TRUE,
3933 actual=retainResults,
3934 onpass="Set retain correct",
3935 onfail="Set retain was incorrect" )
3936