blob: 0dd40edff9aa1b37f771423256e2f8c228583fe7 [file] [log] [blame]
Jon Hall6aec96b2015-01-19 14:49:31 -08001"""
Jon Hall73cf9cc2014-11-20 22:28:38 -08002Description: This test is to determine if ONOS can handle
3 a minority of it's nodes restarting
4
5List of test cases:
6CASE1: Compile ONOS and push it to the test machines
7CASE2: Assign mastership to controllers
8CASE3: Assign intents
9CASE4: Ping across added host intents
10CASE5: Reading state of ONOS
11CASE6: The Failure case.
12CASE7: Check state after control plane failure
13CASE8: Compare topo
14CASE9: Link s3-s28 down
15CASE10: Link s3-s28 up
16CASE11: Switch down
17CASE12: Switch up
18CASE13: Clean up
Jon Hall669173b2014-12-17 11:36:30 -080019CASE14: start election app on all onos nodes
20CASE15: Check that Leadership Election is still functional
Jon Hall390696c2015-05-05 17:13:41 -070021CASE16: Install Distributed Primitives app
22CASE17: Check for basic functionality with distributed primitives
Jon Hall6aec96b2015-01-19 14:49:31 -080023"""
Jon Hall8f89dda2015-01-22 16:03:33 -080024
25
Jon Hall73cf9cc2014-11-20 22:28:38 -080026class HATestMinorityRestart:
27
Jon Hall6aec96b2015-01-19 14:49:31 -080028 def __init__( self ):
Jon Hall73cf9cc2014-11-20 22:28:38 -080029 self.default = ''
30
Jon Hall6aec96b2015-01-19 14:49:31 -080031 def CASE1( self, main ):
32 """
Jon Hall73cf9cc2014-11-20 22:28:38 -080033 CASE1 is to compile ONOS and push it to the test machines
34
35 Startup sequence:
Jon Hall73cf9cc2014-11-20 22:28:38 -080036 cell <name>
37 onos-verify-cell
38 NOTE: temporary - onos-remove-raft-logs
Jon Hall58c76b72015-02-23 11:09:24 -080039 onos-uninstall
40 start mininet
41 git pull
42 mvn clean install
43 onos-package
Jon Hall73cf9cc2014-11-20 22:28:38 -080044 onos-install -f
45 onos-wait-for-start
Jon Hall58c76b72015-02-23 11:09:24 -080046 start cli sessions
47 start tcpdump
Jon Hall6aec96b2015-01-19 14:49:31 -080048 """
Jon Hall390696c2015-05-05 17:13:41 -070049 main.log.report( "ONOS HA test: Restart minority of ONOS nodes - " +
50 "initialization" )
Jon Hall6aec96b2015-01-19 14:49:31 -080051 main.case( "Setting up test environment" )
52 # TODO: save all the timers and output them for plotting
Jon Hall73cf9cc2014-11-20 22:28:38 -080053
Jon Hall5cfd23c2015-03-19 11:40:57 -070054 # load some variables from the params file
Jon Hall8f89dda2015-01-22 16:03:33 -080055 PULLCODE = False
Jon Hall6aec96b2015-01-19 14:49:31 -080056 if main.params[ 'Git' ] == 'True':
Jon Hall8f89dda2015-01-22 16:03:33 -080057 PULLCODE = True
Jon Hall529a37f2015-01-28 10:02:00 -080058 gitBranch = main.params[ 'branch' ]
Jon Hall8f89dda2015-01-22 16:03:33 -080059 cellName = main.params[ 'ENV' ][ 'cellName' ]
Jon Hall6aec96b2015-01-19 14:49:31 -080060
61 # set global variables
Jon Hall8f89dda2015-01-22 16:03:33 -080062 global ONOS1Port
Jon Hall8f89dda2015-01-22 16:03:33 -080063 global ONOS2Port
Jon Hall8f89dda2015-01-22 16:03:33 -080064 global ONOS3Port
Jon Hall8f89dda2015-01-22 16:03:33 -080065 global ONOS4Port
Jon Hall8f89dda2015-01-22 16:03:33 -080066 global ONOS5Port
Jon Hall8f89dda2015-01-22 16:03:33 -080067 global ONOS6Port
Jon Hall8f89dda2015-01-22 16:03:33 -080068 global ONOS7Port
69 global numControllers
Jon Hall8f89dda2015-01-22 16:03:33 -080070 numControllers = int( main.params[ 'num_controllers' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -080071
Jon Hall5cfd23c2015-03-19 11:40:57 -070072 # FIXME: just get controller port from params?
73 # TODO: do we really need all these?
74 ONOS1Port = main.params[ 'CTRL' ][ 'port1' ]
75 ONOS2Port = main.params[ 'CTRL' ][ 'port2' ]
76 ONOS3Port = main.params[ 'CTRL' ][ 'port3' ]
77 ONOS4Port = main.params[ 'CTRL' ][ 'port4' ]
78 ONOS5Port = main.params[ 'CTRL' ][ 'port5' ]
79 ONOS6Port = main.params[ 'CTRL' ][ 'port6' ]
80 ONOS7Port = main.params[ 'CTRL' ][ 'port7' ]
81
82 global CLIs
83 CLIs = []
84 global nodes
85 nodes = []
86 for i in range( 1, numControllers + 1 ):
87 CLIs.append( getattr( main, 'ONOScli' + str( i ) ) )
88 nodes.append( getattr( main, 'ONOS' + str( i ) ) )
89
Jon Hall6aec96b2015-01-19 14:49:31 -080090 main.step( "Applying cell variable to environment" )
Jon Hall8f89dda2015-01-22 16:03:33 -080091 cellResult = main.ONOSbench.setCell( cellName )
92 verifyResult = main.ONOSbench.verifyCell()
Jon Hall73cf9cc2014-11-20 22:28:38 -080093
Jon Hall6aec96b2015-01-19 14:49:31 -080094 # FIXME:this is short term fix
95 main.log.report( "Removing raft logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -080096 main.ONOSbench.onosRemoveRaftLogs()
Jon Hall5cfd23c2015-03-19 11:40:57 -070097
Jon Hall6aec96b2015-01-19 14:49:31 -080098 main.log.report( "Uninstalling ONOS" )
Jon Hall5cfd23c2015-03-19 11:40:57 -070099 for node in nodes:
100 main.ONOSbench.onosUninstall( node.ip_address )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800101
Jon Hall390696c2015-05-05 17:13:41 -0700102 # Make sure ONOS is DEAD
103 main.log.report( "Killing any ONOS processes" )
104 killResults = main.TRUE
105 for node in nodes:
106 killed = main.ONOSbench.onosKill( node.ip_address )
107 killResults = killResults and killed
108
Jon Hall8f89dda2015-01-22 16:03:33 -0800109 cleanInstallResult = main.TRUE
110 gitPullResult = main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -0800111
Jon Hall97f31752015-02-04 12:01:04 -0800112 main.step( "Starting Mininet" )
Jon Hall390696c2015-05-05 17:13:41 -0700113 mnResult = main.Mininet1.startNet( )
114 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
115 onpass="Mininet Started",
116 onfail="Error starting Mininet" )
Jon Hall97f31752015-02-04 12:01:04 -0800117
Jon Hall6aec96b2015-01-19 14:49:31 -0800118 main.step( "Compiling the latest version of ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800119 if PULLCODE:
Jon Hall58c76b72015-02-23 11:09:24 -0800120 main.step( "Git checkout and pull " + gitBranch )
Jon Hall529a37f2015-01-28 10:02:00 -0800121 main.ONOSbench.gitCheckout( gitBranch )
Jon Hall8f89dda2015-01-22 16:03:33 -0800122 gitPullResult = main.ONOSbench.gitPull()
Jon Hall390696c2015-05-05 17:13:41 -0700123 # values of 1 or 3 are good
124 utilities.assert_lesser( expect=0, actual=gitPullResult,
125 onpass="Git pull successful",
126 onfail="Git pull failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800127
Jon Hall390696c2015-05-05 17:13:41 -0700128 main.step( "Using mvn clean and install" )
Jon Hall529a37f2015-01-28 10:02:00 -0800129 cleanInstallResult = main.ONOSbench.cleanInstall()
Jon Hall390696c2015-05-05 17:13:41 -0700130 utilities.assert_equals( expect=main.TRUE,
131 actual=cleanInstallResult,
132 onpass="MCI successful",
133 onfail="MCI failed" )
Jon Hall529a37f2015-01-28 10:02:00 -0800134 else:
135 main.log.warn( "Did not pull new code so skipping mvn " +
136 "clean install" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800137 main.ONOSbench.getVersion( report=True )
Jon Hall390696c2015-05-05 17:13:41 -0700138 # GRAPHS
139 # NOTE: important params here:
140 # job = name of Jenkins job
141 # Plot Name = Plot-HA, only can be used if multiple plots
142 # index = The number of the graph under plot name
143 job = "HAMinorityRestart"
144 graphs = '<ac:structured-macro ac:name="html">\n'
145 graphs += '<ac:plain-text-body><![CDATA[\n'
146 graphs += '<iframe src="https://onos-jenkins.onlab.us/job/' + job +\
147 '/plot/getPlot?index=0&width=500&height=300"' +\
148 'noborder="0" width="500" height="300" scrolling="yes" ' +\
149 'seamless="seamless"></iframe>\n'
150 graphs += ']]></ac:plain-text-body>\n'
151 graphs += '</ac:structured-macro>\n'
152 main.log.wiki(graphs)
Jon Hall73cf9cc2014-11-20 22:28:38 -0800153
Jon Hall6aec96b2015-01-19 14:49:31 -0800154 main.step( "Creating ONOS package" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800155 packageResult = main.ONOSbench.onosPackage()
Jon Hall390696c2015-05-05 17:13:41 -0700156 utilities.assert_equals( expect=main.TRUE, actual=packageResult,
157 onpass="ONOS package successful",
158 onfail="ONOS package failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800159
Jon Hall6aec96b2015-01-19 14:49:31 -0800160 main.step( "Installing ONOS package" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700161 onosInstallResult = main.TRUE
162 for node in nodes:
163 tmpResult = main.ONOSbench.onosInstall( options="-f",
164 node=node.ip_address )
165 onosInstallResult = onosInstallResult and tmpResult
Jon Hall390696c2015-05-05 17:13:41 -0700166 utilities.assert_equals( expect=main.TRUE, actual=onosInstallResult,
167 onpass="ONOS install successful",
168 onfail="ONOS install failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800169
Jon Hall6aec96b2015-01-19 14:49:31 -0800170 main.step( "Checking if ONOS is up yet" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800171 for i in range( 2 ):
Jon Hall5cfd23c2015-03-19 11:40:57 -0700172 onosIsupResult = main.TRUE
173 for node in nodes:
174 started = main.ONOSbench.isup( node.ip_address )
175 if not started:
176 main.log.report( node.name + " didn't start!" )
177 main.ONOSbench.onosStop( node.ip_address )
178 main.ONOSbench.onosStart( node.ip_address )
179 onosIsupResult = onosIsupResult and started
Jon Hall8f89dda2015-01-22 16:03:33 -0800180 if onosIsupResult == main.TRUE:
Jon Hall94fd0472014-12-08 11:52:42 -0800181 break
Jon Hall390696c2015-05-05 17:13:41 -0700182 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
183 onpass="ONOS startup successful",
184 onfail="ONOS startup failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800185
Jon Hall5cfd23c2015-03-19 11:40:57 -0700186 main.log.step( "Starting ONOS CLI sessions" )
187 cliResults = main.TRUE
188 threads = []
189 for i in range( numControllers ):
190 t = main.Thread( target=CLIs[i].startOnosCli,
191 name="startOnosCli-" + str( i ),
192 args=[nodes[i].ip_address] )
193 threads.append( t )
194 t.start()
195
196 for t in threads:
197 t.join()
198 cliResults = cliResults and t.result
Jon Hall390696c2015-05-05 17:13:41 -0700199 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
200 onpass="ONOS cli startup successful",
201 onfail="ONOS cli startup failed" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800202
Jon Hall6aec96b2015-01-19 14:49:31 -0800203 main.step( "Start Packet Capture MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800204 main.Mininet2.startTcpdump(
Jon Hall6aec96b2015-01-19 14:49:31 -0800205 str( main.params[ 'MNtcpdump' ][ 'folder' ] ) + str( main.TEST )
206 + "-MN.pcap",
207 intf=main.params[ 'MNtcpdump' ][ 'intf' ],
208 port=main.params[ 'MNtcpdump' ][ 'port' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800209
Jon Hall390696c2015-05-05 17:13:41 -0700210 main.step( "App Ids check" )
Jon Halla9d26da2015-03-30 16:45:32 -0700211 appCheck = main.TRUE
212 threads = []
213 for i in range( numControllers ):
214 t = main.Thread( target=CLIs[i].appToIDCheck,
215 name="appToIDCheck-" + str( i ),
216 args=[] )
217 threads.append( t )
218 t.start()
219
220 for t in threads:
221 t.join()
222 appCheck = appCheck and t.result
Jon Halla9d26da2015-03-30 16:45:32 -0700223 if appCheck != main.TRUE:
224 main.log.warn( CLIs[0].apps() )
225 main.log.warn( CLIs[0].appIDs() )
Jon Hall390696c2015-05-05 17:13:41 -0700226 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
227 onpass="App Ids seem to be correct",
228 onfail="Something is wrong with app Ids" )
Jon Halla9d26da2015-03-30 16:45:32 -0700229
Jon Hall8f89dda2015-01-22 16:03:33 -0800230 case1Result = ( cleanInstallResult and packageResult and
231 cellResult and verifyResult and onosInstallResult
Jon Hall390696c2015-05-05 17:13:41 -0700232 and onosIsupResult and cliResults )
Jon Hall8f89dda2015-01-22 16:03:33 -0800233 if case1Result == main.FALSE:
Jon Hall94fd0472014-12-08 11:52:42 -0800234 main.cleanup()
235 main.exit()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800236
Jon Hall6aec96b2015-01-19 14:49:31 -0800237 def CASE2( self, main ):
238 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800239 Assign mastership to controllers
Jon Hall6aec96b2015-01-19 14:49:31 -0800240 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800241 import re
Jon Hall390696c2015-05-05 17:13:41 -0700242 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -0700243 assert numControllers, "numControllers not defined"
244 assert main, "main not defined"
245 assert utilities.assert_equals, "utilities.assert_equals not defined"
246 assert CLIs, "CLIs not defined"
247 assert nodes, "nodes not defined"
248 assert ONOS1Port, "ONOS1Port not defined"
249 assert ONOS2Port, "ONOS2Port not defined"
250 assert ONOS3Port, "ONOS3Port not defined"
251 assert ONOS4Port, "ONOS4Port not defined"
252 assert ONOS5Port, "ONOS5Port not defined"
253 assert ONOS6Port, "ONOS6Port not defined"
254 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -0800255
Jon Hall6aec96b2015-01-19 14:49:31 -0800256 main.log.report( "Assigning switches to controllers" )
257 main.case( "Assigning Controllers" )
258 main.step( "Assign switches to controllers" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800259
Jon Hall5cfd23c2015-03-19 11:40:57 -0700260 # TODO: rewrite this function to take lists of ips and ports?
261 # or list of tuples?
Jon Hall6aec96b2015-01-19 14:49:31 -0800262 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800263 main.Mininet1.assignSwController(
Jon Hall6aec96b2015-01-19 14:49:31 -0800264 sw=str( i ),
Jon Hall8f89dda2015-01-22 16:03:33 -0800265 count=numControllers,
Jon Hall5cfd23c2015-03-19 11:40:57 -0700266 ip1=nodes[ 0 ].ip_address, port1=ONOS1Port,
267 ip2=nodes[ 1 ].ip_address, port2=ONOS2Port,
268 ip3=nodes[ 2 ].ip_address, port3=ONOS3Port,
269 ip4=nodes[ 3 ].ip_address, port4=ONOS4Port,
270 ip5=nodes[ 4 ].ip_address, port5=ONOS5Port,
271 ip6=nodes[ 5 ].ip_address, port6=ONOS6Port,
272 ip7=nodes[ 6 ].ip_address, port7=ONOS7Port )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800273
Jon Hall8f89dda2015-01-22 16:03:33 -0800274 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800275 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -0800276 response = main.Mininet1.getSwController( "s" + str( i ) )
Jon Hallffb386d2014-11-21 13:43:38 -0800277 try:
Jon Hall6aec96b2015-01-19 14:49:31 -0800278 main.log.info( str( response ) )
Jon Hallfebb1c72015-03-05 13:30:09 -0800279 except Exception:
Jon Hall6aec96b2015-01-19 14:49:31 -0800280 main.log.info( repr( response ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700281 for node in nodes:
282 if re.search( "tcp:" + node.ip_address, response ):
283 mastershipCheck = mastershipCheck and main.TRUE
284 else:
Jon Halla9d26da2015-03-30 16:45:32 -0700285 main.log.error( "Error, node " + node.ip_address + " is " +
286 "not in the list of controllers s" +
287 str( i ) + " is connecting to." )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700288 mastershipCheck = main.FALSE
Jon Hall8f89dda2015-01-22 16:03:33 -0800289 if mastershipCheck == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800290 main.log.report( "Switch mastership assigned correctly" )
291 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
297 main.step( "Assign mastership of switches to specific controllers" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800298 # Manually assign mastership to the controller we want
Jon Hall8f89dda2015-01-22 16:03:33 -0800299 roleCall = main.TRUE
Jon Hall390696c2015-05-05 17:13:41 -0700300
301 ipList = [ ]
302 deviceList = []
Jon Hall58c76b72015-02-23 11:09:24 -0800303 try:
Jon Halla9d26da2015-03-30 16:45:32 -0700304 for i in range( 1, 29 ): # switches 1 through 28
305 # set up correct variables:
306 if i == 1:
307 ip = nodes[ 0 ].ip_address # ONOS1
308 deviceId = main.ONOScli1.getDevice( "1000" ).get( 'id' )
309 elif i == 2:
310 ip = nodes[ 1 ].ip_address # ONOS2
311 deviceId = main.ONOScli1.getDevice( "2000" ).get( 'id' )
312 elif i == 3:
313 ip = nodes[ 1 ].ip_address # ONOS2
314 deviceId = main.ONOScli1.getDevice( "3000" ).get( 'id' )
315 elif i == 4:
316 ip = nodes[ 3 ].ip_address # ONOS4
317 deviceId = main.ONOScli1.getDevice( "3004" ).get( 'id' )
318 elif i == 5:
319 ip = nodes[ 2 ].ip_address # ONOS3
320 deviceId = main.ONOScli1.getDevice( "5000" ).get( 'id' )
321 elif i == 6:
322 ip = nodes[ 2 ].ip_address # ONOS3
323 deviceId = main.ONOScli1.getDevice( "6000" ).get( 'id' )
324 elif i == 7:
325 ip = nodes[ 5 ].ip_address # ONOS6
326 deviceId = main.ONOScli1.getDevice( "6007" ).get( 'id' )
327 elif i >= 8 and i <= 17:
328 ip = nodes[ 4 ].ip_address # ONOS5
329 dpid = '3' + str( i ).zfill( 3 )
330 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
331 elif i >= 18 and i <= 27:
332 ip = nodes[ 6 ].ip_address # ONOS7
333 dpid = '6' + str( i ).zfill( 3 )
334 deviceId = main.ONOScli1.getDevice( dpid ).get( 'id' )
335 elif i == 28:
336 ip = nodes[ 0 ].ip_address # ONOS1
337 deviceId = main.ONOScli1.getDevice( "2800" ).get( 'id' )
338 else:
339 main.log.error( "You didn't write an else statement for " +
340 "switch s" + str( i ) )
341 # Assign switch
342 assert deviceId, "No device id for s" + str( i ) + " in ONOS"
343 # TODO: make this controller dynamic
344 roleCall = roleCall and main.ONOScli1.deviceRole( deviceId,
345 ip )
Jon Hall390696c2015-05-05 17:13:41 -0700346 ipList.append( ip )
347 deviceList.append( deviceId )
Jon Hall58c76b72015-02-23 11:09:24 -0800348 except ( AttributeError, AssertionError ):
349 main.log.exception( "Something is wrong with ONOS device view" )
350 main.log.info( main.ONOScli1.devices() )
Jon Hall6aec96b2015-01-19 14:49:31 -0800351 utilities.assert_equals(
352 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800353 actual=roleCall,
Jon Hall6aec96b2015-01-19 14:49:31 -0800354 onpass="Re-assigned switch mastership to designated controller",
Jon Hall8f89dda2015-01-22 16:03:33 -0800355 onfail="Something wrong with deviceRole calls" )
Jon Hall94fd0472014-12-08 11:52:42 -0800356
Jon Hall390696c2015-05-05 17:13:41 -0700357 main.step( "Check mastership was correctly assigned" )
358 roleCheck = main.TRUE
359 # NOTE: This is due to the fact that device mastership change is not
360 # atomic and is actually a multi step process
361 time.sleep( 5 )
362 for i in range( len( ipList ) ):
363 ip = ipList[i]
364 deviceId = deviceList[i]
365 # Check assignment
366 master = main.ONOScli1.getRole( deviceId ).get( 'master' )
367 if ip in master:
368 roleCheck = roleCheck and main.TRUE
369 else:
370 roleCheck = roleCheck and main.FALSE
371 main.log.error( "Error, controller " + ip + " is not" +
372 " master " + "of device " +
373 str( deviceId ) + ". Master is " +
374 repr( master ) + "." )
Jon Hall6aec96b2015-01-19 14:49:31 -0800375 utilities.assert_equals(
376 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800377 actual=roleCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -0800378 onpass="Switches were successfully reassigned to designated " +
379 "controller",
380 onfail="Switches were not successfully reassigned" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800381 mastershipCheck = mastershipCheck and roleCall and roleCheck
382 utilities.assert_equals( expect=main.TRUE, actual=mastershipCheck,
Jon Hall21270ac2015-02-16 17:59:55 -0800383 onpass="Switch mastership correctly assigned",
384 onfail="Error in (re)assigning switch" +
385 " mastership" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800386
Jon Hall6aec96b2015-01-19 14:49:31 -0800387 def CASE3( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800388 """
389 Assign intents
Jon Hall73cf9cc2014-11-20 22:28:38 -0800390 """
391 import time
Jon Hallfebb1c72015-03-05 13:30:09 -0800392 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700393 assert numControllers, "numControllers not defined"
394 assert main, "main not defined"
395 assert utilities.assert_equals, "utilities.assert_equals not defined"
396 assert CLIs, "CLIs not defined"
397 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -0800398 main.log.report( "Adding host intents" )
399 main.case( "Adding host Intents" )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800400
Jon Hall390696c2015-05-05 17:13:41 -0700401 main.step( "Discovering Hosts( Via pingall for now )" )
Jon Hall6aec96b2015-01-19 14:49:31 -0800402 # FIXME: Once we have a host discovery mechanism, use that instead
Jon Hall73cf9cc2014-11-20 22:28:38 -0800403
Jon Hall6aec96b2015-01-19 14:49:31 -0800404 # install onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700405 main.step( "Install reactive forwarding app" )
406 installResults = CLIs[0].activateApp( "org.onosproject.fwd" )
407 utilities.assert_equals( expect=main.TRUE, actual=installResults,
408 onpass="Install fwd successful",
409 onfail="Install fwd failed" )
Jon Halla9d26da2015-03-30 16:45:32 -0700410
Jon Halla9d26da2015-03-30 16:45:32 -0700411 appCheck = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700412 threads = []
413 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700414 t = main.Thread( target=CLIs[i].appToIDCheck,
415 name="appToIDCheck-" + str( i ),
416 args=[] )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700417 threads.append( t )
418 t.start()
419
420 for t in threads:
421 t.join()
Jon Halla9d26da2015-03-30 16:45:32 -0700422 appCheck = appCheck and t.result
Jon Halla9d26da2015-03-30 16:45:32 -0700423 if appCheck != main.TRUE:
424 main.log.warn( CLIs[0].apps() )
425 main.log.warn( CLIs[0].appIDs() )
Jon Hall390696c2015-05-05 17:13:41 -0700426 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
427 onpass="App Ids seem to be correct",
428 onfail="Something is wrong with app Ids" )
Jon Hall94fd0472014-12-08 11:52:42 -0800429
Jon Hall6aec96b2015-01-19 14:49:31 -0800430 # REACTIVE FWD test
Jon Hall8f89dda2015-01-22 16:03:33 -0800431 pingResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -0700432 for i in range(2): # Retry if pingall fails first time
433 time1 = time.time()
434 pingResult = main.Mininet1.pingall()
435 utilities.assert_equals(
436 expect=main.TRUE,
437 actual=pingResult,
438 onpass="Reactive Pingall test passed",
Jon Hall390696c2015-05-05 17:13:41 -0700439 onfail="Reactive Pingall failed, " +
440 "one or more ping pairs failed" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700441 time2 = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700442 main.log.info( "Time for pingall: %2f seconds" %
443 ( time2 - time1 ) )
444 # timeout for fwd flows
445 time.sleep( 11 )
Jon Hall6aec96b2015-01-19 14:49:31 -0800446 # uninstall onos-app-fwd
Jon Hall390696c2015-05-05 17:13:41 -0700447 main.step( "Uninstall reactive forwarding app" )
448 uninstallResult = CLIs[0].deactivateApp( "org.onosproject.fwd" )
449 utilities.assert_equals( expect=main.TRUE, actual=uninstallResult,
450 onpass="Uninstall fwd successful",
451 onfail="Uninstall fwd failed" )
452 main.step( "Check app ids check" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700453 threads = []
454 for i in range( numControllers ):
Jon Halla9d26da2015-03-30 16:45:32 -0700455 t = main.Thread( target=CLIs[i].appToIDCheck,
456 name="appToIDCheck-" + str( i ),
457 args=[] )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700458 threads.append( t )
459 t.start()
Jon Hall73cf9cc2014-11-20 22:28:38 -0800460
Jon Hall5cfd23c2015-03-19 11:40:57 -0700461 for t in threads:
462 t.join()
Jon Halla9d26da2015-03-30 16:45:32 -0700463 appCheck = appCheck and t.result
Jon Halla9d26da2015-03-30 16:45:32 -0700464 if appCheck != main.TRUE:
465 main.log.warn( CLIs[0].apps() )
466 main.log.warn( CLIs[0].appIDs() )
Jon Hall390696c2015-05-05 17:13:41 -0700467 utilities.assert_equals( expect=main.TRUE, actual=appCheck,
468 onpass="App Ids seem to be correct",
469 onfail="Something is wrong with app Ids" )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700470
471 main.step( "Add host intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800472 intentIds = []
Jon Hall6aec96b2015-01-19 14:49:31 -0800473 # TODO: move the host numbers to params
Jon Hall58c76b72015-02-23 11:09:24 -0800474 # Maybe look at all the paths we ping?
Jon Hall8f89dda2015-01-22 16:03:33 -0800475 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800476 hostResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800477 for i in range( 8, 18 ):
478 main.log.info( "Adding host intent between h" + str( i ) +
479 " and h" + str( i + 10 ) )
480 host1 = "00:00:00:00:00:" + \
481 str( hex( i )[ 2: ] ).zfill( 2 ).upper()
482 host2 = "00:00:00:00:00:" + \
483 str( hex( i + 10 )[ 2: ] ).zfill( 2 ).upper()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800484 # NOTE: getHost can return None
485 host1Dict = main.ONOScli1.getHost( host1 )
486 host2Dict = main.ONOScli1.getHost( host2 )
487 host1Id = None
488 host2Id = None
489 if host1Dict and host2Dict:
490 host1Id = host1Dict.get( 'id', None )
491 host2Id = host2Dict.get( 'id', None )
Jon Hall8f89dda2015-01-22 16:03:33 -0800492 if host1Id and host2Id:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700493 nodeNum = ( i % 7 )
494 tmpId = CLIs[ nodeNum ].addHostIntent( host1Id, host2Id )
Jon Hall63604932015-02-26 17:09:50 -0800495 if tmpId:
496 main.log.info( "Added intent with id: " + tmpId )
497 intentIds.append( tmpId )
498 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700499 main.log.error( "addHostIntent returned: " +
500 repr( tmpId ) )
Jon Hall669173b2014-12-17 11:36:30 -0800501 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700502 main.log.error( "Error, getHost() failed for h" + str( i ) +
503 " and/or h" + str( i + 10 ) )
504 hosts = CLIs[ 0 ].hosts()
505 main.log.warn( "Hosts output: " )
506 try:
507 main.log.warn( json.dumps( json.loads( hosts ),
508 sort_keys=True,
509 indent=4,
510 separators=( ',', ': ' ) ) )
511 except ( ValueError, TypeError ):
512 main.log.warn( repr( hosts ) )
Jon Hall58c76b72015-02-23 11:09:24 -0800513 hostResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -0700514 # FIXME: DEBUG
515 intentStart = time.time()
Jon Hall58c76b72015-02-23 11:09:24 -0800516 onosIds = main.ONOScli1.getAllIntentsId()
517 main.log.info( "Submitted intents: " + str( intentIds ) )
518 main.log.info( "Intents in ONOS: " + str( onosIds ) )
519 for intent in intentIds:
520 if intent in onosIds:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700521 pass # intent submitted is in onos
Jon Hall58c76b72015-02-23 11:09:24 -0800522 else:
523 intentAddResult = False
Jon Halla9d26da2015-03-30 16:45:32 -0700524 # FIXME: DEBUG
525 if intentAddResult:
526 intentStop = time.time()
527 else:
528 intentStop = None
Jon Hall1b8f54a2015-02-04 13:24:20 -0800529 # Print the intent states
Jon Hall58c76b72015-02-23 11:09:24 -0800530 intents = main.ONOScli1.intents()
Jon Hall1b8f54a2015-02-04 13:24:20 -0800531 intentStates = []
Jon Hall5cfd23c2015-03-19 11:40:57 -0700532 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800533 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
534 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700535 try:
536 for intent in json.loads( intents ):
537 state = intent.get( 'state', None )
538 if "INSTALLED" not in state:
539 installedCheck = False
540 intentId = intent.get( 'id', None )
541 intentStates.append( ( intentId, state ) )
542 except ( ValueError, TypeError ):
543 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800544 # add submitted intents not in the store
545 tmplist = [ i for i, s in intentStates ]
546 missingIntents = False
547 for i in intentIds:
548 if i not in tmplist:
549 intentStates.append( ( i, " - " ) )
550 missingIntents = True
551 intentStates.sort()
552 for i, s in intentStates:
553 count += 1
554 main.log.info( "%-6s%-15s%-15s" %
555 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700556 leaders = main.ONOScli1.leaders()
557 try:
558 if leaders:
559 parsedLeaders = json.loads( leaders )
560 main.log.warn( json.dumps( parsedLeaders,
561 sort_keys=True,
562 indent=4,
563 separators=( ',', ': ' ) ) )
564 # check for all intent partitions
Jon Hall5cfd23c2015-03-19 11:40:57 -0700565 topics = []
566 for i in range( 14 ):
567 topics.append( "intent-partition-" + str( i ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700568 main.log.debug( topics )
569 ONOStopics = [ j['topic'] for j in parsedLeaders ]
570 for topic in topics:
571 if topic not in ONOStopics:
572 main.log.error( "Error: " + topic +
573 " not in leaders" )
574 else:
575 main.log.error( "leaders() returned None" )
576 except ( ValueError, TypeError ):
577 main.log.exception( "Error parsing leaders" )
578 main.log.error( repr( leaders ) )
579 partitions = main.ONOScli1.partitions()
580 try:
581 if partitions :
582 parsedPartitions = json.loads( partitions )
583 main.log.warn( json.dumps( parsedPartitions,
584 sort_keys=True,
585 indent=4,
586 separators=( ',', ': ' ) ) )
587 # TODO check for a leader in all paritions
588 # TODO check for consistency among nodes
589 else:
590 main.log.error( "partitions() returned None" )
591 except ( ValueError, TypeError ):
592 main.log.exception( "Error parsing partitions" )
593 main.log.error( repr( partitions ) )
Jon Hall63604932015-02-26 17:09:50 -0800594 pendingMap = main.ONOScli1.pendingMap()
Jon Hall5cfd23c2015-03-19 11:40:57 -0700595 try:
596 if pendingMap :
597 parsedPending = json.loads( pendingMap )
598 main.log.warn( json.dumps( parsedPending,
599 sort_keys=True,
600 indent=4,
601 separators=( ',', ': ' ) ) )
602 # TODO check something here?
603 else:
604 main.log.error( "pendingMap() returned None" )
605 except ( ValueError, TypeError ):
606 main.log.exception( "Error parsing pending map" )
607 main.log.error( repr( pendingMap ) )
608
Jon Hall58c76b72015-02-23 11:09:24 -0800609 intentAddResult = bool( pingResult and hostResult and intentAddResult
Jon Hall63604932015-02-26 17:09:50 -0800610 and not missingIntents and installedCheck )
Jon Hall6aec96b2015-01-19 14:49:31 -0800611 utilities.assert_equals(
612 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -0800613 actual=intentAddResult,
Jon Hall529a37f2015-01-28 10:02:00 -0800614 onpass="Pushed host intents to ONOS",
615 onfail="Error in pushing host intents to ONOS" )
Jon Hall390696c2015-05-05 17:13:41 -0700616 main.step( "Intent Anti-Entropy dispersion" )
Jon Halla9d26da2015-03-30 16:45:32 -0700617 for i in range(100):
Jon Hall390696c2015-05-05 17:13:41 -0700618 correct = True
Jon Halla9d26da2015-03-30 16:45:32 -0700619 main.log.info( "Submitted intents: " + str( sorted( intentIds ) ) )
Jon Hall390696c2015-05-05 17:13:41 -0700620 for cli in CLIs:
621 onosIds = []
622 ids = cli.getAllIntentsId()
623 onosIds.append( ids )
624 main.log.debug( "Intents in " + cli.name + ": " +
625 str( sorted( onosIds ) ) )
626 if sorted( ids ) != sorted( intentIds ):
627 correct = False
628 if correct:
Jon Halla9d26da2015-03-30 16:45:32 -0700629 break
630 else:
631 time.sleep(1)
Jon Halla9d26da2015-03-30 16:45:32 -0700632 if not intentStop:
633 intentStop = time.time()
Jon Hall390696c2015-05-05 17:13:41 -0700634 global gossipTime
Jon Halla9d26da2015-03-30 16:45:32 -0700635 gossipTime = intentStop - intentStart
636 main.log.info( "It took about " + str( gossipTime ) +
Jon Hall390696c2015-05-05 17:13:41 -0700637 " seconds for all intents to appear in each node" )
Jon Halla9d26da2015-03-30 16:45:32 -0700638 # FIXME: make this time configurable/calculate based off of number of
639 # nodes and gossip rounds
640 utilities.assert_greater_equals(
Jon Hall390696c2015-05-05 17:13:41 -0700641 expect=40, actual=gossipTime,
Jon Halla9d26da2015-03-30 16:45:32 -0700642 onpass="ECM anti-entropy for intents worked within " +
643 "expected time",
644 onfail="Intent ECM anti-entropy took too long" )
Jon Hall390696c2015-05-05 17:13:41 -0700645 if gossipTime <= 40:
Jon Hall678f4512015-03-31 09:48:31 -0700646 intentAddResult = True
Jon Hall58c76b72015-02-23 11:09:24 -0800647
Jon Hall63604932015-02-26 17:09:50 -0800648 if not intentAddResult or "key" in pendingMap:
Jon Hall58c76b72015-02-23 11:09:24 -0800649 import time
Jon Hall63604932015-02-26 17:09:50 -0800650 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800651 main.log.info( "Sleeping 60 seconds to see if intents are found" )
652 time.sleep( 60 )
653 onosIds = main.ONOScli1.getAllIntentsId()
654 main.log.info( "Submitted intents: " + str( intentIds ) )
655 main.log.info( "Intents in ONOS: " + str( onosIds ) )
656 # Print the intent states
657 intents = main.ONOScli1.intents()
658 intentStates = []
659 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
660 count = 0
Jon Hall5cfd23c2015-03-19 11:40:57 -0700661 try:
662 for intent in json.loads( intents ):
663 # Iter through intents of a node
664 state = intent.get( 'state', None )
665 if "INSTALLED" not in state:
666 installedCheck = False
667 intentId = intent.get( 'id', None )
668 intentStates.append( ( intentId, state ) )
669 except ( ValueError, TypeError ):
670 main.log.exception( "Error parsing intents" )
Jon Hall58c76b72015-02-23 11:09:24 -0800671 # add submitted intents not in the store
672 tmplist = [ i for i, s in intentStates ]
673 for i in intentIds:
674 if i not in tmplist:
675 intentStates.append( ( i, " - " ) )
676 intentStates.sort()
677 for i, s in intentStates:
678 count += 1
679 main.log.info( "%-6s%-15s%-15s" %
680 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700681 leaders = main.ONOScli1.leaders()
682 try:
683 if leaders:
684 parsedLeaders = json.loads( leaders )
685 main.log.warn( json.dumps( parsedLeaders,
686 sort_keys=True,
687 indent=4,
688 separators=( ',', ': ' ) ) )
689 # check for all intent partitions
690 # check for election
691 topics = []
692 for i in range( 14 ):
693 topics.append( "intent-partition-" + str( i ) )
694 # FIXME: this should only be after we start the app
695 topics.append( "org.onosproject.election" )
696 main.log.debug( topics )
697 ONOStopics = [ j['topic'] for j in parsedLeaders ]
698 for topic in topics:
699 if topic not in ONOStopics:
700 main.log.error( "Error: " + topic +
701 " not in leaders" )
702 else:
703 main.log.error( "leaders() returned None" )
704 except ( ValueError, TypeError ):
705 main.log.exception( "Error parsing leaders" )
706 main.log.error( repr( leaders ) )
707 partitions = main.ONOScli1.partitions()
708 try:
709 if partitions :
710 parsedPartitions = json.loads( partitions )
711 main.log.warn( json.dumps( parsedPartitions,
712 sort_keys=True,
713 indent=4,
714 separators=( ',', ': ' ) ) )
715 # TODO check for a leader in all paritions
716 # TODO check for consistency among nodes
717 else:
718 main.log.error( "partitions() returned None" )
719 except ( ValueError, TypeError ):
720 main.log.exception( "Error parsing partitions" )
721 main.log.error( repr( partitions ) )
722 pendingMap = main.ONOScli1.pendingMap()
723 try:
724 if pendingMap :
725 parsedPending = json.loads( pendingMap )
726 main.log.warn( json.dumps( parsedPending,
727 sort_keys=True,
728 indent=4,
729 separators=( ',', ': ' ) ) )
730 # TODO check something here?
731 else:
732 main.log.error( "pendingMap() returned None" )
733 except ( ValueError, TypeError ):
734 main.log.exception( "Error parsing pending map" )
735 main.log.error( repr( pendingMap ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800736
Jon Hall6aec96b2015-01-19 14:49:31 -0800737 def CASE4( self, main ):
Jon Hall73cf9cc2014-11-20 22:28:38 -0800738 """
739 Ping across added host intents
740 """
Jon Hallfebb1c72015-03-05 13:30:09 -0800741 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700742 import time
743 assert numControllers, "numControllers not defined"
744 assert main, "main not defined"
745 assert utilities.assert_equals, "utilities.assert_equals not defined"
746 assert CLIs, "CLIs not defined"
747 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -0800748 description = " Ping across added host intents"
Jon Hall6aec96b2015-01-19 14:49:31 -0800749 main.log.report( description )
750 main.case( description )
Jon Hall8f89dda2015-01-22 16:03:33 -0800751 PingResult = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -0800752 for i in range( 8, 18 ):
Jon Hall21270ac2015-02-16 17:59:55 -0800753 ping = main.Mininet1.pingHost( src="h" + str( i ),
754 target="h" + str( i + 10 ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800755 PingResult = PingResult and ping
Jon Hall6aec96b2015-01-19 14:49:31 -0800756 if ping == main.FALSE:
757 main.log.warn( "Ping failed between h" + str( i ) +
758 " and h" + str( i + 10 ) )
759 elif ping == main.TRUE:
760 main.log.info( "Ping test passed!" )
Jon Hall21270ac2015-02-16 17:59:55 -0800761 # Don't set PingResult or you'd override failures
Jon Hall8f89dda2015-01-22 16:03:33 -0800762 if PingResult == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800763 main.log.report(
764 "Intents have not been installed correctly, pings failed." )
Jon Hall58c76b72015-02-23 11:09:24 -0800765 # TODO: pretty print
Jon Hall5cfd23c2015-03-19 11:40:57 -0700766 main.log.warn( "ONOS1 intents: " )
767 try:
768 tmpIntents = main.ONOScli1.intents()
769 main.log.warn( json.dumps( json.loads( tmpIntents ),
770 sort_keys=True,
771 indent=4,
772 separators=( ',', ': ' ) ) )
773 except ( ValueError, TypeError ):
774 main.log.warn( repr( tmpIntents ) )
Jon Hall8f89dda2015-01-22 16:03:33 -0800775 if PingResult == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -0800776 main.log.report(
777 "Intents have been installed correctly and verified by pings" )
778 utilities.assert_equals(
779 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800780 actual=PingResult,
Jon Hall6aec96b2015-01-19 14:49:31 -0800781 onpass="Intents have been installed correctly and pings work",
782 onfail="Intents have not been installed correctly, pings failed." )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800783
Jon Hall63604932015-02-26 17:09:50 -0800784 installedCheck = True
Jon Hall58c76b72015-02-23 11:09:24 -0800785 if PingResult is not main.TRUE:
786 # Print the intent states
787 intents = main.ONOScli1.intents()
788 intentStates = []
789 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
790 count = 0
791 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700792 try:
793 for intent in json.loads( intents ):
794 state = intent.get( 'state', None )
795 if "INSTALLED" not in state:
796 installedCheck = False
797 intentId = intent.get( 'id', None )
798 intentStates.append( ( intentId, state ) )
799 except ( ValueError, TypeError ):
800 main.log.exception( "Error parsing intents." )
Jon Hall58c76b72015-02-23 11:09:24 -0800801 intentStates.sort()
802 for i, s in intentStates:
803 count += 1
804 main.log.info( "%-6s%-15s%-15s" %
805 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700806 leaders = main.ONOScli1.leaders()
807 try:
808 if leaders:
809 parsedLeaders = json.loads( leaders )
810 main.log.warn( json.dumps( parsedLeaders,
811 sort_keys=True,
812 indent=4,
813 separators=( ',', ': ' ) ) )
814 # check for all intent partitions
815 # check for election
816 topics = []
817 for i in range( 14 ):
818 topics.append( "intent-partition-" + str( i ) )
819 # FIXME: this should only be after we start the app
820 topics.append( "org.onosproject.election" )
821 main.log.debug( topics )
822 ONOStopics = [ j['topic'] for j in parsedLeaders ]
823 for topic in topics:
824 if topic not in ONOStopics:
825 main.log.error( "Error: " + topic +
826 " not in leaders" )
827 else:
828 main.log.error( "leaders() returned None" )
829 except ( ValueError, TypeError ):
830 main.log.exception( "Error parsing leaders" )
831 main.log.error( repr( leaders ) )
832 partitions = main.ONOScli1.partitions()
833 try:
834 if partitions :
835 parsedPartitions = json.loads( partitions )
836 main.log.warn( json.dumps( parsedPartitions,
837 sort_keys=True,
838 indent=4,
839 separators=( ',', ': ' ) ) )
840 # TODO check for a leader in all paritions
841 # TODO check for consistency among nodes
842 else:
843 main.log.error( "partitions() returned None" )
844 except ( ValueError, TypeError ):
845 main.log.exception( "Error parsing partitions" )
846 main.log.error( repr( partitions ) )
847 pendingMap = main.ONOScli1.pendingMap()
848 try:
849 if pendingMap :
850 parsedPending = json.loads( pendingMap )
851 main.log.warn( json.dumps( parsedPending,
852 sort_keys=True,
853 indent=4,
854 separators=( ',', ': ' ) ) )
855 # TODO check something here?
856 else:
857 main.log.error( "pendingMap() returned None" )
858 except ( ValueError, TypeError ):
859 main.log.exception( "Error parsing pending map" )
860 main.log.error( repr( pendingMap ) )
861
Jon Hall63604932015-02-26 17:09:50 -0800862 if not installedCheck:
Jon Hall5cfd23c2015-03-19 11:40:57 -0700863 main.log.info( "Waiting 60 seconds to see if the state of " +
864 "intents change" )
Jon Hall63604932015-02-26 17:09:50 -0800865 time.sleep( 60 )
866 # Print the intent states
867 intents = main.ONOScli1.intents()
868 intentStates = []
869 main.log.info( "%-6s%-15s%-15s" % ( 'Count', 'ID', 'State' ) )
870 count = 0
871 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700872 try:
873 for intent in json.loads( intents ):
874 state = intent.get( 'state', None )
875 if "INSTALLED" not in state:
876 installedCheck = False
877 intentId = intent.get( 'id', None )
878 intentStates.append( ( intentId, state ) )
879 except ( ValueError, TypeError ):
880 main.log.exception( "Error parsing intents." )
Jon Hall63604932015-02-26 17:09:50 -0800881 intentStates.sort()
882 for i, s in intentStates:
883 count += 1
884 main.log.info( "%-6s%-15s%-15s" %
885 ( str( count ), str( i ), str( s ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -0700886 leaders = main.ONOScli1.leaders()
887 try:
888 if leaders:
889 parsedLeaders = json.loads( leaders )
890 main.log.warn( json.dumps( parsedLeaders,
891 sort_keys=True,
892 indent=4,
893 separators=( ',', ': ' ) ) )
894 # check for all intent partitions
895 # check for election
896 topics = []
897 for i in range( 14 ):
898 topics.append( "intent-partition-" + str( i ) )
899 # FIXME: this should only be after we start the app
900 topics.append( "org.onosproject.election" )
901 main.log.debug( topics )
902 ONOStopics = [ j['topic'] for j in parsedLeaders ]
903 for topic in topics:
904 if topic not in ONOStopics:
905 main.log.error( "Error: " + topic +
906 " not in leaders" )
907 else:
908 main.log.error( "leaders() returned None" )
909 except ( ValueError, TypeError ):
910 main.log.exception( "Error parsing leaders" )
911 main.log.error( repr( leaders ) )
912 partitions = main.ONOScli1.partitions()
913 try:
914 if partitions :
915 parsedPartitions = json.loads( partitions )
916 main.log.warn( json.dumps( parsedPartitions,
917 sort_keys=True,
918 indent=4,
919 separators=( ',', ': ' ) ) )
920 # TODO check for a leader in all paritions
921 # TODO check for consistency among nodes
922 else:
923 main.log.error( "partitions() returned None" )
924 except ( ValueError, TypeError ):
925 main.log.exception( "Error parsing partitions" )
926 main.log.error( repr( partitions ) )
927 pendingMap = main.ONOScli1.pendingMap()
928 try:
929 if pendingMap :
930 parsedPending = json.loads( pendingMap )
931 main.log.warn( json.dumps( parsedPending,
932 sort_keys=True,
933 indent=4,
934 separators=( ',', ': ' ) ) )
935 # TODO check something here?
936 else:
937 main.log.error( "pendingMap() returned None" )
938 except ( ValueError, TypeError ):
939 main.log.exception( "Error parsing pending map" )
940 main.log.error( repr( pendingMap ) )
Jon Hall390696c2015-05-05 17:13:41 -0700941 main.log.debug( CLIs[0].flows( jsonFormat=False ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -0800942
Jon Hall6aec96b2015-01-19 14:49:31 -0800943 def CASE5( self, main ):
944 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800945 Reading state of ONOS
Jon Hall6aec96b2015-01-19 14:49:31 -0800946 """
Jon Hall73cf9cc2014-11-20 22:28:38 -0800947 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -0700948 import time
949 assert numControllers, "numControllers not defined"
950 assert main, "main not defined"
951 assert utilities.assert_equals, "utilities.assert_equals not defined"
952 assert CLIs, "CLIs not defined"
953 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -0800954 # assumes that sts is already in you PYTHONPATH
955 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -0800956
Jon Hall6aec96b2015-01-19 14:49:31 -0800957 main.log.report( "Setting up and gathering data for current state" )
958 main.case( "Setting up and gathering data for current state" )
959 # The general idea for this test case is to pull the state of
960 # ( intents,flows, topology,... ) from each ONOS node
Jon Hall5cfd23c2015-03-19 11:40:57 -0700961 # We can then compare them with each other and also with past states
Jon Hall73cf9cc2014-11-20 22:28:38 -0800962
Jon Hall5cfd23c2015-03-19 11:40:57 -0700963 main.step( "Check that each switch has a master" )
Jon Hall8f89dda2015-01-22 16:03:33 -0800964 global mastershipState
Jon Hall5cfd23c2015-03-19 11:40:57 -0700965 mastershipState = '[]'
Jon Hall94fd0472014-12-08 11:52:42 -0800966
Jon Hall6aec96b2015-01-19 14:49:31 -0800967 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -0700968 rolesNotNull = main.TRUE
969 threads = []
970 for i in range( numControllers ):
971 t = main.Thread( target=CLIs[i].rolesNotNull,
972 name="rolesNotNull-" + str( i ),
973 args=[] )
974 threads.append( t )
975 t.start()
976
977 for t in threads:
978 t.join()
979 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -0800980 utilities.assert_equals(
981 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -0800982 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -0800983 onpass="Each device has a master",
984 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -0800985
Jon Hall5cfd23c2015-03-19 11:40:57 -0700986 main.step( "Get the Mastership of each switch from each controller" )
987 ONOSMastership = []
988 mastershipCheck = main.FALSE
989 consistentMastership = True
990 rolesResults = True
991 threads = []
992 for i in range( numControllers ):
993 t = main.Thread( target=CLIs[i].roles,
994 name="roles-" + str( i ),
995 args=[] )
996 threads.append( t )
997 t.start()
998
999 for t in threads:
1000 t.join()
1001 ONOSMastership.append( t.result )
1002
1003 for i in range( numControllers ):
1004 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1005 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1006 " roles" )
1007 main.log.warn(
1008 "ONOS" + str( i + 1 ) + " mastership response: " +
1009 repr( ONOSMastership[i] ) )
1010 rolesResults = False
1011 utilities.assert_equals(
1012 expect=True,
1013 actual=rolesResults,
1014 onpass="No error in reading roles output",
1015 onfail="Error in reading roles from ONOS" )
1016
1017 main.step( "Check for consistency in roles from each controller" )
1018 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall6aec96b2015-01-19 14:49:31 -08001019 main.log.report(
1020 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001021 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001022 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001023 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001024 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001025 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001026 onpass="Switch roles are consistent across all ONOS nodes",
1027 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001028
Jon Hall5cfd23c2015-03-19 11:40:57 -07001029 if rolesResults and not consistentMastership:
1030 for i in range( numControllers ):
1031 try:
1032 main.log.warn(
1033 "ONOS" + str( i + 1 ) + " roles: ",
1034 json.dumps(
1035 json.loads( ONOSMastership[ i ] ),
1036 sort_keys=True,
1037 indent=4,
1038 separators=( ',', ': ' ) ) )
1039 except ( ValueError, TypeError ):
1040 main.log.warn( repr( ONOSMastership[ i ] ) )
1041 elif rolesResults and consistentMastership:
1042 mastershipCheck = main.TRUE
1043 mastershipState = ONOSMastership[ 0 ]
1044
Jon Hall6aec96b2015-01-19 14:49:31 -08001045 main.step( "Get the intents from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001046 global intentState
1047 intentState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001048 ONOSIntents = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001049 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001050 consistentIntents = True
1051 intentsResults = True
1052 threads = []
1053 for i in range( numControllers ):
1054 t = main.Thread( target=CLIs[i].intents,
1055 name="intents-" + str( i ),
1056 args=[],
1057 kwargs={ 'jsonFormat': True } )
1058 threads.append( t )
1059 t.start()
1060
1061 for t in threads:
1062 t.join()
1063 ONOSIntents.append( t.result )
1064
1065 for i in range( numControllers ):
1066 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1067 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1068 " intents" )
1069 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1070 repr( ONOSIntents[ i ] ) )
1071 intentsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001072 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001073 expect=True,
1074 actual=intentsResults,
1075 onpass="No error in reading intents output",
1076 onfail="Error in reading intents from ONOS" )
1077
1078 main.step( "Check for consistency in Intents from each controller" )
1079 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1080 main.log.report( "Intents are consistent across all ONOS " +
1081 "nodes" )
1082 else:
1083 consistentIntents = False
1084 main.log.report( "Intents not consistent" )
1085 utilities.assert_equals(
1086 expect=True,
1087 actual=consistentIntents,
Jon Hall6aec96b2015-01-19 14:49:31 -08001088 onpass="Intents are consistent across all ONOS nodes",
1089 onfail="ONOS nodes have different views of intents" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001090
Jon Hall390696c2015-05-05 17:13:41 -07001091 if intentsResults:
1092 # Try to make it easy to figure out what is happening
1093 #
1094 # Intent ONOS1 ONOS2 ...
1095 # 0x01 INSTALLED INSTALLING
1096 # ... ... ...
1097 # ... ... ...
1098 title = " Id"
1099 for n in range( numControllers ):
1100 title += " " * 10 + "ONOS" + str( n + 1 )
1101 main.log.warn( title )
1102 # get all intent keys in the cluster
1103 keys = []
1104 for nodeStr in ONOSIntents:
1105 node = json.loads( nodeStr )
1106 for intent in node:
1107 keys.append( intent.get( 'id' ) )
1108 keys = set( keys )
1109 for key in keys:
1110 row = "%-13s" % key
1111 for nodeStr in ONOSIntents:
1112 node = json.loads( nodeStr )
1113 for intent in node:
1114 if intent.get( 'id', "Error" ) == key:
1115 row += "%-15s" % intent.get( 'state' )
1116 main.log.warn( row )
1117 # End table view
1118
Jon Hall5cfd23c2015-03-19 11:40:57 -07001119 if intentsResults and not consistentIntents:
Jon Hall390696c2015-05-05 17:13:41 -07001120 # print the json objects
Jon Hall5cfd23c2015-03-19 11:40:57 -07001121 n = len(ONOSIntents)
Jon Hall390696c2015-05-05 17:13:41 -07001122 main.log.debug( "ONOS" + str( n ) + " intents: " )
1123 main.log.debug( json.dumps( json.loads( ONOSIntents[ -1 ] ),
1124 sort_keys=True,
1125 indent=4,
1126 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001127 for i in range( numControllers ):
1128 if ONOSIntents[ i ] != ONOSIntents[ -1 ]:
Jon Hall390696c2015-05-05 17:13:41 -07001129 main.log.debug( "ONOS" + str( i + 1 ) + " intents: " )
1130 main.log.debug( json.dumps( json.loads( ONOSIntents[i] ),
1131 sort_keys=True,
1132 indent=4,
1133 separators=( ',', ': ' ) ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001134 else:
Jon Hall390696c2015-05-05 17:13:41 -07001135 main.log.debug( nodes[ i ].name + " intents match ONOS" +
1136 str( n ) + " intents" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001137 elif intentsResults and consistentIntents:
1138 intentCheck = main.TRUE
1139 intentState = ONOSIntents[ 0 ]
1140
Jon Hall6aec96b2015-01-19 14:49:31 -08001141 main.step( "Get the flows from each controller" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001142 global flowState
1143 flowState = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001144 ONOSFlows = []
1145 ONOSFlowsJson = []
Jon Hall8f89dda2015-01-22 16:03:33 -08001146 flowCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001147 consistentFlows = True
1148 flowsResults = True
1149 threads = []
1150 for i in range( numControllers ):
1151 t = main.Thread( target=CLIs[i].flows,
1152 name="flows-" + str( i ),
1153 args=[],
1154 kwargs={ 'jsonFormat': True } )
1155 threads.append( t )
1156 t.start()
1157
Jon Halla9d26da2015-03-30 16:45:32 -07001158 # NOTE: Flows command can take some time to run
Jon Hall5cfd23c2015-03-19 11:40:57 -07001159 time.sleep(30)
1160 for t in threads:
1161 t.join()
1162 result = t.result
1163 ONOSFlows.append( result )
1164
1165 for i in range( numControllers ):
1166 num = str( i + 1 )
1167 if not ONOSFlows[ i ] or "Error" in ONOSFlows[ i ]:
1168 main.log.report( "Error in getting ONOS" + num + " flows" )
1169 main.log.warn( "ONOS" + num + " flows response: " +
1170 repr( ONOSFlows[ i ] ) )
1171 flowsResults = False
1172 ONOSFlowsJson.append( None )
Jon Hall58c76b72015-02-23 11:09:24 -08001173 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001174 try:
1175 ONOSFlowsJson.append( json.loads( ONOSFlows[ i ] ) )
1176 except ( ValueError, TypeError ):
1177 # FIXME: change this to log.error?
1178 main.log.exception( "Error in parsing ONOS" + num +
1179 " response as json." )
1180 main.log.error( repr( ONOSFlows[ i ] ) )
1181 ONOSFlowsJson.append( None )
1182 flowsResults = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001183 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001184 expect=True,
1185 actual=flowsResults,
1186 onpass="No error in reading flows output",
1187 onfail="Error in reading flows from ONOS" )
1188
1189 main.step( "Check for consistency in Flows from each controller" )
1190 tmp = [ len( i ) == len( ONOSFlowsJson[ 0 ] ) for i in ONOSFlowsJson ]
1191 if all( tmp ):
1192 main.log.report( "Flow count is consistent across all ONOS nodes" )
1193 else:
1194 consistentFlows = False
1195 utilities.assert_equals(
1196 expect=True,
1197 actual=consistentFlows,
Jon Hall6aec96b2015-01-19 14:49:31 -08001198 onpass="The flow count is consistent across all ONOS nodes",
1199 onfail="ONOS nodes have different flow counts" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001200
Jon Hall5cfd23c2015-03-19 11:40:57 -07001201 if flowsResults and not consistentFlows:
1202 for i in range( numControllers ):
1203 try:
1204 main.log.warn(
1205 "ONOS" + str( i + 1 ) + " flows: " +
1206 json.dumps( json.loads( ONOSFlows[i] ), sort_keys=True,
1207 indent=4, separators=( ',', ': ' ) ) )
1208 except ( ValueError, TypeError ):
1209 main.log.warn(
1210 "ONOS" + str( i + 1 ) + " flows: " +
1211 repr( ONOSFlows[ i ] ) )
1212 elif flowsResults and consistentFlows:
1213 flowCheck = main.TRUE
1214 flowState = ONOSFlows[ 0 ]
1215
Jon Hall6aec96b2015-01-19 14:49:31 -08001216 main.step( "Get the OF Table entries" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001217 global flows
Jon Hall6aec96b2015-01-19 14:49:31 -08001218 flows = []
1219 for i in range( 1, 29 ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001220 flows.append( main.Mininet2.getFlowTable( 1.3, "s" + str( i ) ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001221 if flowCheck == main.FALSE:
1222 for table in flows:
1223 main.log.warn( table )
Jon Hall6aec96b2015-01-19 14:49:31 -08001224 # TODO: Compare switch flow tables with ONOS flow tables
Jon Hall73cf9cc2014-11-20 22:28:38 -08001225
Jon Hall6aec96b2015-01-19 14:49:31 -08001226 main.step( "Start continuous pings" )
1227 main.Mininet2.pingLong(
1228 src=main.params[ 'PING' ][ 'source1' ],
1229 target=main.params[ 'PING' ][ 'target1' ],
1230 pingTime=500 )
1231 main.Mininet2.pingLong(
1232 src=main.params[ 'PING' ][ 'source2' ],
1233 target=main.params[ 'PING' ][ 'target2' ],
1234 pingTime=500 )
1235 main.Mininet2.pingLong(
1236 src=main.params[ 'PING' ][ 'source3' ],
1237 target=main.params[ 'PING' ][ 'target3' ],
1238 pingTime=500 )
1239 main.Mininet2.pingLong(
1240 src=main.params[ 'PING' ][ 'source4' ],
1241 target=main.params[ 'PING' ][ 'target4' ],
1242 pingTime=500 )
1243 main.Mininet2.pingLong(
1244 src=main.params[ 'PING' ][ 'source5' ],
1245 target=main.params[ 'PING' ][ 'target5' ],
1246 pingTime=500 )
1247 main.Mininet2.pingLong(
1248 src=main.params[ 'PING' ][ 'source6' ],
1249 target=main.params[ 'PING' ][ 'target6' ],
1250 pingTime=500 )
1251 main.Mininet2.pingLong(
1252 src=main.params[ 'PING' ][ 'source7' ],
1253 target=main.params[ 'PING' ][ 'target7' ],
1254 pingTime=500 )
1255 main.Mininet2.pingLong(
1256 src=main.params[ 'PING' ][ 'source8' ],
1257 target=main.params[ 'PING' ][ 'target8' ],
1258 pingTime=500 )
1259 main.Mininet2.pingLong(
1260 src=main.params[ 'PING' ][ 'source9' ],
1261 target=main.params[ 'PING' ][ 'target9' ],
1262 pingTime=500 )
1263 main.Mininet2.pingLong(
1264 src=main.params[ 'PING' ][ 'source10' ],
1265 target=main.params[ 'PING' ][ 'target10' ],
1266 pingTime=500 )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001267
Jon Hall6aec96b2015-01-19 14:49:31 -08001268 main.step( "Create TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001269 ctrls = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001270 for node in nodes:
1271 temp = ( node, node.name, node.ip_address, 6633 )
1272 ctrls.append( temp )
1273 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001274
Jon Hall6aec96b2015-01-19 14:49:31 -08001275 main.step( "Collecting topology information from ONOS" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001276 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001277 threads = []
1278 for i in range( numControllers ):
1279 t = main.Thread( target=CLIs[i].devices,
1280 name="devices-" + str( i ),
1281 args=[ ] )
1282 threads.append( t )
1283 t.start()
1284
1285 for t in threads:
1286 t.join()
1287 devices.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001288 hosts = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001289 threads = []
1290 for i in range( numControllers ):
1291 t = main.Thread( target=CLIs[i].hosts,
1292 name="hosts-" + str( i ),
1293 args=[ ] )
1294 threads.append( t )
1295 t.start()
1296
1297 for t in threads:
1298 t.join()
1299 try:
1300 hosts.append( json.loads( t.result ) )
1301 except ( ValueError, TypeError ):
1302 # FIXME: better handling of this, print which node
1303 # Maybe use thread name?
1304 main.log.exception( "Error parsing json output of hosts" )
1305 # FIXME: should this be an empty json object instead?
1306 hosts.append( None )
1307
Jon Hall73cf9cc2014-11-20 22:28:38 -08001308 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001309 threads = []
1310 for i in range( numControllers ):
1311 t = main.Thread( target=CLIs[i].ports,
1312 name="ports-" + str( i ),
1313 args=[ ] )
1314 threads.append( t )
1315 t.start()
1316
1317 for t in threads:
1318 t.join()
1319 ports.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001320 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001321 threads = []
1322 for i in range( numControllers ):
1323 t = main.Thread( target=CLIs[i].links,
1324 name="links-" + str( i ),
1325 args=[ ] )
1326 threads.append( t )
1327 t.start()
1328
1329 for t in threads:
1330 t.join()
1331 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001332 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001333 threads = []
1334 for i in range( numControllers ):
1335 t = main.Thread( target=CLIs[i].clusters,
1336 name="clusters-" + str( i ),
1337 args=[ ] )
1338 threads.append( t )
1339 t.start()
1340
1341 for t in threads:
1342 t.join()
1343 clusters.append( t.result )
Jon Hall529a37f2015-01-28 10:02:00 -08001344 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08001345
Jon Hall6aec96b2015-01-19 14:49:31 -08001346 # hosts
Jon Hall390696c2015-05-05 17:13:41 -07001347 main.step( "Host view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001348 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001349 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001350 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001351 if "Error" not in hosts[ controller ]:
1352 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001353 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001354 else: # hosts not consistent
1355 main.log.report( "hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001356 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001357 " is inconsistent with ONOS1" )
1358 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001359 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001360
1361 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001362 main.log.report( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001363 controllerStr )
1364 consistentHostsResult = main.FALSE
1365 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001366 " hosts response: " +
1367 repr( hosts[ controller ] ) )
1368 utilities.assert_equals(
1369 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001370 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001371 onpass="Hosts view is consistent across all ONOS nodes",
1372 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08001373
Jon Hall390696c2015-05-05 17:13:41 -07001374 main.step( "Each host has an IP address" )
Jon Hall58c76b72015-02-23 11:09:24 -08001375 ipResult = main.TRUE
1376 for controller in range( 0, len( hosts ) ):
1377 controllerStr = str( controller + 1 )
1378 for host in hosts[ controller ]:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001379 if not host.get( 'ips', [ ] ):
1380 main.log.error( "DEBUG:Error with host ips on controller" +
1381 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001382 ipResult = main.FALSE
1383 utilities.assert_equals(
1384 expect=main.TRUE,
1385 actual=ipResult,
1386 onpass="The ips of the hosts aren't empty",
1387 onfail="The ip of at least one host is missing" )
1388
Jon Hall6aec96b2015-01-19 14:49:31 -08001389 # Strongly connected clusters of devices
Jon Hall390696c2015-05-05 17:13:41 -07001390 main.step( "Cluster view is consistent across ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001391 consistentClustersResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08001392 for controller in range( len( clusters ) ):
Jon Hall5cfd23c2015-03-19 11:40:57 -07001393 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001394 if "Error" not in clusters[ controller ]:
1395 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08001396 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08001397 else: # clusters not consistent
Jon Hall5cfd23c2015-03-19 11:40:57 -07001398 main.log.report( "clusters from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001399 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001400 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001401
1402 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001403 main.log.report( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001404 "from ONOS" + controllerStr )
1405 consistentClustersResult = main.FALSE
1406 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08001407 " clusters response: " +
1408 repr( clusters[ controller ] ) )
1409 utilities.assert_equals(
1410 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001411 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001412 onpass="Clusters view is consistent across all ONOS nodes",
1413 onfail="ONOS nodes have different views of clusters" )
1414 # there should always only be one cluster
Jon Hall390696c2015-05-05 17:13:41 -07001415 main.step( "Cluster view correct across ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001416 try:
1417 numClusters = len( json.loads( clusters[ 0 ] ) )
1418 except ( ValueError, TypeError ):
1419 main.log.exception( "Error parsing clusters[0]: " +
1420 repr( clusters[ 0 ] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001421 clusterResults = main.FALSE
1422 if numClusters == 1:
1423 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001424 utilities.assert_equals(
1425 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08001426 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08001427 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08001428 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08001429
Jon Hall6aec96b2015-01-19 14:49:31 -08001430 main.step( "Comparing ONOS topology to MN" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001431 devicesResults = main.TRUE
1432 portsResults = main.TRUE
1433 linksResults = main.TRUE
1434 for controller in range( numControllers ):
1435 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001436 if devices[ controller ] or "Error" not in devices[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001437 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08001438 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001439 json.loads( devices[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001440 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001441 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001442 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001443 actual=currentDevicesResult,
1444 onpass="ONOS" + controllerStr +
1445 " Switches view is correct",
1446 onfail="ONOS" + controllerStr +
1447 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001448
Jon Hall6aec96b2015-01-19 14:49:31 -08001449 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001450 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08001451 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001452 json.loads( ports[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001453 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001454 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001455 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001456 actual=currentPortsResult,
1457 onpass="ONOS" + controllerStr +
1458 " ports view is correct",
1459 onfail="ONOS" + controllerStr +
1460 " ports view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001461
Jon Hall6aec96b2015-01-19 14:49:31 -08001462 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001463 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08001464 MNTopo,
Jon Hall5cfd23c2015-03-19 11:40:57 -07001465 json.loads( links[ controller ] ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001466 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08001467 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001468 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08001469 actual=currentLinksResult,
1470 onpass="ONOS" + controllerStr +
1471 " links view is correct",
1472 onfail="ONOS" + controllerStr +
1473 " links view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001474
Jon Hall8f89dda2015-01-22 16:03:33 -08001475 devicesResults = devicesResults and currentDevicesResult
1476 portsResults = portsResults and currentPortsResult
1477 linksResults = linksResults and currentLinksResult
Jon Hall73cf9cc2014-11-20 22:28:38 -08001478
Jon Hall5cfd23c2015-03-19 11:40:57 -07001479 topoResult = ( devicesResults and portsResults and linksResults
1480 and consistentHostsResult and consistentClustersResult
1481 and clusterResults and ipResult )
Jon Hall8f89dda2015-01-22 16:03:33 -08001482 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08001483 onpass="Topology Check Test successful",
1484 onfail="Topology Check Test NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001485
Jon Hall6aec96b2015-01-19 14:49:31 -08001486 def CASE6( self, main ):
1487 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001488 The Failure case.
Jon Hall6aec96b2015-01-19 14:49:31 -08001489 """
Jon Hall94fd0472014-12-08 11:52:42 -08001490 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001491 assert numControllers, "numControllers not defined"
1492 assert main, "main not defined"
1493 assert utilities.assert_equals, "utilities.assert_equals not defined"
1494 assert CLIs, "CLIs not defined"
1495 assert nodes, "nodes not defined"
Jon Hall5cfd23c2015-03-19 11:40:57 -07001496 main.case( "Restart minority of ONOS nodes" )
Jon Hall390696c2015-05-05 17:13:41 -07001497 main.step( "Killing 3 ONOS nodes" )
1498 # TODO: Randomize these nodes or base this on partitions
Jon Hall5cfd23c2015-03-19 11:40:57 -07001499 # TODO: use threads in this case
Jon Hall390696c2015-05-05 17:13:41 -07001500 killResults = main.ONOSbench.onosKill( nodes[0].ip_address )
Jon Hall6aec96b2015-01-19 14:49:31 -08001501 time.sleep( 10 )
Jon Hall390696c2015-05-05 17:13:41 -07001502 killResults = killResults and\
1503 main.ONOSbench.onosKill( nodes[1].ip_address )
Jon Hall6aec96b2015-01-19 14:49:31 -08001504 time.sleep( 10 )
Jon Hall390696c2015-05-05 17:13:41 -07001505 killResults = killResults and\
1506 main.ONOSbench.onosKill( nodes[2].ip_address )
1507 utilities.assert_equals( expect=main.TRUE, actual=killResults,
1508 onpass="ONOS Killed successfully",
1509 onfail="ONOS kill NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001510
Jon Hall6aec96b2015-01-19 14:49:31 -08001511 main.step( "Checking if ONOS is up yet" )
Jon Hallffb386d2014-11-21 13:43:38 -08001512 count = 0
Jon Hall8f89dda2015-01-22 16:03:33 -08001513 onosIsupResult = main.FALSE
1514 while onosIsupResult == main.FALSE and count < 10:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001515 onos1Isup = main.ONOSbench.isup( nodes[0].ip_address )
1516 onos2Isup = main.ONOSbench.isup( nodes[1].ip_address )
1517 onos3Isup = main.ONOSbench.isup( nodes[2].ip_address )
Jon Hall8f89dda2015-01-22 16:03:33 -08001518 onosIsupResult = onos1Isup and onos2Isup and onos3Isup
Jon Hallffb386d2014-11-21 13:43:38 -08001519 count = count + 1
Jon Hall73cf9cc2014-11-20 22:28:38 -08001520 # TODO: if it becomes an issue, we can retry this step a few times
Jon Hall390696c2015-05-05 17:13:41 -07001521 utilities.assert_equals( expect=main.TRUE, actual=onosIsupResult,
1522 onpass="ONOS restarted successfully",
1523 onfail="ONOS restart NOT successful" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001524
Jon Hall390696c2015-05-05 17:13:41 -07001525 main.step( "Restarting ONOS CLIs" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001526 cliResult1 = main.ONOScli1.startOnosCli( nodes[0].ip_address )
1527 cliResult2 = main.ONOScli2.startOnosCli( nodes[1].ip_address )
1528 cliResult3 = main.ONOScli3.startOnosCli( nodes[2].ip_address )
Jon Hall8f89dda2015-01-22 16:03:33 -08001529 cliResults = cliResult1 and cliResult2 and cliResult3
Jon Hall390696c2015-05-05 17:13:41 -07001530 utilities.assert_equals( expect=main.TRUE, actual=cliResults,
1531 onpass="ONOS cli restarted",
1532 onfail="ONOS cli did not restart" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001533
Jon Hall21270ac2015-02-16 17:59:55 -08001534 # Grab the time of restart so we chan check how long the gossip
1535 # protocol has had time to work
1536 main.restartTime = time.time()
Jon Hall73cf9cc2014-11-20 22:28:38 -08001537
Jon Hall6aec96b2015-01-19 14:49:31 -08001538 def CASE7( self, main ):
1539 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001540 Check state after ONOS failure
Jon Hall6aec96b2015-01-19 14:49:31 -08001541 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001542 import json
Jon Hall5cfd23c2015-03-19 11:40:57 -07001543 assert numControllers, "numControllers not defined"
1544 assert main, "main not defined"
1545 assert utilities.assert_equals, "utilities.assert_equals not defined"
1546 assert CLIs, "CLIs not defined"
1547 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08001548 main.case( "Running ONOS Constant State Tests" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001549
Jon Hall5cfd23c2015-03-19 11:40:57 -07001550 main.step( "Check that each switch has a master" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001551 # Assert that each device has a master
Jon Hall5cfd23c2015-03-19 11:40:57 -07001552 rolesNotNull = main.TRUE
1553 threads = []
1554 for i in range( numControllers ):
1555 t = main.Thread( target=CLIs[i].rolesNotNull,
1556 name="rolesNotNull-" + str( i ),
1557 args=[ ] )
1558 threads.append( t )
1559 t.start()
1560
1561 for t in threads:
1562 t.join()
1563 rolesNotNull = rolesNotNull and t.result
Jon Hall6aec96b2015-01-19 14:49:31 -08001564 utilities.assert_equals(
1565 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001566 actual=rolesNotNull,
Jon Hall6aec96b2015-01-19 14:49:31 -08001567 onpass="Each device has a master",
1568 onfail="Some devices don't have a master assigned" )
Jon Hall94fd0472014-12-08 11:52:42 -08001569
Jon Hall390696c2015-05-05 17:13:41 -07001570 main.step( "Read device roles from ONOS" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001571 ONOSMastership = []
1572 mastershipCheck = main.FALSE
1573 consistentMastership = True
1574 rolesResults = True
1575 threads = []
1576 for i in range( numControllers ):
1577 t = main.Thread( target=CLIs[i].roles,
1578 name="roles-" + str( i ),
1579 args=[] )
1580 threads.append( t )
1581 t.start()
1582
1583 for t in threads:
1584 t.join()
1585 ONOSMastership.append( t.result )
1586
1587 for i in range( numControllers ):
1588 if not ONOSMastership[i] or "Error" in ONOSMastership[i]:
1589 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1590 " roles" )
1591 main.log.warn(
1592 "ONOS" + str( i + 1 ) + " mastership response: " +
1593 repr( ONOSMastership[i] ) )
1594 rolesResults = False
1595 utilities.assert_equals(
1596 expect=True,
1597 actual=rolesResults,
1598 onpass="No error in reading roles output",
1599 onfail="Error in reading roles from ONOS" )
1600
1601 main.step( "Check for consistency in roles from each controller" )
1602 if all([ i == ONOSMastership[ 0 ] for i in ONOSMastership ] ):
Jon Hall6aec96b2015-01-19 14:49:31 -08001603 main.log.report(
1604 "Switch roles are consistent across all ONOS nodes" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001605 else:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001606 consistentMastership = False
Jon Hall6aec96b2015-01-19 14:49:31 -08001607 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001608 expect=True,
Jon Hall8f89dda2015-01-22 16:03:33 -08001609 actual=consistentMastership,
Jon Hall6aec96b2015-01-19 14:49:31 -08001610 onpass="Switch roles are consistent across all ONOS nodes",
1611 onfail="ONOS nodes have different views of switch roles" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001612
Jon Hall5cfd23c2015-03-19 11:40:57 -07001613 if rolesResults and not consistentMastership:
1614 for i in range( numControllers ):
1615 main.log.warn(
1616 "ONOS" + str( i + 1 ) + " roles: ",
1617 json.dumps(
1618 json.loads( ONOSMastership[ i ] ),
1619 sort_keys=True,
1620 indent=4,
1621 separators=( ',', ': ' ) ) )
1622 elif rolesResults and not consistentMastership:
1623 mastershipCheck = main.TRUE
1624
Jon Hall73cf9cc2014-11-20 22:28:38 -08001625 description2 = "Compare switch roles from before failure"
Jon Hall6aec96b2015-01-19 14:49:31 -08001626 main.step( description2 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001627 try:
1628 currentJson = json.loads( ONOSMastership[0] )
1629 oldJson = json.loads( mastershipState )
1630 except ( ValueError, TypeError ):
1631 main.log.exception( "Something is wrong with parsing " +
1632 "ONOSMastership[0] or mastershipState" )
1633 main.log.error( "ONOSMastership[0]: " + repr( ONOSMastership[0] ) )
1634 main.log.error( "mastershipState" + repr( mastershipState ) )
1635 main.cleanup()
1636 main.exit()
Jon Hall8f89dda2015-01-22 16:03:33 -08001637 mastershipCheck = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08001638 for i in range( 1, 29 ):
1639 switchDPID = str(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001640 main.Mininet1.getSwitchDPID( switch="s" + str( i ) ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001641 current = [ switch[ 'master' ] for switch in currentJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001642 if switchDPID in switch[ 'id' ] ]
Jon Hall8f89dda2015-01-22 16:03:33 -08001643 old = [ switch[ 'master' ] for switch in oldJson
Jon Hall6aec96b2015-01-19 14:49:31 -08001644 if switchDPID in switch[ 'id' ] ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08001645 if current == old:
Jon Hall8f89dda2015-01-22 16:03:33 -08001646 mastershipCheck = mastershipCheck and main.TRUE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001647 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08001648 main.log.warn( "Mastership of switch %s changed" % switchDPID )
Jon Hall8f89dda2015-01-22 16:03:33 -08001649 mastershipCheck = main.FALSE
1650 if mastershipCheck == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001651 main.log.report( "Mastership of Switches was not changed" )
1652 utilities.assert_equals(
1653 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001654 actual=mastershipCheck,
Jon Hall6aec96b2015-01-19 14:49:31 -08001655 onpass="Mastership of Switches was not changed",
1656 onfail="Mastership of some switches changed" )
1657 # NOTE: we expect mastership to change on controller failure
Jon Hall8f89dda2015-01-22 16:03:33 -08001658 mastershipCheck = consistentMastership
Jon Hall73cf9cc2014-11-20 22:28:38 -08001659
Jon Hall58c76b72015-02-23 11:09:24 -08001660 main.step( "Get the intents and compare across all nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001661 ONOSIntents = []
Jon Hall58c76b72015-02-23 11:09:24 -08001662 intentCheck = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001663 consistentIntents = True
1664 intentsResults = True
1665 threads = []
1666 for i in range( numControllers ):
1667 t = main.Thread( target=CLIs[i].intents,
1668 name="intents-" + str( i ),
1669 args=[],
1670 kwargs={ 'jsonFormat': True } )
1671 threads.append( t )
1672 t.start()
1673
1674 for t in threads:
1675 t.join()
1676 ONOSIntents.append( t.result )
1677
1678 for i in range( numControllers ):
1679 if not ONOSIntents[ i ] or "Error" in ONOSIntents[ i ]:
1680 main.log.report( "Error in getting ONOS" + str( i + 1 ) +
1681 " intents" )
1682 main.log.warn( "ONOS" + str( i + 1 ) + " intents response: " +
1683 repr( ONOSIntents[ i ] ) )
1684 intentsResults = False
Jon Hall58c76b72015-02-23 11:09:24 -08001685 utilities.assert_equals(
Jon Hall5cfd23c2015-03-19 11:40:57 -07001686 expect=True,
1687 actual=intentsResults,
1688 onpass="No error in reading intents output",
1689 onfail="Error in reading intents from ONOS" )
1690
1691 main.step( "Check for consistency in Intents from each controller" )
1692 if all([ sorted( i ) == sorted( ONOSIntents[ 0 ] ) for i in ONOSIntents ] ):
1693 main.log.report( "Intents are consistent across all ONOS " +
1694 "nodes" )
1695 else:
1696 consistentIntents = False
Jon Hall390696c2015-05-05 17:13:41 -07001697
1698 # Try to make it easy to figure out what is happening
1699 #
1700 # Intent ONOS1 ONOS2 ...
1701 # 0x01 INSTALLED INSTALLING
1702 # ... ... ...
1703 # ... ... ...
1704 title = " ID"
1705 for n in range( numControllers ):
1706 title += " " * 10 + "ONOS" + str( n + 1 )
1707 main.log.warn( title )
1708 # get all intent keys in the cluster
1709 keys = []
1710 for nodeStr in ONOSIntents:
1711 node = json.loads( nodeStr )
1712 for intent in node:
1713 keys.append( intent.get( 'id' ) )
1714 keys = set( keys )
1715 for key in keys:
1716 row = "%-13s" % key
1717 for nodeStr in ONOSIntents:
1718 node = json.loads( nodeStr )
1719 for intent in node:
1720 if intent.get( 'id' ) == key:
1721 row += "%-15s" % intent.get( 'state' )
1722 main.log.warn( row )
1723 # End table view
1724
Jon Hall5cfd23c2015-03-19 11:40:57 -07001725 utilities.assert_equals(
1726 expect=True,
1727 actual=consistentIntents,
Jon Hall58c76b72015-02-23 11:09:24 -08001728 onpass="Intents are consistent across all ONOS nodes",
1729 onfail="ONOS nodes have different views of intents" )
Jon Hall58c76b72015-02-23 11:09:24 -08001730 intentStates = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001731 for node in ONOSIntents: # Iter through ONOS nodes
Jon Hall58c76b72015-02-23 11:09:24 -08001732 nodeStates = []
1733 # Iter through intents of a node
Jon Hall5cfd23c2015-03-19 11:40:57 -07001734 try:
1735 for intent in json.loads( node ):
1736 nodeStates.append( intent[ 'state' ] )
1737 except ( ValueError, TypeError ):
1738 main.log.exception( "Error in parsing intents" )
1739 main.log.error( repr( node ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001740 intentStates.append( nodeStates )
1741 out = [ (i, nodeStates.count( i ) ) for i in set( nodeStates ) ]
1742 main.log.info( dict( out ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001743
Jon Hall5cfd23c2015-03-19 11:40:57 -07001744 if intentsResults and not consistentIntents:
1745 for i in range( numControllers ):
1746 main.log.warn( "ONOS" + str( i + 1 ) + " intents: " )
1747 main.log.warn( json.dumps(
1748 json.loads( ONOSIntents[ i ] ),
1749 sort_keys=True,
1750 indent=4,
1751 separators=( ',', ': ' ) ) )
1752 elif intentsResults and consistentIntents:
1753 intentCheck = main.TRUE
1754
Jon Hall58c76b72015-02-23 11:09:24 -08001755 # NOTE: Store has no durability, so intents are lost across system
1756 # restarts
1757 main.step( "Compare current intents with intents before the failure" )
1758 # NOTE: this requires case 5 to pass for intentState to be set.
1759 # maybe we should stop the test if that fails?
1760 sameIntents = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001761 if intentState and intentState == ONOSIntents[ 0 ]:
Jon Hall21270ac2015-02-16 17:59:55 -08001762 sameIntents = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08001763 main.log.report( "Intents are consistent with before failure" )
1764 # TODO: possibly the states have changed? we may need to figure out
Jon Hall5cfd23c2015-03-19 11:40:57 -07001765 # what the acceptable states are
Jon Hall58c76b72015-02-23 11:09:24 -08001766 else:
1767 try:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001768 main.log.warn( "ONOS intents: " )
1769 main.log.warn( json.dumps( json.loads( ONOSIntents[ 0 ] ),
1770 sort_keys=True, indent=4,
1771 separators=( ',', ': ' ) ) )
1772 except ( ValueError, TypeError ):
1773 main.log.exception( "Exception printing intents" )
1774 main.log.warn( repr( ONOSIntents[0] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001775 sameIntents = main.FALSE
1776 utilities.assert_equals(
1777 expect=main.TRUE,
1778 actual=sameIntents,
1779 onpass="Intents are consistent with before failure",
1780 onfail="The Intents changed during failure" )
1781 intentCheck = intentCheck and sameIntents
Jon Hall21270ac2015-02-16 17:59:55 -08001782
Jon Hall58c76b72015-02-23 11:09:24 -08001783 main.step( "Get the OF Table entries and compare to before " +
1784 "component failure" )
1785 FlowTables = main.TRUE
1786 flows2 = []
1787 for i in range( 28 ):
1788 main.log.info( "Checking flow table on s" + str( i + 1 ) )
1789 tmpFlows = main.Mininet2.getFlowTable( 1.3, "s" + str( i + 1 ) )
1790 flows2.append( tmpFlows )
1791 tempResult = main.Mininet2.flowComp(
1792 flow1=flows[ i ],
1793 flow2=tmpFlows )
1794 FlowTables = FlowTables and tempResult
1795 if FlowTables == main.FALSE:
1796 main.log.info( "Differences in flow table for switch: s" +
1797 str( i + 1 ) )
1798 if FlowTables == main.TRUE:
1799 main.log.report( "No changes were found in the flow tables" )
1800 utilities.assert_equals(
1801 expect=main.TRUE,
1802 actual=FlowTables,
1803 onpass="No changes were found in the flow tables",
1804 onfail="Changes were found in the flow tables" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001805
Jon Hall6aec96b2015-01-19 14:49:31 -08001806 main.step( "Check the continuous pings to ensure that no packets " +
1807 "were dropped during component failure" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07001808 main.Mininet2.pingKill( main.params[ 'TESTONUSER' ],
1809 main.params[ 'TESTONIP' ] )
Jon Hall8f89dda2015-01-22 16:03:33 -08001810 LossInPings = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001811 # NOTE: checkForLoss returns main.FALSE with 0% packet loss
1812 for i in range( 8, 18 ):
1813 main.log.info(
1814 "Checking for a loss in pings along flow from s" +
1815 str( i ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08001816 LossInPings = main.Mininet2.checkForLoss(
Jon Hall6aec96b2015-01-19 14:49:31 -08001817 "/tmp/ping.h" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001818 str( i ) ) or LossInPings
1819 if LossInPings == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001820 main.log.info( "Loss in ping detected" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001821 elif LossInPings == main.ERROR:
Jon Hall6aec96b2015-01-19 14:49:31 -08001822 main.log.info( "There are multiple mininet process running" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001823 elif LossInPings == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001824 main.log.info( "No Loss in the pings" )
1825 main.log.report( "No loss of dataplane connectivity" )
1826 utilities.assert_equals(
1827 expect=main.FALSE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001828 actual=LossInPings,
Jon Hall6aec96b2015-01-19 14:49:31 -08001829 onpass="No Loss of connectivity",
1830 onfail="Loss of dataplane connectivity detected" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001831
Jon Hall390696c2015-05-05 17:13:41 -07001832 main.step( "Leadership Election is still functional" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001833 # Test of LeadershipElection
Jon Hall8f89dda2015-01-22 16:03:33 -08001834 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001835 # FIXME: make sure this matches nodes that were restarted
1836 restarted = [ nodes[0].ip_address, nodes[1].ip_address,
1837 nodes[2].ip_address ]
Jon Hall390696c2015-05-05 17:13:41 -07001838
Jon Hall8f89dda2015-01-22 16:03:33 -08001839 leaderResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001840 for cli in CLIs:
1841 leaderN = cli.electionTestLeader()
Jon Hall8f89dda2015-01-22 16:03:33 -08001842 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08001843 if leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08001844 # error in response
1845 main.log.report( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001846 "electionTestLeader function, check the" +
Jon Hall6aec96b2015-01-19 14:49:31 -08001847 " error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001848 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001849 elif leaderN is None:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001850 main.log.report( cli.name +
Jon Hall6aec96b2015-01-19 14:49:31 -08001851 " shows no leader for the election-app was" +
1852 " elected after the old one died" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001853 leaderResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001854 elif leaderN in restarted:
1855 main.log.report( cli.name + " shows " + str( leaderN ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08001856 " as leader for the election-app, but it " +
1857 "was restarted" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001858 leaderResult = main.FALSE
1859 if len( set( leaderList ) ) != 1:
1860 leaderResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08001861 main.log.error(
1862 "Inconsistent view of leader for the election test app" )
1863 # TODO: print the list
Jon Hall8f89dda2015-01-22 16:03:33 -08001864 if leaderResult:
1865 main.log.report( "Leadership election tests passed( consistent " +
Jon Hall6aec96b2015-01-19 14:49:31 -08001866 "view of leader across listeners and a new " +
Jon Hall8f89dda2015-01-22 16:03:33 -08001867 "leader was re-elected if applicable )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08001868 utilities.assert_equals(
1869 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08001870 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08001871 onpass="Leadership election passed",
1872 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08001873
Jon Hall6aec96b2015-01-19 14:49:31 -08001874 def CASE8( self, main ):
1875 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001876 Compare topo
Jon Hall6aec96b2015-01-19 14:49:31 -08001877 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08001878 import sys
Jon Hall6aec96b2015-01-19 14:49:31 -08001879 # FIXME add this path to params
1880 sys.path.append( "/home/admin/sts" )
1881 # assumes that sts is already in you PYTHONPATH
1882 from sts.topology.teston_topology import TestONTopology
Jon Hall73cf9cc2014-11-20 22:28:38 -08001883 import json
1884 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07001885 assert numControllers, "numControllers not defined"
1886 assert main, "main not defined"
1887 assert utilities.assert_equals, "utilities.assert_equals not defined"
1888 assert CLIs, "CLIs not defined"
1889 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08001890
Jon Hall6aec96b2015-01-19 14:49:31 -08001891 description = "Compare ONOS Topology view to Mininet topology"
1892 main.case( description )
1893 main.log.report( description )
1894 main.step( "Create TestONTopology object" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001895 ctrls = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001896 for node in nodes:
1897 temp = ( node, node.name, node.ip_address, 6633 )
1898 ctrls.append( temp )
1899 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001900
Jon Hall8f89dda2015-01-22 16:03:33 -08001901 devicesResults = main.TRUE
1902 portsResults = main.TRUE
1903 linksResults = main.TRUE
Jon Hall58c76b72015-02-23 11:09:24 -08001904 hostsResults = main.TRUE
Jon Hall8f89dda2015-01-22 16:03:33 -08001905 topoResult = main.FALSE
Jon Hall73cf9cc2014-11-20 22:28:38 -08001906 elapsed = 0
Jon Hallffb386d2014-11-21 13:43:38 -08001907 count = 0
Jon Hall6aec96b2015-01-19 14:49:31 -08001908 main.step( "Collecting topology information from ONOS" )
Jon Hall8f89dda2015-01-22 16:03:33 -08001909 startTime = time.time()
Jon Hall21270ac2015-02-16 17:59:55 -08001910 # Give time for Gossip to work
Jon Hall8f89dda2015-01-22 16:03:33 -08001911 while topoResult == main.FALSE and elapsed < 60:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001912 count += 1
Jon Hall94fd0472014-12-08 11:52:42 -08001913 if count > 1:
Jon Hall5cfd23c2015-03-19 11:40:57 -07001914 # TODO: Deprecate STS usage
Jon Hall58c76b72015-02-23 11:09:24 -08001915 MNTopo = TestONTopology( main.Mininet1, ctrls )
Jon Hall8f89dda2015-01-22 16:03:33 -08001916 cliStart = time.time()
Jon Hall94fd0472014-12-08 11:52:42 -08001917 devices = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001918 threads = []
1919 for i in range( numControllers ):
1920 t = main.Thread( target=CLIs[i].devices,
1921 name="devices-" + str( i ),
1922 args=[ ] )
1923 threads.append( t )
1924 t.start()
1925
1926 for t in threads:
1927 t.join()
1928 devices.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001929 hosts = []
Jon Hall58c76b72015-02-23 11:09:24 -08001930 ipResult = main.TRUE
Jon Hall5cfd23c2015-03-19 11:40:57 -07001931 threads = []
1932 for i in range( numControllers ):
1933 t = main.Thread( target=CLIs[i].hosts,
1934 name="hosts-" + str( i ),
1935 args=[ ] )
1936 threads.append( t )
1937 t.start()
1938
1939 for t in threads:
1940 t.join()
1941 try:
1942 hosts.append( json.loads( t.result ) )
1943 except ( ValueError, TypeError ):
1944 main.log.exception( "Error parsing hosts results" )
1945 main.log.error( repr( t.result ) )
Jon Hall6aec96b2015-01-19 14:49:31 -08001946 for controller in range( 0, len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08001947 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001948 for host in hosts[ controller ]:
Jon Hall58c76b72015-02-23 11:09:24 -08001949 if host is None or host.get( 'ips', [] ) == []:
Jon Hall6aec96b2015-01-19 14:49:31 -08001950 main.log.error(
1951 "DEBUG:Error with host ips on controller" +
Jon Hall8f89dda2015-01-22 16:03:33 -08001952 controllerStr + ": " + str( host ) )
Jon Hall58c76b72015-02-23 11:09:24 -08001953 ipResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08001954 ports = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001955 threads = []
1956 for i in range( numControllers ):
1957 t = main.Thread( target=CLIs[i].ports,
1958 name="ports-" + str( i ),
1959 args=[ ] )
1960 threads.append( t )
1961 t.start()
1962
1963 for t in threads:
1964 t.join()
1965 ports.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001966 links = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001967 threads = []
1968 for i in range( numControllers ):
1969 t = main.Thread( target=CLIs[i].links,
1970 name="links-" + str( i ),
1971 args=[ ] )
1972 threads.append( t )
1973 t.start()
1974
1975 for t in threads:
1976 t.join()
1977 links.append( t.result )
Jon Hall94fd0472014-12-08 11:52:42 -08001978 clusters = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07001979 threads = []
1980 for i in range( numControllers ):
1981 t = main.Thread( target=CLIs[i].clusters,
1982 name="clusters-" + str( i ),
1983 args=[ ] )
1984 threads.append( t )
1985 t.start()
1986
1987 for t in threads:
1988 t.join()
1989 clusters.append( t.result )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001990
Jon Hall8f89dda2015-01-22 16:03:33 -08001991 elapsed = time.time() - startTime
1992 cliTime = time.time() - cliStart
1993 print "CLI time: " + str( cliTime )
Jon Hall73cf9cc2014-11-20 22:28:38 -08001994
Jon Hall8f89dda2015-01-22 16:03:33 -08001995 for controller in range( numControllers ):
1996 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08001997 if devices[ controller ] or "Error" not in devices[
1998 controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08001999 currentDevicesResult = main.Mininet1.compareSwitches(
Jon Hall6aec96b2015-01-19 14:49:31 -08002000 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002001 json.loads( devices[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002002 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002003 currentDevicesResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002004 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002005 actual=currentDevicesResult,
2006 onpass="ONOS" + controllerStr +
2007 " Switches view is correct",
2008 onfail="ONOS" + controllerStr +
2009 " Switches view is incorrect" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002010
Jon Hall6aec96b2015-01-19 14:49:31 -08002011 if ports[ controller ] or "Error" not in ports[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08002012 currentPortsResult = main.Mininet1.comparePorts(
Jon Hall6aec96b2015-01-19 14:49:31 -08002013 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002014 json.loads( ports[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002015 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002016 currentPortsResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002017 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002018 actual=currentPortsResult,
2019 onpass="ONOS" + controllerStr +
2020 " ports view is correct",
2021 onfail="ONOS" + controllerStr +
2022 " ports view is incorrect" )
Jon Hall94fd0472014-12-08 11:52:42 -08002023
Jon Hall6aec96b2015-01-19 14:49:31 -08002024 if links[ controller ] or "Error" not in links[ controller ]:
Jon Hall8f89dda2015-01-22 16:03:33 -08002025 currentLinksResult = main.Mininet1.compareLinks(
Jon Hall6aec96b2015-01-19 14:49:31 -08002026 MNTopo,
Jon Hall58c76b72015-02-23 11:09:24 -08002027 json.loads( links[ controller ] ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002028 else:
Jon Hall8f89dda2015-01-22 16:03:33 -08002029 currentLinksResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002030 utilities.assert_equals( expect=main.TRUE,
Jon Hall58c76b72015-02-23 11:09:24 -08002031 actual=currentLinksResult,
2032 onpass="ONOS" + controllerStr +
2033 " links view is correct",
2034 onfail="ONOS" + controllerStr +
2035 " links view is incorrect" )
2036
2037 if hosts[ controller ] or "Error" not in hosts[ controller ]:
2038 currentHostsResult = main.Mininet1.compareHosts(
2039 MNTopo, hosts[ controller ] )
2040 else:
2041 currentHostsResult = main.FALSE
2042 utilities.assert_equals( expect=main.TRUE,
2043 actual=currentHostsResult,
2044 onpass="ONOS" + controllerStr +
2045 " hosts exist in Mininet",
2046 onfail="ONOS" + controllerStr +
2047 " hosts don't match Mininet" )
2048
2049 devicesResults = devicesResults and currentDevicesResult
2050 portsResults = portsResults and currentPortsResult
2051 linksResults = linksResults and currentLinksResult
2052 hostsResults = hostsResults and currentHostsResult
Jon Hall94fd0472014-12-08 11:52:42 -08002053
Jon Hall529a37f2015-01-28 10:02:00 -08002054 # Compare json objects for hosts and dataplane clusters
Jon Hall94fd0472014-12-08 11:52:42 -08002055
Jon Hall6aec96b2015-01-19 14:49:31 -08002056 # hosts
Jon Hall390696c2015-05-05 17:13:41 -07002057 main.step( "Hosts view is consistent across all ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002058 consistentHostsResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08002059 for controller in range( len( hosts ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08002060 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08002061 if "Error" not in hosts[ controller ]:
2062 if hosts[ controller ] == hosts[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002063 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08002064 else: # hosts not consistent
Jon Hall8f89dda2015-01-22 16:03:33 -08002065 main.log.report( "hosts from ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08002066 " is inconsistent with ONOS1" )
2067 main.log.warn( repr( hosts[ controller ] ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08002068 consistentHostsResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002069
2070 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08002071 main.log.report( "Error in getting ONOS hosts from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002072 controllerStr )
2073 consistentHostsResult = main.FALSE
2074 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08002075 " hosts response: " +
2076 repr( hosts[ controller ] ) )
2077 utilities.assert_equals(
2078 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002079 actual=consistentHostsResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002080 onpass="Hosts view is consistent across all ONOS nodes",
2081 onfail="ONOS nodes have different views of hosts" )
Jon Hall94fd0472014-12-08 11:52:42 -08002082
Jon Hall6aec96b2015-01-19 14:49:31 -08002083 # Strongly connected clusters of devices
Jon Hall390696c2015-05-05 17:13:41 -07002084 main.step( "Clusters view is consistent across all ONOS nodes" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002085 consistentClustersResult = main.TRUE
Jon Hall94fd0472014-12-08 11:52:42 -08002086 for controller in range( len( clusters ) ):
Jon Hall8f89dda2015-01-22 16:03:33 -08002087 controllerStr = str( controller + 1 )
Jon Hall6aec96b2015-01-19 14:49:31 -08002088 if "Error" not in clusters[ controller ]:
2089 if clusters[ controller ] == clusters[ 0 ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002090 continue
Jon Hall6aec96b2015-01-19 14:49:31 -08002091 else: # clusters not consistent
2092 main.log.report( "clusters from ONOS" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002093 controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08002094 " is inconsistent with ONOS1" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002095 consistentClustersResult = main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08002096
2097 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08002098 main.log.report( "Error in getting dataplane clusters " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002099 "from ONOS" + controllerStr )
2100 consistentClustersResult = main.FALSE
2101 main.log.warn( "ONOS" + controllerStr +
Jon Hall6aec96b2015-01-19 14:49:31 -08002102 " clusters response: " +
2103 repr( clusters[ controller ] ) )
2104 utilities.assert_equals(
2105 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002106 actual=consistentClustersResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002107 onpass="Clusters view is consistent across all ONOS nodes",
2108 onfail="ONOS nodes have different views of clusters" )
2109 # there should always only be one cluster
Jon Hall390696c2015-05-05 17:13:41 -07002110 main.step( "Topology view is correct and consistent across all " +
2111 "ONOS nodes" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002112 try:
2113 numClusters = len( json.loads( clusters[ 0 ] ) )
2114 except ( ValueError, TypeError ):
2115 main.log.exception( "Error parsing clusters[0]: " +
2116 repr( clusters[0] ) )
Jon Hall58c76b72015-02-23 11:09:24 -08002117 clusterResults = main.FALSE
2118 if numClusters == 1:
2119 clusterResults = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002120 utilities.assert_equals(
2121 expect=1,
Jon Hall8f89dda2015-01-22 16:03:33 -08002122 actual=numClusters,
Jon Hall6aec96b2015-01-19 14:49:31 -08002123 onpass="ONOS shows 1 SCC",
Jon Hall58c76b72015-02-23 11:09:24 -08002124 onfail="ONOS shows " + str( numClusters ) + " SCCs" )
Jon Hall94fd0472014-12-08 11:52:42 -08002125
Jon Hall8f89dda2015-01-22 16:03:33 -08002126 topoResult = ( devicesResults and portsResults and linksResults
Jon Hall58c76b72015-02-23 11:09:24 -08002127 and hostsResults and consistentHostsResult
2128 and consistentClustersResult and clusterResults
2129 and ipResult )
Jon Hall94fd0472014-12-08 11:52:42 -08002130
Jon Hall8f89dda2015-01-22 16:03:33 -08002131 topoResult = topoResult and int( count <= 2 )
2132 note = "note it takes about " + str( int( cliTime ) ) + \
2133 " seconds for the test to make all the cli calls to fetch " +\
2134 "the topology from each ONOS instance"
Jon Hall1b8f54a2015-02-04 13:24:20 -08002135 main.log.info(
Jon Hall8f89dda2015-01-22 16:03:33 -08002136 "Very crass estimate for topology discovery/convergence( " +
2137 str( note ) + " ): " + str( elapsed ) + " seconds, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002138 str( count ) + " tries" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002139 utilities.assert_equals( expect=main.TRUE, actual=topoResult,
Jon Hall58c76b72015-02-23 11:09:24 -08002140 onpass="Topology Check Test successful",
2141 onfail="Topology Check Test NOT successful" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002142 if topoResult == main.TRUE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002143 main.log.report( "ONOS topology view matches Mininet topology" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002144
Jon Halla9d26da2015-03-30 16:45:32 -07002145 # FIXME: move this to an ONOS state case
2146 main.step( "Checking ONOS nodes" )
2147 nodesOutput = []
Jon Hall390696c2015-05-05 17:13:41 -07002148 nodeResults = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002149 threads = []
2150 for i in range( numControllers ):
2151 t = main.Thread( target=CLIs[i].nodes,
2152 name="nodes-" + str( i ),
2153 args=[ ] )
2154 threads.append( t )
2155 t.start()
2156
2157 for t in threads:
2158 t.join()
2159 nodesOutput.append( t.result )
2160 ips = [ node.ip_address for node in nodes ]
2161 for i in nodesOutput:
2162 try:
2163 current = json.loads( i )
2164 for node in current:
Jon Hall390696c2015-05-05 17:13:41 -07002165 currentResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002166 if node['ip'] in ips: # node in nodes() output is in cell
2167 if node['state'] == 'ACTIVE':
Jon Hall390696c2015-05-05 17:13:41 -07002168 currentResult = main.TRUE
Jon Halla9d26da2015-03-30 16:45:32 -07002169 else:
2170 main.log.error( "Error in ONOS node availability" )
2171 main.log.error(
2172 json.dumps( current,
2173 sort_keys=True,
2174 indent=4,
2175 separators=( ',', ': ' ) ) )
2176 break
Jon Hall390696c2015-05-05 17:13:41 -07002177 nodeResults = nodeResults and currentResult
Jon Halla9d26da2015-03-30 16:45:32 -07002178 except ( ValueError, TypeError ):
2179 main.log.error( "Error parsing nodes output" )
2180 main.log.warn( repr( i ) )
Jon Hall390696c2015-05-05 17:13:41 -07002181 utilities.assert_equals( expect=main.TRUE, actual=nodeResults,
2182 onpass="Nodes check successful",
2183 onfail="Nodes check NOT successful" )
Jon Halla9d26da2015-03-30 16:45:32 -07002184
Jon Hall6aec96b2015-01-19 14:49:31 -08002185 def CASE9( self, main ):
2186 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002187 Link s3-s28 down
Jon Hall6aec96b2015-01-19 14:49:31 -08002188 """
2189 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002190 assert numControllers, "numControllers not defined"
2191 assert main, "main not defined"
2192 assert utilities.assert_equals, "utilities.assert_equals not defined"
2193 assert CLIs, "CLIs not defined"
2194 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002195 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002196
Jon Hall8f89dda2015-01-22 16:03:33 -08002197 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002198
Jon Hall6aec96b2015-01-19 14:49:31 -08002199 description = "Turn off a link to ensure that Link Discovery " +\
Jon Hall58c76b72015-02-23 11:09:24 -08002200 "is working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002201 main.log.report( description )
2202 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002203
Jon Hall6aec96b2015-01-19 14:49:31 -08002204 main.step( "Kill Link between s3 and s28" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002205 LinkDown = main.Mininet1.link( END1="s3", END2="s28", OPTION="down" )
Jon Hall58c76b72015-02-23 11:09:24 -08002206 main.log.info( "Waiting " + str( linkSleep ) +
2207 " seconds for link down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002208 time.sleep( linkSleep )
2209 utilities.assert_equals( expect=main.TRUE, actual=LinkDown,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002210 onpass="Link down successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002211 onfail="Failed to bring link down" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002212 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002213
Jon Hall6aec96b2015-01-19 14:49:31 -08002214 def CASE10( self, main ):
2215 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002216 Link s3-s28 up
Jon Hall6aec96b2015-01-19 14:49:31 -08002217 """
2218 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002219 assert numControllers, "numControllers not defined"
2220 assert main, "main not defined"
2221 assert utilities.assert_equals, "utilities.assert_equals not defined"
2222 assert CLIs, "CLIs not defined"
2223 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002224 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002225
Jon Hall8f89dda2015-01-22 16:03:33 -08002226 linkSleep = float( main.params[ 'timers' ][ 'LinkDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002227
Jon Hall6aec96b2015-01-19 14:49:31 -08002228 description = "Restore a link to ensure that Link Discovery is " + \
Jon Hall63604932015-02-26 17:09:50 -08002229 "working properly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002230 main.log.report( description )
2231 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002232
Jon Hall6aec96b2015-01-19 14:49:31 -08002233 main.step( "Bring link between s3 and s28 back up" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002234 LinkUp = main.Mininet1.link( END1="s3", END2="s28", OPTION="up" )
Jon Hall58c76b72015-02-23 11:09:24 -08002235 main.log.info( "Waiting " + str( linkSleep ) +
2236 " seconds for link up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002237 time.sleep( linkSleep )
2238 utilities.assert_equals( expect=main.TRUE, actual=LinkUp,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002239 onpass="Link up successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002240 onfail="Failed to bring link up" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002241 # TODO do some sort of check here
Jon Hall73cf9cc2014-11-20 22:28:38 -08002242
Jon Hall6aec96b2015-01-19 14:49:31 -08002243 def CASE11( self, main ):
2244 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002245 Switch Down
Jon Hall6aec96b2015-01-19 14:49:31 -08002246 """
2247 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002248 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002249 assert numControllers, "numControllers not defined"
2250 assert main, "main not defined"
2251 assert utilities.assert_equals, "utilities.assert_equals not defined"
2252 assert CLIs, "CLIs not defined"
2253 assert nodes, "nodes not defined"
Jon Hall73cf9cc2014-11-20 22:28:38 -08002254
Jon Hall8f89dda2015-01-22 16:03:33 -08002255 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002256
2257 description = "Killing a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002258 main.log.report( description )
2259 main.case( description )
2260 switch = main.params[ 'kill' ][ 'switch' ]
2261 switchDPID = main.params[ 'kill' ][ 'dpid' ]
Jon Hall73cf9cc2014-11-20 22:28:38 -08002262
Jon Hall6aec96b2015-01-19 14:49:31 -08002263 # TODO: Make this switch parameterizable
2264 main.step( "Kill " + switch )
2265 main.log.report( "Deleting " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002266 main.Mininet1.delSwitch( switch )
2267 main.log.info( "Waiting " + str( switchSleep ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002268 " seconds for switch down to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002269 time.sleep( switchSleep )
2270 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002271 # Peek at the deleted switch
2272 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002273 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002274 if device and device[ 'available' ] is False:
Jon Hall94fd0472014-12-08 11:52:42 -08002275 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002276 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002277 onpass="Kill switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002278 onfail="Failed to kill switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002279
Jon Hall6aec96b2015-01-19 14:49:31 -08002280 def CASE12( self, main ):
2281 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002282 Switch Up
Jon Hall6aec96b2015-01-19 14:49:31 -08002283 """
2284 # NOTE: You should probably run a topology check after this
Jon Hall73cf9cc2014-11-20 22:28:38 -08002285 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002286 assert numControllers, "numControllers not defined"
2287 assert main, "main not defined"
2288 assert utilities.assert_equals, "utilities.assert_equals not defined"
2289 assert CLIs, "CLIs not defined"
2290 assert nodes, "nodes not defined"
2291 assert ONOS1Port, "ONOS1Port not defined"
2292 assert ONOS2Port, "ONOS2Port not defined"
2293 assert ONOS3Port, "ONOS3Port not defined"
2294 assert ONOS4Port, "ONOS4Port not defined"
2295 assert ONOS5Port, "ONOS5Port not defined"
2296 assert ONOS6Port, "ONOS6Port not defined"
2297 assert ONOS7Port, "ONOS7Port not defined"
Jon Hall669173b2014-12-17 11:36:30 -08002298
Jon Hall8f89dda2015-01-22 16:03:33 -08002299 switchSleep = float( main.params[ 'timers' ][ 'SwitchDiscovery' ] )
Jon Hall6aec96b2015-01-19 14:49:31 -08002300 switch = main.params[ 'kill' ][ 'switch' ]
2301 switchDPID = main.params[ 'kill' ][ 'dpid' ]
2302 links = main.params[ 'kill' ][ 'links' ].split()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002303 description = "Adding a switch to ensure it is discovered correctly"
Jon Hall6aec96b2015-01-19 14:49:31 -08002304 main.log.report( description )
2305 main.case( description )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002306
Jon Hall6aec96b2015-01-19 14:49:31 -08002307 main.step( "Add back " + switch )
2308 main.log.report( "Adding back " + switch )
Jon Hall8f89dda2015-01-22 16:03:33 -08002309 main.Mininet1.addSwitch( switch, dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002310 for peer in links:
Jon Hall8f89dda2015-01-22 16:03:33 -08002311 main.Mininet1.addLink( switch, peer )
Jon Hall58c76b72015-02-23 11:09:24 -08002312 main.Mininet1.assignSwController( sw=switch.split( 's' )[ 1 ],
2313 count=numControllers,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002314 ip1=nodes[ 0 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002315 port1=ONOS1Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002316 ip2=nodes[ 1 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002317 port2=ONOS2Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002318 ip3=nodes[ 2 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002319 port3=ONOS3Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002320 ip4=nodes[ 3 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002321 port4=ONOS4Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002322 ip5=nodes[ 4 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002323 port5=ONOS5Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002324 ip6=nodes[ 5 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002325 port6=ONOS6Port,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002326 ip7=nodes[ 6 ].ip_address,
Jon Hall58c76b72015-02-23 11:09:24 -08002327 port7=ONOS7Port )
2328 main.log.info( "Waiting " + str( switchSleep ) +
2329 " seconds for switch up to be discovered" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002330 time.sleep( switchSleep )
2331 device = main.ONOScli1.getDevice( dpid=switchDPID )
Jon Hall6aec96b2015-01-19 14:49:31 -08002332 # Peek at the deleted switch
2333 main.log.warn( str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08002334 result = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002335 if device and device[ 'available' ]:
Jon Hall94fd0472014-12-08 11:52:42 -08002336 result = main.TRUE
Jon Hall6aec96b2015-01-19 14:49:31 -08002337 utilities.assert_equals( expect=main.TRUE, actual=result,
Jon Hall5cfd23c2015-03-19 11:40:57 -07002338 onpass="add switch successful",
Jon Hall58c76b72015-02-23 11:09:24 -08002339 onfail="Failed to add switch?" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002340
Jon Hall6aec96b2015-01-19 14:49:31 -08002341 def CASE13( self, main ):
2342 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002343 Clean up
Jon Hall6aec96b2015-01-19 14:49:31 -08002344 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002345 import os
2346 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002347 assert numControllers, "numControllers not defined"
2348 assert main, "main not defined"
2349 assert utilities.assert_equals, "utilities.assert_equals not defined"
2350 assert CLIs, "CLIs not defined"
2351 assert nodes, "nodes not defined"
Jon Hall6aec96b2015-01-19 14:49:31 -08002352
2353 # printing colors to terminal
Jon Hall5cfd23c2015-03-19 11:40:57 -07002354 colors = { 'cyan': '\033[96m', 'purple': '\033[95m',
2355 'blue': '\033[94m', 'green': '\033[92m',
2356 'yellow': '\033[93m', 'red': '\033[91m', 'end': '\033[0m' }
Jon Hall73cf9cc2014-11-20 22:28:38 -08002357 description = "Test Cleanup"
Jon Hall6aec96b2015-01-19 14:49:31 -08002358 main.log.report( description )
2359 main.case( description )
2360 main.step( "Killing tcpdumps" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002361 main.Mininet2.stopTcpdump()
Jon Hall73cf9cc2014-11-20 22:28:38 -08002362
Jon Hall6aec96b2015-01-19 14:49:31 -08002363 main.step( "Copying MN pcap and ONOS log files to test station" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002364 testname = main.TEST
Jon Hall8f89dda2015-01-22 16:03:33 -08002365 teststationUser = main.params[ 'TESTONUSER' ]
2366 teststationIP = main.params[ 'TESTONIP' ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002367 # NOTE: MN Pcap file is being saved to ~/packet_captures
Jon Hall73cf9cc2014-11-20 22:28:38 -08002368 # scp this file as MN and TestON aren't necessarily the same vm
Jon Hall6aec96b2015-01-19 14:49:31 -08002369 # FIXME: scp
2370 # mn files
2371 # TODO: Load these from params
2372 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002373 logFolder = "/opt/onos/log/"
2374 logFiles = [ "karaf.log", "karaf.log.1" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002375 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002376 dstDir = "~/packet_captures/"
2377 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002378 for node in nodes:
2379 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2380 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002381 teststationUser + "@" +
2382 teststationIP + ":" +
2383 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002384 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002385 main.ONOSbench.handle.expect( "\$" )
2386
Jon Hall6aec96b2015-01-19 14:49:31 -08002387 # std*.log's
2388 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002389 logFolder = "/opt/onos/var/"
2390 logFiles = [ "stderr.log", "stdout.log" ]
Jon Hall6aec96b2015-01-19 14:49:31 -08002391 # NOTE: must end in /
Jon Hall8f89dda2015-01-22 16:03:33 -08002392 dstDir = "~/packet_captures/"
2393 for f in logFiles:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002394 for node in nodes:
2395 main.ONOSbench.handle.sendline( "scp sdn@" + node.ip_address +
2396 ":" + logFolder + f + " " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002397 teststationUser + "@" +
2398 teststationIP + ":" +
2399 dstDir + str( testname ) +
Jon Hall5cfd23c2015-03-19 11:40:57 -07002400 "-" + node.name + "-" + f )
Jon Hall58c76b72015-02-23 11:09:24 -08002401 main.ONOSbench.handle.expect( "\$" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002402 # sleep so scp can finish
2403 time.sleep( 10 )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002404
2405 main.step( "Stopping Mininet" )
Jon Hall390696c2015-05-05 17:13:41 -07002406 mnResult = main.Mininet1.stopNet()
2407 utilities.assert_equals( expect=main.TRUE, actual=mnResult,
2408 onpass="Mininet stopped",
2409 onfail="MN cleanup NOT successful" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002410
2411 main.step( "Checking ONOS Logs for errors" )
2412 for node in nodes:
2413 print colors[ 'purple' ] + "Checking logs for errors on " + \
2414 node.name + ":" + colors[ 'end' ]
2415 print main.ONOSbench.checkLogs( node.ip_address )
2416
Jon Hall6aec96b2015-01-19 14:49:31 -08002417 main.step( "Packing and rotating pcap archives" )
2418 os.system( "~/TestON/dependencies/rotate.sh " + str( testname ) )
Jon Hall73cf9cc2014-11-20 22:28:38 -08002419
Jon Hall6aec96b2015-01-19 14:49:31 -08002420 def CASE14( self, main ):
2421 """
Jon Hall669173b2014-12-17 11:36:30 -08002422 start election app on all onos nodes
Jon Hall6aec96b2015-01-19 14:49:31 -08002423 """
Jon Hall5cfd23c2015-03-19 11:40:57 -07002424 assert numControllers, "numControllers not defined"
2425 assert main, "main not defined"
2426 assert utilities.assert_equals, "utilities.assert_equals not defined"
2427 assert CLIs, "CLIs not defined"
2428 assert nodes, "nodes not defined"
2429
Jon Hall8f89dda2015-01-22 16:03:33 -08002430 leaderResult = main.TRUE
Jon Hall390696c2015-05-05 17:13:41 -07002431 main.case("Start Leadership Election app")
2432 main.step( "Install leadership election app" )
Jon Halla9d26da2015-03-30 16:45:32 -07002433 main.ONOScli1.activateApp( "org.onosproject.election" )
2434 leaders = []
2435 for cli in CLIs:
Jon Hall390696c2015-05-05 17:13:41 -07002436 cli.electionTestRun()
2437 for cli in CLIs:
Jon Halla9d26da2015-03-30 16:45:32 -07002438 leader = cli.electionTestLeader()
2439 if leader is None or leader == main.FALSE:
2440 main.log.report( cli.name + ": Leader for the election app " +
2441 "should be an ONOS node, instead got '" +
2442 str( leader ) + "'" )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002443 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002444 leaders.append( leader )
2445 if len( set( leaders ) ) != 1:
2446 leaderResult = main.FALSE
2447 main.log.error( "Results of electionTestLeader is order of CLIs:" +
2448 str( leaders ) )
Jon Hall8f89dda2015-01-22 16:03:33 -08002449 if leaderResult:
Jon Hall6aec96b2015-01-19 14:49:31 -08002450 main.log.report( "Leadership election tests passed( consistent " +
2451 "view of leader across listeners and a leader " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002452 "was elected )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002453 utilities.assert_equals(
2454 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002455 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002456 onpass="Leadership election passed",
2457 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002458
Jon Hall6aec96b2015-01-19 14:49:31 -08002459 def CASE15( self, main ):
2460 """
Jon Hall669173b2014-12-17 11:36:30 -08002461 Check that Leadership Election is still functional
Jon Hall6aec96b2015-01-19 14:49:31 -08002462 """
Jon Hall390696c2015-05-05 17:13:41 -07002463 import time
Jon Hall5cfd23c2015-03-19 11:40:57 -07002464 assert numControllers, "numControllers not defined"
2465 assert main, "main not defined"
2466 assert utilities.assert_equals, "utilities.assert_equals not defined"
2467 assert CLIs, "CLIs not defined"
2468 assert nodes, "nodes not defined"
2469
Jon Hall8f89dda2015-01-22 16:03:33 -08002470 leaderResult = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002471 description = "Check that Leadership Election is still functional"
Jon Hall6aec96b2015-01-19 14:49:31 -08002472 main.log.report( description )
2473 main.case( description )
2474 main.step( "Find current leader and withdraw" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002475 leader = main.ONOScli1.electionTestLeader()
Jon Halla9d26da2015-03-30 16:45:32 -07002476 # do some sanity checking on leader before using it
Jon Hall8f89dda2015-01-22 16:03:33 -08002477 withdrawResult = main.FALSE
Jon Hall5cfd23c2015-03-19 11:40:57 -07002478 if leader is None or leader == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002479 main.log.report(
2480 "Leader for the election app should be an ONOS node," +
Jon Hall58c76b72015-02-23 11:09:24 -08002481 "instead got '" + str( leader ) + "'" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002482 leaderResult = main.FALSE
Jon Hall63604932015-02-26 17:09:50 -08002483 oldLeader = None
Jon Hall5cfd23c2015-03-19 11:40:57 -07002484 for i in range( len( CLIs ) ):
2485 if leader == nodes[ i ].ip_address:
2486 oldLeader = CLIs[ i ]
2487 break
Jon Halla9d26da2015-03-30 16:45:32 -07002488 else: # FOR/ELSE statement
Jon Hall5cfd23c2015-03-19 11:40:57 -07002489 main.log.error( "Leader election, could not find current leader" )
Jon Hall63604932015-02-26 17:09:50 -08002490 if oldLeader:
2491 withdrawResult = oldLeader.electionTestWithdraw()
Jon Hall6aec96b2015-01-19 14:49:31 -08002492 utilities.assert_equals(
2493 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002494 actual=withdrawResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002495 onpass="App was withdrawn from election",
2496 onfail="App was not withdrawn from election" )
Jon Hall669173b2014-12-17 11:36:30 -08002497
Jon Hall6aec96b2015-01-19 14:49:31 -08002498 main.step( "Make sure new leader is elected" )
Jon Halla9d26da2015-03-30 16:45:32 -07002499 # FIXME: use threads
Jon Hall8f89dda2015-01-22 16:03:33 -08002500 leaderList = []
Jon Hall5cfd23c2015-03-19 11:40:57 -07002501 for cli in CLIs:
2502 leaderN = cli.electionTestLeader()
2503 leaderList.append( leaderN )
Jon Hall669173b2014-12-17 11:36:30 -08002504 if leaderN == leader:
Jon Hall5cfd23c2015-03-19 11:40:57 -07002505 main.log.report( cli.name + " still sees " + str( leader ) +
2506 " as leader after they withdrew" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002507 leaderResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002508 elif leaderN == main.FALSE:
Jon Hall6aec96b2015-01-19 14:49:31 -08002509 # error in response
2510 # TODO: add check for "Command not found:" in the driver, this
Jon Hall5cfd23c2015-03-19 11:40:57 -07002511 # means the app isn't loaded
Jon Hall6aec96b2015-01-19 14:49:31 -08002512 main.log.report( "Something is wrong with " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002513 "electionTestLeader function, " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002514 "check the error logs" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002515 leaderResult = main.FALSE
Jon Halla9d26da2015-03-30 16:45:32 -07002516 elif leaderN is None:
2517 # node may not have recieved the event yet
Jon Hall390696c2015-05-05 17:13:41 -07002518 time.sleep(7)
Jon Halla9d26da2015-03-30 16:45:32 -07002519 leaderN = cli.electionTestLeader()
2520 leaderList.pop()
2521 leaderList.append( leaderN )
Jon Hall8f89dda2015-01-22 16:03:33 -08002522 consistentLeader = main.FALSE
2523 if len( set( leaderList ) ) == 1:
Jon Hall6aec96b2015-01-19 14:49:31 -08002524 main.log.info( "Each Election-app sees '" +
Jon Hall8f89dda2015-01-22 16:03:33 -08002525 str( leaderList[ 0 ] ) +
Jon Hall6aec96b2015-01-19 14:49:31 -08002526 "' as the leader" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002527 consistentLeader = main.TRUE
Jon Hall669173b2014-12-17 11:36:30 -08002528 else:
Jon Hall6aec96b2015-01-19 14:49:31 -08002529 main.log.report(
2530 "Inconsistent responses for leader of Election-app:" )
Jon Hall8f89dda2015-01-22 16:03:33 -08002531 for n in range( len( leaderList ) ):
Jon Hall6aec96b2015-01-19 14:49:31 -08002532 main.log.report( "ONOS" + str( n + 1 ) + " response: " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002533 str( leaderList[ n ] ) )
Jon Hall5cfd23c2015-03-19 11:40:57 -07002534 leaderResult = leaderResult and consistentLeader
Jon Hall8f89dda2015-01-22 16:03:33 -08002535 if leaderResult:
2536 main.log.report( "Leadership election tests passed( consistent " +
Jon Hall6aec96b2015-01-19 14:49:31 -08002537 "view of leader across listeners and a new " +
2538 "leader was elected when the old leader " +
Jon Hall8f89dda2015-01-22 16:03:33 -08002539 "resigned )" )
Jon Hall6aec96b2015-01-19 14:49:31 -08002540 utilities.assert_equals(
2541 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002542 actual=leaderResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002543 onpass="Leadership election passed",
2544 onfail="Something went wrong with Leadership election" )
Jon Hall669173b2014-12-17 11:36:30 -08002545
Jon Hall58c76b72015-02-23 11:09:24 -08002546 main.step( "Run for election on old leader( just so everyone " +
2547 "is in the hat )" )
Jon Hall63604932015-02-26 17:09:50 -08002548 if oldLeader:
2549 runResult = oldLeader.electionTestRun()
2550 else:
2551 runResult = main.FALSE
Jon Hall6aec96b2015-01-19 14:49:31 -08002552 utilities.assert_equals(
2553 expect=main.TRUE,
Jon Hall8f89dda2015-01-22 16:03:33 -08002554 actual=runResult,
Jon Hall6aec96b2015-01-19 14:49:31 -08002555 onpass="App re-ran for election",
2556 onfail="App failed to run for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002557
2558 afterRun = main.ONOScli1.electionTestLeader()
2559 # verify leader didn't just change
2560 if afterRun == leaderList[ 0 ]:
2561 afterResult = main.TRUE
2562 else:
2563 afterResult = main.FALSE
Jon Hall669173b2014-12-17 11:36:30 -08002564
Jon Hall6aec96b2015-01-19 14:49:31 -08002565 utilities.assert_equals(
2566 expect=main.TRUE,
Jon Hall390696c2015-05-05 17:13:41 -07002567 actual=afterResult,
2568 onpass="Old leader successfully re-ran for election",
Jon Hall6aec96b2015-01-19 14:49:31 -08002569 onfail="Something went wrong with Leadership election after " +
2570 "the old leader re-ran for election" )
Jon Hall390696c2015-05-05 17:13:41 -07002571
2572 case15Result = withdrawResult and leaderResult and runResult and\
2573 afterResult
2574 utilities.assert_equals(
2575 expect=main.TRUE,
2576 actual=case15Result,
2577 onpass="Leadership election is still functional",
2578 onfail="Leadership Election is no longer functional" )
2579
2580 def CASE16( self, main ):
2581 """
2582 Install Distributed Primitives app
2583 """
2584 assert numControllers, "numControllers not defined"
2585 assert main, "main not defined"
2586 assert utilities.assert_equals, "utilities.assert_equals not defined"
2587 assert CLIs, "CLIs not defined"
2588 assert nodes, "nodes not defined"
2589
2590 # Variables for the distributed primitives tests
2591 global pCounterName
2592 global iCounterName
2593 global pCounterValue
2594 global iCounterValue
2595 global onosSet
2596 global onosSetName
2597 pCounterName = "TestON-Partitions"
2598 iCounterName = "TestON-inMemory"
2599 pCounterValue = 0
2600 iCounterValue = 0
2601 onosSet = set([])
2602 onosSetName = "TestON-set"
2603
2604 description = "Install Primitives app"
2605 main.case( description )
2606 main.step( "Install Primitives app" )
2607 appName = "org.onosproject.distributedprimitives"
2608 appResults = CLIs[0].activateApp( appName )
2609 utilities.assert_equals( expect=main.TRUE,
2610 actual=appResults,
2611 onpass="Primitives app activated",
2612 onfail="Primitives app not activated" )
2613
2614 def CASE17( self, main ):
2615 """
2616 Check for basic functionality with distributed primitives
2617 """
2618 # Make sure variables are defined/set
2619 assert numControllers, "numControllers not defined"
2620 assert main, "main not defined"
2621 assert utilities.assert_equals, "utilities.assert_equals not defined"
2622 assert CLIs, "CLIs not defined"
2623 assert nodes, "nodes not defined"
2624 assert pCounterName, "pCounterName not defined"
2625 assert iCounterName, "iCounterName not defined"
2626 assert onosSetName, "onosSetName not defined"
2627 # NOTE: assert fails if value is 0/None/Empty/False
2628 try:
2629 pCounterValue
2630 except NameError:
2631 main.log.error( "pCounterValue not defined, setting to 0" )
2632 pCounterValue = 0
2633 try:
2634 iCounterValue
2635 except NameError:
2636 main.log.error( "iCounterValue not defined, setting to 0" )
2637 iCounterValue = 0
2638 try:
2639 onosSet
2640 except NameError:
2641 main.log.error( "onosSet not defined, setting to empty Set" )
2642 onosSet = set([])
2643 # Variables for the distributed primitives tests. These are local only
2644 addValue = "a"
2645 addAllValue = "a b c d e f"
2646 retainValue = "c d e f"
2647
2648 description = "Check for basic functionality with distributed " +\
2649 "primitives"
2650 main.case( description )
2651 main.caseExplaination = "Test the methods of the distributed primitives (counters and sets) throught the cli"
2652 # DISTRIBUTED ATOMIC COUNTERS
2653 main.step( "Increment and get a default counter on each node" )
2654 pCounters = []
2655 threads = []
2656 for i in range( numControllers ):
2657 t = main.Thread( target=CLIs[i].counterTestIncrement,
2658 name="counterIncrement-" + str( i ),
2659 args=[ pCounterName ] )
2660 pCounterValue += 1
2661 threads.append( t )
2662 t.start()
2663
2664 for t in threads:
2665 t.join()
2666 pCounters.append( t.result )
2667 # Check that counter incremented numController times
2668 pCounterResults = True
2669 for i in range( numControllers ):
2670 pCounterResults and ( i + 1 ) in pCounters
2671 utilities.assert_equals( expect=True,
2672 actual=pCounterResults,
2673 onpass="Default counter incremented",
2674 onfail="Error incrementing default" +
2675 " counter" )
2676
2677 main.step( "Increment and get an in memory counter on each node" )
2678 iCounters = []
2679 threads = []
2680 for i in range( numControllers ):
2681 t = main.Thread( target=CLIs[i].counterTestIncrement,
2682 name="icounterIncrement-" + str( i ),
2683 args=[ iCounterName ],
2684 kwargs={ "inMemory": True } )
2685 iCounterValue += 1
2686 threads.append( t )
2687 t.start()
2688
2689 for t in threads:
2690 t.join()
2691 iCounters.append( t.result )
2692 # Check that counter incremented numController times
2693 iCounterResults = True
2694 for i in range( numControllers ):
2695 iCounterResults and ( i + 1 ) in iCounters
2696 utilities.assert_equals( expect=True,
2697 actual=iCounterResults,
2698 onpass="In memory counter incremented",
2699 onfail="Error incrementing in memory" +
2700 " counter" )
2701
2702 main.step( "Check counters are consistant across nodes" )
2703 onosCounters = []
2704 threads = []
2705 for i in range( numControllers ):
2706 t = main.Thread( target=CLIs[i].counters,
2707 name="counters-" + str( i ) )
2708 threads.append( t )
2709 t.start()
2710 for t in threads:
2711 t.join()
2712 onosCounters.append( t.result )
2713 tmp = [ i == onosCounters[ 0 ] for i in onosCounters ]
2714 if all( tmp ):
2715 main.log.info( "Counters are consistent across all nodes" )
2716 consistentCounterResults = main.TRUE
2717 else:
2718 main.log.error( "Counters are not consistent across all nodes" )
2719 consistentCounterResults = main.FALSE
2720 utilities.assert_equals( expect=main.TRUE,
2721 actual=consistentCounterResults,
2722 onpass="ONOS counters are consistent " +
2723 "across nodes",
2724 onfail="ONOS Counters are inconsistent " +
2725 "across nodes" )
2726
2727 main.step( "Counters we added have the correct values" )
2728 correctResults = main.TRUE
2729 for i in range( numControllers ):
2730 current = onosCounters[i]
2731 try:
2732 pValue = current.get( pCounterName )
2733 iValue = current.get( iCounterName )
2734 if pValue == pCounterValue:
2735 main.log.info( "Partitioned counter value is correct" )
2736 else:
2737 main.log.error( "Partitioned counter value is incorrect," +
2738 " expected value: " + str( pCounterValue )
2739 + " current value: " + str( pValue ) )
2740 correctResults = main.FALSE
2741 if iValue == iCounterValue:
2742 main.log.info( "In memory counter value is correct" )
2743 else:
2744 main.log.error( "In memory counter value is incorrect, " +
2745 "expected value: " + str( iCounterValue ) +
2746 " current value: " + str( iValue ) )
2747 correctResults = main.FALSE
2748 except AttributeError, e:
2749 main.log.error( "ONOS" + str( i + 1 ) + " counters result " +
2750 "is not as expected" )
2751 correctResults = main.FALSE
2752 utilities.assert_equals( expect=main.TRUE,
2753 actual=correctResults,
2754 onpass="Added counters are correct",
2755 onfail="Added counters are incorrect" )
2756 # DISTRIBUTED SETS
2757 main.step( "Distributed Set get" )
2758 size = len( onosSet )
2759 getResponses = []
2760 threads = []
2761 for i in range( numControllers ):
2762 t = main.Thread( target=CLIs[i].setTestGet,
2763 name="setTestGet-" + str( i ),
2764 args=[ onosSetName ] )
2765 threads.append( t )
2766 t.start()
2767 for t in threads:
2768 t.join()
2769 getResponses.append( t.result )
2770
2771 getResults = main.TRUE
2772 for i in range( numControllers ):
2773 if isinstance( getResponses[ i ], list):
2774 current = set( getResponses[ i ] )
2775 if len( current ) == len( getResponses[ i ] ):
2776 # no repeats
2777 if onosSet != current:
2778 main.log.error( "ONOS" + str( i + 1 ) +
2779 " has incorrect view" +
2780 " of set " + onosSetName + ":\n" +
2781 str( getResponses[ i ] ) )
2782 main.log.debug( "Expected: " + str( onosSet ) )
2783 main.log.debug( "Actual: " + str( current ) )
2784 getResults = main.FALSE
2785 else:
2786 # error, set is not a set
2787 main.log.error( "ONOS" + str( i + 1 ) +
2788 " has repeat elements in" +
2789 " set " + onosSetName + ":\n" +
2790 str( getResponses[ i ] ) )
2791 getResults = main.FALSE
2792 elif getResponses[ i ] == main.ERROR:
2793 getResults = main.FALSE
2794 utilities.assert_equals( expect=main.TRUE,
2795 actual=getResults,
2796 onpass="Set elements are correct",
2797 onfail="Set elements are incorrect" )
2798
2799 main.step( "Distributed Set size" )
2800 sizeResponses = []
2801 threads = []
2802 for i in range( numControllers ):
2803 t = main.Thread( target=CLIs[i].setTestSize,
2804 name="setTestSize-" + str( i ),
2805 args=[ onosSetName ] )
2806 threads.append( t )
2807 t.start()
2808 for t in threads:
2809 t.join()
2810 sizeResponses.append( t.result )
2811
2812 sizeResults = main.TRUE
2813 for i in range( numControllers ):
2814 if size != sizeResponses[ i ]:
2815 sizeResults = main.FALSE
2816 main.log.error( "ONOS" + str( i + 1 ) +
2817 " expected a size of " + str( size ) +
2818 " for set " + onosSetName +
2819 " but got " + str( sizeResponses[ i ] ) )
2820 utilities.assert_equals( expect=main.TRUE,
2821 actual=sizeResults,
2822 onpass="Set sizes are correct",
2823 onfail="Set sizes are incorrect" )
2824
2825 main.step( "Distributed Set add()" )
2826 onosSet.add( addValue )
2827 addResponses = []
2828 threads = []
2829 for i in range( numControllers ):
2830 t = main.Thread( target=CLIs[i].setTestAdd,
2831 name="setTestAdd-" + str( i ),
2832 args=[ onosSetName, addValue ] )
2833 threads.append( t )
2834 t.start()
2835 for t in threads:
2836 t.join()
2837 addResponses.append( t.result )
2838
2839 # main.TRUE = successfully changed the set
2840 # main.FALSE = action resulted in no change in set
2841 # main.ERROR - Some error in executing the function
2842 addResults = main.TRUE
2843 for i in range( numControllers ):
2844 if addResponses[ i ] == main.TRUE:
2845 # All is well
2846 pass
2847 elif addResponses[ i ] == main.FALSE:
2848 # Already in set, probably fine
2849 pass
2850 elif addResponses[ i ] == main.ERROR:
2851 # Error in execution
2852 addResults = main.FALSE
2853 else:
2854 # unexpected result
2855 addResults = main.FALSE
2856 if addResults != main.TRUE:
2857 main.log.error( "Error executing set add" )
2858
2859 # Check if set is still correct
2860 size = len( onosSet )
2861 getResponses = []
2862 threads = []
2863 for i in range( numControllers ):
2864 t = main.Thread( target=CLIs[i].setTestGet,
2865 name="setTestGet-" + str( i ),
2866 args=[ onosSetName ] )
2867 threads.append( t )
2868 t.start()
2869 for t in threads:
2870 t.join()
2871 getResponses.append( t.result )
2872 getResults = main.TRUE
2873 for i in range( numControllers ):
2874 if isinstance( getResponses[ i ], list):
2875 current = set( getResponses[ i ] )
2876 if len( current ) == len( getResponses[ i ] ):
2877 # no repeats
2878 if onosSet != current:
2879 main.log.error( "ONOS" + str( i + 1 ) +
2880 " has incorrect view" +
2881 " of set " + onosSetName + ":\n" +
2882 str( getResponses[ i ] ) )
2883 main.log.debug( "Expected: " + str( onosSet ) )
2884 main.log.debug( "Actual: " + str( current ) )
2885 getResults = main.FALSE
2886 else:
2887 # error, set is not a set
2888 main.log.error( "ONOS" + str( i + 1 ) +
2889 " has repeat elements in" +
2890 " set " + onosSetName + ":\n" +
2891 str( getResponses[ i ] ) )
2892 getResults = main.FALSE
2893 elif getResponses[ i ] == main.ERROR:
2894 getResults = main.FALSE
2895 sizeResponses = []
2896 threads = []
2897 for i in range( numControllers ):
2898 t = main.Thread( target=CLIs[i].setTestSize,
2899 name="setTestSize-" + str( i ),
2900 args=[ onosSetName ] )
2901 threads.append( t )
2902 t.start()
2903 for t in threads:
2904 t.join()
2905 sizeResponses.append( t.result )
2906 sizeResults = main.TRUE
2907 for i in range( numControllers ):
2908 if size != sizeResponses[ i ]:
2909 sizeResults = main.FALSE
2910 main.log.error( "ONOS" + str( i + 1 ) +
2911 " expected a size of " + str( size ) +
2912 " for set " + onosSetName +
2913 " but got " + str( sizeResponses[ i ] ) )
2914 addResults = addResults and getResults and sizeResults
2915 utilities.assert_equals( expect=main.TRUE,
2916 actual=addResults,
2917 onpass="Set add correct",
2918 onfail="Set add was incorrect" )
2919
2920 main.step( "Distributed Set addAll()" )
2921 onosSet.update( addAllValue.split() )
2922 addResponses = []
2923 threads = []
2924 for i in range( numControllers ):
2925 t = main.Thread( target=CLIs[i].setTestAdd,
2926 name="setTestAddAll-" + str( i ),
2927 args=[ onosSetName, addAllValue ] )
2928 threads.append( t )
2929 t.start()
2930 for t in threads:
2931 t.join()
2932 addResponses.append( t.result )
2933
2934 # main.TRUE = successfully changed the set
2935 # main.FALSE = action resulted in no change in set
2936 # main.ERROR - Some error in executing the function
2937 addAllResults = main.TRUE
2938 for i in range( numControllers ):
2939 if addResponses[ i ] == main.TRUE:
2940 # All is well
2941 pass
2942 elif addResponses[ i ] == main.FALSE:
2943 # Already in set, probably fine
2944 pass
2945 elif addResponses[ i ] == main.ERROR:
2946 # Error in execution
2947 addAllResults = main.FALSE
2948 else:
2949 # unexpected result
2950 addAllResults = main.FALSE
2951 if addAllResults != main.TRUE:
2952 main.log.error( "Error executing set addAll" )
2953
2954 # Check if set is still correct
2955 size = len( onosSet )
2956 getResponses = []
2957 threads = []
2958 for i in range( numControllers ):
2959 t = main.Thread( target=CLIs[i].setTestGet,
2960 name="setTestGet-" + str( i ),
2961 args=[ onosSetName ] )
2962 threads.append( t )
2963 t.start()
2964 for t in threads:
2965 t.join()
2966 getResponses.append( t.result )
2967 getResults = main.TRUE
2968 for i in range( numControllers ):
2969 if isinstance( getResponses[ i ], list):
2970 current = set( getResponses[ i ] )
2971 if len( current ) == len( getResponses[ i ] ):
2972 # no repeats
2973 if onosSet != current:
2974 main.log.error( "ONOS" + str( i + 1 ) +
2975 " has incorrect view" +
2976 " of set " + onosSetName + ":\n" +
2977 str( getResponses[ i ] ) )
2978 main.log.debug( "Expected: " + str( onosSet ) )
2979 main.log.debug( "Actual: " + str( current ) )
2980 getResults = main.FALSE
2981 else:
2982 # error, set is not a set
2983 main.log.error( "ONOS" + str( i + 1 ) +
2984 " has repeat elements in" +
2985 " set " + onosSetName + ":\n" +
2986 str( getResponses[ i ] ) )
2987 getResults = main.FALSE
2988 elif getResponses[ i ] == main.ERROR:
2989 getResults = main.FALSE
2990 sizeResponses = []
2991 threads = []
2992 for i in range( numControllers ):
2993 t = main.Thread( target=CLIs[i].setTestSize,
2994 name="setTestSize-" + str( i ),
2995 args=[ onosSetName ] )
2996 threads.append( t )
2997 t.start()
2998 for t in threads:
2999 t.join()
3000 sizeResponses.append( t.result )
3001 sizeResults = main.TRUE
3002 for i in range( numControllers ):
3003 if size != sizeResponses[ i ]:
3004 sizeResults = main.FALSE
3005 main.log.error( "ONOS" + str( i + 1 ) +
3006 " expected a size of " + str( size ) +
3007 " for set " + onosSetName +
3008 " but got " + str( sizeResponses[ i ] ) )
3009 addAllResults = addAllResults and getResults and sizeResults
3010 utilities.assert_equals( expect=main.TRUE,
3011 actual=addAllResults,
3012 onpass="Set addAll correct",
3013 onfail="Set addAll was incorrect" )
3014
3015 main.step( "Distributed Set contains()" )
3016 containsResponses = []
3017 threads = []
3018 for i in range( numControllers ):
3019 t = main.Thread( target=CLIs[i].setTestGet,
3020 name="setContains-" + str( i ),
3021 args=[ onosSetName ],
3022 kwargs={ "values": addValue } )
3023 threads.append( t )
3024 t.start()
3025 for t in threads:
3026 t.join()
3027 # NOTE: This is the tuple
3028 containsResponses.append( t.result )
3029
3030 containsResults = main.TRUE
3031 for i in range( numControllers ):
3032 if containsResponses[ i ] == main.ERROR:
3033 containsResults = main.FALSE
3034 else:
3035 containsResults = containsResults and\
3036 containsResponses[ i ][ 1 ]
3037 utilities.assert_equals( expect=main.TRUE,
3038 actual=containsResults,
3039 onpass="Set contains is functional",
3040 onfail="Set contains failed" )
3041
3042 main.step( "Distributed Set containsAll()" )
3043 containsAllResponses = []
3044 threads = []
3045 for i in range( numControllers ):
3046 t = main.Thread( target=CLIs[i].setTestGet,
3047 name="setContainsAll-" + str( i ),
3048 args=[ onosSetName ],
3049 kwargs={ "values": addAllValue } )
3050 threads.append( t )
3051 t.start()
3052 for t in threads:
3053 t.join()
3054 # NOTE: This is the tuple
3055 containsAllResponses.append( t.result )
3056
3057 containsAllResults = main.TRUE
3058 for i in range( numControllers ):
3059 if containsResponses[ i ] == main.ERROR:
3060 containsResults = main.FALSE
3061 else:
3062 containsResults = containsResults and\
3063 containsResponses[ i ][ 1 ]
3064 utilities.assert_equals( expect=main.TRUE,
3065 actual=containsAllResults,
3066 onpass="Set containsAll is functional",
3067 onfail="Set containsAll failed" )
3068
3069 main.step( "Distributed Set remove()" )
3070 onosSet.remove( addValue )
3071 removeResponses = []
3072 threads = []
3073 for i in range( numControllers ):
3074 t = main.Thread( target=CLIs[i].setTestRemove,
3075 name="setTestRemove-" + str( i ),
3076 args=[ onosSetName, addValue ] )
3077 threads.append( t )
3078 t.start()
3079 for t in threads:
3080 t.join()
3081 removeResponses.append( t.result )
3082
3083 # main.TRUE = successfully changed the set
3084 # main.FALSE = action resulted in no change in set
3085 # main.ERROR - Some error in executing the function
3086 removeResults = main.TRUE
3087 for i in range( numControllers ):
3088 if removeResponses[ i ] == main.TRUE:
3089 # All is well
3090 pass
3091 elif removeResponses[ i ] == main.FALSE:
3092 # not in set, probably fine
3093 pass
3094 elif removeResponses[ i ] == main.ERROR:
3095 # Error in execution
3096 removeResults = main.FALSE
3097 else:
3098 # unexpected result
3099 removeResults = main.FALSE
3100 if removeResults != main.TRUE:
3101 main.log.error( "Error executing set remove" )
3102
3103 # Check if set is still correct
3104 size = len( onosSet )
3105 getResponses = []
3106 threads = []
3107 for i in range( numControllers ):
3108 t = main.Thread( target=CLIs[i].setTestGet,
3109 name="setTestGet-" + str( i ),
3110 args=[ onosSetName ] )
3111 threads.append( t )
3112 t.start()
3113 for t in threads:
3114 t.join()
3115 getResponses.append( t.result )
3116 getResults = main.TRUE
3117 for i in range( numControllers ):
3118 if isinstance( getResponses[ i ], list):
3119 current = set( getResponses[ i ] )
3120 if len( current ) == len( getResponses[ i ] ):
3121 # no repeats
3122 if onosSet != current:
3123 main.log.error( "ONOS" + str( i + 1 ) +
3124 " has incorrect view" +
3125 " of set " + onosSetName + ":\n" +
3126 str( getResponses[ i ] ) )
3127 main.log.debug( "Expected: " + str( onosSet ) )
3128 main.log.debug( "Actual: " + str( current ) )
3129 getResults = main.FALSE
3130 else:
3131 # error, set is not a set
3132 main.log.error( "ONOS" + str( i + 1 ) +
3133 " has repeat elements in" +
3134 " set " + onosSetName + ":\n" +
3135 str( getResponses[ i ] ) )
3136 getResults = main.FALSE
3137 elif getResponses[ i ] == main.ERROR:
3138 getResults = main.FALSE
3139 sizeResponses = []
3140 threads = []
3141 for i in range( numControllers ):
3142 t = main.Thread( target=CLIs[i].setTestSize,
3143 name="setTestSize-" + str( i ),
3144 args=[ onosSetName ] )
3145 threads.append( t )
3146 t.start()
3147 for t in threads:
3148 t.join()
3149 sizeResponses.append( t.result )
3150 sizeResults = main.TRUE
3151 for i in range( numControllers ):
3152 if size != sizeResponses[ i ]:
3153 sizeResults = main.FALSE
3154 main.log.error( "ONOS" + str( i + 1 ) +
3155 " expected a size of " + str( size ) +
3156 " for set " + onosSetName +
3157 " but got " + str( sizeResponses[ i ] ) )
3158 removeResults = removeResults and getResults and sizeResults
3159 utilities.assert_equals( expect=main.TRUE,
3160 actual=removeResults,
3161 onpass="Set remove correct",
3162 onfail="Set remove was incorrect" )
3163
3164 main.step( "Distributed Set removeAll()" )
3165 onosSet.difference_update( addAllValue.split() )
3166 removeAllResponses = []
3167 threads = []
3168 try:
3169 for i in range( numControllers ):
3170 t = main.Thread( target=CLIs[i].setTestRemove,
3171 name="setTestRemoveAll-" + str( i ),
3172 args=[ onosSetName, addAllValue ] )
3173 threads.append( t )
3174 t.start()
3175 for t in threads:
3176 t.join()
3177 removeAllResponses.append( t.result )
3178 except Exception, e:
3179 main.log.exception(e)
3180
3181 # main.TRUE = successfully changed the set
3182 # main.FALSE = action resulted in no change in set
3183 # main.ERROR - Some error in executing the function
3184 removeAllResults = main.TRUE
3185 for i in range( numControllers ):
3186 if removeAllResponses[ i ] == main.TRUE:
3187 # All is well
3188 pass
3189 elif removeAllResponses[ i ] == main.FALSE:
3190 # not in set, probably fine
3191 pass
3192 elif removeAllResponses[ i ] == main.ERROR:
3193 # Error in execution
3194 removeAllResults = main.FALSE
3195 else:
3196 # unexpected result
3197 removeAllResults = main.FALSE
3198 if removeAllResults != main.TRUE:
3199 main.log.error( "Error executing set removeAll" )
3200
3201 # Check if set is still correct
3202 size = len( onosSet )
3203 getResponses = []
3204 threads = []
3205 for i in range( numControllers ):
3206 t = main.Thread( target=CLIs[i].setTestGet,
3207 name="setTestGet-" + str( i ),
3208 args=[ onosSetName ] )
3209 threads.append( t )
3210 t.start()
3211 for t in threads:
3212 t.join()
3213 getResponses.append( t.result )
3214 getResults = main.TRUE
3215 for i in range( numControllers ):
3216 if isinstance( getResponses[ i ], list):
3217 current = set( getResponses[ i ] )
3218 if len( current ) == len( getResponses[ i ] ):
3219 # no repeats
3220 if onosSet != current:
3221 main.log.error( "ONOS" + str( i + 1 ) +
3222 " has incorrect view" +
3223 " of set " + onosSetName + ":\n" +
3224 str( getResponses[ i ] ) )
3225 main.log.debug( "Expected: " + str( onosSet ) )
3226 main.log.debug( "Actual: " + str( current ) )
3227 getResults = main.FALSE
3228 else:
3229 # error, set is not a set
3230 main.log.error( "ONOS" + str( i + 1 ) +
3231 " has repeat elements in" +
3232 " set " + onosSetName + ":\n" +
3233 str( getResponses[ i ] ) )
3234 getResults = main.FALSE
3235 elif getResponses[ i ] == main.ERROR:
3236 getResults = main.FALSE
3237 sizeResponses = []
3238 threads = []
3239 for i in range( numControllers ):
3240 t = main.Thread( target=CLIs[i].setTestSize,
3241 name="setTestSize-" + str( i ),
3242 args=[ onosSetName ] )
3243 threads.append( t )
3244 t.start()
3245 for t in threads:
3246 t.join()
3247 sizeResponses.append( t.result )
3248 sizeResults = main.TRUE
3249 for i in range( numControllers ):
3250 if size != sizeResponses[ i ]:
3251 sizeResults = main.FALSE
3252 main.log.error( "ONOS" + str( i + 1 ) +
3253 " expected a size of " + str( size ) +
3254 " for set " + onosSetName +
3255 " but got " + str( sizeResponses[ i ] ) )
3256 removeAllResults = removeAllResults and getResults and sizeResults
3257 utilities.assert_equals( expect=main.TRUE,
3258 actual=removeAllResults,
3259 onpass="Set removeAll correct",
3260 onfail="Set removeAll was incorrect" )
3261
3262 main.step( "Distributed Set addAll()" )
3263 onosSet.update( addAllValue.split() )
3264 addResponses = []
3265 threads = []
3266 for i in range( numControllers ):
3267 t = main.Thread( target=CLIs[i].setTestAdd,
3268 name="setTestAddAll-" + str( i ),
3269 args=[ onosSetName, addAllValue ] )
3270 threads.append( t )
3271 t.start()
3272 for t in threads:
3273 t.join()
3274 addResponses.append( t.result )
3275
3276 # main.TRUE = successfully changed the set
3277 # main.FALSE = action resulted in no change in set
3278 # main.ERROR - Some error in executing the function
3279 addAllResults = main.TRUE
3280 for i in range( numControllers ):
3281 if addResponses[ i ] == main.TRUE:
3282 # All is well
3283 pass
3284 elif addResponses[ i ] == main.FALSE:
3285 # Already in set, probably fine
3286 pass
3287 elif addResponses[ i ] == main.ERROR:
3288 # Error in execution
3289 addAllResults = main.FALSE
3290 else:
3291 # unexpected result
3292 addAllResults = main.FALSE
3293 if addAllResults != main.TRUE:
3294 main.log.error( "Error executing set addAll" )
3295
3296 # Check if set is still correct
3297 size = len( onosSet )
3298 getResponses = []
3299 threads = []
3300 for i in range( numControllers ):
3301 t = main.Thread( target=CLIs[i].setTestGet,
3302 name="setTestGet-" + str( i ),
3303 args=[ onosSetName ] )
3304 threads.append( t )
3305 t.start()
3306 for t in threads:
3307 t.join()
3308 getResponses.append( t.result )
3309 getResults = main.TRUE
3310 for i in range( numControllers ):
3311 if isinstance( getResponses[ i ], list):
3312 current = set( getResponses[ i ] )
3313 if len( current ) == len( getResponses[ i ] ):
3314 # no repeats
3315 if onosSet != current:
3316 main.log.error( "ONOS" + str( i + 1 ) +
3317 " has incorrect view" +
3318 " of set " + onosSetName + ":\n" +
3319 str( getResponses[ i ] ) )
3320 main.log.debug( "Expected: " + str( onosSet ) )
3321 main.log.debug( "Actual: " + str( current ) )
3322 getResults = main.FALSE
3323 else:
3324 # error, set is not a set
3325 main.log.error( "ONOS" + str( i + 1 ) +
3326 " has repeat elements in" +
3327 " set " + onosSetName + ":\n" +
3328 str( getResponses[ i ] ) )
3329 getResults = main.FALSE
3330 elif getResponses[ i ] == main.ERROR:
3331 getResults = main.FALSE
3332 sizeResponses = []
3333 threads = []
3334 for i in range( numControllers ):
3335 t = main.Thread( target=CLIs[i].setTestSize,
3336 name="setTestSize-" + str( i ),
3337 args=[ onosSetName ] )
3338 threads.append( t )
3339 t.start()
3340 for t in threads:
3341 t.join()
3342 sizeResponses.append( t.result )
3343 sizeResults = main.TRUE
3344 for i in range( numControllers ):
3345 if size != sizeResponses[ i ]:
3346 sizeResults = main.FALSE
3347 main.log.error( "ONOS" + str( i + 1 ) +
3348 " expected a size of " + str( size ) +
3349 " for set " + onosSetName +
3350 " but got " + str( sizeResponses[ i ] ) )
3351 addAllResults = addAllResults and getResults and sizeResults
3352 utilities.assert_equals( expect=main.TRUE,
3353 actual=addAllResults,
3354 onpass="Set addAll correct",
3355 onfail="Set addAll was incorrect" )
3356
3357 main.step( "Distributed Set clear()" )
3358 onosSet.clear()
3359 clearResponses = []
3360 threads = []
3361 for i in range( numControllers ):
3362 t = main.Thread( target=CLIs[i].setTestRemove,
3363 name="setTestClear-" + str( i ),
3364 args=[ onosSetName, " "], # Values doesn't matter
3365 kwargs={ "clear": True } )
3366 threads.append( t )
3367 t.start()
3368 for t in threads:
3369 t.join()
3370 clearResponses.append( t.result )
3371
3372 # main.TRUE = successfully changed the set
3373 # main.FALSE = action resulted in no change in set
3374 # main.ERROR - Some error in executing the function
3375 clearResults = main.TRUE
3376 for i in range( numControllers ):
3377 if clearResponses[ i ] == main.TRUE:
3378 # All is well
3379 pass
3380 elif clearResponses[ i ] == main.FALSE:
3381 # Nothing set, probably fine
3382 pass
3383 elif clearResponses[ i ] == main.ERROR:
3384 # Error in execution
3385 clearResults = main.FALSE
3386 else:
3387 # unexpected result
3388 clearResults = main.FALSE
3389 if clearResults != main.TRUE:
3390 main.log.error( "Error executing set clear" )
3391
3392 # Check if set is still correct
3393 size = len( onosSet )
3394 getResponses = []
3395 threads = []
3396 for i in range( numControllers ):
3397 t = main.Thread( target=CLIs[i].setTestGet,
3398 name="setTestGet-" + str( i ),
3399 args=[ onosSetName ] )
3400 threads.append( t )
3401 t.start()
3402 for t in threads:
3403 t.join()
3404 getResponses.append( t.result )
3405 getResults = main.TRUE
3406 for i in range( numControllers ):
3407 if isinstance( getResponses[ i ], list):
3408 current = set( getResponses[ i ] )
3409 if len( current ) == len( getResponses[ i ] ):
3410 # no repeats
3411 if onosSet != current:
3412 main.log.error( "ONOS" + str( i + 1 ) +
3413 " has incorrect view" +
3414 " of set " + onosSetName + ":\n" +
3415 str( getResponses[ i ] ) )
3416 main.log.debug( "Expected: " + str( onosSet ) )
3417 main.log.debug( "Actual: " + str( current ) )
3418 getResults = main.FALSE
3419 else:
3420 # error, set is not a set
3421 main.log.error( "ONOS" + str( i + 1 ) +
3422 " has repeat elements in" +
3423 " set " + onosSetName + ":\n" +
3424 str( getResponses[ i ] ) )
3425 getResults = main.FALSE
3426 elif getResponses[ i ] == main.ERROR:
3427 getResults = main.FALSE
3428 sizeResponses = []
3429 threads = []
3430 for i in range( numControllers ):
3431 t = main.Thread( target=CLIs[i].setTestSize,
3432 name="setTestSize-" + str( i ),
3433 args=[ onosSetName ] )
3434 threads.append( t )
3435 t.start()
3436 for t in threads:
3437 t.join()
3438 sizeResponses.append( t.result )
3439 sizeResults = main.TRUE
3440 for i in range( numControllers ):
3441 if size != sizeResponses[ i ]:
3442 sizeResults = main.FALSE
3443 main.log.error( "ONOS" + str( i + 1 ) +
3444 " expected a size of " + str( size ) +
3445 " for set " + onosSetName +
3446 " but got " + str( sizeResponses[ i ] ) )
3447 clearResults = clearResults and getResults and sizeResults
3448 utilities.assert_equals( expect=main.TRUE,
3449 actual=clearResults,
3450 onpass="Set clear correct",
3451 onfail="Set clear was incorrect" )
3452
3453 main.step( "Distributed Set addAll()" )
3454 onosSet.update( addAllValue.split() )
3455 addResponses = []
3456 threads = []
3457 for i in range( numControllers ):
3458 t = main.Thread( target=CLIs[i].setTestAdd,
3459 name="setTestAddAll-" + str( i ),
3460 args=[ onosSetName, addAllValue ] )
3461 threads.append( t )
3462 t.start()
3463 for t in threads:
3464 t.join()
3465 addResponses.append( t.result )
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 addAllResults = main.TRUE
3471 for i in range( numControllers ):
3472 if addResponses[ i ] == main.TRUE:
3473 # All is well
3474 pass
3475 elif addResponses[ i ] == main.FALSE:
3476 # Already in set, probably fine
3477 pass
3478 elif addResponses[ i ] == main.ERROR:
3479 # Error in execution
3480 addAllResults = main.FALSE
3481 else:
3482 # unexpected result
3483 addAllResults = main.FALSE
3484 if addAllResults != main.TRUE:
3485 main.log.error( "Error executing set addAll" )
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 addAllResults = addAllResults and getResults and sizeResults
3543 utilities.assert_equals( expect=main.TRUE,
3544 actual=addAllResults,
3545 onpass="Set addAll correct",
3546 onfail="Set addAll was incorrect" )
3547
3548 main.step( "Distributed Set retain()" )
3549 onosSet.intersection_update( retainValue.split() )
3550 retainResponses = []
3551 threads = []
3552 for i in range( numControllers ):
3553 t = main.Thread( target=CLIs[i].setTestRemove,
3554 name="setTestRetain-" + str( i ),
3555 args=[ onosSetName, retainValue ],
3556 kwargs={ "retain": True } )
3557 threads.append( t )
3558 t.start()
3559 for t in threads:
3560 t.join()
3561 retainResponses.append( t.result )
3562
3563 # main.TRUE = successfully changed the set
3564 # main.FALSE = action resulted in no change in set
3565 # main.ERROR - Some error in executing the function
3566 retainResults = main.TRUE
3567 for i in range( numControllers ):
3568 if retainResponses[ i ] == main.TRUE:
3569 # All is well
3570 pass
3571 elif retainResponses[ i ] == main.FALSE:
3572 # Already in set, probably fine
3573 pass
3574 elif retainResponses[ i ] == main.ERROR:
3575 # Error in execution
3576 retainResults = main.FALSE
3577 else:
3578 # unexpected result
3579 retainResults = main.FALSE
3580 if retainResults != main.TRUE:
3581 main.log.error( "Error executing set retain" )
3582
3583 # Check if set is still correct
3584 size = len( onosSet )
3585 getResponses = []
3586 threads = []
3587 for i in range( numControllers ):
3588 t = main.Thread( target=CLIs[i].setTestGet,
3589 name="setTestGet-" + str( i ),
3590 args=[ onosSetName ] )
3591 threads.append( t )
3592 t.start()
3593 for t in threads:
3594 t.join()
3595 getResponses.append( t.result )
3596 getResults = main.TRUE
3597 for i in range( numControllers ):
3598 if isinstance( getResponses[ i ], list):
3599 current = set( getResponses[ i ] )
3600 if len( current ) == len( getResponses[ i ] ):
3601 # no repeats
3602 if onosSet != current:
3603 main.log.error( "ONOS" + str( i + 1 ) +
3604 " has incorrect view" +
3605 " of set " + onosSetName + ":\n" +
3606 str( getResponses[ i ] ) )
3607 main.log.debug( "Expected: " + str( onosSet ) )
3608 main.log.debug( "Actual: " + str( current ) )
3609 getResults = main.FALSE
3610 else:
3611 # error, set is not a set
3612 main.log.error( "ONOS" + str( i + 1 ) +
3613 " has repeat elements in" +
3614 " set " + onosSetName + ":\n" +
3615 str( getResponses[ i ] ) )
3616 getResults = main.FALSE
3617 elif getResponses[ i ] == main.ERROR:
3618 getResults = main.FALSE
3619 sizeResponses = []
3620 threads = []
3621 for i in range( numControllers ):
3622 t = main.Thread( target=CLIs[i].setTestSize,
3623 name="setTestSize-" + str( i ),
3624 args=[ onosSetName ] )
3625 threads.append( t )
3626 t.start()
3627 for t in threads:
3628 t.join()
3629 sizeResponses.append( t.result )
3630 sizeResults = main.TRUE
3631 for i in range( numControllers ):
3632 if size != sizeResponses[ i ]:
3633 sizeResults = main.FALSE
3634 main.log.error( "ONOS" + str( i + 1 ) +
3635 " expected a size of " +
3636 str( size ) + " for set " + onosSetName +
3637 " but got " + str( sizeResponses[ i ] ) )
3638 retainResults = retainResults and getResults and sizeResults
3639 utilities.assert_equals( expect=main.TRUE,
3640 actual=retainResults,
3641 onpass="Set retain correct",
3642 onfail="Set retain was incorrect" )
3643