blob: a81845fbf007a90bcb649faa57b7c9b31a9f14d0 [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 Hall73cf9cc2014-11-20 22:28:38 -08001080
Jon Hall6aec96b2015-01-19 14:49:31 -08001081 main.case( "Setting up and gathering data for current state" )
1082 # The general idea for this test case is to pull the state of
1083 # ( intents,flows, topology,... ) from each ONOS node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001084 # We can then compare them with each other and also with past states
Jon Hall73cf9cc2014-11-20 22:28:38 -08001085
Jon Hall5cfd23c2015-03-19 11:40:57 -07001086 main.step( "Check that each switch has a master" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001087 global mastershipState
Jon Hall5cfd23c2015-03-19 11:40:57 -07001088 mastershipState = '[]'
Jon Hall94fd0472014-12-08 11:52:42 -08001089
Jon Hall6aec96b2015-01-19 14:49:31 -08001090 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -07001091 rolesNotNull = main.TRUE
1092 threads = []
1093 for i in range( numControllers ):
1094 t = main.Thread( target=CLIs[i].rolesNotNull,
1095 name="rolesNotNull-" + str( i ),
1096 args=[] )
1097 threads.append( t )
1098 t.start()
1099
1100 for t in threads:
1101 t.join()
1102 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001103 utilities.assert_equals(
1104 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001105 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001106 onpass="Each device has a master",
1107 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001108
Jon Hall5cfd23c2015-03-19 11:40:57 -07001109 main.step( "Get the Mastership of each switch from each controller" )
1110 ONOSMastership = []
1111 mastershipCheck = main.FALSE
1112 consistentMastership = True
1113 rolesResults = True
1114 threads = []
1115 for i in range( numControllers ):
1116 t = main.Thread( target=CLIs[i].roles,
1117 name="roles-" + str( i ),
1118 args=[] )
1119 threads.append( t )
1120 t.start()
1121
1122 for t in threads:
1123 t.join()
1124 ONOSMastership.append( t.result )
1125
1126 for i in range( numControllers ):
1127 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001128 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001129 " roles" )
1130 main.log.warn(
1131 "ONOS" + str( i + 1 ) + " mastership response: " +
1132 repr( ONOSMastership[i] ) )
1133 rolesResults = False
1134 utilities.assert_equals(
1135 expect=True,
1136 actual=rolesResults,
1137 onpass="No error in reading roles output",
1138 onfail="Error in reading roles from ONOS" )
1139
1140 main.step( "Check for consistency in roles from each controller" )
1141 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001142 main.log.info(
Jon Hall6aec96b2015-01-19 14:49:31 -08001143 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001144 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001145 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001146 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001147 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001148 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001149 onpass="Switch roles are consistent across all ONOS nodes",
1150 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001151
Jon Hall5cfd23c2015-03-19 11:40:57 -07001152 if rolesResults and not consistentMastership:
1153 for i in range( numControllers ):
1154 try:
1155 main.log.warn(
1156 "ONOS" + str( i + 1 ) + " roles: ",
1157 json.dumps(
1158 json.loads( ONOSMastership[ i ] ),
1159 sort_keys=True,
1160 indent=4,
1161 separators=( ',', ': ' ) ) )
1162 except ( ValueError, TypeError ):
1163 main.log.warn( repr( ONOSMastership[ i ] ) )
1164 elif rolesResults and consistentMastership:
1165 mastershipCheck = main.TRUE
1166 mastershipState = ONOSMastership[ 0 ]
1167
Jon Hall6aec96b2015-01-19 14:49:31 -08001168 main.step( "Get the intents from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001169 global intentState
1170 intentState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001171 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001172 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001173 consistentIntents = True
1174 intentsResults = True
1175 threads = []
1176 for i in range( numControllers ):
1177 t = main.Thread( target=CLIs[i].intents,
1178 name="intents-" + str( i ),
1179 args=[],
1180 kwargs={ 'jsonFormat': True } )
1181 threads.append( t )
1182 t.start()
1183
1184 for t in threads:
1185 t.join()
1186 ONOSIntents.append( t.result )
1187
1188 for i in range( numControllers ):
1189 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001190 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001191 " intents" )
1192 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1193 repr( ONOSIntents[ i ] ) )
1194 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001195 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001196 expect=True,
1197 actual=intentsResults,
1198 onpass="No error in reading intents output",
1199 onfail="Error in reading intents from ONOS" )
1200
1201 main.step( "Check for consistency in Intents from each controller" )
1202 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001203 main.log.info( "Intents are consistent across all ONOS " +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001204 "nodes" )
1205 else:
1206 consistentIntents = False
Jon Hall40d2cbd2015-06-03 16:24:29 -07001207 main.log.error( "Intents not consistent" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001208 utilities.assert_equals(
1209 expect=True,
1210 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001211 onpass="Intents are consistent across all ONOS nodes",
1212 onfail="ONOS nodes have different views of intents" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001213
Jon Hall390696c2015-05-05 17:13:41 -07001214 if intentsResults:
1215 # Try to make it easy to figure out what is happening
1216 #
1217 # Intent ONOS1 ONOS2 ...
1218 # 0x01 INSTALLED INSTALLING
1219 # ... ... ...
1220 # ... ... ...
1221 title = " Id"
1222 for n in range( numControllers ):
1223 title += " " * 10 + "ONOS" + str( n + 1 )
1224 main.log.warn( title )
1225 # get all intent keys in the cluster
1226 keys = []
1227 for nodeStr in ONOSIntents:
1228 node = json.loads( nodeStr )
1229 for intent in node:
1230 keys.append( intent.get( 'id' ) )
1231 keys = set( keys )
1232 for key in keys:
1233 row = "%-13s" % key
1234 for nodeStr in ONOSIntents:
1235 node = json.loads( nodeStr )
1236 for intent in node:
1237 if intent.get( 'id', "Error" ) == key:
1238 row += "%-15s" % intent.get( 'state' )
1239 main.log.warn( row )
1240 # End table view
1241
Jon Hall5cfd23c2015-03-19 11:40:57 -07001242 if intentsResults and not consistentIntents:
Jon Hall390696c2015-05-05 17:13:41 -07001243 # print the json objects
Jon Hall5cfd23c2015-03-19 11:40:57 -07001244 n = len(ONOSIntents)
Jon Hall390696c2015-05-05 17:13:41 -07001245 main.log.debug( "ONOS" + str( n ) + " intents: " )
1246 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1247 sort_keys=True,
1248 indent=4,
1249 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001250 for i in range( numControllers ):
1251 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
Jon Hall390696c2015-05-05 17:13:41 -07001252 main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
1253 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1254 sort_keys=True,
1255 indent=4,
1256 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001257 else:
Jon Hall390696c2015-05-05 17:13:41 -07001258 main.log.debug( nodes[ i ].name + " intents match ONOS" +
1259 str( n ) + " intents" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001260 elif intentsResults and consistentIntents:
1261 intentCheck = main.TRUE
1262 intentState = ONOSIntents[ 0 ]
1263
Jon Hall6aec96b2015-01-19 14:49:31 -08001264 main.step( "Get the flows from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001265 global flowState
1266 flowState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001267 ONOSFlows = []
1268 ONOSFlowsJson = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001269 flowCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001270 consistentFlows = True
1271 flowsResults = True
1272 threads = []
1273 for i in range( numControllers ):
1274 t = main.Thread( target=CLIs[i].flows,
1275 name="flows-" + str( i ),
1276 args=[],
1277 kwargs={ 'jsonFormat': True } )
1278 threads.append( t )
1279 t.start()
1280
Jon Halla9d26da2015-03-30 16:45:32 -07001281 # NOTE: Flows command can take some time to run
Jon Hall5cfd23c2015-03-19 11:40:57 -07001282 time.sleep(30)
1283 for t in threads:
1284 t.join()
1285 result = t.result
1286 ONOSFlows.append( result )
1287
1288 for i in range( numControllers ):
1289 num = str( i + 1 )
1290 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001291 main.log.error( "Error in getting ONOS" + num + " flows" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001292 main.log.warn( "ONOS" + num + " flows response: " +
1293 repr( ONOSFlows[ i ] ) )
1294 flowsResults = False
1295 ONOSFlowsJson.append( None )
Jon Hall58c76b72015-02-23 11:09:24 -08001296 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001297 try:
1298 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1299 except ( ValueError, TypeError ):
1300 # FIXME: change this to log.error?
1301 main.log.exception( "Error in parsing ONOS" + num +
1302 " response as json." )
1303 main.log.error( repr( ONOSFlows[ i ] ) )
1304 ONOSFlowsJson.append( None )
1305 flowsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001306 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001307 expect=True,
1308 actual=flowsResults,
1309 onpass="No error in reading flows output",
1310 onfail="Error in reading flows from ONOS" )
1311
1312 main.step( "Check for consistency in Flows from each controller" )
1313 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1314 if all( tmp ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001315 main.log.info( "Flow count is consistent across all ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001316 else:
1317 consistentFlows = False
1318 utilities.assert_equals(
1319 expect=True,
1320 actual=consistentFlows,
Jon Hall6aec96b2015-01-19 14:49:31 -08001321 onpass="The flow count is consistent across all ONOS nodes",
1322 onfail="ONOS nodes have different flow counts" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001323
Jon Hall5cfd23c2015-03-19 11:40:57 -07001324 if flowsResults and not consistentFlows:
1325 for i in range( numControllers ):
1326 try:
1327 main.log.warn(
1328 "ONOS" + str( i + 1 ) + " flows: " +
1329 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1330 indent=4, separators=( ',', ': ' ) ) )
1331 except ( ValueError, TypeError ):
1332 main.log.warn(
1333 "ONOS" + str( i + 1 ) + " flows: " +
1334 repr( ONOSFlows[ i ] ) )
1335 elif flowsResults and consistentFlows:
1336 flowCheck = main.TRUE
1337 flowState = ONOSFlows[ 0 ]
1338
Jon Hall6aec96b2015-01-19 14:49:31 -08001339 main.step( "Get the OF Table entries" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001340 global flows
Jon Hall6aec96b2015-01-19 14:49:31 -08001341 flows = []
1342 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001343 flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001344 if flowCheck == main.FALSE:
1345 for table in flows:
1346 main.log.warn( table )
Jon Hall6aec96b2015-01-19 14:49:31 -08001347 # TODO: Compare switch flow tables with ONOS flow tables
Jon Hall73cf9cc2014-11-20 22:28:38 -08001348
Jon Hall6aec96b2015-01-19 14:49:31 -08001349 main.step( "Start continuous pings" )
1350 main.Mininet2.pingLong(
1351 src=main.params[ 'PING' ][ 'source1' ],
1352 target=main.params[ 'PING' ][ 'target1' ],
1353 pingTime=500 )
1354 main.Mininet2.pingLong(
1355 src=main.params[ 'PING' ][ 'source2' ],
1356 target=main.params[ 'PING' ][ 'target2' ],
1357 pingTime=500 )
1358 main.Mininet2.pingLong(
1359 src=main.params[ 'PING' ][ 'source3' ],
1360 target=main.params[ 'PING' ][ 'target3' ],
1361 pingTime=500 )
1362 main.Mininet2.pingLong(
1363 src=main.params[ 'PING' ][ 'source4' ],
1364 target=main.params[ 'PING' ][ 'target4' ],
1365 pingTime=500 )
1366 main.Mininet2.pingLong(
1367 src=main.params[ 'PING' ][ 'source5' ],
1368 target=main.params[ 'PING' ][ 'target5' ],
1369 pingTime=500 )
1370 main.Mininet2.pingLong(
1371 src=main.params[ 'PING' ][ 'source6' ],
1372 target=main.params[ 'PING' ][ 'target6' ],
1373 pingTime=500 )
1374 main.Mininet2.pingLong(
1375 src=main.params[ 'PING' ][ 'source7' ],
1376 target=main.params[ 'PING' ][ 'target7' ],
1377 pingTime=500 )
1378 main.Mininet2.pingLong(
1379 src=main.params[ 'PING' ][ 'source8' ],
1380 target=main.params[ 'PING' ][ 'target8' ],
1381 pingTime=500 )
1382 main.Mininet2.pingLong(
1383 src=main.params[ 'PING' ][ 'source9' ],
1384 target=main.params[ 'PING' ][ 'target9' ],
1385 pingTime=500 )
1386 main.Mininet2.pingLong(
1387 src=main.params[ 'PING' ][ 'source10' ],
1388 target=main.params[ 'PING' ][ 'target10' ],
1389 pingTime=500 )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001390
Jon Hall6aec96b2015-01-19 14:49:31 -08001391 main.step( "Collecting topology information from ONOS" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001392 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001393 threads = []
1394 for i in range( numControllers ):
1395 t = main.Thread( target=CLIs[i].devices,
1396 name="devices-" + str( i ),
1397 args=[ ] )
1398 threads.append( t )
1399 t.start()
1400
1401 for t in threads:
1402 t.join()
1403 devices.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001404 hosts = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001405 threads = []
1406 for i in range( numControllers ):
1407 t = main.Thread( target=CLIs[i].hosts,
1408 name="hosts-" + str( i ),
1409 args=[ ] )
1410 threads.append( t )
1411 t.start()
1412
1413 for t in threads:
1414 t.join()
1415 try:
1416 hosts.append( json.loads( t.result ) )
1417 except ( ValueError, TypeError ):
1418 # FIXME: better handling of this, print which node
1419 # Maybe use thread name?
1420 main.log.exception( "Error parsing json output of hosts" )
1421 # FIXME: should this be an empty json object instead?
1422 hosts.append( None )
1423
Jon Hall73cf9cc2014-11-20 22:28:38 -08001424 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001425 threads = []
1426 for i in range( numControllers ):
1427 t = main.Thread( target=CLIs[i].ports,
1428 name="ports-" + str( i ),
1429 args=[ ] )
1430 threads.append( t )
1431 t.start()
1432
1433 for t in threads:
1434 t.join()
1435 ports.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001436 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001437 threads = []
1438 for i in range( numControllers ):
1439 t = main.Thread( target=CLIs[i].links,
1440 name="links-" + str( i ),
1441 args=[ ] )
1442 threads.append( t )
1443 t.start()
1444
1445 for t in threads:
1446 t.join()
1447 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001448 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001449 threads = []
1450 for i in range( numControllers ):
1451 t = main.Thread( target=CLIs[i].clusters,
1452 name="clusters-" + str( i ),
1453 args=[ ] )
1454 threads.append( t )
1455 t.start()
1456
1457 for t in threads:
1458 t.join()
1459 clusters.append( t.result )
Jon Hall529a37f2015-01-28 10:02:00 -08001460 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001461
Jon Hall6aec96b2015-01-19 14:49:31 -08001462 # hosts
Jon Hall390696c2015-05-05 17:13:41 -07001463 main.step( "Host view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001464 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001465 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001466 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001467 if "Error" not in hosts[ controller ]:
1468 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001469 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001470 else: # hosts not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07001471 main.log.error( "hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001472 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001473 " is inconsistent with ONOS1" )
1474 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001475 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001476
1477 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001478 main.log.error( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001479 controllerStr )
1480 consistentHostsResult = main.FALSE
1481 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001482 " hosts response: " +
1483 repr( hosts[ controller ] ) )
1484 utilities.assert_equals(
1485 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001486 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001487 onpass="Hosts view is consistent across all ONOS nodes",
1488 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001489
Jon Hall390696c2015-05-05 17:13:41 -07001490 main.step( "Each host has an IP address" )
Jon Hall58c76b72015-02-23 11:09:24 -08001491 ipResult = main.TRUE
1492 for controller in range( 0, len( hosts ) ):
1493 controllerStr = str( controller + 1 )
1494 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07001495 if not host.get( 'ipAddresses', [ ] ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001496 main.log.error( "DEBUG:Error with host ips on controller" +
1497 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001498 ipResult = main.FALSE
1499 utilities.assert_equals(
1500 expect=main.TRUE,
1501 actual=ipResult,
1502 onpass="The ips of the hosts aren't empty",
1503 onfail="The ip of at least one host is missing" )
1504
Jon Hall6aec96b2015-01-19 14:49:31 -08001505 # Strongly connected clusters of devices
Jon Hall390696c2015-05-05 17:13:41 -07001506 main.step( "Cluster view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001507 consistentClustersResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001508 for controller in range( len( clusters ) ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001509 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001510 if "Error" not in clusters[ controller ]:
1511 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001512 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001513 else: # clusters not consistent
Jon Hall40d2cbd2015-06-03 16:24:29 -07001514 main.log.error( "clusters from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001515 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001516 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001517
1518 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001519 main.log.error( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001520 "from ONOS" + controllerStr )
1521 consistentClustersResult = main.FALSE
1522 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001523 " clusters response: " +
1524 repr( clusters[ controller ] ) )
1525 utilities.assert_equals(
1526 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001527 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001528 onpass="Clusters view is consistent across all ONOS nodes",
1529 onfail="ONOS nodes have different views of clusters" )
1530 # there should always only be one cluster
Jon Hall390696c2015-05-05 17:13:41 -07001531 main.step( "Cluster view correct across ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001532 try:
1533 numClusters = len( json.loads( clusters[ 0 ] ) )
1534 except ( ValueError, TypeError ):
1535 main.log.exception( "Error parsing clusters[0]: " +
1536 repr( clusters[ 0 ] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001537 clusterResults = main.FALSE
1538 if numClusters == 1:
1539 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001540 utilities.assert_equals(
1541 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08001542 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08001543 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08001544 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08001545
Jon Hall6aec96b2015-01-19 14:49:31 -08001546 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001547 devicesResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08001548 linksResults = main.TRUE
Jon Hallafa8a472015-06-12 14:02:42 -07001549 hostsResults = main.TRUE
1550 mnSwitches = main.Mininet1.getSwitches()
1551 mnLinks = main.Mininet1.getLinks()
1552 mnHosts = main.Mininet1.getHosts()
Jon Hall8f89dda2015-01-22 16:03:33 -08001553 for controller in range( numControllers ):
1554 controllerStr = str( controller + 1 )
Jon Hallafa8a472015-06-12 14:02:42 -07001555 if devices[ controller ] and ports[ controller ] and\
1556 "Error" not in devices[ controller ] and\
1557 "Error" not in ports[ controller ]:
1558
Jon Hall8f89dda2015-01-22 16:03:33 -08001559 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hallafa8a472015-06-12 14:02:42 -07001560 mnSwitches,
1561 json.loads( devices[ controller ] ),
1562 json.loads( ports[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001563 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001564 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001565 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001566 actual=currentDevicesResult,
1567 onpass="ONOS" + controllerStr +
1568 " Switches view is correct",
1569 onfail="ONOS" + controllerStr +
1570 " Switches view is incorrect" )
Jon Hallafa8a472015-06-12 14:02:42 -07001571 if links[ controller ] and "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001572 currentLinksResult = main.Mininet1.compareLinks(
Jon Hallafa8a472015-06-12 14:02:42 -07001573 mnSwitches, mnLinks,
1574 json.loads( links[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001575 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001576 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001577 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001578 actual=currentLinksResult,
1579 onpass="ONOS" + controllerStr +
1580 " links view is correct",
1581 onfail="ONOS" + controllerStr +
1582 " links view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001583
Jon Hallafa8a472015-06-12 14:02:42 -07001584 if hosts[ controller ] or "Error" not in hosts[ controller ]:
1585 currentHostsResult = main.Mininet1.compareHosts(
1586 mnHosts,
1587 hosts[ controller ] )
1588 else:
1589 currentHostsResult = main.FALSE
1590 utilities.assert_equals( expect=main.TRUE,
1591 actual=currentHostsResult,
1592 onpass="ONOS" + controllerStr +
1593 " hosts exist in Mininet",
1594 onfail="ONOS" + controllerStr +
1595 " hosts don't match Mininet" )
Jon Hallb6a54872015-06-12 14:02:42 -07001596
Jon Hallafa8a472015-06-12 14:02:42 -07001597 devicesResults = devicesResults and currentDevicesResult
1598 linksResults = linksResults and currentLinksResult
1599 hostsResults = hostsResults and currentHostsResult
1600
1601 main.step( "Device information is correct" )
1602 utilities.assert_equals(
1603 expect=main.TRUE,
1604 actual=devicesResults,
1605 onpass="Device information is correct",
1606 onfail="Device information is incorrect" )
1607
1608 main.step( "Links are correct" )
1609 utilities.assert_equals(
1610 expect=main.TRUE,
1611 actual=linksResults,
1612 onpass="Link are correct",
1613 onfail="Links are incorrect" )
1614
1615 main.step( "Hosts are correct" )
1616 utilities.assert_equals(
1617 expect=main.TRUE,
1618 actual=hostsResults,
1619 onpass="Hosts are correct",
1620 onfail="Hosts are incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001621
Jon Hall6aec96b2015-01-19 14:49:31 -08001622 def CASE6( self, main ):
1623 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001624 The Failure case.
Jon Hall6aec96b2015-01-19 14:49:31 -08001625 """
Jon Hall94fd0472014-12-08 11:52:42 -08001626 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001627 assert numControllers, "numControllers not defined"
1628 assert main, "main not defined"
1629 assert utilities.assert_equals, "utilities.assert_equals not defined"
1630 assert CLIs, "CLIs not defined"
1631 assert nodes, "nodes not defined"
Jon Hall5cfd23c2015-03-19 11:40:57 -07001632 main.case( "Restart minority of ONOS nodes" )
Jon Hall390696c2015-05-05 17:13:41 -07001633 main.step( "Killing 3 ONOS nodes" )
Jon Hallfeff3082015-05-19 10:23:26 -07001634 killTime = time.time()
Jon Hall390696c2015-05-05 17:13:41 -07001635 # TODO: Randomize these nodes or base this on partitions
Jon Hall5cfd23c2015-03-19 11:40:57 -07001636 # TODO: use threads in this case
Jon Hall390696c2015-05-05 17:13:41 -07001637 killResults = main.ONOSbench.onosKill( nodes[0].ip_address )
Jon Hall6aec96b2015-01-19 14:49:31 -08001638 time.sleep( 10 )
Jon Hall390696c2015-05-05 17:13:41 -07001639 killResults = killResults and\
1640 main.ONOSbench.onosKill( nodes[1].ip_address )
Jon Hall6aec96b2015-01-19 14:49:31 -08001641 time.sleep( 10 )
Jon Hall390696c2015-05-05 17:13:41 -07001642 killResults = killResults and\
1643 main.ONOSbench.onosKill( nodes[2].ip_address )
1644 utilities.assert_equals( expect=main.TRUE, actual=killResults,
1645 onpass="ONOS Killed successfully",
1646 onfail="ONOS kill NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001647
Jon Hall6aec96b2015-01-19 14:49:31 -08001648 main.step( "Checking if ONOS is up yet" )
Jon Hallffb386d2014-11-21 13:43:38 -08001649 count = 0
Jon Hall8f89dda2015-01-22 16:03:33 -08001650 onosIsupResult = main.FALSE
1651 while onosIsupResult == main.FALSE and count < 10:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001652 onos1Isup = main.ONOSbench.isup( nodes[0].ip_address )
1653 onos2Isup = main.ONOSbench.isup( nodes[1].ip_address )
1654 onos3Isup = main.ONOSbench.isup( nodes[2].ip_address )
Jon Hall8f89dda2015-01-22 16:03:33 -08001655 onosIsupResult = onos1Isup and onos2Isup and onos3Isup
Jon Hallffb386d2014-11-21 13:43:38 -08001656 count = count + 1
Jon Hall73cf9cc2014-11-20 22:28:38 -08001657 # TODO: if it becomes an issue, we can retry this step a few times
Jon Hall390696c2015-05-05 17:13:41 -07001658 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1659 onpass="ONOS restarted successfully",
1660 onfail="ONOS restart NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001661
Jon Hall390696c2015-05-05 17:13:41 -07001662 main.step( "Restarting ONOS CLIs" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001663 cliResult1 = main.ONOScli1.startOnosCli( nodes[0].ip_address )
1664 cliResult2 = main.ONOScli2.startOnosCli( nodes[1].ip_address )
1665 cliResult3 = main.ONOScli3.startOnosCli( nodes[2].ip_address )
Jon Hall8f89dda2015-01-22 16:03:33 -08001666 cliResults = cliResult1 and cliResult2 and cliResult3
Jon Hall390696c2015-05-05 17:13:41 -07001667 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1668 onpass="ONOS cli restarted",
1669 onfail="ONOS cli did not restart" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001670
Jon Hall21270ac2015-02-16 17:59:55 -08001671 # Grab the time of restart so we chan check how long the gossip
1672 # protocol has had time to work
Jon Hallfeff3082015-05-19 10:23:26 -07001673 main.restartTime = time.time() - killTime
1674 main.log.debug( "Restart time: " + str( main.restartTime ) )
1675 '''
1676 # FIXME: revisit test plan for election with madan
1677 # Rerun for election on restarted nodes
1678 run1 = CLIs[0].electionTestRun()
1679 run2 = CLIs[1].electionTestRun()
1680 run3 = CLIs[2].electionTestRun()
1681 runResults = run1 and run2 and run3
1682 utilities.assert_equals( expect=main.TRUE, actual=runResults,
1683 onpass="Reran for election",
1684 onfail="Failed to rerun for election" )
1685 '''
1686 # TODO: MAke this configurable. Also, we are breaking the above timer
1687 time.sleep( 60 )
1688 main.log.debug( CLIs[0].nodes( jsonFormat=False ) )
1689 main.log.debug( CLIs[0].leaders( jsonFormat=False ) )
1690 main.log.debug( CLIs[0].partitions( jsonFormat=False ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001691
Jon Hall6aec96b2015-01-19 14:49:31 -08001692 def CASE7( self, main ):
1693 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001694 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -08001695 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001696 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001697 assert numControllers, "numControllers not defined"
1698 assert main, "main not defined"
1699 assert utilities.assert_equals, "utilities.assert_equals not defined"
1700 assert CLIs, "CLIs not defined"
1701 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001702 main.case( "Running ONOS Constant State Tests" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001703
Jon Hall5cfd23c2015-03-19 11:40:57 -07001704 main.step( "Check that each switch has a master" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001705 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -07001706 rolesNotNull = main.TRUE
1707 threads = []
1708 for i in range( numControllers ):
1709 t = main.Thread( target=CLIs[i].rolesNotNull,
1710 name="rolesNotNull-" + str( i ),
1711 args=[ ] )
1712 threads.append( t )
1713 t.start()
1714
1715 for t in threads:
1716 t.join()
1717 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001718 utilities.assert_equals(
1719 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001720 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001721 onpass="Each device has a master",
1722 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001723
Jon Hall390696c2015-05-05 17:13:41 -07001724 main.step( "Read device roles from ONOS" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001725 ONOSMastership = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001726 consistentMastership = True
1727 rolesResults = True
1728 threads = []
1729 for i in range( numControllers ):
1730 t = main.Thread( target=CLIs[i].roles,
1731 name="roles-" + str( i ),
1732 args=[] )
1733 threads.append( t )
1734 t.start()
1735
1736 for t in threads:
1737 t.join()
1738 ONOSMastership.append( t.result )
1739
1740 for i in range( numControllers ):
1741 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001742 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001743 " roles" )
1744 main.log.warn(
1745 "ONOS" + str( i + 1 ) + " mastership response: " +
1746 repr( ONOSMastership[i] ) )
1747 rolesResults = False
1748 utilities.assert_equals(
1749 expect=True,
1750 actual=rolesResults,
1751 onpass="No error in reading roles output",
1752 onfail="Error in reading roles from ONOS" )
1753
1754 main.step( "Check for consistency in roles from each controller" )
1755 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001756 main.log.info(
Jon Hall6aec96b2015-01-19 14:49:31 -08001757 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001758 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001759 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001760 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001761 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001762 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001763 onpass="Switch roles are consistent across all ONOS nodes",
1764 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001765
Jon Hall5cfd23c2015-03-19 11:40:57 -07001766 if rolesResults and not consistentMastership:
1767 for i in range( numControllers ):
1768 main.log.warn(
1769 "ONOS" + str( i + 1 ) + " roles: ",
1770 json.dumps(
1771 json.loads( ONOSMastership[ i ] ),
1772 sort_keys=True,
1773 indent=4,
1774 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001775
Jon Hallfeff3082015-05-19 10:23:26 -07001776 # NOTE: we expect mastership to change on controller failure
1777 '''
Jon Hall73cf9cc2014-11-20 22:28:38 -08001778 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -08001779 main.step( description2 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001780 try:
1781 currentJson = json.loads( ONOSMastership[0] )
1782 oldJson = json.loads( mastershipState )
1783 except ( ValueError, TypeError ):
1784 main.log.exception( "Something is wrong with parsing " +
1785 "ONOSMastership[0] or mastershipState" )
1786 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1787 main.log.error( "mastershipState" + repr( mastershipState ) )
1788 main.cleanup()
1789 main.exit()
Jon Hall8f89dda2015-01-22 16:03:33 -08001790 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001791 for i in range( 1, 29 ):
1792 switchDPID = str(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001793 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001794 current = [ switch[ 'master' ] for switch in currentJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001795 if switchDPID in switch[ 'id' ] ]
Jon Hall8f89dda2015-01-22 16:03:33 -08001796 old = [ switch[ 'master' ] for switch in oldJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001797 if switchDPID in switch[ 'id' ] ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08001798 if current == old:
Jon Hall8f89dda2015-01-22 16:03:33 -08001799 mastershipCheck = mastershipCheck and main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001800 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001801 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall8f89dda2015-01-22 16:03:33 -08001802 mastershipCheck = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001803 utilities.assert_equals(
1804 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001805 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -08001806 onpass="Mastership of Switches was not changed",
1807 onfail="Mastership of some switches changed" )
Jon Hallfeff3082015-05-19 10:23:26 -07001808 '''
Jon Hall73cf9cc2014-11-20 22:28:38 -08001809
Jon Hall58c76b72015-02-23 11:09:24 -08001810 main.step( "Get the intents and compare across all nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001811 ONOSIntents = []
Jon Hall58c76b72015-02-23 11:09:24 -08001812 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001813 consistentIntents = True
1814 intentsResults = True
1815 threads = []
1816 for i in range( numControllers ):
1817 t = main.Thread( target=CLIs[i].intents,
1818 name="intents-" + str( i ),
1819 args=[],
1820 kwargs={ 'jsonFormat': True } )
1821 threads.append( t )
1822 t.start()
1823
1824 for t in threads:
1825 t.join()
1826 ONOSIntents.append( t.result )
1827
1828 for i in range( numControllers ):
1829 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001830 main.log.error( "Error in getting ONOS" + str( i + 1 ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001831 " intents" )
1832 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1833 repr( ONOSIntents[ i ] ) )
1834 intentsResults = False
Jon Hall58c76b72015-02-23 11:09:24 -08001835 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001836 expect=True,
1837 actual=intentsResults,
1838 onpass="No error in reading intents output",
1839 onfail="Error in reading intents from ONOS" )
1840
1841 main.step( "Check for consistency in Intents from each controller" )
1842 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07001843 main.log.info( "Intents are consistent across all ONOS " +
Jon Hall5cfd23c2015-03-19 11:40:57 -07001844 "nodes" )
1845 else:
1846 consistentIntents = False
Jon Hall390696c2015-05-05 17:13:41 -07001847
1848 # Try to make it easy to figure out what is happening
1849 #
1850 # Intent ONOS1 ONOS2 ...
1851 # 0x01 INSTALLED INSTALLING
1852 # ... ... ...
1853 # ... ... ...
1854 title = " ID"
1855 for n in range( numControllers ):
1856 title += " " * 10 + "ONOS" + str( n + 1 )
1857 main.log.warn( title )
1858 # get all intent keys in the cluster
1859 keys = []
1860 for nodeStr in ONOSIntents:
1861 node = json.loads( nodeStr )
1862 for intent in node:
1863 keys.append( intent.get( 'id' ) )
1864 keys = set( keys )
1865 for key in keys:
1866 row = "%-13s" % key
1867 for nodeStr in ONOSIntents:
1868 node = json.loads( nodeStr )
1869 for intent in node:
1870 if intent.get( 'id' ) == key:
1871 row += "%-15s" % intent.get( 'state' )
1872 main.log.warn( row )
1873 # End table view
1874
Jon Hall5cfd23c2015-03-19 11:40:57 -07001875 utilities.assert_equals(
1876 expect=True,
1877 actual=consistentIntents,
Jon Hall58c76b72015-02-23 11:09:24 -08001878 onpass="Intents are consistent across all ONOS nodes",
1879 onfail="ONOS nodes have different views of intents" )
Jon Hall58c76b72015-02-23 11:09:24 -08001880 intentStates = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001881 for node in ONOSIntents: # Iter through ONOS nodes
Jon Hall58c76b72015-02-23 11:09:24 -08001882 nodeStates = []
1883 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001884 try:
1885 for intent in json.loads( node ):
1886 nodeStates.append( intent[ 'state' ] )
1887 except ( ValueError, TypeError ):
1888 main.log.exception( "Error in parsing intents" )
1889 main.log.error( repr( node ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001890 intentStates.append( nodeStates )
1891 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1892 main.log.info( dict( out ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001893
Jon Hall5cfd23c2015-03-19 11:40:57 -07001894 if intentsResults and not consistentIntents:
1895 for i in range( numControllers ):
1896 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1897 main.log.warn( json.dumps(
1898 json.loads( ONOSIntents[ i ] ),
1899 sort_keys=True,
1900 indent=4,
1901 separators=( ',', ': ' ) ) )
1902 elif intentsResults and consistentIntents:
1903 intentCheck = main.TRUE
1904
Jon Hall58c76b72015-02-23 11:09:24 -08001905 # NOTE: Store has no durability, so intents are lost across system
1906 # restarts
1907 main.step( "Compare current intents with intents before the failure" )
1908 # NOTE: this requires case 5 to pass for intentState to be set.
1909 # maybe we should stop the test if that fails?
Jon Hall40d2cbd2015-06-03 16:24:29 -07001910 sameIntents = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001911 if intentState and intentState == ONOSIntents[ 0 ]:
Jon Hall21270ac2015-02-16 17:59:55 -08001912 sameIntents = main.TRUE
Jon Hallfeff3082015-05-19 10:23:26 -07001913 main.log.info( "Intents are consistent with before failure" )
Jon Hall58c76b72015-02-23 11:09:24 -08001914 # TODO: possibly the states have changed? we may need to figure out
Jon Hall5cfd23c2015-03-19 11:40:57 -07001915 # what the acceptable states are
Jon Hall40d2cbd2015-06-03 16:24:29 -07001916 elif len( intentState ) == len( ONOSIntents[ 0 ] ):
1917 sameIntents = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08001918 try:
Jon Hall40d2cbd2015-06-03 16:24:29 -07001919 before = json.loads( intentState )
1920 after = json.loads( ONOSIntents[ 0 ] )
1921 for intent in before:
1922 if intent not in after:
1923 sameIntents = main.FALSE
Jon Hallc9eabec2015-06-10 14:33:14 -07001924 main.log.debug( "Intent is not currently in ONOS " +
Jon Hall40d2cbd2015-06-03 16:24:29 -07001925 "(at least in the same form):" )
1926 main.log.debug( json.dumps( intent ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001927 except ( ValueError, TypeError ):
1928 main.log.exception( "Exception printing intents" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001929 main.log.debug( repr( ONOSIntents[0] ) )
1930 main.log.debug( repr( intentState ) )
1931 if sameIntents == main.FALSE:
1932 try:
1933 main.log.debug( "ONOS intents before: " )
1934 main.log.debug( json.dumps( json.loads( intentState ),
1935 sort_keys=True, indent=4,
1936 separators=( ',', ': ' ) ) )
1937 main.log.debug( "Current ONOS intents: " )
1938 main.log.debug( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1939 sort_keys=True, indent=4,
1940 separators=( ',', ': ' ) ) )
1941 except ( ValueError, TypeError ):
1942 main.log.exception( "Exception printing intents" )
1943 main.log.debug( repr( ONOSIntents[0] ) )
1944 main.log.debug( repr( intentState ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001945 utilities.assert_equals(
1946 expect=main.TRUE,
1947 actual=sameIntents,
1948 onpass="Intents are consistent with before failure",
1949 onfail="The Intents changed during failure" )
1950 intentCheck = intentCheck and sameIntents
Jon Hall21270ac2015-02-16 17:59:55 -08001951
Jon Hall58c76b72015-02-23 11:09:24 -08001952 main.step( "Get the OF Table entries and compare to before " +
1953 "component failure" )
1954 FlowTables = main.TRUE
1955 flows2 = []
1956 for i in range( 28 ):
1957 main.log.info( "Checking flow table on s" + str( i + 1 ) )
1958 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
1959 flows2.append( tmpFlows )
1960 tempResult = main.Mininet2.flowComp(
1961 flow1=flows[ i ],
1962 flow2=tmpFlows )
1963 FlowTables = FlowTables and tempResult
1964 if FlowTables == main.FALSE:
1965 main.log.info( "Differences in flow table for switch: s" +
1966 str( i + 1 ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001967 utilities.assert_equals(
1968 expect=main.TRUE,
1969 actual=FlowTables,
1970 onpass="No changes were found in the flow tables",
1971 onfail="Changes were found in the flow tables" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001972
Jon Hall6aec96b2015-01-19 14:49:31 -08001973 main.step( "Check the continuous pings to ensure that no packets " +
1974 "were dropped during component failure" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001975 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
1976 main.params[ 'TESTONIP' ] )
Jon Hall8f89dda2015-01-22 16:03:33 -08001977 LossInPings = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001978 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
1979 for i in range( 8, 18 ):
1980 main.log.info(
1981 "Checking for a loss in pings along flow from s" +
1982 str( i ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001983 LossInPings = main.Mininet2.checkForLoss(
Jon Hall6aec96b2015-01-19 14:49:31 -08001984 "/tmp/ping.h" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001985 str( i ) ) or LossInPings
1986 if LossInPings == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001987 main.log.info( "Loss in ping detected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001988 elif LossInPings == main.ERROR:
Jon Hall6aec96b2015-01-19 14:49:31 -08001989 main.log.info( "There are multiple mininet process running" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001990 elif LossInPings == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001991 main.log.info( "No Loss in the pings" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07001992 main.log.info( "No loss of dataplane connectivity" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001993 utilities.assert_equals(
1994 expect=main.FALSE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001995 actual=LossInPings,
Jon Hall6aec96b2015-01-19 14:49:31 -08001996 onpass="No Loss of connectivity",
1997 onfail="Loss of dataplane connectivity detected" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001998
Jon Hall390696c2015-05-05 17:13:41 -07001999 main.step( "Leadership Election is still functional" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002000 # Test of LeadershipElection
Jon Hall8f89dda2015-01-22 16:03:33 -08002001 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002002 # FIXME: make sure this matches nodes that were restarted
2003 restarted = [ nodes[0].ip_address, nodes[1].ip_address,
2004 nodes[2].ip_address ]
Jon Hall390696c2015-05-05 17:13:41 -07002005
Jon Hall8f89dda2015-01-22 16:03:33 -08002006 leaderResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002007 for cli in CLIs:
2008 leaderN = cli.electionTestLeader()
Jon Hall8f89dda2015-01-22 16:03:33 -08002009 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002010 if leaderN == main.FALSE:
Jon Hallfeff3082015-05-19 10:23:26 -07002011 # error in response
Jon Hall40d2cbd2015-06-03 16:24:29 -07002012 main.log.error( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002013 "electionTestLeader function, check the" +
Jon Hall6aec96b2015-01-19 14:49:31 -08002014 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002015 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002016 elif leaderN is None:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002017 main.log.error( cli.name +
Jon Hall6aec96b2015-01-19 14:49:31 -08002018 " shows no leader for the election-app was" +
2019 " elected after the old one died" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002020 leaderResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002021 elif leaderN in restarted:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002022 main.log.error( cli.name + " shows " + str( leaderN ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002023 " as leader for the election-app, but it " +
2024 "was restarted" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002025 leaderResult = main.FALSE
2026 if len( set( leaderList ) ) != 1:
2027 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002028 main.log.error(
2029 "Inconsistent view of leader for the election test app" )
2030 # TODO: print the list
Jon Hall6aec96b2015-01-19 14:49:31 -08002031 utilities.assert_equals(
2032 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002033 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002034 onpass="Leadership election passed",
2035 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002036
Jon Hall6aec96b2015-01-19 14:49:31 -08002037 def CASE8( self, main ):
2038 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002039 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -08002040 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002041 import json
2042 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002043 assert numControllers, "numControllers not defined"
2044 assert main, "main not defined"
2045 assert utilities.assert_equals, "utilities.assert_equals not defined"
2046 assert CLIs, "CLIs not defined"
2047 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08002048
Jon Hallfeff3082015-05-19 10:23:26 -07002049 main.case( "Compare ONOS Topology view to Mininet topology" )
2050 main.caseExplaination = "Compare topology objects between Mininet" +\
2051 " and ONOS"
Jon Hall73cf9cc2014-11-20 22:28:38 -08002052
Jon Hallfeff3082015-05-19 10:23:26 -07002053 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002054 devicesResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08002055 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08002056 hostsResults = main.TRUE
Jon Hallc9eabec2015-06-10 14:33:14 -07002057 hostAttachmentResults = True
Jon Hall8f89dda2015-01-22 16:03:33 -08002058 topoResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08002059 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -08002060 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -08002061 main.step( "Collecting topology information from ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002062 startTime = time.time()
Jon Hall21270ac2015-02-16 17:59:55 -08002063 # Give time for Gossip to work
Jon Hall8f89dda2015-01-22 16:03:33 -08002064 while topoResult == main.FALSE and elapsed < 60:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002065 count += 1
Jon Hall8f89dda2015-01-22 16:03:33 -08002066 cliStart = time.time()
Jon Hall94fd0472014-12-08 11:52:42 -08002067 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002068 threads = []
2069 for i in range( numControllers ):
2070 t = main.Thread( target=CLIs[i].devices,
2071 name="devices-" + str( i ),
2072 args=[ ] )
2073 threads.append( t )
2074 t.start()
2075
2076 for t in threads:
2077 t.join()
2078 devices.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002079 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -08002080 ipResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002081 threads = []
2082 for i in range( numControllers ):
2083 t = main.Thread( target=CLIs[i].hosts,
2084 name="hosts-" + str( i ),
2085 args=[ ] )
2086 threads.append( t )
2087 t.start()
2088
2089 for t in threads:
2090 t.join()
2091 try:
2092 hosts.append( json.loads( t.result ) )
2093 except ( ValueError, TypeError ):
2094 main.log.exception( "Error parsing hosts results" )
2095 main.log.error( repr( t.result ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08002096 for controller in range( 0, len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08002097 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08002098 for host in hosts[ controller ]:
Jon Hallfeff3082015-05-19 10:23:26 -07002099 if host is None or host.get( 'ipAddresses', [] ) == []:
Jon Hall6aec96b2015-01-19 14:49:31 -08002100 main.log.error(
Jon Hall40d2cbd2015-06-03 16:24:29 -07002101 "DEBUG:Error with host ipAddresses on controller" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002102 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08002103 ipResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002104 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002105 threads = []
2106 for i in range( numControllers ):
2107 t = main.Thread( target=CLIs[i].ports,
2108 name="ports-" + str( i ),
2109 args=[ ] )
2110 threads.append( t )
2111 t.start()
2112
2113 for t in threads:
2114 t.join()
2115 ports.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002116 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002117 threads = []
2118 for i in range( numControllers ):
2119 t = main.Thread( target=CLIs[i].links,
2120 name="links-" + str( i ),
2121 args=[ ] )
2122 threads.append( t )
2123 t.start()
2124
2125 for t in threads:
2126 t.join()
2127 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08002128 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002129 threads = []
2130 for i in range( numControllers ):
2131 t = main.Thread( target=CLIs[i].clusters,
2132 name="clusters-" + str( i ),
2133 args=[ ] )
2134 threads.append( t )
2135 t.start()
2136
2137 for t in threads:
2138 t.join()
2139 clusters.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002140
Jon Hall8f89dda2015-01-22 16:03:33 -08002141 elapsed = time.time() - startTime
2142 cliTime = time.time() - cliStart
Jon Hallc9eabec2015-06-10 14:33:14 -07002143 print "Elapsed time: " + str( elapsed )
Jon Hall8f89dda2015-01-22 16:03:33 -08002144 print "CLI time: " + str( cliTime )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002145
Jon Hallafa8a472015-06-12 14:02:42 -07002146 mnSwitches = main.Mininet1.getSwitches()
2147 mnLinks = main.Mininet1.getLinks()
2148 mnHosts = main.Mininet1.getHosts()
Jon Hall8f89dda2015-01-22 16:03:33 -08002149 for controller in range( numControllers ):
2150 controllerStr = str( controller + 1 )
Jon Hallafa8a472015-06-12 14:02:42 -07002151 if devices[ controller ] and ports[ controller ] and\
2152 "Error" not in devices[ controller ] and\
2153 "Error" not in ports[ controller ]:
2154
Jon Hall8f89dda2015-01-22 16:03:33 -08002155 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hallafa8a472015-06-12 14:02:42 -07002156 mnSwitches,
2157 json.loads( devices[ controller ] ),
2158 json.loads( ports[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002159 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002160 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002161 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002162 actual=currentDevicesResult,
2163 onpass="ONOS" + controllerStr +
2164 " Switches view is correct",
2165 onfail="ONOS" + controllerStr +
2166 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002167
Jon Hallafa8a472015-06-12 14:02:42 -07002168 if links[ controller ] and "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08002169 currentLinksResult = main.Mininet1.compareLinks(
Jon Hallafa8a472015-06-12 14:02:42 -07002170 mnSwitches, mnLinks,
2171 json.loads( links[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002172 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002173 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002174 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002175 actual=currentLinksResult,
2176 onpass="ONOS" + controllerStr +
2177 " links view is correct",
2178 onfail="ONOS" + controllerStr +
2179 " links view is incorrect" )
2180
2181 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2182 currentHostsResult = main.Mininet1.compareHosts(
Jon Hallafa8a472015-06-12 14:02:42 -07002183 mnHosts,
2184 hosts[ controller ] )
Jon Hall58c76b72015-02-23 11:09:24 -08002185 else:
2186 currentHostsResult = main.FALSE
2187 utilities.assert_equals( expect=main.TRUE,
2188 actual=currentHostsResult,
2189 onpass="ONOS" + controllerStr +
2190 " hosts exist in Mininet",
2191 onfail="ONOS" + controllerStr +
2192 " hosts don't match Mininet" )
Jon Hallc9eabec2015-06-10 14:33:14 -07002193 # CHECKING HOST ATTACHMENT POINTS
2194 hostAttachment = True
Jon Hallafa8a472015-06-12 14:02:42 -07002195 zeroHosts = False
Jon Hallc9eabec2015-06-10 14:33:14 -07002196 # FIXME: topo-HA/obelisk specific mappings:
2197 # key is mac and value is dpid
2198 mappings = {}
2199 for i in range( 1, 29 ): # hosts 1 through 28
2200 # set up correct variables:
2201 macId = "00:" * 5 + hex( i ).split( "0x" )[1].upper().zfill(2)
2202 if i == 1:
2203 deviceId = "1000".zfill(16)
2204 elif i == 2:
2205 deviceId = "2000".zfill(16)
2206 elif i == 3:
2207 deviceId = "3000".zfill(16)
2208 elif i == 4:
2209 deviceId = "3004".zfill(16)
2210 elif i == 5:
2211 deviceId = "5000".zfill(16)
2212 elif i == 6:
2213 deviceId = "6000".zfill(16)
2214 elif i == 7:
2215 deviceId = "6007".zfill(16)
2216 elif i >= 8 and i <= 17:
2217 dpid = '3' + str( i ).zfill( 3 )
2218 deviceId = dpid.zfill(16)
2219 elif i >= 18 and i <= 27:
2220 dpid = '6' + str( i ).zfill( 3 )
2221 deviceId = dpid.zfill(16)
2222 elif i == 28:
2223 deviceId = "2800".zfill(16)
2224 mappings[ macId ] = deviceId
2225 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2226 if hosts[ controller ] == []:
2227 main.log.warn( "There are no hosts discovered" )
Jon Hallafa8a472015-06-12 14:02:42 -07002228 zeroHosts = True
Jon Hallc9eabec2015-06-10 14:33:14 -07002229 else:
2230 for host in hosts[ controller ]:
2231 mac = None
2232 location = None
2233 device = None
2234 port = None
2235 try:
2236 mac = host.get( 'mac' )
2237 assert mac, "mac field could not be found for this host object"
Jon Hall58c76b72015-02-23 11:09:24 -08002238
Jon Hallc9eabec2015-06-10 14:33:14 -07002239 location = host.get( 'location' )
2240 assert location, "location field could not be found for this host object"
2241
2242 # Trim the protocol identifier off deviceId
2243 device = str( location.get( 'elementId' ) ).split(':')[1]
2244 assert device, "elementId field could not be found for this host location object"
2245
2246 port = location.get( 'port' )
2247 assert port, "port field could not be found for this host location object"
2248
2249 # Now check if this matches where they should be
2250 if mac and device and port:
2251 if str( port ) != "1":
2252 main.log.error( "The attachment port is incorrect for " +
2253 "host " + str( mac ) +
2254 ". Expected: 1 Actual: " + str( port) )
2255 hostAttachment = False
2256 if device != mappings[ str( mac ) ]:
2257 main.log.error( "The attachment device is incorrect for " +
2258 "host " + str( mac ) +
2259 ". Expected: " + mappings[ str( mac ) ] +
2260 " Actual: " + device )
2261 hostAttachment = False
2262 else:
2263 hostAttachment = False
2264 except AssertionError:
2265 main.log.exception( "Json object not as expected" )
2266 main.log.error( repr( host ) )
2267 hostAttachment = False
2268 else:
2269 main.log.error( "No hosts json output or \"Error\"" +
2270 " in output. hosts = " +
2271 repr( hosts[ controller ] ) )
Jon Hallafa8a472015-06-12 14:02:42 -07002272 if zeroHosts is False:
Jon Hallc9eabec2015-06-10 14:33:14 -07002273 hostAttachment = True
2274
2275 # END CHECKING HOST ATTACHMENT POINTS
Jon Hall58c76b72015-02-23 11:09:24 -08002276 devicesResults = devicesResults and currentDevicesResult
Jon Hall58c76b72015-02-23 11:09:24 -08002277 linksResults = linksResults and currentLinksResult
2278 hostsResults = hostsResults and currentHostsResult
Jon Hallafa8a472015-06-12 14:02:42 -07002279 hostAttachmentResults = hostAttachmentResults and\
2280 hostAttachment
Jon Hall94fd0472014-12-08 11:52:42 -08002281
Jon Hallc9eabec2015-06-10 14:33:14 -07002282 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08002283
Jon Hallc9eabec2015-06-10 14:33:14 -07002284 # hosts
2285 main.step( "Hosts view is consistent across all ONOS nodes" )
2286 consistentHostsResult = main.TRUE
2287 for controller in range( len( hosts ) ):
2288 controllerStr = str( controller + 1 )
2289 if "Error" not in hosts[ controller ]:
2290 if hosts[ controller ] == hosts[ 0 ]:
2291 continue
2292 else: # hosts not consistent
2293 main.log.error( "hosts from ONOS" + controllerStr +
2294 " is inconsistent with ONOS1" )
2295 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08002296 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002297
Jon Hallc9eabec2015-06-10 14:33:14 -07002298 else:
2299 main.log.error( "Error in getting ONOS hosts from ONOS" +
2300 controllerStr )
2301 consistentHostsResult = main.FALSE
2302 main.log.warn( "ONOS" + controllerStr +
2303 " hosts response: " +
2304 repr( hosts[ controller ] ) )
2305 utilities.assert_equals(
2306 expect=main.TRUE,
2307 actual=consistentHostsResult,
2308 onpass="Hosts view is consistent across all ONOS nodes",
2309 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08002310
Jon Hallc9eabec2015-06-10 14:33:14 -07002311 main.step( "Hosts information is correct" )
2312 hostsResults = hostsResults and ipResult
2313 utilities.assert_equals(
2314 expect=main.TRUE,
2315 actual=hostsResults,
2316 onpass="Host information is correct",
2317 onfail="Host information is incorrect" )
2318
2319 main.step( "Host attachment points to the network" )
2320 utilities.assert_equals(
2321 expect=True,
2322 actual=hostAttachmentResults,
2323 onpass="Hosts are correctly attached to the network",
2324 onfail="ONOS did not correctly attach hosts to the network" )
2325
2326 # Strongly connected clusters of devices
2327 main.step( "Clusters view is consistent across all ONOS nodes" )
2328 consistentClustersResult = main.TRUE
2329 for controller in range( len( clusters ) ):
2330 controllerStr = str( controller + 1 )
2331 if "Error" not in clusters[ controller ]:
2332 if clusters[ controller ] == clusters[ 0 ]:
2333 continue
2334 else: # clusters not consistent
2335 main.log.error( "clusters from ONOS" +
2336 controllerStr +
2337 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002338 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002339
Jon Hallc9eabec2015-06-10 14:33:14 -07002340 else:
2341 main.log.error( "Error in getting dataplane clusters " +
2342 "from ONOS" + controllerStr )
2343 consistentClustersResult = main.FALSE
2344 main.log.warn( "ONOS" + controllerStr +
2345 " clusters response: " +
2346 repr( clusters[ controller ] ) )
2347 utilities.assert_equals(
2348 expect=main.TRUE,
2349 actual=consistentClustersResult,
2350 onpass="Clusters view is consistent across all ONOS nodes",
2351 onfail="ONOS nodes have different views of clusters" )
2352
2353 main.step( "There is only one SCC" )
2354 # there should always only be one cluster
2355 try:
2356 numClusters = len( json.loads( clusters[ 0 ] ) )
2357 except ( ValueError, TypeError ):
2358 main.log.exception( "Error parsing clusters[0]: " +
2359 repr( clusters[0] ) )
2360 clusterResults = main.FALSE
2361 if numClusters == 1:
2362 clusterResults = main.TRUE
2363 utilities.assert_equals(
2364 expect=1,
2365 actual=numClusters,
2366 onpass="ONOS shows 1 SCC",
2367 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
2368
Jon Hallafa8a472015-06-12 14:02:42 -07002369 topoResult = ( devicesResults and linksResults
Jon Hallc9eabec2015-06-10 14:33:14 -07002370 and hostsResults and consistentHostsResult
2371 and consistentClustersResult and clusterResults
2372 and ipResult and hostAttachmentResults )
Jon Hall94fd0472014-12-08 11:52:42 -08002373
Jon Hall8f89dda2015-01-22 16:03:33 -08002374 topoResult = topoResult and int( count <= 2 )
2375 note = "note it takes about " + str( int( cliTime ) ) + \
2376 " seconds for the test to make all the cli calls to fetch " +\
2377 "the topology from each ONOS instance"
Jon Hall1b8f54a2015-02-04 13:24:20 -08002378 main.log.info(
Jon Hall8f89dda2015-01-22 16:03:33 -08002379 "Very crass estimate for topology discovery/convergence( " +
2380 str( note ) + " ): " + str( elapsed ) + " seconds, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002381 str( count ) + " tries" )
Jon Hallc9eabec2015-06-10 14:33:14 -07002382
2383 main.step( "Device information is correct" )
2384 utilities.assert_equals(
2385 expect=main.TRUE,
2386 actual=devicesResults,
2387 onpass="Device information is correct",
2388 onfail="Device information is incorrect" )
2389
Jon Hallc9eabec2015-06-10 14:33:14 -07002390 main.step( "Links are correct" )
2391 utilities.assert_equals(
2392 expect=main.TRUE,
2393 actual=linksResults,
2394 onpass="Link are correct",
2395 onfail="Links are incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002396
Jon Halla9d26da2015-03-30 16:45:32 -07002397 # FIXME: move this to an ONOS state case
2398 main.step( "Checking ONOS nodes" )
2399 nodesOutput = []
Jon Hall390696c2015-05-05 17:13:41 -07002400 nodeResults = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002401 threads = []
2402 for i in range( numControllers ):
2403 t = main.Thread( target=CLIs[i].nodes,
2404 name="nodes-" + str( i ),
2405 args=[ ] )
2406 threads.append( t )
2407 t.start()
2408
2409 for t in threads:
2410 t.join()
2411 nodesOutput.append( t.result )
2412 ips = [ node.ip_address for node in nodes ]
2413 for i in nodesOutput:
2414 try:
2415 current = json.loads( i )
2416 for node in current:
Jon Hall390696c2015-05-05 17:13:41 -07002417 currentResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002418 if node['ip'] in ips: # node in nodes() output is in cell
2419 if node['state'] == 'ACTIVE':
Jon Hall390696c2015-05-05 17:13:41 -07002420 currentResult = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002421 else:
2422 main.log.error( "Error in ONOS node availability" )
2423 main.log.error(
2424 json.dumps( current,
2425 sort_keys=True,
2426 indent=4,
2427 separators=( ',', ': ' ) ) )
2428 break
Jon Hall390696c2015-05-05 17:13:41 -07002429 nodeResults = nodeResults and currentResult
Jon Halla9d26da2015-03-30 16:45:32 -07002430 except ( ValueError, TypeError ):
2431 main.log.error( "Error parsing nodes output" )
2432 main.log.warn( repr( i ) )
Jon Hall390696c2015-05-05 17:13:41 -07002433 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2434 onpass="Nodes check successful",
2435 onfail="Nodes check NOT successful" )
Jon Halla9d26da2015-03-30 16:45:32 -07002436
Jon Hall6aec96b2015-01-19 14:49:31 -08002437 def CASE9( self, main ):
2438 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002439 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -08002440 """
2441 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002442 assert numControllers, "numControllers not defined"
2443 assert main, "main not defined"
2444 assert utilities.assert_equals, "utilities.assert_equals not defined"
2445 assert CLIs, "CLIs not defined"
2446 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002447 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002448
Jon Hall8f89dda2015-01-22 16:03:33 -08002449 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002450
Jon Hall6aec96b2015-01-19 14:49:31 -08002451 description = "Turn off a link to ensure that Link Discovery " +\
Jon Hall58c76b72015-02-23 11:09:24 -08002452 "is working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002453 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002454
Jon Hall6aec96b2015-01-19 14:49:31 -08002455 main.step( "Kill Link between s3 and s28" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002456 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
Jon Hall58c76b72015-02-23 11:09:24 -08002457 main.log.info( "Waiting " + str( linkSleep ) +
2458 " seconds for link down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002459 time.sleep( linkSleep )
2460 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002461 onpass="Link down successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002462 onfail="Failed to bring link down" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002463 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002464
Jon Hall6aec96b2015-01-19 14:49:31 -08002465 def CASE10( self, main ):
2466 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002467 Link s3-s28 up
Jon Hall6aec96b2015-01-19 14:49:31 -08002468 """
2469 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002470 assert numControllers, "numControllers not defined"
2471 assert main, "main not defined"
2472 assert utilities.assert_equals, "utilities.assert_equals not defined"
2473 assert CLIs, "CLIs not defined"
2474 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002475 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002476
Jon Hall8f89dda2015-01-22 16:03:33 -08002477 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002478
Jon Hall6aec96b2015-01-19 14:49:31 -08002479 description = "Restore a link to ensure that Link Discovery is " + \
Jon Hall63604932015-02-26 17:09:50 -08002480 "working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002481 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002482
Jon Hall6aec96b2015-01-19 14:49:31 -08002483 main.step( "Bring link between s3 and s28 back up" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002484 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
Jon Hall58c76b72015-02-23 11:09:24 -08002485 main.log.info( "Waiting " + str( linkSleep ) +
2486 " seconds for link up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002487 time.sleep( linkSleep )
2488 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002489 onpass="Link up successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002490 onfail="Failed to bring link up" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002491 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002492
Jon Hall6aec96b2015-01-19 14:49:31 -08002493 def CASE11( self, main ):
2494 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002495 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -08002496 """
2497 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002498 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002499 assert numControllers, "numControllers not defined"
2500 assert main, "main not defined"
2501 assert utilities.assert_equals, "utilities.assert_equals not defined"
2502 assert CLIs, "CLIs not defined"
2503 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08002504
Jon Hall8f89dda2015-01-22 16:03:33 -08002505 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002506
2507 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002508 main.case( description )
2509 switch = main.params[ 'kill' ][ 'switch' ]
2510 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08002511
Jon Hall6aec96b2015-01-19 14:49:31 -08002512 # TODO: Make this switch parameterizable
2513 main.step( "Kill " + switch )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002514 main.log.info( "Deleting " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002515 main.Mininet1.delSwitch( switch )
2516 main.log.info( "Waiting " + str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002517 " seconds for switch down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002518 time.sleep( switchSleep )
2519 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002520 # Peek at the deleted switch
2521 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002522 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002523 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -08002524 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002525 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002526 onpass="Kill switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002527 onfail="Failed to kill switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002528
Jon Hall6aec96b2015-01-19 14:49:31 -08002529 def CASE12( self, main ):
2530 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002531 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -08002532 """
2533 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002534 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002535 assert numControllers, "numControllers not defined"
2536 assert main, "main not defined"
2537 assert utilities.assert_equals, "utilities.assert_equals not defined"
2538 assert CLIs, "CLIs not defined"
2539 assert nodes, "nodes not defined"
2540 assert ONOS1Port, "ONOS1Port not defined"
2541 assert ONOS2Port, "ONOS2Port not defined"
2542 assert ONOS3Port, "ONOS3Port not defined"
2543 assert ONOS4Port, "ONOS4Port not defined"
2544 assert ONOS5Port, "ONOS5Port not defined"
2545 assert ONOS6Port, "ONOS6Port not defined"
2546 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall669173b2014-12-17 11:36:30 -08002547
Jon Hall8f89dda2015-01-22 16:03:33 -08002548 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall6aec96b2015-01-19 14:49:31 -08002549 switch = main.params[ 'kill' ][ 'switch' ]
2550 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2551 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002552 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002553 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002554
Jon Hall6aec96b2015-01-19 14:49:31 -08002555 main.step( "Add back " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002556 main.Mininet1.addSwitch( switch, dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002557 for peer in links:
Jon Hall8f89dda2015-01-22 16:03:33 -08002558 main.Mininet1.addLink( switch, peer )
Jon Hall0f523f22015-07-06 09:31:09 -07002559 ipList = []
2560 for i in range( numControllers ):
2561 ipList.append( nodes[ i ].ip_address )
2562 main.Mininet1.assignSwController( sw=switch, ip=ipList )
Jon Hall58c76b72015-02-23 11:09:24 -08002563 main.log.info( "Waiting " + str( switchSleep ) +
2564 " seconds for switch up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002565 time.sleep( switchSleep )
2566 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002567 # Peek at the deleted switch
2568 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002569 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002570 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002571 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002572 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002573 onpass="add switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002574 onfail="Failed to add switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002575
Jon Hall6aec96b2015-01-19 14:49:31 -08002576 def CASE13( self, main ):
2577 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002578 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -08002579 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002580 import os
2581 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002582 assert numControllers, "numControllers not defined"
2583 assert main, "main not defined"
2584 assert utilities.assert_equals, "utilities.assert_equals not defined"
2585 assert CLIs, "CLIs not defined"
2586 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002587
2588 # printing colors to terminal
Jon Hall5cfd23c2015-03-19 11:40:57 -07002589 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2590 'blue': '\033[94m', 'green': '\033[92m',
2591 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
Jon Hall40d2cbd2015-06-03 16:24:29 -07002592 main.case( "Test Cleanup" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002593 main.step( "Killing tcpdumps" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002594 main.Mininet2.stopTcpdump()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002595
Jon Hall6aec96b2015-01-19 14:49:31 -08002596 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002597 testname = main.TEST
Jon Hall8f89dda2015-01-22 16:03:33 -08002598 teststationUser = main.params[ 'TESTONUSER' ]
2599 teststationIP = main.params[ 'TESTONIP' ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002600 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -08002601 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -08002602 # FIXME: scp
2603 # mn files
2604 # TODO: Load these from params
2605 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002606 logFolder = "/opt/onos/log/"
2607 logFiles = [ "karaf.log", "karaf.log.1" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002608 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002609 dstDir = "~/packet_captures/"
2610 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002611 for node in nodes:
2612 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2613 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002614 teststationUser + "@" +
2615 teststationIP + ":" +
2616 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002617 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002618 main.ONOSbench.handle.expect( "\$" )
2619
Jon Hall6aec96b2015-01-19 14:49:31 -08002620 # std*.log's
2621 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002622 logFolder = "/opt/onos/var/"
2623 logFiles = [ "stderr.log", "stdout.log" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002624 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002625 dstDir = "~/packet_captures/"
2626 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002627 for node in nodes:
2628 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2629 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002630 teststationUser + "@" +
2631 teststationIP + ":" +
2632 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002633 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002634 main.ONOSbench.handle.expect( "\$" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002635 # sleep so scp can finish
2636 time.sleep( 10 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002637
2638 main.step( "Stopping Mininet" )
Jon Hall390696c2015-05-05 17:13:41 -07002639 mnResult = main.Mininet1.stopNet()
2640 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2641 onpass="Mininet stopped",
2642 onfail="MN cleanup NOT successful" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002643
2644 main.step( "Checking ONOS Logs for errors" )
2645 for node in nodes:
2646 print colors[ 'purple' ] + "Checking logs for errors on " + \
2647 node.name + ":" + colors[ 'end' ]
Jon Hall40d2cbd2015-06-03 16:24:29 -07002648 print main.ONOSbench.checkLogs( node.ip_address, restart=True )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002649
Jon Hall6aec96b2015-01-19 14:49:31 -08002650 main.step( "Packing and rotating pcap archives" )
2651 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002652
Jon Hallfeff3082015-05-19 10:23:26 -07002653 try:
2654 timerLog = open( main.logdir + "/Timers.csv", 'w')
2655 # Overwrite with empty line and close
Jon Hall40d2cbd2015-06-03 16:24:29 -07002656 labels = "Gossip Intents, Restart"
2657 data = str( gossipTime ) + ", " + str( main.restartTime )
2658 timerLog.write( labels + "\n" + data )
Jon Hallfeff3082015-05-19 10:23:26 -07002659 timerLog.close()
2660 except NameError, e:
2661 main.log.exception(e)
2662
Jon Hall6aec96b2015-01-19 14:49:31 -08002663 def CASE14( self, main ):
2664 """
Jon Hall669173b2014-12-17 11:36:30 -08002665 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -08002666 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07002667 assert numControllers, "numControllers not defined"
2668 assert main, "main not defined"
2669 assert utilities.assert_equals, "utilities.assert_equals not defined"
2670 assert CLIs, "CLIs not defined"
2671 assert nodes, "nodes not defined"
2672
Jon Hall390696c2015-05-05 17:13:41 -07002673 main.case("Start Leadership Election app")
2674 main.step( "Install leadership election app" )
Jon Hallfeff3082015-05-19 10:23:26 -07002675 appResult = main.ONOScli1.activateApp( "org.onosproject.election" )
2676 utilities.assert_equals(
2677 expect=main.TRUE,
2678 actual=appResult,
2679 onpass="Election app installed",
2680 onfail="Something went wrong with installing Leadership election" )
2681
2682 main.step( "Run for election on each node" )
2683 leaderResult = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002684 leaders = []
2685 for cli in CLIs:
Jon Hall390696c2015-05-05 17:13:41 -07002686 cli.electionTestRun()
2687 for cli in CLIs:
Jon Halla9d26da2015-03-30 16:45:32 -07002688 leader = cli.electionTestLeader()
2689 if leader is None or leader == main.FALSE:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002690 main.log.error( cli.name + ": Leader for the election app " +
Jon Halla9d26da2015-03-30 16:45:32 -07002691 "should be an ONOS node, instead got '" +
2692 str( leader ) + "'" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002693 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002694 leaders.append( leader )
Jon Hall6aec96b2015-01-19 14:49:31 -08002695 utilities.assert_equals(
2696 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002697 actual=leaderResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002698 onpass="Successfully ran for leadership",
2699 onfail="Failed to run for leadership" )
2700
2701 main.step( "Check that each node shows the same leader" )
2702 sameLeader = main.TRUE
2703 if len( set( leaders ) ) != 1:
2704 sameLeader = main.FALSE
2705 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2706 str( leaders ) )
2707 utilities.assert_equals(
2708 expect=main.TRUE,
2709 actual=sameLeader,
2710 onpass="Leadership is consistent for the election topic",
2711 onfail="Nodes have different leaders" )
Jon Hall669173b2014-12-17 11:36:30 -08002712
Jon Hall6aec96b2015-01-19 14:49:31 -08002713 def CASE15( self, main ):
2714 """
Jon Hall669173b2014-12-17 11:36:30 -08002715 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08002716 """
Jon Hall390696c2015-05-05 17:13:41 -07002717 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002718 assert numControllers, "numControllers not defined"
2719 assert main, "main not defined"
2720 assert utilities.assert_equals, "utilities.assert_equals not defined"
2721 assert CLIs, "CLIs not defined"
2722 assert nodes, "nodes not defined"
2723
Jon Hall8f89dda2015-01-22 16:03:33 -08002724 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002725 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08002726 main.case( description )
Jon Hallfeff3082015-05-19 10:23:26 -07002727
2728 main.step( "Check that each node shows the same leader" )
2729 sameLeader = main.TRUE
2730 leaders = []
2731 for cli in CLIs:
2732 leader = cli.electionTestLeader()
2733 leaders.append( leader )
2734 if len( set( leaders ) ) != 1:
2735 sameLeader = main.FALSE
2736 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2737 str( leaders ) )
2738 utilities.assert_equals(
2739 expect=main.TRUE,
2740 actual=sameLeader,
2741 onpass="Leadership is consistent for the election topic",
2742 onfail="Nodes have different leaders" )
2743
Jon Hall6aec96b2015-01-19 14:49:31 -08002744 main.step( "Find current leader and withdraw" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002745 leader = main.ONOScli1.electionTestLeader()
Jon Halla9d26da2015-03-30 16:45:32 -07002746 # do some sanity checking on leader before using it
Jon Hall8f89dda2015-01-22 16:03:33 -08002747 withdrawResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002748 if leader is None or leader == main.FALSE:
Jon Hallfeff3082015-05-19 10:23:26 -07002749 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002750 "Leader for the election app should be an ONOS node," +
Jon Hall58c76b72015-02-23 11:09:24 -08002751 "instead got '" + str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002752 leaderResult = main.FALSE
Jon Hall63604932015-02-26 17:09:50 -08002753 oldLeader = None
Jon Hall5cfd23c2015-03-19 11:40:57 -07002754 for i in range( len( CLIs ) ):
2755 if leader == nodes[ i ].ip_address:
2756 oldLeader = CLIs[ i ]
2757 break
Jon Halla9d26da2015-03-30 16:45:32 -07002758 else: # FOR/ELSE statement
Jon Hall5cfd23c2015-03-19 11:40:57 -07002759 main.log.error( "Leader election, could not find current leader" )
Jon Hall63604932015-02-26 17:09:50 -08002760 if oldLeader:
2761 withdrawResult = oldLeader.electionTestWithdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08002762 utilities.assert_equals(
2763 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002764 actual=withdrawResult,
Jon Hallfeff3082015-05-19 10:23:26 -07002765 onpass="Node was withdrawn from election",
2766 onfail="Node was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08002767
Jon Hall6aec96b2015-01-19 14:49:31 -08002768 main.step( "Make sure new leader is elected" )
Jon Halla9d26da2015-03-30 16:45:32 -07002769 # FIXME: use threads
Jon Hall8f89dda2015-01-22 16:03:33 -08002770 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002771 for cli in CLIs:
2772 leaderN = cli.electionTestLeader()
2773 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002774 if leaderN == leader:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002775 main.log.error( cli.name + " still sees " + str( leader ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002776 " as leader after they withdrew" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002777 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002778 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002779 # error in response
2780 # TODO: add check for "Command not found:" in the driver, this
Jon Hall5cfd23c2015-03-19 11:40:57 -07002781 # means the app isn't loaded
Jon Hall40d2cbd2015-06-03 16:24:29 -07002782 main.log.error( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002783 "electionTestLeader function, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002784 "check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002785 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002786 elif leaderN is None:
2787 # node may not have recieved the event yet
Jon Hall390696c2015-05-05 17:13:41 -07002788 time.sleep(7)
Jon Halla9d26da2015-03-30 16:45:32 -07002789 leaderN = cli.electionTestLeader()
2790 leaderList.pop()
2791 leaderList.append( leaderN )
Jon Hall8f89dda2015-01-22 16:03:33 -08002792 consistentLeader = main.FALSE
2793 if len( set( leaderList ) ) == 1:
Jon Hall6aec96b2015-01-19 14:49:31 -08002794 main.log.info( "Each Election-app sees '" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002795 str( leaderList[ 0 ] ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002796 "' as the leader" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002797 consistentLeader = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002798 else:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002799 main.log.error(
Jon Hall6aec96b2015-01-19 14:49:31 -08002800 "Inconsistent responses for leader of Election-app:" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002801 for n in range( len( leaderList ) ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07002802 main.log.error( "ONOS" + str( n + 1 ) + " response: " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002803 str( leaderList[ n ] ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002804 leaderResult = leaderResult and consistentLeader
Jon Hall6aec96b2015-01-19 14:49:31 -08002805 utilities.assert_equals(
2806 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002807 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002808 onpass="Leadership election passed",
2809 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002810
Jon Hall58c76b72015-02-23 11:09:24 -08002811 main.step( "Run for election on old leader( just so everyone " +
2812 "is in the hat )" )
Jon Hall63604932015-02-26 17:09:50 -08002813 if oldLeader:
2814 runResult = oldLeader.electionTestRun()
2815 else:
2816 runResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002817 utilities.assert_equals(
2818 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002819 actual=runResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002820 onpass="App re-ran for election",
2821 onfail="App failed to run for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002822
Jon Hallfeff3082015-05-19 10:23:26 -07002823 main.step( "Leader did not change when old leader re-ran" )
Jon Hall390696c2015-05-05 17:13:41 -07002824 afterRun = main.ONOScli1.electionTestLeader()
2825 # verify leader didn't just change
2826 if afterRun == leaderList[ 0 ]:
2827 afterResult = main.TRUE
2828 else:
2829 afterResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002830
Jon Hall6aec96b2015-01-19 14:49:31 -08002831 utilities.assert_equals(
2832 expect=main.TRUE,
Jon Hall390696c2015-05-05 17:13:41 -07002833 actual=afterResult,
2834 onpass="Old leader successfully re-ran for election",
Jon Hall6aec96b2015-01-19 14:49:31 -08002835 onfail="Something went wrong with Leadership election after " +
2836 "the old leader re-ran for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002837
Jon Hall390696c2015-05-05 17:13:41 -07002838 def CASE16( self, main ):
2839 """
2840 Install Distributed Primitives app
2841 """
Jon Hall40d2cbd2015-06-03 16:24:29 -07002842 import time
Jon Hall390696c2015-05-05 17:13:41 -07002843 assert numControllers, "numControllers not defined"
2844 assert main, "main not defined"
2845 assert utilities.assert_equals, "utilities.assert_equals not defined"
2846 assert CLIs, "CLIs not defined"
2847 assert nodes, "nodes not defined"
2848
2849 # Variables for the distributed primitives tests
2850 global pCounterName
2851 global iCounterName
2852 global pCounterValue
2853 global iCounterValue
2854 global onosSet
2855 global onosSetName
2856 pCounterName = "TestON-Partitions"
2857 iCounterName = "TestON-inMemory"
2858 pCounterValue = 0
2859 iCounterValue = 0
2860 onosSet = set([])
2861 onosSetName = "TestON-set"
2862
2863 description = "Install Primitives app"
2864 main.case( description )
2865 main.step( "Install Primitives app" )
2866 appName = "org.onosproject.distributedprimitives"
2867 appResults = CLIs[0].activateApp( appName )
2868 utilities.assert_equals( expect=main.TRUE,
2869 actual=appResults,
2870 onpass="Primitives app activated",
2871 onfail="Primitives app not activated" )
Jon Hall40d2cbd2015-06-03 16:24:29 -07002872 time.sleep( 5 ) # To allow all nodes to activate
Jon Hall390696c2015-05-05 17:13:41 -07002873
2874 def CASE17( self, main ):
2875 """
2876 Check for basic functionality with distributed primitives
2877 """
Jon Hallc9eabec2015-06-10 14:33:14 -07002878 import json
Jon Hall390696c2015-05-05 17:13:41 -07002879 # Make sure variables are defined/set
2880 assert numControllers, "numControllers not defined"
2881 assert main, "main not defined"
2882 assert utilities.assert_equals, "utilities.assert_equals not defined"
2883 assert CLIs, "CLIs not defined"
2884 assert nodes, "nodes not defined"
2885 assert pCounterName, "pCounterName not defined"
2886 assert iCounterName, "iCounterName not defined"
2887 assert onosSetName, "onosSetName not defined"
2888 # NOTE: assert fails if value is 0/None/Empty/False
2889 try:
2890 pCounterValue
2891 except NameError:
2892 main.log.error( "pCounterValue not defined, setting to 0" )
2893 pCounterValue = 0
2894 try:
2895 iCounterValue
2896 except NameError:
2897 main.log.error( "iCounterValue not defined, setting to 0" )
2898 iCounterValue = 0
2899 try:
2900 onosSet
2901 except NameError:
2902 main.log.error( "onosSet not defined, setting to empty Set" )
2903 onosSet = set([])
2904 # Variables for the distributed primitives tests. These are local only
2905 addValue = "a"
2906 addAllValue = "a b c d e f"
2907 retainValue = "c d e f"
2908
2909 description = "Check for basic functionality with distributed " +\
2910 "primitives"
2911 main.case( description )
2912 main.caseExplaination = "Test the methods of the distributed primitives (counters and sets) throught the cli"
2913 # DISTRIBUTED ATOMIC COUNTERS
2914 main.step( "Increment and get a default counter on each node" )
2915 pCounters = []
2916 threads = []
Jon Hallfeff3082015-05-19 10:23:26 -07002917 addedPValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002918 for i in range( numControllers ):
2919 t = main.Thread( target=CLIs[i].counterTestIncrement,
2920 name="counterIncrement-" + str( i ),
2921 args=[ pCounterName ] )
2922 pCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002923 addedPValues.append( pCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002924 threads.append( t )
2925 t.start()
2926
2927 for t in threads:
2928 t.join()
2929 pCounters.append( t.result )
2930 # Check that counter incremented numController times
2931 pCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002932 for i in addedPValues:
Jon Hall40d2cbd2015-06-03 16:24:29 -07002933 tmpResult = i in pCounters
Jon Hallfeff3082015-05-19 10:23:26 -07002934 pCounterResults = pCounterResults and tmpResult
2935 if not tmpResult:
2936 main.log.error( str( i ) + " is not in partitioned "
2937 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002938 utilities.assert_equals( expect=True,
2939 actual=pCounterResults,
2940 onpass="Default counter incremented",
2941 onfail="Error incrementing default" +
2942 " counter" )
2943
2944 main.step( "Increment and get an in memory counter on each node" )
2945 iCounters = []
Jon Hallfeff3082015-05-19 10:23:26 -07002946 addedIValues = []
Jon Hall390696c2015-05-05 17:13:41 -07002947 threads = []
2948 for i in range( numControllers ):
2949 t = main.Thread( target=CLIs[i].counterTestIncrement,
2950 name="icounterIncrement-" + str( i ),
2951 args=[ iCounterName ],
2952 kwargs={ "inMemory": True } )
2953 iCounterValue += 1
Jon Hallfeff3082015-05-19 10:23:26 -07002954 addedIValues.append( iCounterValue )
Jon Hall390696c2015-05-05 17:13:41 -07002955 threads.append( t )
2956 t.start()
2957
2958 for t in threads:
2959 t.join()
2960 iCounters.append( t.result )
2961 # Check that counter incremented numController times
2962 iCounterResults = True
Jon Hallfeff3082015-05-19 10:23:26 -07002963 for i in addedIValues:
2964 tmpResult = i in iCounters
2965 iCounterResults = iCounterResults and tmpResult
2966 if not tmpResult:
2967 main.log.error( str( i ) + " is not in the in-memory "
2968 "counter incremented results" )
Jon Hall390696c2015-05-05 17:13:41 -07002969 utilities.assert_equals( expect=True,
2970 actual=iCounterResults,
2971 onpass="In memory counter incremented",
2972 onfail="Error incrementing in memory" +
2973 " counter" )
2974
2975 main.step( "Check counters are consistant across nodes" )
2976 onosCounters = []
2977 threads = []
2978 for i in range( numControllers ):
2979 t = main.Thread( target=CLIs[i].counters,
2980 name="counters-" + str( i ) )
2981 threads.append( t )
2982 t.start()
2983 for t in threads:
2984 t.join()
2985 onosCounters.append( t.result )
2986 tmp = [ i == onosCounters[ 0 ] for i in onosCounters ]
2987 if all( tmp ):
2988 main.log.info( "Counters are consistent across all nodes" )
2989 consistentCounterResults = main.TRUE
2990 else:
2991 main.log.error( "Counters are not consistent across all nodes" )
2992 consistentCounterResults = main.FALSE
2993 utilities.assert_equals( expect=main.TRUE,
2994 actual=consistentCounterResults,
2995 onpass="ONOS counters are consistent " +
2996 "across nodes",
2997 onfail="ONOS Counters are inconsistent " +
2998 "across nodes" )
2999
3000 main.step( "Counters we added have the correct values" )
3001 correctResults = main.TRUE
3002 for i in range( numControllers ):
Jon Hall40d2cbd2015-06-03 16:24:29 -07003003 current = json.loads( onosCounters[i] )
3004 pValue = None
3005 iValue = None
Jon Hall390696c2015-05-05 17:13:41 -07003006 try:
Jon Hall40d2cbd2015-06-03 16:24:29 -07003007 for database in current:
3008 partitioned = database.get( 'partitionedDatabaseCounters' )
3009 if partitioned:
3010 for value in partitioned:
3011 if value.get( 'name' ) == pCounterName:
3012 pValue = value.get( 'value' )
3013 break
3014 inMemory = database.get( 'inMemoryDatabaseCounters' )
3015 if inMemory:
3016 for value in inMemory:
3017 if value.get( 'name' ) == iCounterName:
3018 iValue = value.get( 'value' )
3019 break
Jon Hall390696c2015-05-05 17:13:41 -07003020 except AttributeError, e:
3021 main.log.error( "ONOS" + str( i + 1 ) + " counters result " +
3022 "is not as expected" )
3023 correctResults = main.FALSE
Jon Hall40d2cbd2015-06-03 16:24:29 -07003024 if pValue == pCounterValue:
3025 main.log.info( "Partitioned counter value is correct" )
3026 else:
3027 main.log.error( "Partitioned counter value is incorrect," +
3028 " expected value: " + str( pCounterValue )
3029 + " current value: " + str( pValue ) )
3030 correctResults = main.FALSE
3031 if iValue == iCounterValue:
3032 main.log.info( "In memory counter value is correct" )
3033 else:
3034 main.log.error( "In memory counter value is incorrect, " +
3035 "expected value: " + str( iCounterValue ) +
3036 " current value: " + str( iValue ) )
3037 correctResults = main.FALSE
Jon Hall390696c2015-05-05 17:13:41 -07003038 utilities.assert_equals( expect=main.TRUE,
3039 actual=correctResults,
3040 onpass="Added counters are correct",
3041 onfail="Added counters are incorrect" )
3042 # DISTRIBUTED SETS
3043 main.step( "Distributed Set get" )
3044 size = len( onosSet )
3045 getResponses = []
3046 threads = []
3047 for i in range( numControllers ):
3048 t = main.Thread( target=CLIs[i].setTestGet,
3049 name="setTestGet-" + str( i ),
3050 args=[ onosSetName ] )
3051 threads.append( t )
3052 t.start()
3053 for t in threads:
3054 t.join()
3055 getResponses.append( t.result )
3056
3057 getResults = main.TRUE
3058 for i in range( numControllers ):
3059 if isinstance( getResponses[ i ], list):
3060 current = set( getResponses[ i ] )
3061 if len( current ) == len( getResponses[ i ] ):
3062 # no repeats
3063 if onosSet != current:
3064 main.log.error( "ONOS" + str( i + 1 ) +
3065 " has incorrect view" +
3066 " of set " + onosSetName + ":\n" +
3067 str( getResponses[ i ] ) )
3068 main.log.debug( "Expected: " + str( onosSet ) )
3069 main.log.debug( "Actual: " + str( current ) )
3070 getResults = main.FALSE
3071 else:
3072 # error, set is not a set
3073 main.log.error( "ONOS" + str( i + 1 ) +
3074 " has repeat elements in" +
3075 " set " + onosSetName + ":\n" +
3076 str( getResponses[ i ] ) )
3077 getResults = main.FALSE
3078 elif getResponses[ i ] == main.ERROR:
3079 getResults = main.FALSE
3080 utilities.assert_equals( expect=main.TRUE,
3081 actual=getResults,
3082 onpass="Set elements are correct",
3083 onfail="Set elements are incorrect" )
3084
3085 main.step( "Distributed Set size" )
3086 sizeResponses = []
3087 threads = []
3088 for i in range( numControllers ):
3089 t = main.Thread( target=CLIs[i].setTestSize,
3090 name="setTestSize-" + str( i ),
3091 args=[ onosSetName ] )
3092 threads.append( t )
3093 t.start()
3094 for t in threads:
3095 t.join()
3096 sizeResponses.append( t.result )
3097
3098 sizeResults = main.TRUE
3099 for i in range( numControllers ):
3100 if size != sizeResponses[ i ]:
3101 sizeResults = main.FALSE
3102 main.log.error( "ONOS" + str( i + 1 ) +
3103 " expected a size of " + str( size ) +
3104 " for set " + onosSetName +
3105 " but got " + str( sizeResponses[ i ] ) )
3106 utilities.assert_equals( expect=main.TRUE,
3107 actual=sizeResults,
3108 onpass="Set sizes are correct",
3109 onfail="Set sizes are incorrect" )
3110
3111 main.step( "Distributed Set add()" )
3112 onosSet.add( addValue )
3113 addResponses = []
3114 threads = []
3115 for i in range( numControllers ):
3116 t = main.Thread( target=CLIs[i].setTestAdd,
3117 name="setTestAdd-" + str( i ),
3118 args=[ onosSetName, addValue ] )
3119 threads.append( t )
3120 t.start()
3121 for t in threads:
3122 t.join()
3123 addResponses.append( t.result )
3124
3125 # main.TRUE = successfully changed the set
3126 # main.FALSE = action resulted in no change in set
3127 # main.ERROR - Some error in executing the function
3128 addResults = main.TRUE
3129 for i in range( numControllers ):
3130 if addResponses[ i ] == main.TRUE:
3131 # All is well
3132 pass
3133 elif addResponses[ i ] == main.FALSE:
3134 # Already in set, probably fine
3135 pass
3136 elif addResponses[ i ] == main.ERROR:
3137 # Error in execution
3138 addResults = main.FALSE
3139 else:
3140 # unexpected result
3141 addResults = main.FALSE
3142 if addResults != main.TRUE:
3143 main.log.error( "Error executing set add" )
3144
3145 # Check if set is still correct
3146 size = len( onosSet )
3147 getResponses = []
3148 threads = []
3149 for i in range( numControllers ):
3150 t = main.Thread( target=CLIs[i].setTestGet,
3151 name="setTestGet-" + str( i ),
3152 args=[ onosSetName ] )
3153 threads.append( t )
3154 t.start()
3155 for t in threads:
3156 t.join()
3157 getResponses.append( t.result )
3158 getResults = main.TRUE
3159 for i in range( numControllers ):
3160 if isinstance( getResponses[ i ], list):
3161 current = set( getResponses[ i ] )
3162 if len( current ) == len( getResponses[ i ] ):
3163 # no repeats
3164 if onosSet != current:
3165 main.log.error( "ONOS" + str( i + 1 ) +
3166 " has incorrect view" +
3167 " of set " + onosSetName + ":\n" +
3168 str( getResponses[ i ] ) )
3169 main.log.debug( "Expected: " + str( onosSet ) )
3170 main.log.debug( "Actual: " + str( current ) )
3171 getResults = main.FALSE
3172 else:
3173 # error, set is not a set
3174 main.log.error( "ONOS" + str( i + 1 ) +
3175 " has repeat elements in" +
3176 " set " + onosSetName + ":\n" +
3177 str( getResponses[ i ] ) )
3178 getResults = main.FALSE
3179 elif getResponses[ i ] == main.ERROR:
3180 getResults = main.FALSE
3181 sizeResponses = []
3182 threads = []
3183 for i in range( numControllers ):
3184 t = main.Thread( target=CLIs[i].setTestSize,
3185 name="setTestSize-" + str( i ),
3186 args=[ onosSetName ] )
3187 threads.append( t )
3188 t.start()
3189 for t in threads:
3190 t.join()
3191 sizeResponses.append( t.result )
3192 sizeResults = main.TRUE
3193 for i in range( numControllers ):
3194 if size != sizeResponses[ i ]:
3195 sizeResults = main.FALSE
3196 main.log.error( "ONOS" + str( i + 1 ) +
3197 " expected a size of " + str( size ) +
3198 " for set " + onosSetName +
3199 " but got " + str( sizeResponses[ i ] ) )
3200 addResults = addResults and getResults and sizeResults
3201 utilities.assert_equals( expect=main.TRUE,
3202 actual=addResults,
3203 onpass="Set add correct",
3204 onfail="Set add was incorrect" )
3205
3206 main.step( "Distributed Set addAll()" )
3207 onosSet.update( addAllValue.split() )
3208 addResponses = []
3209 threads = []
3210 for i in range( numControllers ):
3211 t = main.Thread( target=CLIs[i].setTestAdd,
3212 name="setTestAddAll-" + str( i ),
3213 args=[ onosSetName, addAllValue ] )
3214 threads.append( t )
3215 t.start()
3216 for t in threads:
3217 t.join()
3218 addResponses.append( t.result )
3219
3220 # main.TRUE = successfully changed the set
3221 # main.FALSE = action resulted in no change in set
3222 # main.ERROR - Some error in executing the function
3223 addAllResults = main.TRUE
3224 for i in range( numControllers ):
3225 if addResponses[ i ] == main.TRUE:
3226 # All is well
3227 pass
3228 elif addResponses[ i ] == main.FALSE:
3229 # Already in set, probably fine
3230 pass
3231 elif addResponses[ i ] == main.ERROR:
3232 # Error in execution
3233 addAllResults = main.FALSE
3234 else:
3235 # unexpected result
3236 addAllResults = main.FALSE
3237 if addAllResults != main.TRUE:
3238 main.log.error( "Error executing set addAll" )
3239
3240 # Check if set is still correct
3241 size = len( onosSet )
3242 getResponses = []
3243 threads = []
3244 for i in range( numControllers ):
3245 t = main.Thread( target=CLIs[i].setTestGet,
3246 name="setTestGet-" + str( i ),
3247 args=[ onosSetName ] )
3248 threads.append( t )
3249 t.start()
3250 for t in threads:
3251 t.join()
3252 getResponses.append( t.result )
3253 getResults = main.TRUE
3254 for i in range( numControllers ):
3255 if isinstance( getResponses[ i ], list):
3256 current = set( getResponses[ i ] )
3257 if len( current ) == len( getResponses[ i ] ):
3258 # no repeats
3259 if onosSet != current:
3260 main.log.error( "ONOS" + str( i + 1 ) +
3261 " has incorrect view" +
3262 " of set " + onosSetName + ":\n" +
3263 str( getResponses[ i ] ) )
3264 main.log.debug( "Expected: " + str( onosSet ) )
3265 main.log.debug( "Actual: " + str( current ) )
3266 getResults = main.FALSE
3267 else:
3268 # error, set is not a set
3269 main.log.error( "ONOS" + str( i + 1 ) +
3270 " has repeat elements in" +
3271 " set " + onosSetName + ":\n" +
3272 str( getResponses[ i ] ) )
3273 getResults = main.FALSE
3274 elif getResponses[ i ] == main.ERROR:
3275 getResults = main.FALSE
3276 sizeResponses = []
3277 threads = []
3278 for i in range( numControllers ):
3279 t = main.Thread( target=CLIs[i].setTestSize,
3280 name="setTestSize-" + str( i ),
3281 args=[ onosSetName ] )
3282 threads.append( t )
3283 t.start()
3284 for t in threads:
3285 t.join()
3286 sizeResponses.append( t.result )
3287 sizeResults = main.TRUE
3288 for i in range( numControllers ):
3289 if size != sizeResponses[ i ]:
3290 sizeResults = main.FALSE
3291 main.log.error( "ONOS" + str( i + 1 ) +
3292 " expected a size of " + str( size ) +
3293 " for set " + onosSetName +
3294 " but got " + str( sizeResponses[ i ] ) )
3295 addAllResults = addAllResults and getResults and sizeResults
3296 utilities.assert_equals( expect=main.TRUE,
3297 actual=addAllResults,
3298 onpass="Set addAll correct",
3299 onfail="Set addAll was incorrect" )
3300
3301 main.step( "Distributed Set contains()" )
3302 containsResponses = []
3303 threads = []
3304 for i in range( numControllers ):
3305 t = main.Thread( target=CLIs[i].setTestGet,
3306 name="setContains-" + str( i ),
3307 args=[ onosSetName ],
3308 kwargs={ "values": addValue } )
3309 threads.append( t )
3310 t.start()
3311 for t in threads:
3312 t.join()
3313 # NOTE: This is the tuple
3314 containsResponses.append( t.result )
3315
3316 containsResults = main.TRUE
3317 for i in range( numControllers ):
3318 if containsResponses[ i ] == main.ERROR:
3319 containsResults = main.FALSE
3320 else:
3321 containsResults = containsResults and\
3322 containsResponses[ i ][ 1 ]
3323 utilities.assert_equals( expect=main.TRUE,
3324 actual=containsResults,
3325 onpass="Set contains is functional",
3326 onfail="Set contains failed" )
3327
3328 main.step( "Distributed Set containsAll()" )
3329 containsAllResponses = []
3330 threads = []
3331 for i in range( numControllers ):
3332 t = main.Thread( target=CLIs[i].setTestGet,
3333 name="setContainsAll-" + str( i ),
3334 args=[ onosSetName ],
3335 kwargs={ "values": addAllValue } )
3336 threads.append( t )
3337 t.start()
3338 for t in threads:
3339 t.join()
3340 # NOTE: This is the tuple
3341 containsAllResponses.append( t.result )
3342
3343 containsAllResults = main.TRUE
3344 for i in range( numControllers ):
3345 if containsResponses[ i ] == main.ERROR:
3346 containsResults = main.FALSE
3347 else:
3348 containsResults = containsResults and\
3349 containsResponses[ i ][ 1 ]
3350 utilities.assert_equals( expect=main.TRUE,
3351 actual=containsAllResults,
3352 onpass="Set containsAll is functional",
3353 onfail="Set containsAll failed" )
3354
3355 main.step( "Distributed Set remove()" )
3356 onosSet.remove( addValue )
3357 removeResponses = []
3358 threads = []
3359 for i in range( numControllers ):
3360 t = main.Thread( target=CLIs[i].setTestRemove,
3361 name="setTestRemove-" + str( i ),
3362 args=[ onosSetName, addValue ] )
3363 threads.append( t )
3364 t.start()
3365 for t in threads:
3366 t.join()
3367 removeResponses.append( t.result )
3368
3369 # main.TRUE = successfully changed the set
3370 # main.FALSE = action resulted in no change in set
3371 # main.ERROR - Some error in executing the function
3372 removeResults = main.TRUE
3373 for i in range( numControllers ):
3374 if removeResponses[ i ] == main.TRUE:
3375 # All is well
3376 pass
3377 elif removeResponses[ i ] == main.FALSE:
3378 # not in set, probably fine
3379 pass
3380 elif removeResponses[ i ] == main.ERROR:
3381 # Error in execution
3382 removeResults = main.FALSE
3383 else:
3384 # unexpected result
3385 removeResults = main.FALSE
3386 if removeResults != main.TRUE:
3387 main.log.error( "Error executing set remove" )
3388
3389 # Check if set is still correct
3390 size = len( onosSet )
3391 getResponses = []
3392 threads = []
3393 for i in range( numControllers ):
3394 t = main.Thread( target=CLIs[i].setTestGet,
3395 name="setTestGet-" + str( i ),
3396 args=[ onosSetName ] )
3397 threads.append( t )
3398 t.start()
3399 for t in threads:
3400 t.join()
3401 getResponses.append( t.result )
3402 getResults = main.TRUE
3403 for i in range( numControllers ):
3404 if isinstance( getResponses[ i ], list):
3405 current = set( getResponses[ i ] )
3406 if len( current ) == len( getResponses[ i ] ):
3407 # no repeats
3408 if onosSet != current:
3409 main.log.error( "ONOS" + str( i + 1 ) +
3410 " has incorrect view" +
3411 " of set " + onosSetName + ":\n" +
3412 str( getResponses[ i ] ) )
3413 main.log.debug( "Expected: " + str( onosSet ) )
3414 main.log.debug( "Actual: " + str( current ) )
3415 getResults = main.FALSE
3416 else:
3417 # error, set is not a set
3418 main.log.error( "ONOS" + str( i + 1 ) +
3419 " has repeat elements in" +
3420 " set " + onosSetName + ":\n" +
3421 str( getResponses[ i ] ) )
3422 getResults = main.FALSE
3423 elif getResponses[ i ] == main.ERROR:
3424 getResults = main.FALSE
3425 sizeResponses = []
3426 threads = []
3427 for i in range( numControllers ):
3428 t = main.Thread( target=CLIs[i].setTestSize,
3429 name="setTestSize-" + str( i ),
3430 args=[ onosSetName ] )
3431 threads.append( t )
3432 t.start()
3433 for t in threads:
3434 t.join()
3435 sizeResponses.append( t.result )
3436 sizeResults = main.TRUE
3437 for i in range( numControllers ):
3438 if size != sizeResponses[ i ]:
3439 sizeResults = main.FALSE
3440 main.log.error( "ONOS" + str( i + 1 ) +
3441 " expected a size of " + str( size ) +
3442 " for set " + onosSetName +
3443 " but got " + str( sizeResponses[ i ] ) )
3444 removeResults = removeResults and getResults and sizeResults
3445 utilities.assert_equals( expect=main.TRUE,
3446 actual=removeResults,
3447 onpass="Set remove correct",
3448 onfail="Set remove was incorrect" )
3449
3450 main.step( "Distributed Set removeAll()" )
3451 onosSet.difference_update( addAllValue.split() )
3452 removeAllResponses = []
3453 threads = []
3454 try:
3455 for i in range( numControllers ):
3456 t = main.Thread( target=CLIs[i].setTestRemove,
3457 name="setTestRemoveAll-" + str( i ),
3458 args=[ onosSetName, addAllValue ] )
3459 threads.append( t )
3460 t.start()
3461 for t in threads:
3462 t.join()
3463 removeAllResponses.append( t.result )
3464 except Exception, e:
3465 main.log.exception(e)
3466
3467 # main.TRUE = successfully changed the set
3468 # main.FALSE = action resulted in no change in set
3469 # main.ERROR - Some error in executing the function
3470 removeAllResults = main.TRUE
3471 for i in range( numControllers ):
3472 if removeAllResponses[ i ] == main.TRUE:
3473 # All is well
3474 pass
3475 elif removeAllResponses[ i ] == main.FALSE:
3476 # not in set, probably fine
3477 pass
3478 elif removeAllResponses[ i ] == main.ERROR:
3479 # Error in execution
3480 removeAllResults = main.FALSE
3481 else:
3482 # unexpected result
3483 removeAllResults = main.FALSE
3484 if removeAllResults != main.TRUE:
3485 main.log.error( "Error executing set removeAll" )
3486
3487 # Check if set is still correct
3488 size = len( onosSet )
3489 getResponses = []
3490 threads = []
3491 for i in range( numControllers ):
3492 t = main.Thread( target=CLIs[i].setTestGet,
3493 name="setTestGet-" + str( i ),
3494 args=[ onosSetName ] )
3495 threads.append( t )
3496 t.start()
3497 for t in threads:
3498 t.join()
3499 getResponses.append( t.result )
3500 getResults = main.TRUE
3501 for i in range( numControllers ):
3502 if isinstance( getResponses[ i ], list):
3503 current = set( getResponses[ i ] )
3504 if len( current ) == len( getResponses[ i ] ):
3505 # no repeats
3506 if onosSet != current:
3507 main.log.error( "ONOS" + str( i + 1 ) +
3508 " has incorrect view" +
3509 " of set " + onosSetName + ":\n" +
3510 str( getResponses[ i ] ) )
3511 main.log.debug( "Expected: " + str( onosSet ) )
3512 main.log.debug( "Actual: " + str( current ) )
3513 getResults = main.FALSE
3514 else:
3515 # error, set is not a set
3516 main.log.error( "ONOS" + str( i + 1 ) +
3517 " has repeat elements in" +
3518 " set " + onosSetName + ":\n" +
3519 str( getResponses[ i ] ) )
3520 getResults = main.FALSE
3521 elif getResponses[ i ] == main.ERROR:
3522 getResults = main.FALSE
3523 sizeResponses = []
3524 threads = []
3525 for i in range( numControllers ):
3526 t = main.Thread( target=CLIs[i].setTestSize,
3527 name="setTestSize-" + str( i ),
3528 args=[ onosSetName ] )
3529 threads.append( t )
3530 t.start()
3531 for t in threads:
3532 t.join()
3533 sizeResponses.append( t.result )
3534 sizeResults = main.TRUE
3535 for i in range( numControllers ):
3536 if size != sizeResponses[ i ]:
3537 sizeResults = main.FALSE
3538 main.log.error( "ONOS" + str( i + 1 ) +
3539 " expected a size of " + str( size ) +
3540 " for set " + onosSetName +
3541 " but got " + str( sizeResponses[ i ] ) )
3542 removeAllResults = removeAllResults and getResults and sizeResults
3543 utilities.assert_equals( expect=main.TRUE,
3544 actual=removeAllResults,
3545 onpass="Set removeAll correct",
3546 onfail="Set removeAll was incorrect" )
3547
3548 main.step( "Distributed Set addAll()" )
3549 onosSet.update( addAllValue.split() )
3550 addResponses = []
3551 threads = []
3552 for i in range( numControllers ):
3553 t = main.Thread( target=CLIs[i].setTestAdd,
3554 name="setTestAddAll-" + str( i ),
3555 args=[ onosSetName, addAllValue ] )
3556 threads.append( t )
3557 t.start()
3558 for t in threads:
3559 t.join()
3560 addResponses.append( t.result )
3561
3562 # main.TRUE = successfully changed the set
3563 # main.FALSE = action resulted in no change in set
3564 # main.ERROR - Some error in executing the function
3565 addAllResults = main.TRUE
3566 for i in range( numControllers ):
3567 if addResponses[ i ] == main.TRUE:
3568 # All is well
3569 pass
3570 elif addResponses[ i ] == main.FALSE:
3571 # Already in set, probably fine
3572 pass
3573 elif addResponses[ i ] == main.ERROR:
3574 # Error in execution
3575 addAllResults = main.FALSE
3576 else:
3577 # unexpected result
3578 addAllResults = main.FALSE
3579 if addAllResults != main.TRUE:
3580 main.log.error( "Error executing set addAll" )
3581
3582 # Check if set is still correct
3583 size = len( onosSet )
3584 getResponses = []
3585 threads = []
3586 for i in range( numControllers ):
3587 t = main.Thread( target=CLIs[i].setTestGet,
3588 name="setTestGet-" + str( i ),
3589 args=[ onosSetName ] )
3590 threads.append( t )
3591 t.start()
3592 for t in threads:
3593 t.join()
3594 getResponses.append( t.result )
3595 getResults = main.TRUE
3596 for i in range( numControllers ):
3597 if isinstance( getResponses[ i ], list):
3598 current = set( getResponses[ i ] )
3599 if len( current ) == len( getResponses[ i ] ):
3600 # no repeats
3601 if onosSet != current:
3602 main.log.error( "ONOS" + str( i + 1 ) +
3603 " has incorrect view" +
3604 " of set " + onosSetName + ":\n" +
3605 str( getResponses[ i ] ) )
3606 main.log.debug( "Expected: " + str( onosSet ) )
3607 main.log.debug( "Actual: " + str( current ) )
3608 getResults = main.FALSE
3609 else:
3610 # error, set is not a set
3611 main.log.error( "ONOS" + str( i + 1 ) +
3612 " has repeat elements in" +
3613 " set " + onosSetName + ":\n" +
3614 str( getResponses[ i ] ) )
3615 getResults = main.FALSE
3616 elif getResponses[ i ] == main.ERROR:
3617 getResults = main.FALSE
3618 sizeResponses = []
3619 threads = []
3620 for i in range( numControllers ):
3621 t = main.Thread( target=CLIs[i].setTestSize,
3622 name="setTestSize-" + str( i ),
3623 args=[ onosSetName ] )
3624 threads.append( t )
3625 t.start()
3626 for t in threads:
3627 t.join()
3628 sizeResponses.append( t.result )
3629 sizeResults = main.TRUE
3630 for i in range( numControllers ):
3631 if size != sizeResponses[ i ]:
3632 sizeResults = main.FALSE
3633 main.log.error( "ONOS" + str( i + 1 ) +
3634 " expected a size of " + str( size ) +
3635 " for set " + onosSetName +
3636 " but got " + str( sizeResponses[ i ] ) )
3637 addAllResults = addAllResults and getResults and sizeResults
3638 utilities.assert_equals( expect=main.TRUE,
3639 actual=addAllResults,
3640 onpass="Set addAll correct",
3641 onfail="Set addAll was incorrect" )
3642
3643 main.step( "Distributed Set clear()" )
3644 onosSet.clear()
3645 clearResponses = []
3646 threads = []
3647 for i in range( numControllers ):
3648 t = main.Thread( target=CLIs[i].setTestRemove,
3649 name="setTestClear-" + str( i ),
3650 args=[ onosSetName, " "], # Values doesn't matter
3651 kwargs={ "clear": True } )
3652 threads.append( t )
3653 t.start()
3654 for t in threads:
3655 t.join()
3656 clearResponses.append( t.result )
3657
3658 # main.TRUE = successfully changed the set
3659 # main.FALSE = action resulted in no change in set
3660 # main.ERROR - Some error in executing the function
3661 clearResults = main.TRUE
3662 for i in range( numControllers ):
3663 if clearResponses[ i ] == main.TRUE:
3664 # All is well
3665 pass
3666 elif clearResponses[ i ] == main.FALSE:
3667 # Nothing set, probably fine
3668 pass
3669 elif clearResponses[ i ] == main.ERROR:
3670 # Error in execution
3671 clearResults = main.FALSE
3672 else:
3673 # unexpected result
3674 clearResults = main.FALSE
3675 if clearResults != main.TRUE:
3676 main.log.error( "Error executing set clear" )
3677
3678 # Check if set is still correct
3679 size = len( onosSet )
3680 getResponses = []
3681 threads = []
3682 for i in range( numControllers ):
3683 t = main.Thread( target=CLIs[i].setTestGet,
3684 name="setTestGet-" + str( i ),
3685 args=[ onosSetName ] )
3686 threads.append( t )
3687 t.start()
3688 for t in threads:
3689 t.join()
3690 getResponses.append( t.result )
3691 getResults = main.TRUE
3692 for i in range( numControllers ):
3693 if isinstance( getResponses[ i ], list):
3694 current = set( getResponses[ i ] )
3695 if len( current ) == len( getResponses[ i ] ):
3696 # no repeats
3697 if onosSet != current:
3698 main.log.error( "ONOS" + str( i + 1 ) +
3699 " has incorrect view" +
3700 " of set " + onosSetName + ":\n" +
3701 str( getResponses[ i ] ) )
3702 main.log.debug( "Expected: " + str( onosSet ) )
3703 main.log.debug( "Actual: " + str( current ) )
3704 getResults = main.FALSE
3705 else:
3706 # error, set is not a set
3707 main.log.error( "ONOS" + str( i + 1 ) +
3708 " has repeat elements in" +
3709 " set " + onosSetName + ":\n" +
3710 str( getResponses[ i ] ) )
3711 getResults = main.FALSE
3712 elif getResponses[ i ] == main.ERROR:
3713 getResults = main.FALSE
3714 sizeResponses = []
3715 threads = []
3716 for i in range( numControllers ):
3717 t = main.Thread( target=CLIs[i].setTestSize,
3718 name="setTestSize-" + str( i ),
3719 args=[ onosSetName ] )
3720 threads.append( t )
3721 t.start()
3722 for t in threads:
3723 t.join()
3724 sizeResponses.append( t.result )
3725 sizeResults = main.TRUE
3726 for i in range( numControllers ):
3727 if size != sizeResponses[ i ]:
3728 sizeResults = main.FALSE
3729 main.log.error( "ONOS" + str( i + 1 ) +
3730 " expected a size of " + str( size ) +
3731 " for set " + onosSetName +
3732 " but got " + str( sizeResponses[ i ] ) )
3733 clearResults = clearResults and getResults and sizeResults
3734 utilities.assert_equals( expect=main.TRUE,
3735 actual=clearResults,
3736 onpass="Set clear correct",
3737 onfail="Set clear was incorrect" )
3738
3739 main.step( "Distributed Set addAll()" )
3740 onosSet.update( addAllValue.split() )
3741 addResponses = []
3742 threads = []
3743 for i in range( numControllers ):
3744 t = main.Thread( target=CLIs[i].setTestAdd,
3745 name="setTestAddAll-" + str( i ),
3746 args=[ onosSetName, addAllValue ] )
3747 threads.append( t )
3748 t.start()
3749 for t in threads:
3750 t.join()
3751 addResponses.append( t.result )
3752
3753 # main.TRUE = successfully changed the set
3754 # main.FALSE = action resulted in no change in set
3755 # main.ERROR - Some error in executing the function
3756 addAllResults = main.TRUE
3757 for i in range( numControllers ):
3758 if addResponses[ i ] == main.TRUE:
3759 # All is well
3760 pass
3761 elif addResponses[ i ] == main.FALSE:
3762 # Already in set, probably fine
3763 pass
3764 elif addResponses[ i ] == main.ERROR:
3765 # Error in execution
3766 addAllResults = main.FALSE
3767 else:
3768 # unexpected result
3769 addAllResults = main.FALSE
3770 if addAllResults != main.TRUE:
3771 main.log.error( "Error executing set addAll" )
3772
3773 # Check if set is still correct
3774 size = len( onosSet )
3775 getResponses = []
3776 threads = []
3777 for i in range( numControllers ):
3778 t = main.Thread( target=CLIs[i].setTestGet,
3779 name="setTestGet-" + str( i ),
3780 args=[ onosSetName ] )
3781 threads.append( t )
3782 t.start()
3783 for t in threads:
3784 t.join()
3785 getResponses.append( t.result )
3786 getResults = main.TRUE
3787 for i in range( numControllers ):
3788 if isinstance( getResponses[ i ], list):
3789 current = set( getResponses[ i ] )
3790 if len( current ) == len( getResponses[ i ] ):
3791 # no repeats
3792 if onosSet != current:
3793 main.log.error( "ONOS" + str( i + 1 ) +
3794 " has incorrect view" +
3795 " of set " + onosSetName + ":\n" +
3796 str( getResponses[ i ] ) )
3797 main.log.debug( "Expected: " + str( onosSet ) )
3798 main.log.debug( "Actual: " + str( current ) )
3799 getResults = main.FALSE
3800 else:
3801 # error, set is not a set
3802 main.log.error( "ONOS" + str( i + 1 ) +
3803 " has repeat elements in" +
3804 " set " + onosSetName + ":\n" +
3805 str( getResponses[ i ] ) )
3806 getResults = main.FALSE
3807 elif getResponses[ i ] == main.ERROR:
3808 getResults = main.FALSE
3809 sizeResponses = []
3810 threads = []
3811 for i in range( numControllers ):
3812 t = main.Thread( target=CLIs[i].setTestSize,
3813 name="setTestSize-" + str( i ),
3814 args=[ onosSetName ] )
3815 threads.append( t )
3816 t.start()
3817 for t in threads:
3818 t.join()
3819 sizeResponses.append( t.result )
3820 sizeResults = main.TRUE
3821 for i in range( numControllers ):
3822 if size != sizeResponses[ i ]:
3823 sizeResults = main.FALSE
3824 main.log.error( "ONOS" + str( i + 1 ) +
3825 " expected a size of " + str( size ) +
3826 " for set " + onosSetName +
3827 " but got " + str( sizeResponses[ i ] ) )
3828 addAllResults = addAllResults and getResults and sizeResults
3829 utilities.assert_equals( expect=main.TRUE,
3830 actual=addAllResults,
3831 onpass="Set addAll correct",
3832 onfail="Set addAll was incorrect" )
3833
3834 main.step( "Distributed Set retain()" )
3835 onosSet.intersection_update( retainValue.split() )
3836 retainResponses = []
3837 threads = []
3838 for i in range( numControllers ):
3839 t = main.Thread( target=CLIs[i].setTestRemove,
3840 name="setTestRetain-" + str( i ),
3841 args=[ onosSetName, retainValue ],
3842 kwargs={ "retain": True } )
3843 threads.append( t )
3844 t.start()
3845 for t in threads:
3846 t.join()
3847 retainResponses.append( t.result )
3848
3849 # main.TRUE = successfully changed the set
3850 # main.FALSE = action resulted in no change in set
3851 # main.ERROR - Some error in executing the function
3852 retainResults = main.TRUE
3853 for i in range( numControllers ):
3854 if retainResponses[ i ] == main.TRUE:
3855 # All is well
3856 pass
3857 elif retainResponses[ i ] == main.FALSE:
3858 # Already in set, probably fine
3859 pass
3860 elif retainResponses[ i ] == main.ERROR:
3861 # Error in execution
3862 retainResults = main.FALSE
3863 else:
3864 # unexpected result
3865 retainResults = main.FALSE
3866 if retainResults != main.TRUE:
3867 main.log.error( "Error executing set retain" )
3868
3869 # Check if set is still correct
3870 size = len( onosSet )
3871 getResponses = []
3872 threads = []
3873 for i in range( numControllers ):
3874 t = main.Thread( target=CLIs[i].setTestGet,
3875 name="setTestGet-" + str( i ),
3876 args=[ onosSetName ] )
3877 threads.append( t )
3878 t.start()
3879 for t in threads:
3880 t.join()
3881 getResponses.append( t.result )
3882 getResults = main.TRUE
3883 for i in range( numControllers ):
3884 if isinstance( getResponses[ i ], list):
3885 current = set( getResponses[ i ] )
3886 if len( current ) == len( getResponses[ i ] ):
3887 # no repeats
3888 if onosSet != current:
3889 main.log.error( "ONOS" + str( i + 1 ) +
3890 " has incorrect view" +
3891 " of set " + onosSetName + ":\n" +
3892 str( getResponses[ i ] ) )
3893 main.log.debug( "Expected: " + str( onosSet ) )
3894 main.log.debug( "Actual: " + str( current ) )
3895 getResults = main.FALSE
3896 else:
3897 # error, set is not a set
3898 main.log.error( "ONOS" + str( i + 1 ) +
3899 " has repeat elements in" +
3900 " set " + onosSetName + ":\n" +
3901 str( getResponses[ i ] ) )
3902 getResults = main.FALSE
3903 elif getResponses[ i ] == main.ERROR:
3904 getResults = main.FALSE
3905 sizeResponses = []
3906 threads = []
3907 for i in range( numControllers ):
3908 t = main.Thread( target=CLIs[i].setTestSize,
3909 name="setTestSize-" + str( i ),
3910 args=[ onosSetName ] )
3911 threads.append( t )
3912 t.start()
3913 for t in threads:
3914 t.join()
3915 sizeResponses.append( t.result )
3916 sizeResults = main.TRUE
3917 for i in range( numControllers ):
3918 if size != sizeResponses[ i ]:
3919 sizeResults = main.FALSE
3920 main.log.error( "ONOS" + str( i + 1 ) +
3921 " expected a size of " +
3922 str( size ) + " for set " + onosSetName +
3923 " but got " + str( sizeResponses[ i ] ) )
3924 retainResults = retainResults and getResults and sizeResults
3925 utilities.assert_equals( expect=main.TRUE,
3926 actual=retainResults,
3927 onpass="Set retain correct",
3928 onfail="Set retain was incorrect" )
3929